Add support for REGISTER & MESSAGE
This commit is contained in:
parent
28745079d3
commit
ef95a195a9
|
@ -209,31 +209,31 @@
|
|||
Name="sm"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\src\sm_dialog_info_sm.h"
|
||||
RelativePath=".\src\sm_dialog_info_sm.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\sm_dialog_invite_sm.h"
|
||||
RelativePath=".\src\sm_dialog_invite_sm.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\sm_dialog_message_sm.h"
|
||||
RelativePath=".\src\sm_dialog_message_sm.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\sm_dialog_options_sm.h"
|
||||
RelativePath=".\src\sm_dialog_options_sm.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\sm_dialog_publish_sm.h"
|
||||
RelativePath=".\src\sm_dialog_publish_sm.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\sm_dialog_register_sm.h"
|
||||
RelativePath=".\src\sm_dialog_register_sm.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\sm_dialog_subscribe_sm.h"
|
||||
RelativePath=".\src\sm_dialog_subscribe_sm.cxx"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
|
@ -245,10 +245,26 @@
|
|||
RelativePath=".\src\api_engine.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\api_stack.cxx"
|
||||
<Filter
|
||||
Name="sip"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\api_sip.cxx"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="stack"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\src\api_stack.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\api_stack_sip.cxx"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
|
@ -305,31 +321,31 @@
|
|||
Name="sm"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\src\sm_dialog_info_sm.cxx"
|
||||
RelativePath=".\src\sm_dialog_info_sm.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\sm_dialog_invite_sm.cxx"
|
||||
RelativePath=".\src\sm_dialog_invite_sm.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\sm_dialog_message_sm.cxx"
|
||||
RelativePath=".\src\sm_dialog_message_sm.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\sm_dialog_options_sm.cxx"
|
||||
RelativePath=".\src\sm_dialog_options_sm.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\sm_dialog_publish_sm.cxx"
|
||||
RelativePath=".\src\sm_dialog_publish_sm.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\sm_dialog_register_sm.cxx"
|
||||
RelativePath=".\src\sm_dialog_register_sm.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\sm_dialog_subscribe_sm.cxx"
|
||||
RelativePath=".\src\sm_dialog_subscribe_sm.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
|
@ -345,10 +361,26 @@
|
|||
RelativePath=".\src\api_errors.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\api_stack.h"
|
||||
<Filter
|
||||
Name="sip"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\api_sip.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\api_sip_states.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="stack"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\src\api_stack.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
|
|
|
@ -38,15 +38,32 @@
|
|||
//-------------------------------------------------------------------------------------
|
||||
// Initialized
|
||||
//-------------------------------------------------------------------------------------
|
||||
Initialized
|
||||
Entry
|
||||
{
|
||||
}
|
||||
Exit
|
||||
{
|
||||
}
|
||||
//
|
||||
{
|
||||
}
|
||||
Initialized Entry { OnStateChanged(SS_MESSAGE_INITIALIZED); }
|
||||
{
|
||||
sm_messageSent() Trying { }
|
||||
}
|
||||
|
||||
Trying Entry { OnStateChanged(SS_MESSAGE_TRYING); }
|
||||
{
|
||||
sm_1xx_response() nil {}
|
||||
sm_2xx_response() Terminated {}
|
||||
sm_401_407_421_494_response() Authentifying {}
|
||||
sm_unsupported_response Terminated { }
|
||||
}
|
||||
|
||||
Authentifying Entry { OnStateChanged(SS_MESSAGE_AUTHENTIFYING); }
|
||||
{
|
||||
}
|
||||
|
||||
Terminated Entry { OnStateChanged(SS_MESSAGE_TERMINATED); }
|
||||
{
|
||||
Default nil {}
|
||||
}
|
||||
|
||||
Default Entry { OnStateChanged(SS_MESSAGE_UNKNOWN); }
|
||||
{
|
||||
sm_401_407_421_494_response() Authentifying {}
|
||||
Default nil {}
|
||||
}
|
||||
|
||||
%%
|
|
@ -38,16 +38,38 @@
|
|||
//-------------------------------------------------------------------------------------
|
||||
// Initialized
|
||||
//-------------------------------------------------------------------------------------
|
||||
Initialized
|
||||
Entry
|
||||
{
|
||||
|
||||
}
|
||||
Exit
|
||||
{
|
||||
}
|
||||
//
|
||||
{
|
||||
}
|
||||
Initialized Entry { OnStateChanged(SS_REGISTER_INITIALIZED); }
|
||||
{
|
||||
sm_registerSent() Trying { set_registering(true); }
|
||||
}
|
||||
|
||||
Trying Entry { OnStateChanged(SS_REGISTER_TRYING); }
|
||||
{
|
||||
sm_1xx_response() nil {}
|
||||
sm_2xx_response() [ctxt.get_registering() == true] Established {}
|
||||
sm_2xx_response() [ctxt.get_registering() == false] Terminated {}
|
||||
sm_401_407_421_494_response() Authentifying {}
|
||||
sm_unsupported_response() Terminated {}
|
||||
}
|
||||
|
||||
Established Entry { OnStateChanged(SS_REGISTER_ESTABLISHED); }
|
||||
{
|
||||
sm_unregisterSent() Trying { set_registering(false); }
|
||||
}
|
||||
|
||||
Authentifying Entry { OnStateChanged(SS_REGISTER_AUTHENTIFYING); }
|
||||
{
|
||||
}
|
||||
|
||||
Terminated Entry { OnStateChanged(SS_REGISTER_TERMINATED); }
|
||||
{
|
||||
Default nil {}
|
||||
}
|
||||
|
||||
Default Entry { OnStateChanged(SS_REGISTER_UNKNOWN); }
|
||||
{
|
||||
sm_401_407_421_494_response() Authentifying {}
|
||||
Default nil {}
|
||||
}
|
||||
|
||||
%%
|
|
@ -1,9 +1,11 @@
|
|||
#include "api_engine.h"
|
||||
#include "api_stack.h"
|
||||
|
||||
/* TODO: add mutex */
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <list>
|
||||
#include <assert.h>
|
||||
|
||||
#include <sofia-sip/su.h>
|
||||
|
||||
|
@ -58,7 +60,8 @@ ERR engine_deinitialize()
|
|||
std::list<PSTACK>::iterator iter = __stacks.begin();
|
||||
for ( ; iter!=__stacks.end(); iter++ )
|
||||
{
|
||||
delete(*iter);
|
||||
(*iter)->shutdown();
|
||||
//delete(*iter);
|
||||
}
|
||||
__stacks.clear();
|
||||
|
||||
|
@ -77,14 +80,14 @@ ERR engine_stack_create(int stack_id)
|
|||
{
|
||||
return ERR_STACK_ALREADY_EXIST;
|
||||
}
|
||||
stack* sk = new stack(stack_id, engine_callback);
|
||||
if(sk->get_initialized())
|
||||
stack* stk = new stack(stack_id, engine_callback);
|
||||
if(stk->get_initialized())
|
||||
{
|
||||
__stacks.push_back(sk);
|
||||
__stacks.push_back(stk);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete sk;
|
||||
delete stk;
|
||||
return ERR_STACK_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
|
@ -96,7 +99,15 @@ ERR engine_stack_run(int stack_id)
|
|||
{
|
||||
if(!__initialized) return ERR_ENGINE_NOT_INITIALIZED;
|
||||
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
stack* stk = (stack*)engine_stack_find(stack_id);
|
||||
if(stk)
|
||||
{
|
||||
return stk->run();
|
||||
}
|
||||
else
|
||||
{
|
||||
return ERR_STACK_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
/* shutdown downs the stack with the specified id */
|
||||
|
@ -104,7 +115,15 @@ ERR engine_stack_shutdown(int stack_id)
|
|||
{
|
||||
if(!__initialized) return ERR_ENGINE_NOT_INITIALIZED;
|
||||
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
stack* stk = (stack*)engine_stack_find(stack_id);
|
||||
if(stk)
|
||||
{
|
||||
return stk->shutdown();
|
||||
}
|
||||
else
|
||||
{
|
||||
return ERR_STACK_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
/* shutdown downs all stacks */
|
||||
|
@ -116,8 +135,10 @@ ERR engine_stack_shutdown_all(void)
|
|||
}
|
||||
|
||||
/* find stack by id*/
|
||||
stack* engine_stack_find(int stack_id)
|
||||
void* engine_stack_find(int stack_id)
|
||||
{
|
||||
if(!__initialized) return NULL;
|
||||
|
||||
std::list<PSTACK>::iterator iter = __stacks.begin();
|
||||
iter = std::find_if( iter, __stacks.end(), std::bind2nd( pred_stack_find_by_id(), stack_id ) );
|
||||
if(iter != __stacks.end())
|
||||
|
@ -128,17 +149,12 @@ stack* engine_stack_find(int stack_id)
|
|||
}
|
||||
|
||||
/* engine callback*/
|
||||
void engine_callback(nua_event_t event,
|
||||
int status,
|
||||
char const *phrase,
|
||||
nua_t *nua,
|
||||
nua_magic_t *magic,
|
||||
nua_handle_t *nh,
|
||||
nua_hmagic_t *hmagic,
|
||||
sip_t const *sip,
|
||||
tagi_t tags[])
|
||||
void engine_callback(nua_event_t event, int status, char const *phrase,
|
||||
nua_t *nua, nua_magic_t *magic, nua_handle_t *nh,
|
||||
nua_hmagic_t *hmagic, sip_t const *sip, tagi_t tags[])
|
||||
{
|
||||
|
||||
((stack*)magic)->callback_handle(event, status, phrase, nua, magic,
|
||||
nh, hmagic, sip, tags);
|
||||
}
|
||||
|
||||
#undef PSTACK
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
#include "pref.h"
|
||||
#include "api_errors.h"
|
||||
#include "api_stack.h"
|
||||
|
||||
PREF_NAMESPACE_START
|
||||
|
||||
|
@ -15,7 +14,7 @@ DOUBANGO_API_C ERR engine_stack_run(int stack_id);
|
|||
DOUBANGO_API_C ERR engine_stack_shutdown(int stack_id);
|
||||
DOUBANGO_API_C ERR engine_stack_shutdown_all(void);
|
||||
|
||||
stack* engine_stack_find(int stack_id);
|
||||
void* engine_stack_find(int stack_id);
|
||||
|
||||
PREF_NAMESPACE_END
|
||||
|
||||
|
|
|
@ -20,8 +20,13 @@ typedef enum tag_ERR
|
|||
ERR_ENGINE_NOT_INITIALIZED, /* engine not initialized or initialization failed*/
|
||||
ERR_ENGINE_ALREADY_INITIALIZED, /* engine have been already initialized */
|
||||
|
||||
/* SIP DIALOG */
|
||||
ERR_SIP_DIALOG_UNKNOWN,
|
||||
ERR_SIP_DIALOG_NOT_FOUND, /* dialog not found */
|
||||
|
||||
/* STACK errors */
|
||||
ERR_STACK_ALREADY_EXIST,
|
||||
ERR_STACK_NOT_FOUND, /* stack not found*/
|
||||
ERR_STACK_ALREADY_EXIST, /* state already exist */
|
||||
ERR_STACK_NOT_INITIALIZED, /* stack not initialized or initialization failed*/
|
||||
ERR_STACK_IS_INVALID, /* stack is in an invalide state (NULL, destroyed, locked, ...) */
|
||||
ERR_STACK_NOT_RUNNING, /* operation failed because the stack is not running */
|
||||
|
|
|
@ -0,0 +1,289 @@
|
|||
#include "api_sip.h"
|
||||
#include "api_engine.h"
|
||||
#include "api_stack.h"
|
||||
|
||||
#include <sofia-sip/auth_module.h>
|
||||
#include <sofia-sip/su_tag.h> // FIXME: remove
|
||||
#include <sofia-sip/sip_tag.h> // FIXME: remove
|
||||
|
||||
PREF_NAMESPACE_START
|
||||
|
||||
#define GET_STACK(stack_id, stk) \
|
||||
stack* stk = (stack*)engine_stack_find(stack_id); \
|
||||
if(!stk) return ERR_STACK_NOT_FOUND; \
|
||||
if(!stk->get_initialized()) return ERR_STACK_NOT_INITIALIZED; \
|
||||
if(!stk->get_running()) return ERR_STACK_NOT_RUNNING;
|
||||
|
||||
#define SAFE_FREE_HOME_PTR(home, ptr) { if(ptr){ su_free(home, ptr); } }
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// sip REGISTER
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/* send sip register message */
|
||||
ERR sip_register(int stack_id)
|
||||
{
|
||||
GET_STACK(stack_id, stk);
|
||||
return stk->sip_register();
|
||||
}
|
||||
|
||||
/* send sip unregister (register with expires=0) message*/
|
||||
ERR sip_unregister(int stack_id)
|
||||
{
|
||||
GET_STACK(stack_id, stk);
|
||||
return stk->sip_unregister();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// sip MESSAGE
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/* send sip register message */
|
||||
ERR sip_message(int stack_id, const char* dest_address, const char* content_type, const char* content)
|
||||
{
|
||||
GET_STACK(stack_id, stk);
|
||||
return stk->sip_message(dest_address, content_type, content);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// authentication
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
ERR auth_set(int stack_id, const char* public_id, const char* private_id, const char* password, const char* realm)
|
||||
{
|
||||
ERR error = ERR_SUCCESS;
|
||||
if( !ERR_SUCCEED( (error = auth_set_public_id(stack_id, public_id)) ) ) return error;
|
||||
if( !ERR_SUCCEED( (error = auth_set_private_id(stack_id, private_id)) ) ) return error;
|
||||
if( !ERR_SUCCEED( (error = auth_set_password(stack_id, password)) ) ) return error;
|
||||
if( !ERR_SUCCEED( (error = auth_set_realm(stack_id, realm)) ) ) return error;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
ERR auth_set_displayname(int stack_id, const char* displayname)
|
||||
{
|
||||
GET_STACK(stack_id, stk);
|
||||
SAFE_FREE_HOME_PTR(stk->get_home(), stk->get_displayname());
|
||||
stk->set_displayname( su_strdup(stk->get_home(), displayname) );
|
||||
nua_set_params(stk->get_nua(),
|
||||
NUTAG_M_DISPLAY(displayname),
|
||||
TAG_NULL());
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
ERR auth_set_public_id(int stack_id, const char* public_id)
|
||||
{
|
||||
GET_STACK(stack_id, stk);
|
||||
SAFE_FREE_HOME_PTR(stk->get_home(), stk->get_public_id());
|
||||
stk->set_public_id( su_strdup(stk->get_home(), public_id) );
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
ERR auth_set_private_id(int stack_id, const char* private_id)
|
||||
{
|
||||
GET_STACK(stack_id, stk);
|
||||
SAFE_FREE_HOME_PTR(stk->get_home(), stk->get_private_id());
|
||||
stk->set_private_id( su_strdup(stk->get_home(), private_id) );
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
ERR auth_set_preferred_id(int stack_id, const char* preferred_id)
|
||||
{
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
ERR auth_set_password(int stack_id, const char* password)
|
||||
{
|
||||
GET_STACK(stack_id, stk);
|
||||
SAFE_FREE_HOME_PTR(stk->get_home(), stk->get_password());
|
||||
stk->set_password( su_strdup(stk->get_home(), password) );
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
ERR auth_set_realm(int stack_id, const char* realm)
|
||||
{
|
||||
GET_STACK(stack_id, stk);
|
||||
SAFE_FREE_HOME_PTR(stk->get_home(), stk->get_realm());
|
||||
stk->set_realm( su_strdup(stk->get_home(), realm) );
|
||||
nua_set_params(stk->get_nua(),
|
||||
AUTHTAG_REALM(realm),
|
||||
TAG_NULL());
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
ERR auth_set_operator_id(int stack_id, const char* operator_id)
|
||||
{
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
ERR auth_set_amf(int stack_id, const char* amf)
|
||||
{
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
ERR auth_set_privacy(int stack_id, const char* privacy)
|
||||
{
|
||||
GET_STACK(stack_id, stk);
|
||||
SAFE_FREE_HOME_PTR(stk->get_home(), stk->get_privacy());
|
||||
stk->set_privacy( su_strdup(stk->get_home(), privacy) );
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
ERR auth_set_security_mechanism(int stack_id, const char* security_mechanism)
|
||||
{
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// network
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
ERR network_set(int stack_id, const char* pcscf_ip, int pcscf_port, const char* transport)
|
||||
{
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
ERR network_set_pcscf(int stack_id, const char* pcscf_ip, int pcscf_port)
|
||||
{
|
||||
GET_STACK(stack_id, stk);
|
||||
char* pcscf = su_sprintf(stk->get_home(), "sip:%s:%d", pcscf_ip, pcscf_port);
|
||||
nua_set_params(stk->get_nua(),
|
||||
NUTAG_PROXY(pcscf),
|
||||
NUTAG_OUTBOUND("no-validate"),
|
||||
TAG_NULL());
|
||||
su_free(stk->get_home(), pcscf);
|
||||
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
ERR network_set_transport(int stack_id, const char* transport)
|
||||
{
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* SIP Header: P-Access-Network-Info
|
||||
RFC 3455
|
||||
*/
|
||||
ERR network_set_net_info(int stack_id, const char* net_info)
|
||||
{
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// qos
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
ERR qos_set_audio_bandwith(int stack_id, int audio_bandwith)
|
||||
{
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
ERR qos_set_audio_dscp(int stack_id, int audio_dscp)
|
||||
{
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
ERR qos_set_video_bandwith(int stack_id, int video_bandwith)
|
||||
{
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
ERR qos_set_video_dscp(int stack_id, int video_dscp)
|
||||
{
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
ERR qos_set_msrp_bandwith(int stack_id, int msrp_bandwith)
|
||||
{
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
ERR qos_set_msrp_dscp(int stack_id, int msrp_dscp)
|
||||
{
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// ipsec
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
ERR ipsec_set(int stack_id, const char* mode, const char* protocol, const char* auth_algo, const char* enc_algo)
|
||||
{
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
ERR ipsec_set_mode(int stack_id, const char* mode)
|
||||
{
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
ERR ipsec_set_protocol(int stack_id, const char* protocol)
|
||||
{
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
ERR ipsec_set_auth_algo(int stack_id, const char* auth_algo)
|
||||
{
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
ERR ipsec_set_enc_algo(int stack_id, const char* enc_algo)
|
||||
{
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// tls
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
ERR tls_set_priv_key_path(int stack_id, const char* priv_key_path)
|
||||
{
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
ERR tls_set_pub_key_path(int stack_id, const char* pub_key_path)
|
||||
{
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
ERR tls_set_cert_path(int stack_id, const char* cert_path)
|
||||
{
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// sigcomp
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
ERR sigcomp_set_comp_id(int stack_id, const char* comp_id)
|
||||
{
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
ERR sigcomp_enable_sipdict(int stack_id, bool enable)
|
||||
{
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
ERR sigcomp_enable_presdict(int stack_id, bool enable)
|
||||
{
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
ERR sigcomp_set_dms(int stack_id, int dms)
|
||||
{
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
ERR sigcomp_set_sms(int stack_id, int sms)
|
||||
{
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
ERR sigcomp_set_cpb(int stack_id, int cpb)
|
||||
{
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
PREF_NAMESPACE_END
|
|
@ -0,0 +1,81 @@
|
|||
#ifndef _DOUBANGO_API_SIP_REGISTRATION_H_
|
||||
#define _DOUBANGO_API_SIP_REGISTRATION_H_
|
||||
|
||||
#include "pref.h"
|
||||
#include "api_errors.h"
|
||||
|
||||
PREF_NAMESPACE_START
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// sip REGISTER
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
DOUBANGO_API_C ERR sip_register(int stack_id);
|
||||
DOUBANGO_API_C ERR sip_unregister(int stack_id);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// sip MESSAGE
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
DOUBANGO_API_C ERR sip_message(int stack_id, const char* dest_address, const char* content_type, const char* content);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// authentication
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
DOUBANGO_API_C ERR auth_set(int stack_id, const char* public_id, const char* private_id, const char* password, const char* realm);
|
||||
DOUBANGO_API_C ERR auth_set_displayname(int stack_id, const char* displayname);
|
||||
DOUBANGO_API_C ERR auth_set_public_id(int stack_id, const char* public_id);
|
||||
DOUBANGO_API_C ERR auth_set_private_id(int stack_id, const char* private_id);
|
||||
DOUBANGO_API_C ERR auth_set_preferred_id(int stack_id, const char* preferred_id);
|
||||
DOUBANGO_API_C ERR auth_set_password(int stack_id, const char* password);
|
||||
DOUBANGO_API_C ERR auth_set_realm(int stack_id, const char* realm);
|
||||
DOUBANGO_API_C ERR auth_set_operator_id(int stack_id, const char* operator_id);
|
||||
DOUBANGO_API_C ERR auth_set_amf(int stack_id, const char* amf);
|
||||
DOUBANGO_API_C ERR auth_set_privacy(int stack_id, const char* privacy);
|
||||
DOUBANGO_API_C ERR auth_set_security_mechanism(int stack_id, const char* security_mechanism);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// network
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
DOUBANGO_API_C ERR network_set(int stack_id, const char* pcscf_ip, int pcscf_port, const char* transport);
|
||||
DOUBANGO_API_C ERR network_set_pcscf(int stack_id, const char* pcscf_ip, int pcscf_port);
|
||||
DOUBANGO_API_C ERR network_set_transport(int stack_id, const char* transport);
|
||||
DOUBANGO_API_C ERR network_set_net_info(int stack_id, const char* net_info);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// qos
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
DOUBANGO_API_C ERR qos_set_audio_bandwith(int stack_id, int audio_bandwith);
|
||||
DOUBANGO_API_C ERR qos_set_audio_dscp(int stack_id, int audio_dscp);
|
||||
DOUBANGO_API_C ERR qos_set_video_bandwith(int stack_id, int video_bandwith);
|
||||
DOUBANGO_API_C ERR qos_set_video_dscp(int stack_id, int video_dscp);
|
||||
DOUBANGO_API_C ERR qos_set_msrp_bandwith(int stack_id, int msrp_bandwith);
|
||||
DOUBANGO_API_C ERR qos_set_msrp_dscp(int stack_id, int msrp_dscp);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// ipsec
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
DOUBANGO_API_C ERR ipsec_set(int stack_id, const char* mode, const char* protocol, const char* auth_algo, const char* enc_algo);
|
||||
DOUBANGO_API_C ERR ipsec_set_mode(int stack_id, const char* mode);
|
||||
DOUBANGO_API_C ERR ipsec_set_protocol(int stack_id, const char* protocol);
|
||||
DOUBANGO_API_C ERR ipsec_set_auth_algo(int stack_id, const char* auth_algo);
|
||||
DOUBANGO_API_C ERR ipsec_set_enc_algo(int stack_id, const char* enc_algo);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// tls
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
DOUBANGO_API_C ERR tls_set_priv_key_path(int stack_id, const char* priv_key_path);
|
||||
DOUBANGO_API_C ERR tls_set_pub_key_path(int stack_id, const char* pub_key_path);
|
||||
DOUBANGO_API_C ERR tls_set_cert_path(int stack_id, const char* cert_path);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// sigcomp
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
DOUBANGO_API_C ERR sigcomp_set_comp_id(int stack_id, const char* comp_id);
|
||||
DOUBANGO_API_C ERR sigcomp_enable_sipdict(int stack_id, bool enable);
|
||||
DOUBANGO_API_C ERR sigcomp_enable_presdict(int stack_id, bool enable);
|
||||
DOUBANGO_API_C ERR sigcomp_set_dms(int stack_id, int dms);
|
||||
DOUBANGO_API_C ERR sigcomp_set_sms(int stack_id, int sms);
|
||||
DOUBANGO_API_C ERR sigcomp_set_cpb(int stack_id, int cpb);
|
||||
|
||||
PREF_NAMESPACE_END
|
||||
|
||||
#endif /* _DOUBANGO_API_SIP_REGISTRATION_H_ */
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef _DOUBANGO_SIP_STATES_H_
|
||||
#define _DOUBANGO_SIP_STATES_H_
|
||||
|
||||
#include "pref.h"
|
||||
|
||||
PREF_NAMESPACE_START
|
||||
|
||||
typedef enum tag_SIP_STATE
|
||||
{
|
||||
SS_UNKNOWN_UNKNOWN,
|
||||
|
||||
/* REGISTER */
|
||||
SS_REGISTER_UNKNOWN,
|
||||
SS_REGISTER_INITIALIZED,
|
||||
SS_REGISTER_TRYING,
|
||||
SS_REGISTER_AUTHENTIFYING,
|
||||
SS_REGISTER_ESTABLISHED,
|
||||
SS_REGISTER_TERMINATED,
|
||||
|
||||
/* MESSAGE */
|
||||
SS_MESSAGE_UNKNOWN,
|
||||
SS_MESSAGE_INITIALIZED,
|
||||
SS_MESSAGE_TRYING,
|
||||
SS_MESSAGE_AUTHENTIFYING,
|
||||
SS_MESSAGE_TERMINATED,
|
||||
}
|
||||
SIP_STATE;
|
||||
|
||||
PREF_NAMESPACE_END
|
||||
|
||||
#endif /* _DOUBANGO_SIP_STATES_H_ */
|
|
@ -1,13 +1,93 @@
|
|||
#include "api_stack.h"
|
||||
|
||||
#define DEFAULT_USER_AGENT "IM-client/OMA1.0"
|
||||
|
||||
PREF_NAMESPACE_START
|
||||
|
||||
/* stack constructor */
|
||||
stack::stack(int _id, nua_callback_f callback): id(_id), initialized(false)
|
||||
stack::stack(int _id, nua_callback_f _callback)
|
||||
{
|
||||
if(!_callback) return;
|
||||
|
||||
// initialize
|
||||
this->id = _id;
|
||||
this->callback = _callback;
|
||||
|
||||
this->initialized = false;
|
||||
this->thread = NULL;
|
||||
this->nua = NULL;
|
||||
this->root = NULL;
|
||||
this->running = false;
|
||||
|
||||
/* authentication */
|
||||
displayname = NULL, public_id = NULL, private_id = NULL, realm = NULL,
|
||||
password = NULL, privacy = NULL, pcscf_ip = NULL, pcscf_port = 5060;
|
||||
|
||||
/* Features */
|
||||
smsip = true, oma_large_msg = true, oma_sip_im = true, gsma_is = true, gsma_vs = true;
|
||||
|
||||
// initialize memory handling
|
||||
if( su_home_init(this->home) ) return;
|
||||
|
||||
this->initialized = true;
|
||||
}
|
||||
|
||||
/* stack destructor */
|
||||
stack::~stack()
|
||||
{
|
||||
if(this->thread) CloseHandle(this->thread);
|
||||
}
|
||||
|
||||
/* run main loop for processing of messages */
|
||||
inline ERR stack::run()
|
||||
{
|
||||
if(this->initialized && !this->running && !this->thread)
|
||||
{
|
||||
#ifdef WIN32
|
||||
DWORD threadId;
|
||||
this->thread = CreateThread(NULL, 0, ThreadRunner, this, 0, &threadId);
|
||||
for(int i=0; i<5; i++)
|
||||
{
|
||||
if(this->running)
|
||||
{
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
Sleep(1000);
|
||||
}
|
||||
|
||||
return ERR_STACK_NOT_RUNNING;
|
||||
#else
|
||||
# error "must be implemented"
|
||||
#endif
|
||||
}
|
||||
|
||||
return (!this->initialized ? ERR_STACK_NOT_INITIALIZED : (this->running? ERR_STACK_ALREADY_EXIST : ERR_GLOBAL_FAILURE));
|
||||
}
|
||||
|
||||
/* shutdown the stack */
|
||||
inline ERR stack::shutdown()
|
||||
{
|
||||
if(this->running)
|
||||
{
|
||||
if(this->root)
|
||||
{
|
||||
su_root_break(this->root);
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ERR_GLOBAL_FAILURE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return ERR_STACK_NOT_RUNNING;
|
||||
}
|
||||
}
|
||||
|
||||
/* event loop processing */
|
||||
void stack::loop()
|
||||
{
|
||||
// initialize root object
|
||||
this->root = su_root_create(this);
|
||||
if(!this->root)
|
||||
|
@ -17,7 +97,9 @@ stack::stack(int _id, nua_callback_f callback): id(_id), initialized(false)
|
|||
}
|
||||
|
||||
// create NUA stack
|
||||
this->nua = nua_create(this->root, callback, this,
|
||||
this->nua = nua_create(this->root, this->callback, this,
|
||||
NUTAG_USER_AGENT(DEFAULT_USER_AGENT),
|
||||
NUTAG_PROXY("sip:127.0.0.1:5060"),
|
||||
/* tags as necessary ...*/
|
||||
TAG_NULL());
|
||||
if (!this->nua)
|
||||
|
@ -27,43 +109,55 @@ stack::stack(int _id, nua_callback_f callback): id(_id), initialized(false)
|
|||
return;
|
||||
}
|
||||
|
||||
// set necessary parameters
|
||||
nua_set_params(this->nua,
|
||||
/* tags as necessary ...*/
|
||||
TAG_NULL());
|
||||
// FIXME
|
||||
this->running = true;
|
||||
|
||||
// enter main loop for processing of messages
|
||||
su_root_run(this->root);
|
||||
|
||||
this->initialized = true;
|
||||
// Release resources
|
||||
if(this->nua) {
|
||||
nua_shutdown(this->nua);
|
||||
//nua_destroy(this->nua);
|
||||
this->nua = NULL;
|
||||
}
|
||||
if(this->root) {
|
||||
su_root_destroy(this->root);
|
||||
this->root = NULL;
|
||||
}
|
||||
if(this->home) {
|
||||
su_home_deinit(this->home);
|
||||
}
|
||||
|
||||
this->running = false;
|
||||
}
|
||||
|
||||
/* stack destructor */
|
||||
stack::~stack()
|
||||
#ifdef WIN32
|
||||
/* static threads runner*/
|
||||
DWORD WINAPI stack::ThreadRunner( void* magic ) {
|
||||
((stack*)magic)->loop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* handle callback event*/
|
||||
void stack::callback_handle(nua_event_t _event,
|
||||
int status, char const *phrase,
|
||||
nua_t *nua, nua_magic_t *magic,
|
||||
nua_handle_t *nh, nua_hmagic_t *hmagic,
|
||||
sip_t const *sip,
|
||||
tagi_t tags[])
|
||||
{
|
||||
if(this->initialized)
|
||||
GET_DIALOG_BY_HANDLE(dlg, nh);
|
||||
if(dlg)
|
||||
{
|
||||
dlg->dialog_callback(_event, status, phrase, nua, magic,
|
||||
nh, hmagic, sip, tags);
|
||||
}
|
||||
else
|
||||
{
|
||||
// destroy NUA stack
|
||||
nua_destroy(this->nua);
|
||||
|
||||
// deinit root object
|
||||
su_root_destroy(this->root);
|
||||
|
||||
// deinitialize memory handling
|
||||
su_home_deinit(this->home);
|
||||
}
|
||||
}
|
||||
|
||||
/* gets the stack id */
|
||||
inline int stack::get_id()const
|
||||
{
|
||||
return this->id;
|
||||
}
|
||||
|
||||
/* returns true if initialized, false otherwise */
|
||||
inline bool stack::get_initialized() const
|
||||
{
|
||||
return this->initialized;
|
||||
}
|
||||
|
||||
PREF_NAMESPACE_END
|
|
@ -2,28 +2,146 @@
|
|||
#define __DOUBANGO_STACK_H__
|
||||
|
||||
#include "pref.h"
|
||||
#include "api_errors.h"
|
||||
#include "sip_dialog.h"
|
||||
#include <sofia-sip/nua.h>
|
||||
|
||||
#include <list>
|
||||
#include <algorithm>
|
||||
|
||||
PREF_NAMESPACE_START
|
||||
|
||||
/* generate setter and getter methods*/
|
||||
#define DEFINE_GET_SET(type, member)\
|
||||
inline type &get_##member(){ return this->##member; } \
|
||||
inline void set_##member(type val){ this->##member = val; }
|
||||
|
||||
/* predicate: find dialog by handle */
|
||||
struct pred_dialog_find_by_handle: public std::binary_function< sip_dialog*, nua_handle_t*, bool > {
|
||||
bool operator () ( const sip_dialog* dlg, const nua_handle_t* handle ) const {
|
||||
return dlg->get_handle() == handle;
|
||||
}
|
||||
};
|
||||
/* predicate: find dialog by sipmethod */
|
||||
struct pred_dialog_find_by_sipmethod: public std::binary_function< sip_dialog*, const char*, bool > {
|
||||
bool operator () ( const sip_dialog* dlg, const char* sipmethod ) const {
|
||||
return !stricmp(dlg->get_sipmethod(), sipmethod);
|
||||
}
|
||||
};
|
||||
/* predicate: find all dialogs in terminated state */
|
||||
//==> IN C++ bool isDlgTerminated(const sip_dialog* dlg){ return dlg->get_terminated(); }
|
||||
#define GET_DIALOG_TERMINATED(dlg)\
|
||||
sip_dialog* dlg = NULL; \
|
||||
std::list<sip_dialog*>::iterator iter = std::find_if( this->dialogs.begin(), this->dialogs.end(), isDlgTerminated ); \
|
||||
if(iter != this->dialogs.end()) dlg = *iter;
|
||||
|
||||
/* find dialog by sipmethod*/
|
||||
#define GET_DIALOG_BY_SIPMETHOD(dlg, sipmethod) \
|
||||
sip_dialog* dlg = NULL; \
|
||||
std::list<sip_dialog*>::iterator iter = std::find_if( this->dialogs.begin(), this->dialogs.end(), std::bind2nd( pred_dialog_find_by_sipmethod(), sipmethod ) ); \
|
||||
if(iter != this->dialogs.end()) dlg = *iter;
|
||||
|
||||
/* find dialog by handle */
|
||||
#define GET_DIALOG_BY_HANDLE(dlg, handle) \
|
||||
sip_dialog* dlg = NULL; \
|
||||
std::list<sip_dialog*>::iterator iter = std::find_if( this->dialogs.begin(), this->dialogs.end(), std::bind2nd( pred_dialog_find_by_handle(), handle ) ); \
|
||||
if(iter != this->dialogs.end()) dlg = *iter;
|
||||
|
||||
class DOUBANGO_API stack
|
||||
{
|
||||
public:
|
||||
stack(int id, nua_callback_f callback);
|
||||
~stack();
|
||||
|
||||
inline int get_id() const;
|
||||
inline bool get_initialized() const;
|
||||
inline ERR run();
|
||||
inline ERR shutdown();
|
||||
|
||||
inline int get_id() const { return this->id; }
|
||||
inline bool get_running() const { return this->running; }
|
||||
inline bool get_initialized() const { return this->initialized; }
|
||||
inline su_home_t* get_home() { return this->home; }
|
||||
inline nua_t* get_nua() { return this->nua; }
|
||||
|
||||
//
|
||||
// SIP
|
||||
//
|
||||
ERR sip_register();
|
||||
ERR sip_unregister();
|
||||
|
||||
ERR sip_message(const char* dest_address, const char* content_type, const char* content);
|
||||
|
||||
|
||||
//
|
||||
// Authentication
|
||||
//
|
||||
DEFINE_GET_SET(char*, displayname);
|
||||
DEFINE_GET_SET(char*, public_id);
|
||||
DEFINE_GET_SET(char*, private_id);
|
||||
DEFINE_GET_SET(char*, realm);
|
||||
DEFINE_GET_SET(char*, password);
|
||||
DEFINE_GET_SET(char*, privacy);
|
||||
DEFINE_GET_SET(char*, pcscf_ip);
|
||||
DEFINE_GET_SET(int, pcscf_port);
|
||||
|
||||
//
|
||||
// Features
|
||||
//
|
||||
DEFINE_GET_SET(bool, smsip);
|
||||
DEFINE_GET_SET(bool, oma_large_msg);
|
||||
DEFINE_GET_SET(bool, oma_sip_im);
|
||||
DEFINE_GET_SET(bool, gsma_is);
|
||||
DEFINE_GET_SET(bool, gsma_vs);
|
||||
|
||||
void callback_handle(nua_event_t event,
|
||||
int status, char const *phrase,
|
||||
nua_t *nua, nua_magic_t *magic,
|
||||
nua_handle_t *nh, nua_hmagic_t *hmagic,
|
||||
sip_t const *sip,
|
||||
tagi_t tags[]);
|
||||
private:
|
||||
#ifdef WIN32
|
||||
static DWORD WINAPI ThreadRunner( void* magic );
|
||||
#endif
|
||||
void loop();
|
||||
|
||||
private:
|
||||
int id;
|
||||
bool initialized;
|
||||
bool running;
|
||||
|
||||
nua_callback_f callback;
|
||||
void* thread;
|
||||
|
||||
std::list<sip_dialog*>dialogs;
|
||||
|
||||
su_home_t home[1]; /* memory home */
|
||||
su_root_t *root; /* root object */
|
||||
nua_t *nua; /* NUA stack object */
|
||||
|
||||
//
|
||||
// Authentication
|
||||
//
|
||||
char* displayname;
|
||||
char* public_id;
|
||||
char* private_id;
|
||||
char* realm;
|
||||
char* password;
|
||||
char* privacy;
|
||||
char* pcscf_ip;
|
||||
int pcscf_port;
|
||||
|
||||
//
|
||||
// Features
|
||||
//
|
||||
bool smsip;
|
||||
bool oma_large_msg;
|
||||
bool oma_sip_im;
|
||||
bool gsma_is;
|
||||
bool gsma_vs;
|
||||
};
|
||||
|
||||
#undef DEFINE_GET_SET
|
||||
|
||||
PREF_NAMESPACE_END
|
||||
|
||||
#endif /* __DOUBANGO_STACK_H__ */
|
|
@ -0,0 +1,41 @@
|
|||
#include "api_stack.h"
|
||||
#include "sip_dialog_register.h"
|
||||
#include "sip_dialog_message.h"
|
||||
//#include<sofia-sip/auth_module.h>
|
||||
|
||||
PREF_NAMESPACE_START
|
||||
|
||||
/* SIP REGISTER*/
|
||||
ERR stack::sip_register()
|
||||
{
|
||||
GET_DIALOG_BY_SIPMETHOD(dlg, "REGISTER");
|
||||
if(dlg){
|
||||
return ((sip_dialog_register*)dlg)->Start();
|
||||
}
|
||||
else{
|
||||
sip_dialog_register* dlg_register = new sip_dialog_register(this);
|
||||
this->dialogs.push_back(dlg_register);
|
||||
return dlg_register->Start();
|
||||
}
|
||||
}
|
||||
|
||||
/* SIP UNREGISTER */
|
||||
ERR stack::sip_unregister()
|
||||
{
|
||||
GET_DIALOG_BY_SIPMETHOD(dlg, "REGISTER");
|
||||
if(dlg){
|
||||
return ((sip_dialog_register*)dlg)->Stop();
|
||||
}
|
||||
else return ERR_SIP_DIALOG_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* SIP MESSAGE */
|
||||
ERR stack::sip_message(const char* dest_address, const char* content_type, const char* content)
|
||||
{
|
||||
sip_dialog_message* dlg_message = new sip_dialog_message(this, dest_address, content_type, content);
|
||||
this->dialogs.push_back(dlg_message);
|
||||
return dlg_message->Start();
|
||||
}
|
||||
|
||||
|
||||
PREF_NAMESPACE_END
|
|
@ -31,6 +31,7 @@
|
|||
extern "C"
|
||||
{
|
||||
#include "api_engine.h"
|
||||
#include "api_sip.h"
|
||||
}
|
||||
|
||||
#endif /* __DOUBANGO_DOUBANGO_H__ */
|
|
@ -47,7 +47,7 @@
|
|||
|
||||
/* disable warnings */
|
||||
#ifdef WIN32
|
||||
#pragma warning( disable : 4132 4100 4127 4152 4355 4996)
|
||||
#pragma warning( disable : 4132 4100 4127 4152 4355 4996 4251)
|
||||
#endif
|
||||
|
||||
/* namespace definition*/
|
||||
|
|
|
@ -29,8 +29,10 @@
|
|||
PREF_NAMESPACE_START
|
||||
|
||||
/* sip_dialog constructor */
|
||||
sip_dialog::sip_dialog()
|
||||
sip_dialog::sip_dialog(stack* _stk)
|
||||
{
|
||||
this->handle = NULL;
|
||||
this->stk = _stk;
|
||||
}
|
||||
|
||||
/* sip_dialog destructor*/
|
||||
|
@ -38,4 +40,11 @@ sip_dialog::~sip_dialog()
|
|||
{
|
||||
}
|
||||
|
||||
/* called when dialog state change*/
|
||||
void sip_dialog::OnStateChanged(SIP_STATE state)
|
||||
{
|
||||
this->state_current = state;
|
||||
SU_DEBUG_3(("%s::OnStateChanged ==> %d\n", this->get_sipmethod(), state));
|
||||
}
|
||||
|
||||
PREF_NAMESPACE_END
|
|
@ -29,14 +29,46 @@
|
|||
#define __DOUBANGO_DIALOG_SM_H__
|
||||
|
||||
#include "pref.h"
|
||||
#include "api_sip_states.h"
|
||||
#include "api_errors.h"
|
||||
|
||||
#include <sofia-sip/nua_tag.h>
|
||||
#include <sofia-sip/nua.h>
|
||||
#include <sofia-sip/su_debug.h>
|
||||
|
||||
PREF_NAMESPACE_START
|
||||
|
||||
class sip_dialog
|
||||
class stack;
|
||||
|
||||
class DOUBANGO_API sip_dialog
|
||||
{
|
||||
public:
|
||||
sip_dialog();
|
||||
sip_dialog(stack* stk);
|
||||
~sip_dialog();
|
||||
|
||||
inline nua_handle_t* get_handle() const{ return this->handle; }
|
||||
inline void set_handle(nua_handle_t* h) { this->handle = h; }
|
||||
|
||||
inline SIP_STATE get_state_current() const{ return this->state_current; }
|
||||
inline void set_state_current(SIP_STATE s) { this->state_current = s; }
|
||||
|
||||
virtual ERR Start() = 0;
|
||||
virtual ERR Stop() = 0;
|
||||
virtual void OnStateChanged(SIP_STATE state);
|
||||
virtual inline const char* get_sipmethod()const = 0;
|
||||
virtual inline bool get_terminated()const = 0;
|
||||
virtual void dialog_callback(nua_event_t event,
|
||||
int status, char const *phrase,
|
||||
nua_t *nua, nua_magic_t *magic,
|
||||
nua_handle_t *nh, nua_hmagic_t *hmagic,
|
||||
sip_t const *sip,
|
||||
tagi_t tags[]) = 0;
|
||||
|
||||
|
||||
protected:
|
||||
nua_handle_t* handle;
|
||||
stack* stk;
|
||||
SIP_STATE state_current;
|
||||
};
|
||||
|
||||
PREF_NAMESPACE_END
|
||||
|
|
|
@ -29,8 +29,8 @@
|
|||
PREF_NAMESPACE_START
|
||||
|
||||
/* sip_dialog_info constructor*/
|
||||
sip_dialog_info::sip_dialog_info()
|
||||
:sm_ctx(*this)
|
||||
sip_dialog_info::sip_dialog_info(stack* stk)
|
||||
:sip_dialog(stk), sm_ctx(*this)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ PREF_NAMESPACE_START
|
|||
class sip_dialog_info : public sip_dialog
|
||||
{
|
||||
public:
|
||||
sip_dialog_info();
|
||||
sip_dialog_info(stack* stk);
|
||||
~sip_dialog_info();
|
||||
|
||||
private:
|
||||
|
|
|
@ -29,8 +29,8 @@
|
|||
PREF_NAMESPACE_START
|
||||
|
||||
/* sip_dialog_invite constructor*/
|
||||
sip_dialog_invite::sip_dialog_invite()
|
||||
:sm_ctx(*this)
|
||||
sip_dialog_invite::sip_dialog_invite(stack* stk)
|
||||
:sip_dialog(stk),sm_ctx(*this)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ PREF_NAMESPACE_START
|
|||
class sip_dialog_invite : public sip_dialog
|
||||
{
|
||||
public:
|
||||
sip_dialog_invite();
|
||||
sip_dialog_invite(stack* stk);
|
||||
~sip_dialog_invite();
|
||||
|
||||
private:
|
||||
|
|
|
@ -25,18 +25,99 @@
|
|||
*
|
||||
*/
|
||||
#include "sip_dialog_message.h"
|
||||
#include "api_stack.h"
|
||||
|
||||
PREF_NAMESPACE_START
|
||||
|
||||
/* sip_dialog_message constructor*/
|
||||
sip_dialog_message::sip_dialog_message()
|
||||
:sm_ctx(*this)
|
||||
sip_dialog_message::sip_dialog_message(stack* stk, const char* _dest_address, const char* _content_type, const char* _content)
|
||||
:sip_dialog(stk),sm_ctx(*this)
|
||||
{
|
||||
this->dest_address = su_strdup(this->stk->get_home(), _dest_address);
|
||||
this->content_type = su_strdup(this->stk->get_home(), _content_type);
|
||||
this->content = su_strdup(this->stk->get_home(), _content);
|
||||
}
|
||||
|
||||
/* sip_dialog_message destructor */
|
||||
sip_dialog_message::~sip_dialog_message()
|
||||
{
|
||||
// FIXME: destroy handle
|
||||
su_free(this->stk->get_home(), this->dest_address);
|
||||
su_free(this->stk->get_home(), this->content_type);
|
||||
su_free(this->stk->get_home(), this->content);
|
||||
}
|
||||
|
||||
/* start sending MESSAGE */
|
||||
ERR sip_dialog_message::Start()
|
||||
{
|
||||
this->handle = nua_handle(this->stk->get_nua(), this->stk->get_home(),
|
||||
SIPTAG_TO_STR(this->dest_address), TAG_END());
|
||||
|
||||
if(!this->handle)
|
||||
{
|
||||
return ERR_GLOBAL_FAILURE;
|
||||
}
|
||||
|
||||
nua_message(this->handle,
|
||||
SIPTAG_CONTENT_TYPE_STR(this->content_type),
|
||||
SIPTAG_PAYLOAD_STR(this->content),
|
||||
TAG_END());
|
||||
|
||||
this->sm_ctx.sm_messageSent();
|
||||
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
/* terminate/stop dialog */
|
||||
ERR sip_dialog_message::Stop()
|
||||
{
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* dialog state changed */
|
||||
void sip_dialog_message::OnStateChanged(SIP_STATE state)
|
||||
{
|
||||
sip_dialog::OnStateChanged(state);
|
||||
}
|
||||
|
||||
/* get sip method */
|
||||
inline const char* sip_dialog_message::get_sipmethod()const
|
||||
{
|
||||
return "MESSAGE";
|
||||
}
|
||||
|
||||
/* returns true if terminated and false otherwise*/
|
||||
inline bool sip_dialog_message::get_terminated()const
|
||||
{
|
||||
return (this->state_current == SS_MESSAGE_TERMINATED);
|
||||
}
|
||||
|
||||
/* dialog callback */
|
||||
void sip_dialog_message::dialog_callback(nua_event_t _event,
|
||||
int status, char const *phrase,
|
||||
nua_t *nua, nua_magic_t *magic,
|
||||
nua_handle_t *nh, nua_hmagic_t *hmagic,
|
||||
sip_t const *sip,
|
||||
tagi_t tags[])
|
||||
{
|
||||
switch(_event)
|
||||
{
|
||||
case nua_r_message:
|
||||
{
|
||||
if(status <200) this->sm_ctx.sm_1xx_response();
|
||||
else if(status <300) this->sm_ctx.sm_2xx_response();
|
||||
else if(status == 401 || status == 407 || status == 421 || status == 494) this->sm_ctx.sm_401_407_421_494_response();
|
||||
else this->sm_ctx.sm_unsupported_response();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PREF_NAMESPACE_END
|
|
@ -35,14 +35,31 @@
|
|||
PREF_NAMESPACE_START
|
||||
|
||||
/* MESSAGE */
|
||||
class sip_dialog_message : public sip_dialog
|
||||
class DOUBANGO_API sip_dialog_message : public sip_dialog
|
||||
{
|
||||
public:
|
||||
sip_dialog_message();
|
||||
sip_dialog_message(stack* stk, const char* dest_address, const char* content_type, const char* content);
|
||||
~sip_dialog_message();
|
||||
|
||||
/* sip_dialog override*/
|
||||
ERR Start();
|
||||
ERR Stop();
|
||||
void OnStateChanged(SIP_STATE state);
|
||||
inline const char* get_sipmethod()const;
|
||||
inline bool get_terminated()const;
|
||||
void dialog_callback(nua_event_t event,
|
||||
int status, char const *phrase,
|
||||
nua_t *nua, nua_magic_t *magic,
|
||||
nua_handle_t *nh, nua_hmagic_t *hmagic,
|
||||
sip_t const *sip,
|
||||
tagi_t tags[]);
|
||||
|
||||
private:
|
||||
sip_dialog_messageContext sm_ctx;
|
||||
|
||||
char* dest_address;
|
||||
char* content_type;
|
||||
char* content;
|
||||
};
|
||||
|
||||
PREF_NAMESPACE_END
|
||||
|
|
|
@ -30,8 +30,8 @@
|
|||
PREF_NAMESPACE_START
|
||||
|
||||
/* sip_dialog_message constructor*/
|
||||
sip_dialog_options::sip_dialog_options()
|
||||
:sm_ctx(*this)
|
||||
sip_dialog_options::sip_dialog_options(stack* stk)
|
||||
:sip_dialog(stk),sm_ctx(*this)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ PREF_NAMESPACE_START
|
|||
class sip_dialog_options : public sip_dialog
|
||||
{
|
||||
public:
|
||||
sip_dialog_options();
|
||||
sip_dialog_options(stack* stk);
|
||||
~sip_dialog_options();
|
||||
|
||||
private:
|
||||
|
|
|
@ -29,8 +29,8 @@
|
|||
PREF_NAMESPACE_START
|
||||
|
||||
/* sip_dialog_publish constructor*/
|
||||
sip_dialog_publish::sip_dialog_publish()
|
||||
:sm_ctx(*this)
|
||||
sip_dialog_publish::sip_dialog_publish(stack* stk)
|
||||
:sip_dialog(stk),sm_ctx(*this)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ PREF_NAMESPACE_START
|
|||
class sip_dialog_publish : public sip_dialog
|
||||
{
|
||||
public:
|
||||
sip_dialog_publish();
|
||||
sip_dialog_publish(stack* stk);
|
||||
~sip_dialog_publish();
|
||||
|
||||
private:
|
||||
|
|
|
@ -25,18 +25,116 @@
|
|||
*
|
||||
*/
|
||||
#include "sip_dialog_register.h"
|
||||
#include "api_stack.h"
|
||||
|
||||
PREF_NAMESPACE_START
|
||||
|
||||
/* sip_dialog_register constructor*/
|
||||
sip_dialog_register::sip_dialog_register()
|
||||
:sm_ctx(*this)
|
||||
sip_dialog_register::sip_dialog_register(stack* stk)
|
||||
:sip_dialog(stk),sm_ctx(*this)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/* sip_dialog_register destructor */
|
||||
sip_dialog_register::~sip_dialog_register()
|
||||
{
|
||||
// FIXME: destroy handle
|
||||
}
|
||||
|
||||
/* start */
|
||||
ERR sip_dialog_register::Start()
|
||||
{
|
||||
this->sm_ctx.enterStartState();
|
||||
|
||||
this->handle = nua_handle(this->stk->get_nua(), this->stk->get_home(),
|
||||
SIPTAG_TO_STR(this->stk->get_realm()), TAG_END());
|
||||
|
||||
if(!this->handle)
|
||||
{
|
||||
return ERR_GLOBAL_FAILURE;
|
||||
}
|
||||
|
||||
nua_register(this->handle,
|
||||
SIPTAG_PRIVACY_STR(this->stk->get_privacy()),
|
||||
NUTAG_OUTBOUND("no-options-keepalive"),
|
||||
NUTAG_OUTBOUND("no-validate"),
|
||||
NUTAG_KEEPALIVE(0),
|
||||
SIPTAG_EXPIRES_STR("20"),
|
||||
//NUTAG_M_USERNAME("doubango"),
|
||||
SIPTAG_FROM_STR(this->stk->get_public_id()),
|
||||
SIPTAG_TO_STR(this->stk->get_public_id()),
|
||||
NUTAG_M_FEATURES("audio"),
|
||||
NUTAG_CALLEE_CAPS(0),
|
||||
SIPTAG_SUPPORTED_STR("timer, precondition, path, replaces, 100rel, gruu"),
|
||||
|
||||
|
||||
//NUTAG_M_FEATURES("+g.3gpp.smsip;+g.3gpp.cs-voice"),
|
||||
//TAG_IF(this->gsma_vs, NUTAG_M_FEATURES("+g.3gpp.cs-voice")),
|
||||
|
||||
TAG_END());
|
||||
this->sm_ctx.sm_registerSent();
|
||||
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
/* stop */
|
||||
ERR sip_dialog_register::Stop()
|
||||
{
|
||||
if(this->handle)
|
||||
{
|
||||
nua_unregister(this->handle, TAG_END());
|
||||
this->sm_ctx.sm_unregisterSent();
|
||||
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
else return ERR_SIP_DIALOG_UNKNOWN;
|
||||
}
|
||||
|
||||
/* state changed */
|
||||
void sip_dialog_register::OnStateChanged(SIP_STATE state)
|
||||
{
|
||||
sip_dialog::OnStateChanged(state);
|
||||
}
|
||||
|
||||
/* sip method name */
|
||||
inline const char* sip_dialog_register::get_sipmethod()const
|
||||
{
|
||||
return "REGISTER";
|
||||
}
|
||||
|
||||
/* returns true if terminated and false otherwise*/
|
||||
inline bool sip_dialog_register::get_terminated()const
|
||||
{
|
||||
return (this->state_current == SS_REGISTER_TERMINATED);
|
||||
}
|
||||
|
||||
/* dialog callback function*/
|
||||
void sip_dialog_register::dialog_callback(nua_event_t _event,
|
||||
int status, char const *phrase,
|
||||
nua_t *nua, nua_magic_t *magic,
|
||||
nua_handle_t *nh, nua_hmagic_t *hmagic,
|
||||
sip_t const *sip,
|
||||
tagi_t tags[])
|
||||
{
|
||||
switch(_event)
|
||||
{
|
||||
case nua_r_register:
|
||||
case nua_r_unregister:
|
||||
{
|
||||
if(status <200) this->sm_ctx.sm_1xx_response();
|
||||
else if(status <300) this->sm_ctx.sm_2xx_response();
|
||||
else if(status == 401 || status == 407 || status == 421 || status == 494) this->sm_ctx.sm_401_407_421_494_response();
|
||||
else this->sm_ctx.sm_unsupported_response();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PREF_NAMESPACE_END
|
|
@ -35,14 +35,32 @@
|
|||
PREF_NAMESPACE_START
|
||||
|
||||
/* REGISTER */
|
||||
class sip_dialog_register : public sip_dialog
|
||||
class DOUBANGO_API sip_dialog_register : public sip_dialog
|
||||
{
|
||||
public:
|
||||
sip_dialog_register();
|
||||
sip_dialog_register(stack* stk);
|
||||
~sip_dialog_register();
|
||||
|
||||
/* sip_dialog override*/
|
||||
ERR Start();
|
||||
ERR Stop();
|
||||
void OnStateChanged(SIP_STATE state);
|
||||
inline const char* get_sipmethod()const;
|
||||
inline bool get_terminated()const;
|
||||
void dialog_callback(nua_event_t event,
|
||||
int status, char const *phrase,
|
||||
nua_t *nua, nua_magic_t *magic,
|
||||
nua_handle_t *nh, nua_hmagic_t *hmagic,
|
||||
sip_t const *sip,
|
||||
tagi_t tags[]);
|
||||
|
||||
|
||||
bool get_registering() { return this->registering; }
|
||||
void set_registering(bool val) { this->registering = val; }
|
||||
|
||||
private:
|
||||
sip_dialog_registerContext sm_ctx;
|
||||
bool registering;
|
||||
};
|
||||
|
||||
PREF_NAMESPACE_END
|
||||
|
|
|
@ -29,8 +29,8 @@
|
|||
PREF_NAMESPACE_START
|
||||
|
||||
/* sip_dialog_subscribe constructor*/
|
||||
sip_dialog_subscribe::sip_dialog_subscribe()
|
||||
:sm_ctx(*this)
|
||||
sip_dialog_subscribe::sip_dialog_subscribe(stack* stk)
|
||||
:sip_dialog(stk),sm_ctx(*this)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ PREF_NAMESPACE_START
|
|||
class sip_dialog_subscribe : public sip_dialog
|
||||
{
|
||||
public:
|
||||
sip_dialog_subscribe();
|
||||
sip_dialog_subscribe(stack* stk);
|
||||
~sip_dialog_subscribe();
|
||||
|
||||
private:
|
||||
|
|
|
@ -43,11 +43,151 @@ namespace dgo
|
|||
{
|
||||
// Static class declarations.
|
||||
map_dialog_message_Initialized map_dialog_message::Initialized("map_dialog_message::Initialized", 0);
|
||||
map_dialog_message_Trying map_dialog_message::Trying("map_dialog_message::Trying", 1);
|
||||
map_dialog_message_Authentifying map_dialog_message::Authentifying("map_dialog_message::Authentifying", 2);
|
||||
map_dialog_message_Terminated map_dialog_message::Terminated("map_dialog_message::Terminated", 3);
|
||||
|
||||
void sip_dialog_messageState::sm_1xx_response(sip_dialog_messageContext& context)
|
||||
{
|
||||
Default(context);
|
||||
return;
|
||||
}
|
||||
|
||||
void sip_dialog_messageState::sm_2xx_response(sip_dialog_messageContext& context)
|
||||
{
|
||||
Default(context);
|
||||
return;
|
||||
}
|
||||
|
||||
void sip_dialog_messageState::sm_401_407_421_494_response(sip_dialog_messageContext& context)
|
||||
{
|
||||
Default(context);
|
||||
return;
|
||||
}
|
||||
|
||||
void sip_dialog_messageState::sm_messageSent(sip_dialog_messageContext& context)
|
||||
{
|
||||
Default(context);
|
||||
return;
|
||||
}
|
||||
|
||||
void sip_dialog_messageState::sm_unsupported_response(sip_dialog_messageContext& context)
|
||||
{
|
||||
Default(context);
|
||||
return;
|
||||
}
|
||||
|
||||
void sip_dialog_messageState::Default(sip_dialog_messageContext& context)
|
||||
{
|
||||
assert(1==0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void map_dialog_message_Default::sm_401_407_421_494_response(sip_dialog_messageContext& context)
|
||||
{
|
||||
|
||||
(context.getState()).Exit(context);
|
||||
context.setState(map_dialog_message::Authentifying);
|
||||
(context.getState()).Entry(context);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void map_dialog_message_Default::Default(sip_dialog_messageContext& context)
|
||||
{
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void map_dialog_message_Initialized::Entry(sip_dialog_messageContext& context)
|
||||
|
||||
{
|
||||
sip_dialog_message& ctxt(context.getOwner());
|
||||
|
||||
ctxt.OnStateChanged(SS_MESSAGE_INITIALIZED);
|
||||
return;
|
||||
}
|
||||
|
||||
void map_dialog_message_Initialized::sm_messageSent(sip_dialog_messageContext& context)
|
||||
{
|
||||
|
||||
(context.getState()).Exit(context);
|
||||
context.setState(map_dialog_message::Trying);
|
||||
(context.getState()).Entry(context);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void map_dialog_message_Trying::Entry(sip_dialog_messageContext& context)
|
||||
|
||||
{
|
||||
sip_dialog_message& ctxt(context.getOwner());
|
||||
|
||||
ctxt.OnStateChanged(SS_MESSAGE_TRYING);
|
||||
return;
|
||||
}
|
||||
|
||||
void map_dialog_message_Trying::sm_1xx_response(sip_dialog_messageContext& context)
|
||||
{
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void map_dialog_message_Trying::sm_2xx_response(sip_dialog_messageContext& context)
|
||||
{
|
||||
|
||||
(context.getState()).Exit(context);
|
||||
context.setState(map_dialog_message::Terminated);
|
||||
(context.getState()).Entry(context);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void map_dialog_message_Trying::sm_401_407_421_494_response(sip_dialog_messageContext& context)
|
||||
{
|
||||
|
||||
(context.getState()).Exit(context);
|
||||
context.setState(map_dialog_message::Authentifying);
|
||||
(context.getState()).Entry(context);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void map_dialog_message_Trying::sm_unsupported_response(sip_dialog_messageContext& context)
|
||||
{
|
||||
|
||||
(context.getState()).Exit(context);
|
||||
context.setState(map_dialog_message::Terminated);
|
||||
(context.getState()).Entry(context);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void map_dialog_message_Authentifying::Entry(sip_dialog_messageContext& context)
|
||||
|
||||
{
|
||||
sip_dialog_message& ctxt(context.getOwner());
|
||||
|
||||
ctxt.OnStateChanged(SS_MESSAGE_AUTHENTIFYING);
|
||||
return;
|
||||
}
|
||||
|
||||
void map_dialog_message_Terminated::Entry(sip_dialog_messageContext& context)
|
||||
|
||||
{
|
||||
sip_dialog_message& ctxt(context.getOwner());
|
||||
|
||||
ctxt.OnStateChanged(SS_MESSAGE_TERMINATED);
|
||||
return;
|
||||
}
|
||||
|
||||
void map_dialog_message_Terminated::Default(sip_dialog_messageContext& context)
|
||||
{
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,9 @@ namespace dgo
|
|||
// Forward declarations.
|
||||
class map_dialog_message;
|
||||
class map_dialog_message_Initialized;
|
||||
class map_dialog_message_Trying;
|
||||
class map_dialog_message_Authentifying;
|
||||
class map_dialog_message_Terminated;
|
||||
class map_dialog_message_Default;
|
||||
class sip_dialog_messageState;
|
||||
class sip_dialog_messageContext;
|
||||
|
@ -37,6 +40,11 @@ namespace dgo
|
|||
virtual void Entry(sip_dialog_messageContext&) {};
|
||||
virtual void Exit(sip_dialog_messageContext&) {};
|
||||
|
||||
virtual void sm_1xx_response(sip_dialog_messageContext& context);
|
||||
virtual void sm_2xx_response(sip_dialog_messageContext& context);
|
||||
virtual void sm_401_407_421_494_response(sip_dialog_messageContext& context);
|
||||
virtual void sm_messageSent(sip_dialog_messageContext& context);
|
||||
virtual void sm_unsupported_response(sip_dialog_messageContext& context);
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -48,6 +56,9 @@ namespace dgo
|
|||
public:
|
||||
|
||||
static map_dialog_message_Initialized Initialized;
|
||||
static map_dialog_message_Trying Trying;
|
||||
static map_dialog_message_Authentifying Authentifying;
|
||||
static map_dialog_message_Terminated Terminated;
|
||||
};
|
||||
|
||||
class map_dialog_message_Default :
|
||||
|
@ -59,6 +70,8 @@ namespace dgo
|
|||
: sip_dialog_messageState(name, stateId)
|
||||
{};
|
||||
|
||||
virtual void sm_401_407_421_494_response(sip_dialog_messageContext& context);
|
||||
virtual void Default(sip_dialog_messageContext& context);
|
||||
};
|
||||
|
||||
class map_dialog_message_Initialized :
|
||||
|
@ -69,6 +82,46 @@ namespace dgo
|
|||
: map_dialog_message_Default(name, stateId)
|
||||
{};
|
||||
|
||||
void Entry(sip_dialog_messageContext&);
|
||||
void sm_messageSent(sip_dialog_messageContext& context);
|
||||
};
|
||||
|
||||
class map_dialog_message_Trying :
|
||||
public map_dialog_message_Default
|
||||
{
|
||||
public:
|
||||
map_dialog_message_Trying(const char *name, int stateId)
|
||||
: map_dialog_message_Default(name, stateId)
|
||||
{};
|
||||
|
||||
void Entry(sip_dialog_messageContext&);
|
||||
void sm_1xx_response(sip_dialog_messageContext& context);
|
||||
void sm_2xx_response(sip_dialog_messageContext& context);
|
||||
void sm_401_407_421_494_response(sip_dialog_messageContext& context);
|
||||
void sm_unsupported_response(sip_dialog_messageContext& context);
|
||||
};
|
||||
|
||||
class map_dialog_message_Authentifying :
|
||||
public map_dialog_message_Default
|
||||
{
|
||||
public:
|
||||
map_dialog_message_Authentifying(const char *name, int stateId)
|
||||
: map_dialog_message_Default(name, stateId)
|
||||
{};
|
||||
|
||||
void Entry(sip_dialog_messageContext&);
|
||||
};
|
||||
|
||||
class map_dialog_message_Terminated :
|
||||
public map_dialog_message_Default
|
||||
{
|
||||
public:
|
||||
map_dialog_message_Terminated(const char *name, int stateId)
|
||||
: map_dialog_message_Default(name, stateId)
|
||||
{};
|
||||
|
||||
void Entry(sip_dialog_messageContext&);
|
||||
void Default(sip_dialog_messageContext& context);
|
||||
};
|
||||
|
||||
class sip_dialog_messageContext :
|
||||
|
@ -107,6 +160,31 @@ namespace dgo
|
|||
return (dynamic_cast<sip_dialog_messageState&>(*_state));
|
||||
};
|
||||
|
||||
void sm_1xx_response()
|
||||
{
|
||||
(getState()).sm_1xx_response(*this);
|
||||
};
|
||||
|
||||
void sm_2xx_response()
|
||||
{
|
||||
(getState()).sm_2xx_response(*this);
|
||||
};
|
||||
|
||||
void sm_401_407_421_494_response()
|
||||
{
|
||||
(getState()).sm_401_407_421_494_response(*this);
|
||||
};
|
||||
|
||||
void sm_messageSent()
|
||||
{
|
||||
(getState()).sm_messageSent(*this);
|
||||
};
|
||||
|
||||
void sm_unsupported_response()
|
||||
{
|
||||
(getState()).sm_unsupported_response(*this);
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
sip_dialog_message& _owner;
|
||||
|
|
|
@ -43,11 +43,213 @@ namespace dgo
|
|||
{
|
||||
// Static class declarations.
|
||||
map_dialog_register_Initialized map_dialog_register::Initialized("map_dialog_register::Initialized", 0);
|
||||
map_dialog_register_Trying map_dialog_register::Trying("map_dialog_register::Trying", 1);
|
||||
map_dialog_register_Established map_dialog_register::Established("map_dialog_register::Established", 2);
|
||||
map_dialog_register_Authentifying map_dialog_register::Authentifying("map_dialog_register::Authentifying", 3);
|
||||
map_dialog_register_Terminated map_dialog_register::Terminated("map_dialog_register::Terminated", 4);
|
||||
|
||||
void sip_dialog_registerState::sm_1xx_response(sip_dialog_registerContext& context)
|
||||
{
|
||||
Default(context);
|
||||
return;
|
||||
}
|
||||
|
||||
void sip_dialog_registerState::sm_2xx_response(sip_dialog_registerContext& context)
|
||||
{
|
||||
Default(context);
|
||||
return;
|
||||
}
|
||||
|
||||
void sip_dialog_registerState::sm_401_407_421_494_response(sip_dialog_registerContext& context)
|
||||
{
|
||||
Default(context);
|
||||
return;
|
||||
}
|
||||
|
||||
void sip_dialog_registerState::sm_registerSent(sip_dialog_registerContext& context)
|
||||
{
|
||||
Default(context);
|
||||
return;
|
||||
}
|
||||
|
||||
void sip_dialog_registerState::sm_unregisterSent(sip_dialog_registerContext& context)
|
||||
{
|
||||
Default(context);
|
||||
return;
|
||||
}
|
||||
|
||||
void sip_dialog_registerState::sm_unsupported_response(sip_dialog_registerContext& context)
|
||||
{
|
||||
Default(context);
|
||||
return;
|
||||
}
|
||||
|
||||
void sip_dialog_registerState::Default(sip_dialog_registerContext& context)
|
||||
{
|
||||
assert(1==0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void map_dialog_register_Default::sm_401_407_421_494_response(sip_dialog_registerContext& context)
|
||||
{
|
||||
|
||||
(context.getState()).Exit(context);
|
||||
context.setState(map_dialog_register::Authentifying);
|
||||
(context.getState()).Entry(context);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void map_dialog_register_Default::Default(sip_dialog_registerContext& context)
|
||||
{
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void map_dialog_register_Initialized::Entry(sip_dialog_registerContext& context)
|
||||
|
||||
{
|
||||
sip_dialog_register& ctxt(context.getOwner());
|
||||
|
||||
ctxt.OnStateChanged(SS_REGISTER_INITIALIZED);
|
||||
return;
|
||||
}
|
||||
|
||||
void map_dialog_register_Initialized::sm_registerSent(sip_dialog_registerContext& context)
|
||||
{
|
||||
sip_dialog_register& ctxt(context.getOwner());
|
||||
|
||||
(context.getState()).Exit(context);
|
||||
context.clearState();
|
||||
try
|
||||
{
|
||||
ctxt.set_registering(true);
|
||||
context.setState(map_dialog_register::Trying);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
context.setState(map_dialog_register::Trying);
|
||||
}
|
||||
(context.getState()).Entry(context);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void map_dialog_register_Trying::Entry(sip_dialog_registerContext& context)
|
||||
|
||||
{
|
||||
sip_dialog_register& ctxt(context.getOwner());
|
||||
|
||||
ctxt.OnStateChanged(SS_REGISTER_TRYING);
|
||||
return;
|
||||
}
|
||||
|
||||
void map_dialog_register_Trying::sm_1xx_response(sip_dialog_registerContext& context)
|
||||
{
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void map_dialog_register_Trying::sm_2xx_response(sip_dialog_registerContext& context)
|
||||
{
|
||||
sip_dialog_register& ctxt(context.getOwner());
|
||||
|
||||
if (ctxt.get_registering() == true)
|
||||
{
|
||||
(context.getState()).Exit(context);
|
||||
// No actions.
|
||||
context.setState(map_dialog_register::Established);
|
||||
(context.getState()).Entry(context);
|
||||
}
|
||||
else if (ctxt.get_registering() == false)
|
||||
|
||||
{
|
||||
(context.getState()).Exit(context);
|
||||
// No actions.
|
||||
context.setState(map_dialog_register::Terminated);
|
||||
(context.getState()).Entry(context);
|
||||
} else
|
||||
{
|
||||
map_dialog_register_Default::sm_2xx_response(context);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void map_dialog_register_Trying::sm_401_407_421_494_response(sip_dialog_registerContext& context)
|
||||
{
|
||||
|
||||
(context.getState()).Exit(context);
|
||||
context.setState(map_dialog_register::Authentifying);
|
||||
(context.getState()).Entry(context);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void map_dialog_register_Trying::sm_unsupported_response(sip_dialog_registerContext& context)
|
||||
{
|
||||
|
||||
(context.getState()).Exit(context);
|
||||
context.setState(map_dialog_register::Terminated);
|
||||
(context.getState()).Entry(context);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void map_dialog_register_Established::Entry(sip_dialog_registerContext& context)
|
||||
|
||||
{
|
||||
sip_dialog_register& ctxt(context.getOwner());
|
||||
|
||||
ctxt.OnStateChanged(SS_REGISTER_ESTABLISHED);
|
||||
return;
|
||||
}
|
||||
|
||||
void map_dialog_register_Established::sm_unregisterSent(sip_dialog_registerContext& context)
|
||||
{
|
||||
sip_dialog_register& ctxt(context.getOwner());
|
||||
|
||||
(context.getState()).Exit(context);
|
||||
context.clearState();
|
||||
try
|
||||
{
|
||||
ctxt.set_registering(false);
|
||||
context.setState(map_dialog_register::Trying);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
context.setState(map_dialog_register::Trying);
|
||||
}
|
||||
(context.getState()).Entry(context);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void map_dialog_register_Authentifying::Entry(sip_dialog_registerContext& context)
|
||||
|
||||
{
|
||||
sip_dialog_register& ctxt(context.getOwner());
|
||||
|
||||
ctxt.OnStateChanged(SS_REGISTER_AUTHENTIFYING);
|
||||
return;
|
||||
}
|
||||
|
||||
void map_dialog_register_Terminated::Entry(sip_dialog_registerContext& context)
|
||||
|
||||
{
|
||||
sip_dialog_register& ctxt(context.getOwner());
|
||||
|
||||
ctxt.OnStateChanged(SS_REGISTER_TERMINATED);
|
||||
return;
|
||||
}
|
||||
|
||||
void map_dialog_register_Terminated::Default(sip_dialog_registerContext& context)
|
||||
{
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,10 @@ namespace dgo
|
|||
// Forward declarations.
|
||||
class map_dialog_register;
|
||||
class map_dialog_register_Initialized;
|
||||
class map_dialog_register_Trying;
|
||||
class map_dialog_register_Established;
|
||||
class map_dialog_register_Authentifying;
|
||||
class map_dialog_register_Terminated;
|
||||
class map_dialog_register_Default;
|
||||
class sip_dialog_registerState;
|
||||
class sip_dialog_registerContext;
|
||||
|
@ -37,6 +41,12 @@ namespace dgo
|
|||
virtual void Entry(sip_dialog_registerContext&) {};
|
||||
virtual void Exit(sip_dialog_registerContext&) {};
|
||||
|
||||
virtual void sm_1xx_response(sip_dialog_registerContext& context);
|
||||
virtual void sm_2xx_response(sip_dialog_registerContext& context);
|
||||
virtual void sm_401_407_421_494_response(sip_dialog_registerContext& context);
|
||||
virtual void sm_registerSent(sip_dialog_registerContext& context);
|
||||
virtual void sm_unregisterSent(sip_dialog_registerContext& context);
|
||||
virtual void sm_unsupported_response(sip_dialog_registerContext& context);
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -48,6 +58,10 @@ namespace dgo
|
|||
public:
|
||||
|
||||
static map_dialog_register_Initialized Initialized;
|
||||
static map_dialog_register_Trying Trying;
|
||||
static map_dialog_register_Established Established;
|
||||
static map_dialog_register_Authentifying Authentifying;
|
||||
static map_dialog_register_Terminated Terminated;
|
||||
};
|
||||
|
||||
class map_dialog_register_Default :
|
||||
|
@ -59,6 +73,8 @@ namespace dgo
|
|||
: sip_dialog_registerState(name, stateId)
|
||||
{};
|
||||
|
||||
virtual void sm_401_407_421_494_response(sip_dialog_registerContext& context);
|
||||
virtual void Default(sip_dialog_registerContext& context);
|
||||
};
|
||||
|
||||
class map_dialog_register_Initialized :
|
||||
|
@ -69,6 +85,58 @@ namespace dgo
|
|||
: map_dialog_register_Default(name, stateId)
|
||||
{};
|
||||
|
||||
void Entry(sip_dialog_registerContext&);
|
||||
void sm_registerSent(sip_dialog_registerContext& context);
|
||||
};
|
||||
|
||||
class map_dialog_register_Trying :
|
||||
public map_dialog_register_Default
|
||||
{
|
||||
public:
|
||||
map_dialog_register_Trying(const char *name, int stateId)
|
||||
: map_dialog_register_Default(name, stateId)
|
||||
{};
|
||||
|
||||
void Entry(sip_dialog_registerContext&);
|
||||
void sm_1xx_response(sip_dialog_registerContext& context);
|
||||
void sm_2xx_response(sip_dialog_registerContext& context);
|
||||
void sm_401_407_421_494_response(sip_dialog_registerContext& context);
|
||||
void sm_unsupported_response(sip_dialog_registerContext& context);
|
||||
};
|
||||
|
||||
class map_dialog_register_Established :
|
||||
public map_dialog_register_Default
|
||||
{
|
||||
public:
|
||||
map_dialog_register_Established(const char *name, int stateId)
|
||||
: map_dialog_register_Default(name, stateId)
|
||||
{};
|
||||
|
||||
void Entry(sip_dialog_registerContext&);
|
||||
void sm_unregisterSent(sip_dialog_registerContext& context);
|
||||
};
|
||||
|
||||
class map_dialog_register_Authentifying :
|
||||
public map_dialog_register_Default
|
||||
{
|
||||
public:
|
||||
map_dialog_register_Authentifying(const char *name, int stateId)
|
||||
: map_dialog_register_Default(name, stateId)
|
||||
{};
|
||||
|
||||
void Entry(sip_dialog_registerContext&);
|
||||
};
|
||||
|
||||
class map_dialog_register_Terminated :
|
||||
public map_dialog_register_Default
|
||||
{
|
||||
public:
|
||||
map_dialog_register_Terminated(const char *name, int stateId)
|
||||
: map_dialog_register_Default(name, stateId)
|
||||
{};
|
||||
|
||||
void Entry(sip_dialog_registerContext&);
|
||||
void Default(sip_dialog_registerContext& context);
|
||||
};
|
||||
|
||||
class sip_dialog_registerContext :
|
||||
|
@ -107,6 +175,36 @@ namespace dgo
|
|||
return (dynamic_cast<sip_dialog_registerState&>(*_state));
|
||||
};
|
||||
|
||||
void sm_1xx_response()
|
||||
{
|
||||
(getState()).sm_1xx_response(*this);
|
||||
};
|
||||
|
||||
void sm_2xx_response()
|
||||
{
|
||||
(getState()).sm_2xx_response(*this);
|
||||
};
|
||||
|
||||
void sm_401_407_421_494_response()
|
||||
{
|
||||
(getState()).sm_401_407_421_494_response(*this);
|
||||
};
|
||||
|
||||
void sm_registerSent()
|
||||
{
|
||||
(getState()).sm_registerSent(*this);
|
||||
};
|
||||
|
||||
void sm_unregisterSent()
|
||||
{
|
||||
(getState()).sm_unregisterSent(*this);
|
||||
};
|
||||
|
||||
void sm_unsupported_response()
|
||||
{
|
||||
(getState()).sm_unsupported_response(*this);
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
sip_dialog_register& _owner;
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
RFC 3261
|
||||
RFC 2617
|
||||
RFC 3262
|
||||
RFC 3263
|
||||
RFC 3265
|
||||
RFC 2806
|
||||
RFC 2976
|
||||
RFC 3311
|
||||
RFC 3313
|
||||
RFC 3323
|
||||
RFC 3326
|
||||
RFC 3325
|
||||
RFC 3327
|
||||
RFC 3329
|
||||
RFC 3361
|
||||
RFC 3420
|
||||
RFC 3428
|
||||
RFC 3486
|
||||
RFC 3515
|
||||
RFC 2327
|
||||
RFC 3581
|
||||
RFC 3608
|
||||
RFC 3680
|
||||
RFC 3824
|
||||
RFC 3840
|
||||
RFC 3841
|
||||
RFC 3842
|
||||
RFC 3856
|
||||
RFC 3857
|
||||
RFC 3858
|
||||
RFC 3859
|
||||
RFC 3860
|
||||
RFC 3891
|
||||
RFC 3892
|
||||
RFC 3903
|
||||
RFC 4028
|
||||
RFC 4168
|
||||
RFC 4320
|
||||
RFC 4488
|
||||
RFC 5057
|
||||
RFC 4566
|
||||
RFC 3264
|
||||
RFC 3266
|
||||
RFC 3312
|
||||
RFC 3388
|
||||
RFC 3407
|
||||
RFC 3524
|
||||
RFC 3551
|
||||
RFC 3556
|
||||
RFC 3605
|
||||
RFC 3890
|
||||
RFC 3455
|
||||
draft-ietf-sip-outbound
|
||||
draft-ietf-sip-gruu-14
|
||||
|
|
@ -4,6 +4,10 @@
|
|||
#include "stdafx.h"
|
||||
#include <doubango.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#define STACK_ID 1234
|
||||
|
||||
int _tmain(int argc, _TCHAR* argv[])
|
||||
|
@ -12,9 +16,25 @@ int _tmain(int argc, _TCHAR* argv[])
|
|||
|
||||
assert( ERR_SUCCEED(dgo::engine_stack_create(STACK_ID)) );
|
||||
assert( ERR_SUCCEED(dgo::engine_stack_run(STACK_ID)) );
|
||||
|
||||
//Sleep(1000);
|
||||
|
||||
assert( ERR_SUCCEED(dgo::auth_set(STACK_ID, "sip:doubango@wonderland.net", "doubango", "doubango", "wonderland.net" )) );
|
||||
assert( ERR_SUCCEED(dgo::auth_set_privacy(STACK_ID, "none")) );
|
||||
assert( ERR_SUCCEED(dgo::auth_set_displayname(STACK_ID, "My display Name")) );
|
||||
assert( ERR_SUCCEED(dgo::network_set_pcscf(STACK_ID, "192.168.0.14", 5060)) );
|
||||
|
||||
assert( ERR_SUCCEED(dgo::sip_register(STACK_ID)) );
|
||||
Sleep(1000);
|
||||
assert( ERR_SUCCEED(dgo::sip_message(STACK_ID, "sip:toto@wonderland.net", "text/plain", "test")) );
|
||||
Sleep(50000);
|
||||
assert( ERR_SUCCEED(dgo::sip_unregister(STACK_ID)) );
|
||||
Sleep(5000);
|
||||
|
||||
assert( ERR_SUCCEED(dgo::engine_deinitialize()) );
|
||||
|
||||
Sleep(5000);
|
||||
// FIXME:http://209.85.229.132/search?q=cache:8_OFeYfRS9EJ:fisheye.freeswitch.org/browse/~raw,r%3D14993/FreeSWITCH/src/mod/endpoints/mod_sofia/sofia_reg.c+nua_unregister&cd=7&hl=en&ct=clnk
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue