r3176 - in trunk/libminisip: . include include/libminisip/sip
source/sip
mikma at minisip.org
mikma at minisip.org
Thu Feb 1 15:08:34 CET 2007
Author: mikma
Date: 2007-02-01 15:08:33 +0100 (Thu, 01 Feb 2007)
New Revision: 3176
Removed:
trunk/libminisip/include/libminisip/sip/SipDialogVoipServer100rel.h
trunk/libminisip/source/sip/SipDialogVoipServer100rel.cxx
Modified:
trunk/libminisip/Makefile.am
trunk/libminisip/include/Makefile.am
trunk/libminisip/include/libminisip/sip/SipDialogVoipServer.h
trunk/libminisip/source/sip/DefaultDialogHandler.cxx
trunk/libminisip/source/sip/SipDialogVoipClient.cxx
trunk/libminisip/source/sip/SipDialogVoipServer.cxx
Log:
Integrate support for reliable provisional responses into
SipDialogVoipServer. Sending both 183 Session Progress, and 180 Ringing
reliable, if 100rel is enabled in SipStackConfig and it's supported or
required by the INVITE.
Modified: trunk/libminisip/Makefile.am
===================================================================
--- trunk/libminisip/Makefile.am 2007-02-01 10:31:30 UTC (rev 3175)
+++ trunk/libminisip/Makefile.am 2007-02-01 14:08:33 UTC (rev 3176)
@@ -144,7 +144,6 @@
libsip_src = source/sip/SipDialogVoip.cxx \
source/sip/SipDialogVoipClient.cxx \
source/sip/SipDialogVoipServer.cxx \
- source/sip/SipDialogVoipServer100rel.cxx \
source/sip/SipDialogConfVoip.cxx \
source/sip/SipDialogPresenceClient.cxx \
source/sip/SipDialogPresenceServer.cxx \
Modified: trunk/libminisip/include/Makefile.am
===================================================================
--- trunk/libminisip/include/Makefile.am 2007-02-01 10:31:30 UTC (rev 3175)
+++ trunk/libminisip/include/Makefile.am 2007-02-01 14:08:33 UTC (rev 3176)
@@ -69,7 +69,6 @@
libminisip/sip/Sip.h \
libminisip/sip/SipDialogPresenceClient.h \
libminisip/sip/SipDialogVoipServer.h \
- libminisip/sip/SipDialogVoipServer100rel.h \
libminisip/sip/DefaultDialogHandler.h \
libminisip/sip/PresenceMessageContent.h \
libminisip/sip/SipDialogVoipClient.h \
Modified: trunk/libminisip/include/libminisip/sip/SipDialogVoipServer.h
===================================================================
--- trunk/libminisip/include/libminisip/sip/SipDialogVoipServer.h 2007-02-01 10:31:30 UTC (rev 3175)
+++ trunk/libminisip/include/libminisip/sip/SipDialogVoipServer.h 2007-02-01 14:08:33 UTC (rev 3176)
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004-2006 the Minisip Team
+ Copyright (C) 2004-2007 the Minisip Team
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,11 +16,12 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-/* Copyright (C) 2004
+/* Copyright (C) 2004-2007
*
* Authors: Erik Eliasson <eliasson at it.kth.se>
* Johan Bilien <jobi at via.ecp.fr>
* Joachim Orrblad <joachim at orrblad.com>
+ * Mikael Magnusson <mikma at users.sourceforge.net>
*/
/* Name
@@ -28,7 +29,13 @@
* Author
* Erik Eliasson, eliasson at it.kth.se
* Purpose
- *
+ * If a 100rel Voip server is used, it will send a
+ * 183 session progress reliably before the 180
+ * ringing is transmitted. This is so that authentication
+ * is done before the phone starts ringing. We must
+ * have mutual authentication before the phone starts
+ * ringing to avoid ghost ringing when Alice policy
+ * does not accept Bob's information.
*/
#ifndef SipDialogVoipServer_H
@@ -60,7 +67,9 @@
virtual std::string getName(){return "SipDialogVoipServer[callid="+dialogState.callId +"]";}
protected:
- void sendRinging(const std::string &branch, bool use100Rel);
+ void sendRinging();
+ bool isMatchingPrack( MRef<SipMessage*> provisional,
+ MRef<SipRequest*> prack );
private:
@@ -69,6 +78,8 @@
void sendInviteOk(const std::string &branch);
void sendReject(const std::string &branch);
void sendNotAcceptable(const std::string &branch);
+ void sendSessionProgress();
+ void sendPrackOk( MRef<SipRequest*> prack );
bool a3001_start_ringing_INVITE( const SipSMCommand &command);
bool a3002_ringing_incall_accept( const SipSMCommand &command);
@@ -76,6 +87,14 @@
bool a3004_ringing_termwait_CANCEL( const SipSMCommand &command);
bool a3005_ringing_termwait_reject( const SipSMCommand &command);
bool a3006_start_termwait_INVITE( const SipSMCommand &command);
+ bool a3007_start_100rel_INVITE( const SipSMCommand &command);
+ bool a3008_100rel_ringing_PRACK( const SipSMCommand &command);
+ bool a3009_any_any_ResendTimer1xx( const SipSMCommand &command);
+ bool a3010_any_any_PRACK( const SipSMCommand &command);
+
+ bool use100Rel;
+ int resendTimer1xx;
+ MRef<SipMessage*> lastProvisional;
};
#endif
Deleted: trunk/libminisip/include/libminisip/sip/SipDialogVoipServer100rel.h
===================================================================
--- trunk/libminisip/include/libminisip/sip/SipDialogVoipServer100rel.h 2007-02-01 10:31:30 UTC (rev 3175)
+++ trunk/libminisip/include/libminisip/sip/SipDialogVoipServer100rel.h 2007-02-01 14:08:33 UTC (rev 3176)
@@ -1,81 +0,0 @@
-/*
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* Copyright (C) 2006
- *
- * Authors: Erik Eliasson <eliasson at it.kth.se>
-*/
-
-/* Name
- * SipDialogVoipServer100rel.h
- * Author
- * Erik Eliasson, eliasson at it.kth.se
- * Purpose
- * If a 100rel Voip server is used, it will send a
- * 183 session progress reliably before the 180
- * ringing is transmitted. This is so that authentication
- * is done before the phone starts ringing. We must
- * have mutual authentication before the phone starts
- * ringing to avoid ghost ringing when Alice policy
- * does not accept Bob's information.
-*/
-
-
-
-#ifndef SipDialogVoipServer100rel_H
-#define SipDialogVoipServer100rel_H
-
-
-#include<config.h>
-
-
-#include<libmsip/SipDialog.h>
-#include<libmsip/SipResponse.h>
-#include<libmutil/StateMachine.h>
-
-#include<libminisip/sip/SipSoftPhoneConfiguration.h>
-#include<libminisip/sip/SipDialogVoipServer.h>
-
-class Session;
-class SipDialogContainer;
-class SipDialogConfig;
-class LogEntry;
-
-class SipDialogVoipServer100rel: public SipDialogVoipServer{
- public:
- SipDialogVoipServer100rel(MRef<SipStack*> stack, MRef<SipIdentity*> ident, MRef<SipSoftPhoneConfiguration*> phoneconf, MRef<Session *> mediaSession, std::string callId="");
-
- virtual ~SipDialogVoipServer100rel();
-
- virtual std::string getMemObjectType() const {return "SipDialogVoipServer100rel";}
-
- virtual std::string getName(){return "SipDialogVoipServer100rel[callid="+dialogState.callId +"]";}
-
- private:
- int _1xxResendTimer;
- MRef<SipMessage*> lastProgress;
-
- void setUpStateMachine();
- void sendSessionProgress(const std::string &branch);
- void resendSessionProgress();
- void sendPrackOk(const std::string &branch, MRef<SipMessage*> prack);
-
- bool a4001_start_100rel_100relINVITE( const SipSMCommand &command);
- bool a4002_100rel_ringing_PRACK( const SipSMCommand &command);
- bool a4003_100rel_100rel_1xxResendTimer( const SipSMCommand &command);
-};
-
-#endif
Modified: trunk/libminisip/source/sip/DefaultDialogHandler.cxx
===================================================================
--- trunk/libminisip/source/sip/DefaultDialogHandler.cxx 2007-02-01 10:31:30 UTC (rev 3175)
+++ trunk/libminisip/source/sip/DefaultDialogHandler.cxx 2007-02-01 14:08:33 UTC (rev 3176)
@@ -41,7 +41,6 @@
#include<libminisip/sip/SipDialogVoipClient.h>
#include<libminisip/sip/SipDialogVoipServer.h>
-#include<libminisip/sip/SipDialogVoipServer100rel.h>
#include<libminisip/sip/SipDialogConfVoip.h>
#include<libminisip/sip/SipDialogPresenceClient.h>
#include<libminisip/sip/SipDialogPresenceServer.h>
@@ -240,19 +239,11 @@
}
*/
MRef<SipDialog*> voipCall;
-// if (pkt->supported("100rel")){
-// voipCall = new SipDialogVoipServer100rel(sipStack,
-// callConf,
-// phoneconf,
-// mediaSession,
-// pkt->getCallId());
-// }else{
voipCall = new SipDialogVoipServer(sipStack,
id,
phoneconf,
mediaSession,
pkt->getCallId());
-// }
sipStack->addDialog(voipCall);
Modified: trunk/libminisip/source/sip/SipDialogVoipClient.cxx
===================================================================
--- trunk/libminisip/source/sip/SipDialogVoipClient.cxx 2007-02-01 10:31:30 UTC (rev 3175)
+++ trunk/libminisip/source/sip/SipDialogVoipClient.cxx 2007-02-01 14:08:33 UTC (rev 3176)
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004-2006 the Minisip Team
+ Copyright (C) 2004-2007 the Minisip Team
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,7 +16,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-/* Copyright (C) 2004,2005,2006
+/* Copyright (C) 2004-2007
*
* Authors: Erik Eliasson <eliasson at it.kth.se>
* Johan Bilien <jobi at via.ecp.fr>
@@ -160,29 +160,47 @@
#ifdef ENABLE_TS
ts.save( RINGING );
#endif
+ bool doPrack = false;
if (resp->requires("100rel") && resp->getStatusCode()!=100){
- if( !handleRel1xx( resp ) )
+ if( !handleRel1xx( resp ) ){
// Ignore retransmission
+// cerr << "Ignore 18x retransmission" << endl;
return true;
+ }
+ doPrack = true;
}
else{
//We must maintain the dialog state.
dialogState.updateState( resp );
}
-
- CommandString cmdstr(dialogState.callId, SipCommandString::remote_ringing);
- getSipStack()->getCallback()->handleCommand("gui", cmdstr);
-
+
//string peerUri = command.getCommandPacket()->getTo().getString();
string peerUri = dialogState.remoteUri; //use the dialog state ...
-
MRef<SipMessageContent *> content = resp->getContent();
if( !content.isNull() ){
MRef<SdpPacket*> sdp((SdpPacket*)*content);
//Early media
- getMediaSession()->setSdpAnswer( sdp, peerUri );
+ if( !sortMIME( content , peerUri, 3) ){
+ // MIKEY failed
+ // TODO reason header
+ sendCancel("");
+
+ getMediaSession()->stop();
+ signalIfNoTransactions();
+ // Skip prack
+// cerr << "Send cancel, skip prack" << endl;
+ return true;
+ }
}
+ if( doPrack )
+ sendPrack(resp);
+
+ if( resp->getStatusCode() == 180 ){
+ CommandString cmdstr(dialogState.callId, SipCommandString::remote_ringing, peerUri, (getMediaSession()->isSecure()?"secure":"unprotected"));
+ getSipStack()->getCallback()->handleCommand("gui", cmdstr);
+ }
+
return true;
}else{
return false;
@@ -198,9 +216,13 @@
MRef<SipResponse*> resp = (SipResponse*)*command.getCommandPacket();
if (resp->requires("100rel") && resp->getStatusCode()!=100){
- if( !handleRel1xx( resp ) )
+ if( !handleRel1xx( resp ) ){
// Ignore retransmission
+// cerr << "Ignore 1xx retransmission" << endl;
return true;
+ }
+
+ sendPrack(resp);
}
return true;
@@ -641,13 +663,12 @@
// First reliable provisional response
// Next in-order reliable provisional response
if( !(dialogState.rseqNo == (uint32_t)-1 ||
- dialogState.rseqNo > rseqNo ) )
+ rseqNo > dialogState.rseqNo ) )
return false;
dialogState.updateState( resp );
dialogState.seqNo++;
dialogState.rseqNo = rseqNo;
- sendPrack(resp);
return true;
}
Modified: trunk/libminisip/source/sip/SipDialogVoipServer.cxx
===================================================================
--- trunk/libminisip/source/sip/SipDialogVoipServer.cxx 2007-02-01 10:31:30 UTC (rev 3175)
+++ trunk/libminisip/source/sip/SipDialogVoipServer.cxx 2007-02-01 14:08:33 UTC (rev 3176)
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004-2006 the Minisip Team
+ Copyright (C) 2004-2007 the Minisip Team
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,11 +16,12 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-/* Copyright (C) 2004
+/* Copyright (C) 2004-2007
*
* Authors: Erik Eliasson <eliasson at it.kth.se>
* Johan Bilien <jobi at via.ecp.fr>
* Joachim Orrblad <joachim[at]orrblad.com>
+ * Mikael Magnusson <mikma at users.sourceforge.net>
*/
/* Name
@@ -41,8 +42,10 @@
#include<libmsip/SipHeaderWarning.h>
#include<libmsip/SipHeaderContact.h>
#include<libmsip/SipHeaderFrom.h>
+#include<libmsip/SipHeaderRAck.h>
#include<libmsip/SipHeaderRoute.h>
#include<libmsip/SipHeaderRequire.h>
+#include<libmsip/SipHeaderRSeq.h>
#include<libmsip/SipHeaderTo.h>
#include<libmsip/SipMessageContentMime.h>
#include<libmsip/SipMessageContent.h>
@@ -78,19 +81,29 @@
The "dotted" states are implemented in SipDialogVoip.cxx.
-
- +---------------+
- | |
- | start |
- | |
- +---------------+
- |
- | INVITE
- | a3001:transIR; send 180
- V
- +---------------+
- | |
- | ringing |----------+ reject
+ INVITE & !100rel
+ a3001:transIR; +---------------+
+ send 180 | |
+ +----------| start |
+ | | |
+ | +---------------+
+ | |
+ | | INVITE && supports 100rel
+ | | a3007:transIR; send 183
+ | |
+ | V
+ | +---------------+
+ | | |
+ | | 100rel |----------+
+ | | | |
+ | +---------------+ |
+ | | PRACK & 100rel |
+ | | a3008: send 200 |
+ | | send 180 |
+ | V |
+ | +---------------+ |
+ | | | |
+ +--------->| ringing |----------+ reject
| | | a3005:send40X
+---------------+ |
| | CANCEL
@@ -119,16 +132,65 @@
. terminated .
. .
+ . . . . . . . +
+
+
+ +---------------+
+ +---->| |<----+ ResendTimer1xx
+ | | ANY | | a3009: resend 1XX
+ +-----| |-----+
+ PRACK & 100rel +---------------+
+ a3010: send 200 &
+ cancel timer
*/
+bool SipDialogVoipServer::a3007_start_100rel_INVITE( const SipSMCommand &command){
+ if( !transitionMatch("INVITE",
+ command,
+ SipSMCommand::transaction_layer,
+ SipSMCommand::dialog_layer) ||
+ !getSipStack()->getStackConfig()->use100Rel ){
+ return false;
+ }
+
+ MRef<SipRequest*> inv = (SipRequest *)*command.getCommandPacket();
+ if( !inv->supported("100rel") && !inv->requires("100rel") ){
+ return false;
+ }
+
+ use100Rel = true;
+ resendTimer1xx=getSipStack()->getTimers()->getA();
+ requestTimeout(resendTimer1xx,"ResendTimer1xx");
+ dialogState.rseqNo = rand() % (1<<31);
+
+ setLastInvite(inv);
+ dialogState.updateState( getLastInvite() );
+
+ string peerUri = dialogState.remoteUri;
+
+ getDialogConfig()->sipIdentity->setSipUri(command.getCommandPacket()->getHeaderValueTo()->getUri().getUserIpString());
+
+ if(!sortMIME(*command.getCommandPacket()->getContent(), peerUri, 10)){
+ merr << "No MIME match" << end;
+ return false;
+ }
+
+ sendSessionProgress();
+
+ return true;
+}
+
bool SipDialogVoipServer::a3001_start_ringing_INVITE( const SipSMCommand &command)
{
if (transitionMatch("INVITE", command, SipSMCommand::transaction_layer, SipSMCommand::dialog_layer)){
MRef<SipRequest*> inv = (SipRequest *)*command.getCommandPacket();
- string branch = inv->getDestinationBranch();
+ if( inv->requires("100rel") ){
+ // TODO reject unsupported extension
+ return false;
+ }
+
setLastInvite(inv);
dialogState.updateState( inv );
@@ -180,10 +242,8 @@
);
getSipStack()->getCallback()->handleCommand("gui", cmdstr );
- bool rel100Supported = inv->supported("100rel");
+ sendRinging();
- sendRinging(branch, rel100Supported && getSipStack()->getStackConfig()->use100Rel );
-
if( getSipStack()->getStackConfig()->autoAnswer ){
CommandString accept( dialogState.callId, SipCommandString::accept_invite );
SipSMCommand sipcmd(accept, SipSMCommand::dialog_layer, SipSMCommand::dialog_layer);
@@ -349,18 +409,148 @@
}
}
+bool SipDialogVoipServer::isMatchingPrack( MRef<SipMessage*> provisional,
+ MRef<SipRequest*> prack ){
+ MRef<SipHeaderValue *> value = prack->getHeaderValueNo( SIP_HEADER_TYPE_RACK, 0 );
+ if( !value ){
+ // TODO reject 481
+ cerr << "No RAck" << endl;
+ return false;
+ }
+
+ MRef<SipHeaderValueRAck *> rack = dynamic_cast<SipHeaderValueRAck*>(*value);
+ if( !rack ){
+ // TODO reject 481
+ cerr << "Bad RAck" << endl;
+ return false;
+ }
+
+ if( rack->getMethod() != provisional->getCSeqMethod() ||
+ rack->getCSeqNum() != provisional->getCSeq() ||
+ rack->getResponseNum() != dialogState.rseqNo ){
+ // TODO reject 481
+ cerr << "Non matching RAck" << endl;
+ return false;
+ }
+
+ return true;
+}
+
+bool SipDialogVoipServer::a3008_100rel_ringing_PRACK( const SipSMCommand &command){
+ if( use100Rel &&
+ lastProvisional &&
+ !transitionMatch("PRACK",
+ command,
+ SipSMCommand::transaction_layer,
+ SipSMCommand::dialog_layer) ){
+ return false;
+ }
+
+ MRef<SipRequest*> prack =
+ dynamic_cast<SipRequest *>(*command.getCommandPacket());
+ dialogState.updateState( prack );
+
+ if( !isMatchingPrack( lastProvisional, prack ) ){
+ return false;
+ }
+
+// cerr << "RAck ok, send 200 Ok" << endl;
+
+ lastProvisional = NULL;
+ sendPrackOk( prack );
+
+ CommandString cmdstr(dialogState.callId,
+ SipCommandString::incoming_available,
+ dialogState.remoteUri,
+ (getMediaSession()->isSecure()?"secure":"unprotected")
+ );
+ getSipStack()->getCallback()->handleCommand("gui", cmdstr );
+
+ sendRinging();
+
+ return true;
+}
+
+bool SipDialogVoipServer::a3009_any_any_ResendTimer1xx( const SipSMCommand &command){
+ if( !transitionMatch(command,
+ "ResendTimer1xx",
+ SipSMCommand::dialog_layer,
+ SipSMCommand::dialog_layer) ){
+ return false;
+ }
+
+ if( !lastProvisional ){
+ // Stop retransmissions.
+ return true;
+ }
+
+ resendTimer1xx *=2;
+
+ // Stop retransmissions after 64*T1
+ if( resendTimer1xx >= 64 * getSipStack()->getTimers()->getA() ){
+ MRef<SipResponse*> reject =
+ createSipResponse( getLastInvite(), 504,
+ "Server Time-out" );
+ sendSipMessage( *reject );
+ CommandString cmdstr(dialogState.callId, SipCommandString::remote_cancelled_invite,"");
+ getSipStack()->getCallback()->handleCommand("gui", cmdstr );
+
+ getMediaSession()->stop();
+ signalIfNoTransactions();
+ return true;
+ }
+
+ sendSipMessage( lastProvisional );
+ requestTimeout(resendTimer1xx,"ResendTimer1xx");
+ return true;
+}
+
+bool SipDialogVoipServer::a3010_any_any_PRACK( const SipSMCommand &command){
+ if( use100Rel &&
+ !transitionMatch("PRACK",
+ command,
+ SipSMCommand::transaction_layer,
+ SipSMCommand::dialog_layer) ){
+ return false;
+ }
+
+ MRef<SipRequest*> prack =
+ dynamic_cast<SipRequest *>(*command.getCommandPacket());
+ dialogState.updateState( prack );
+
+ if( !isMatchingPrack( lastProvisional, prack ) ){
+ return false;
+ }
+
+// cerr << "RAck ok, send 200 Ok" << endl;
+
+ lastProvisional = NULL;
+ sendPrackOk( prack );
+
+ return true;
+}
+
void SipDialogVoipServer::setUpStateMachine(){
State<SipSMCommand,string> *s_start=new State<SipSMCommand,string>(this,"start");
addState(s_start);
+ State<SipSMCommand,string> *s_100rel=new State<SipSMCommand,string>(this,"100rel");
+ addState(s_100rel);
+
State<SipSMCommand,string> *s_ringing=new State<SipSMCommand,string>(this,"ringing");
addState(s_ringing);
MRef<State<SipSMCommand,string> *> s_incall = getState("incall");
MRef<State<SipSMCommand,string> *> s_termwait= getState("termwait");
+ MRef<State<SipSMCommand,string> *> s_any = anyState;
+ new StateTransition<SipSMCommand,string>(this, "transition_start_100rel_INVITE",
+ (bool (StateMachine<SipSMCommand,string>::*)(const SipSMCommand&)) &SipDialogVoipServer::a3007_start_100rel_INVITE,
+ s_start, s_100rel);
+
+ // Fallback to unreliable provisinal responses
new StateTransition<SipSMCommand,string>(this, "transition_start_ringing_INVITE",
(bool (StateMachine<SipSMCommand,string>::*)(const SipSMCommand&)) &SipDialogVoipServer::a3001_start_ringing_INVITE,
s_start, s_ringing);
@@ -385,13 +575,34 @@
(bool (StateMachine<SipSMCommand,string>::*)(const SipSMCommand&)) &SipDialogVoipServer::a3006_start_termwait_INVITE,
s_start, s_termwait);
+ new StateTransition<SipSMCommand,string>(this, "transition_100rel_ringing_PRACK",
+ (bool (StateMachine<SipSMCommand,string>::*)(const SipSMCommand&)) &SipDialogVoipServer::a3008_100rel_ringing_PRACK,
+ s_100rel, s_ringing);
+
+ new StateTransition<SipSMCommand,string>(this, "transition_100rel_100rel_ResendTimer1xx",
+ (bool (StateMachine<SipSMCommand,string>::*)(const SipSMCommand&)) &SipDialogVoipServer::a3009_any_any_ResendTimer1xx,
+ s_any, s_any);
+
+ new StateTransition<SipSMCommand,string>(this, "transition_ringing_ringing_PRACK",
+ (bool (StateMachine<SipSMCommand,string>::*)(const SipSMCommand&)) &SipDialogVoipServer::a3010_any_any_PRACK,
+ s_any, s_any);
+
+ // 100rel -> termwait
+ new StateTransition<SipSMCommand,string>(this, "transition_100rel_termwait_CANCEL",
+ (bool (StateMachine<SipSMCommand,string>::*)(const SipSMCommand&)) &SipDialogVoipServer::a3004_ringing_termwait_CANCEL,
+ s_100rel, s_termwait);
+ new StateTransition<SipSMCommand,string>(this, "transition_100rel_termwait_reject",
+ (bool (StateMachine<SipSMCommand,string>::*)(const SipSMCommand&)) &SipDialogVoipServer::a3005_ringing_termwait_reject,
+ s_100rel, s_termwait);
+
setCurrentState(s_start);
}
SipDialogVoipServer::SipDialogVoipServer(MRef<SipStack*> stack, MRef<SipIdentity*> ident, MRef<SipSoftPhoneConfiguration*> pconf, MRef<Session *> mediaSession, string cid) :
- SipDialogVoip(stack, ident, pconf, mediaSession, cid)
+ SipDialogVoip(stack, ident, pconf, mediaSession, cid),
+ use100Rel( false ), resendTimer1xx( 0 )
{
setUpStateMachine();
}
@@ -410,7 +621,9 @@
getDialogConfig()->getContactUri(phoneconf->useSTUN),
-1); //set expires to -1, we do not use it (only in register)
ok->addHeader( new SipHeader(*contact) );
-
+
+ if( !use100Rel ){
+
//There might be so that there are no SDP. Check!
MRef<SdpPacket *> sdp;
if (mediaSession){
@@ -445,6 +658,7 @@
// /* if sdp is NULL, the offer was refused, send 606 */
// // FIXME
// else return;
+ }
MRef<SipMessage*> pref(*ok);
SipSMCommand cmd( pref, SipSMCommand::dialog_layer, SipSMCommand::transaction_layer);
@@ -459,24 +673,24 @@
getSipStack()->enqueueCommand(cmd, HIGH_PRIO_QUEUE );
}
-void SipDialogVoipServer::sendRinging(const string &branch, bool use100Rel){
- MRef<SipResponse*> ringing = new SipResponse(branch,180,"Ringing", *getLastInvite());
+void SipDialogVoipServer::sendRinging(){
+ MRef<SipResponse*> ringing =
+ createSipResponse( getLastInvite(), 180, "Ringing" );
if (use100Rel){
ringing->addHeader(new SipHeader(new SipHeaderValueRequire("100rel")));
+ dialogState.rseqNo++;
+ ringing->addHeader(new SipHeader(new SipHeaderValueRSeq( dialogState.rseqNo )));
+ lastProvisional = *ringing;
}
- ringing->getHeaderValueTo()->setParameter("tag",dialogState.localTag);
-
MRef<SipHeaderValue *> contact =
new SipHeaderValueContact(
getDialogConfig()->getContactUri(phoneconf->useSTUN),
-1); //set expires to -1, we do not use it (only in register)
ringing->addHeader( new SipHeader(*contact) );
- MRef<SipMessage*> pref(*ringing);
- SipSMCommand cmd( pref, SipSMCommand::dialog_layer, SipSMCommand::transaction_layer);
- getSipStack()->enqueueCommand(cmd, HIGH_PRIO_QUEUE );
+ sendSipMessage( *ringing );
}
void SipDialogVoipServer::sendNotAcceptable(const string &branch){
@@ -496,3 +710,55 @@
getSipStack()->enqueueCommand(cmd, HIGH_PRIO_QUEUE );
}
+void SipDialogVoipServer::sendPrackOk( MRef<SipRequest*> prack ){
+ MRef<SipResponse*> ok = createSipResponse( prack, 200, "OK" );
+ MRef<SipHeaderValue *> contact =
+ new SipHeaderValueContact(
+ getDialogConfig()->getContactUri(phoneconf->useSTUN),
+ -1); //set expires to -1, we do not use it (only in register)
+ ok->addHeader( new SipHeader(*contact) );
+
+ sendSipMessage( *ok );
+}
+
+void SipDialogVoipServer::sendSessionProgress(){
+ MRef<SipResponse*> progress =
+ createSipResponse( getLastInvite(), 183,"Session progress" );
+
+ progress->addHeader(new SipHeader(new SipHeaderValueRequire("100rel")));
+
+ dialogState.rseqNo++;
+ progress->addHeader(new SipHeader(new SipHeaderValueRSeq( dialogState.rseqNo )));
+
+ MRef<SipHeaderValue *> contact =
+ new SipHeaderValueContact(
+ getDialogConfig()->getContactUri(phoneconf->useSTUN),
+ -1); //set expires to -1, we do not use it (only in register)
+ progress->addHeader( new SipHeader(*contact) );
+
+ MRef<SdpPacket *> sdp;
+ if (mediaSession){
+#ifdef ENABLE_TS
+ ts.save("getSdpAnswer");
+#endif
+ sdp = mediaSession->getSdpAnswer();
+#ifdef ENABLE_TS
+ ts.save("getSdpAnswer");
+#endif
+ if( !sdp ){
+ // FIXME: this most probably means that the
+ // creation of the MIKEY message failed, it
+ // should not happen
+ merr << "Sdp was NULL in sendInviteOk" << end;
+ return;
+ }
+ }
+
+ /* Add the latter to the INVITE message */ // If it exists
+ progress->setContent( *sdp );
+
+ lastProvisional = *progress;
+
+ sendSipMessage( lastProvisional );
+}
+
Deleted: trunk/libminisip/source/sip/SipDialogVoipServer100rel.cxx
===================================================================
--- trunk/libminisip/source/sip/SipDialogVoipServer100rel.cxx 2007-02-01 10:31:30 UTC (rev 3175)
+++ trunk/libminisip/source/sip/SipDialogVoipServer100rel.cxx 2007-02-01 14:08:33 UTC (rev 3176)
@@ -1,325 +0,0 @@
-/*
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* Copyright (C) 2004, 2006
- *
- * Authors: Erik Eliasson <eliasson at it.kth.se>
- * Johan Bilien <jobi at via.ecp.fr>
- * Joachim Orrblad <joachim[at]orrblad.com>
- * Mikael Magnusson <mikma at users.sourceforge.net>
-*/
-
-/* Name
- * SipDialogVoipServer100rel.cxx
- * Author
- * Erik Eliasson, eliasson at it.kth.se
- * Purpose
- *
-*/
-#include<libminisip/sip/SipDialogVoipServer100rel.h>
-
-#include<libmutil/massert.h>
-
-#include<libmsip/SipTransitionUtils.h>
-#include<libmsip/SipCommandString.h>
-#include<libmsip/SipHeaderWarning.h>
-#include<libmsip/SipHeaderContact.h>
-#include<libmsip/SipHeaderFrom.h>
-#include<libmsip/SipHeaderRoute.h>
-#include<libmsip/SipHeaderRequire.h>
-#include<libmsip/SipHeaderRSeq.h>
-#include<libmsip/SipHeaderTo.h>
-#include<libmsip/SipMessageContentMime.h>
-#include<libmsip/SipMessageContent.h>
-#include<libmutil/stringutils.h>
-#include<libmcrypto/base64.h>
-#include<libmutil/Timestamp.h>
-#include<libmutil/termmanip.h>
-#include<libmutil/dbg.h>
-#include<libmsip/SipSMCommand.h>
-#include <time.h>
-#include<libminisip/gui/LogEntry.h>
-
-#include <iostream>
-#include<time.h>
-
-#ifdef _WIN32_WCE
-# include"../include/minisip_wce_extra_includes.h"
-#endif
-
-using namespace std;
-
-
-/*
-
- TODO: do not remove the old start_ringing stansaction, but instead
- place our before the old one.
-
- The "dotted" states are inherited from superclasses.
-
-
- +. . . . . . . .+
- . .
- . start .
- . .
- +. . . . . . . .+
- |
- | INVITE && supports 100rel
- | a4001:transIR; send 183
- V
- +---------------+
- | |-----+
- | 100rel | | 1xxResendTimer
- | |<----+ a4003: resend 183
- +---------------+
- |
- | PRACK
- | a4002: send 200; send 180
- V
- +. . . . . . . .+
- . .
- . ringing .
- . .
- +. . . . . . . .+
-
-*/
-
-
-bool SipDialogVoipServer100rel::a4001_start_100rel_100relINVITE( const SipSMCommand &command)
-{
- if (transitionMatch("INVITE",
- command,
- SipSMCommand::transaction_layer,
- SipSMCommand::dialog_layer)){
-
- MRef<SipRequest*> inv = (SipRequest *)*command.getCommandPacket();
- if (!inv->supported("100rel"))
- return false;
-
- _1xxResendTimer=getSipStack()->getTimers()->getA();
- requestTimeout(_1xxResendTimer,"1xxResendTimer");
-
- setLastInvite(inv);
- dialogState.updateState( getLastInvite() );
-
- string peerUri = dialogState.remoteUri;
-
- getDialogConfig()->sipIdentity->setSipUri(command.getCommandPacket()->getHeaderValueTo()->getUri().getUserIpString());
-
- if(!sortMIME(*command.getCommandPacket()->getContent(), peerUri, 10)){
- merr << "No MIME match" << end;
- return false;
- }
-
- //The transaction layer must receive to this message as
- //well. We re-post it with the transaction layer
- //as destination
-// SipSMCommand cmd(command);
-// cmd.setDestination(SipSMCommand::transaction);
-// getDialogContainer()->enqueueCommand(cmd, HIGH_PRIO_QUEUE, PRIO_LAST_IN_QUEUE);
-
-/* MRef<SipHeaderValue*> identity = command.getCommandPacket()->getHeaderValueNo(SIP_HEADER_TYPE_IDENTITY, 0);
- MRef<SipHeaderValue*> identityinfo = command.getCommandPacket()->getHeaderValueNo(SIP_HEADER_TYPE_IDENTITYINFO, 0);
-
- bool identityVerified=false;
- if (identity && identityinfo){
- cerr << "IDENTITY: found identity and identity-info header values"<< endl;
- assert(dynamic_cast<SipHeaderValueIdentity*>( *identity));
- assert(dynamic_cast<SipHeaderValueIdentityInfo*>( *identityinfo));
- MRef<SipHeaderValueIdentity*> ident = (SipHeaderValueIdentity*) *identity;
- MRef<SipHeaderValueIdentity*> identinfo = (SipHeaderValueIdentity*) *identityinfo;
-
- cerr << "IDENTITY: algorithm is: <"<< identinfo->getParameter("alg") << ">"<< endl;
-
- //downloadCertificate( identinfo->getCertUri() );
-
- identityVerified = verifyIdentityHeader(ident);
-
-
- //TODO: check that the identity is rsa-sha1
-
- if (!identityVerified){
-#ifdef DEBUG_OUTPUT
- cerr << "IDENTITY: the verification FAILED!"<< endl;
-#endif
- }
-
-
- }else{
- cerr << "IDENTITY: did not find identity header value"<< endl;
- }
-*/
-
-/* CommandString cmdstr(dialogState.callId,
- SipCommandString::incoming_available,
- dialogState.remoteUri,
- (getMediaSession()->isSecure()?"secure":"unprotected")
- );
- getDialogContainer()->getCallback()->handleCommand("gui", cmdstr );
-*/
- sendSessionProgress(inv->getDestinationBranch());
-
-// if( getDialogConfig()->inherited->autoAnswer ){
-// CommandString accept( dialogState.callId, SipCommandString::accept_invite );
-// SipSMCommand sipcmd(accept, SipSMCommand::remote, SipSMCommand::TU);
-// getDialogContainer()->enqueueCommand(sipcmd,HIGH_PRIO_QUEUE, PRIO_LAST_IN_QUEUE);
-// }
- return true;
- }else{
- return false;
- }
-}
-
-bool SipDialogVoipServer100rel::a4002_100rel_ringing_PRACK( const SipSMCommand &command)
-{
- if (transitionMatch("PRACK",
- command,
- SipSMCommand::transaction_layer,
- SipSMCommand::dialog_layer)){
-
- MRef<SipRequest*> prack = (SipRequest *)*command.getCommandPacket();
- dialogState.updateState( prack );
-
- dialogState.seqNo++;
-
- sendPrackOk(prack->getDestinationBranch(), *prack);
-
- CommandString cmdstr(dialogState.callId,
- SipCommandString::incoming_available,
- dialogState.remoteUri,
- (getMediaSession()->isSecure()?"secure":"unprotected")
- );
- getSipStack()->getCallback()->handleCommand("gui", cmdstr );
-
- sendRinging(getLastInvite()->getDestinationBranch(),false); //we don't do th 180 reliably, only the 183
-
- return true;
- }else{
- return false;
- }
-}
-
-bool SipDialogVoipServer100rel::a4003_100rel_100rel_1xxResendTimer( const SipSMCommand &command)
-{
- if (transitionMatch(command,
- "1xxResendTimer",
- SipSMCommand::dialog_layer,
- SipSMCommand::dialog_layer) ){
- resendSessionProgress();
- _1xxResendTimer *=2;
- requestTimeout(_1xxResendTimer,"1xxResendTimer");
- return true;
- }else{
- return false;
- }
-}
-
-void SipDialogVoipServer100rel::setUpStateMachine(){
-
- State<SipSMCommand,string> *s_100rel=new State<SipSMCommand,string>(this,"100rel");
- addState(s_100rel);
-
- MRef<State<SipSMCommand,string> *> s_start= getState("start");
- MRef<State<SipSMCommand,string> *> s_ringing= getState("ringing");
-
-
- bool success = s_start->removeTransition("transition_start_ringing_INVITE");
-
-
-
- if (!success){
- merr << "ERROR: Could not remove transition from state machine in SipDialogVoipServer (BUGBUG!!)"<<endl;
- massert(0==1);
- }
-
-
- new StateTransition<SipSMCommand,string>(this, "transition_start_100rel_100relINVITE",
- (bool (StateMachine<SipSMCommand,string>::*)(const SipSMCommand&)) &SipDialogVoipServer100rel::a4001_start_100rel_100relINVITE,
- s_start, s_100rel);
-
- new StateTransition<SipSMCommand,string>(this, "transition_100rel_ringing_PRACK",
- (bool (StateMachine<SipSMCommand,string>::*)(const SipSMCommand&)) &SipDialogVoipServer100rel::a4002_100rel_ringing_PRACK,
- s_100rel, s_ringing);
-
- new StateTransition<SipSMCommand,string>(this, "transition_100rel_100rel_1xxResendTimer",
- (bool (StateMachine<SipSMCommand,string>::*)(const SipSMCommand&)) &SipDialogVoipServer100rel::a4003_100rel_100rel_1xxResendTimer,
- s_100rel, s_100rel);
-
-
- // We need to put the "fallback" transition last in the list of
- // transitions to be tried.
- MRef< StateTransition<SipSMCommand,string> *> trans = s_start->getTransition("transition_start_termwait_INVITEnothandled");
- success = s_start->removeTransition("transition_start_termwait_INVITEnothandled");
- massert(trans && success);
- s_start->register_transition(trans);
-}
-
-
-SipDialogVoipServer100rel::SipDialogVoipServer100rel(MRef<SipStack*> stack, MRef<SipIdentity*> ident, MRef<SipSoftPhoneConfiguration*> pconf, MRef<Session *> mediaSession, string cid) :
- SipDialogVoipServer(stack, ident, pconf, mediaSession, cid)
-{
- setUpStateMachine();
-}
-
-SipDialogVoipServer100rel::~SipDialogVoipServer100rel(){
-}
-
-void SipDialogVoipServer100rel::sendPrackOk(const string &branch, MRef<SipMessage*> prack){
- MRef<SipResponse*> ok= new SipResponse(branch, 200,"OK", prack);
- ok->getHeaderValueTo()->setParameter("tag",dialogState.localTag);
-
- MRef<SipHeaderValue *> contact =
- new SipHeaderValueContact(
- getDialogConfig()->getContactUri(phoneconf->useSTUN),
- -1); //set expires to -1, we do not use it (only in register)
- ok->addHeader( new SipHeader(*contact) );
-
- MRef<SipMessage*> pref(*ok);
- SipSMCommand cmd( pref, SipSMCommand::dialog_layer, SipSMCommand::transaction_layer);
- getSipStack()->enqueueCommand(cmd, HIGH_PRIO_QUEUE);
-}
-
-void SipDialogVoipServer100rel::resendSessionProgress(){
- MRef<SipHeaderValueRSeq *> rseq = (SipHeaderValueRSeq*)*lastProgress->getHeaderValueNo( SIP_HEADER_TYPE_RSEQ, 0 );
-
- rseq->setRSeq( rseq->getRSeq() + 1 );
-
- SipSMCommand cmd( lastProgress, SipSMCommand::dialog_layer, SipSMCommand::transaction_layer);
- getSipStack()->enqueueCommand(cmd, HIGH_PRIO_QUEUE);
-}
-
-void SipDialogVoipServer100rel::sendSessionProgress(const string &branch){
- MRef<SipResponse*> progress = new SipResponse(branch,183,"Session progress", MRef<SipMessage*>(*getLastInvite()));
-
- progress->addHeader(new SipHeader(new SipHeaderValueRequire("100rel"))); //EEEEEE
-
- progress->getHeaderValueTo()->setParameter("tag",dialogState.localTag);
-
- progress->addHeader(new SipHeader(new SipHeaderValueRSeq( rand() % (1<<31) )));
-
- MRef<SipHeaderValue *> contact =
- new SipHeaderValueContact(
- getDialogConfig()->getContactUri(phoneconf->useSTUN),
- -1); //set expires to -1, we do not use it (only in register)
- progress->addHeader( new SipHeader(*contact) );
-
- lastProgress = *progress;
-
- MRef<SipMessage*> pref(*progress);
- SipSMCommand cmd( pref, SipSMCommand::dialog_layer, SipSMCommand::transaction_layer);
- getSipStack()->enqueueCommand(cmd, HIGH_PRIO_QUEUE);
-}
-
More information about the Minisip-devel
mailing list