Add support for REGISTER & MESSAGE
This commit is contained in:
parent
28745079d3
commit
ef95a195a9
|
@ -209,31 +209,31 @@
|
||||||
Name="sm"
|
Name="sm"
|
||||||
>
|
>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\sm_dialog_info_sm.h"
|
RelativePath=".\src\sm_dialog_info_sm.cxx"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\sm_dialog_invite_sm.h"
|
RelativePath=".\src\sm_dialog_invite_sm.cxx"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\sm_dialog_message_sm.h"
|
RelativePath=".\src\sm_dialog_message_sm.cxx"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\sm_dialog_options_sm.h"
|
RelativePath=".\src\sm_dialog_options_sm.cxx"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\sm_dialog_publish_sm.h"
|
RelativePath=".\src\sm_dialog_publish_sm.cxx"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\sm_dialog_register_sm.h"
|
RelativePath=".\src\sm_dialog_register_sm.cxx"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\sm_dialog_subscribe_sm.h"
|
RelativePath=".\src\sm_dialog_subscribe_sm.cxx"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
@ -245,10 +245,26 @@
|
||||||
RelativePath=".\src\api_engine.cxx"
|
RelativePath=".\src\api_engine.cxx"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<Filter
|
||||||
RelativePath=".\src\api_stack.cxx"
|
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>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
|
@ -305,31 +321,31 @@
|
||||||
Name="sm"
|
Name="sm"
|
||||||
>
|
>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\sm_dialog_info_sm.cxx"
|
RelativePath=".\src\sm_dialog_info_sm.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\sm_dialog_invite_sm.cxx"
|
RelativePath=".\src\sm_dialog_invite_sm.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\sm_dialog_message_sm.cxx"
|
RelativePath=".\src\sm_dialog_message_sm.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\sm_dialog_options_sm.cxx"
|
RelativePath=".\src\sm_dialog_options_sm.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\sm_dialog_publish_sm.cxx"
|
RelativePath=".\src\sm_dialog_publish_sm.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\sm_dialog_register_sm.cxx"
|
RelativePath=".\src\sm_dialog_register_sm.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\sm_dialog_subscribe_sm.cxx"
|
RelativePath=".\src\sm_dialog_subscribe_sm.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
@ -345,10 +361,26 @@
|
||||||
RelativePath=".\src\api_errors.h"
|
RelativePath=".\src\api_errors.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<Filter
|
||||||
RelativePath=".\src\api_stack.h"
|
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>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
|
|
|
@ -38,15 +38,32 @@
|
||||||
//-------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------
|
||||||
// Initialized
|
// Initialized
|
||||||
//-------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------
|
||||||
Initialized
|
Initialized Entry { OnStateChanged(SS_MESSAGE_INITIALIZED); }
|
||||||
Entry
|
{
|
||||||
{
|
sm_messageSent() Trying { }
|
||||||
}
|
}
|
||||||
Exit
|
|
||||||
{
|
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
|
||||||
//-------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------
|
||||||
Initialized
|
Initialized Entry { OnStateChanged(SS_REGISTER_INITIALIZED); }
|
||||||
Entry
|
{
|
||||||
{
|
sm_registerSent() Trying { set_registering(true); }
|
||||||
|
}
|
||||||
}
|
|
||||||
Exit
|
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_engine.h"
|
||||||
|
#include "api_stack.h"
|
||||||
|
|
||||||
/* TODO: add mutex */
|
/* TODO: add mutex */
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#include <sofia-sip/su.h>
|
#include <sofia-sip/su.h>
|
||||||
|
|
||||||
|
@ -58,7 +60,8 @@ ERR engine_deinitialize()
|
||||||
std::list<PSTACK>::iterator iter = __stacks.begin();
|
std::list<PSTACK>::iterator iter = __stacks.begin();
|
||||||
for ( ; iter!=__stacks.end(); iter++ )
|
for ( ; iter!=__stacks.end(); iter++ )
|
||||||
{
|
{
|
||||||
delete(*iter);
|
(*iter)->shutdown();
|
||||||
|
//delete(*iter);
|
||||||
}
|
}
|
||||||
__stacks.clear();
|
__stacks.clear();
|
||||||
|
|
||||||
|
@ -77,14 +80,14 @@ ERR engine_stack_create(int stack_id)
|
||||||
{
|
{
|
||||||
return ERR_STACK_ALREADY_EXIST;
|
return ERR_STACK_ALREADY_EXIST;
|
||||||
}
|
}
|
||||||
stack* sk = new stack(stack_id, engine_callback);
|
stack* stk = new stack(stack_id, engine_callback);
|
||||||
if(sk->get_initialized())
|
if(stk->get_initialized())
|
||||||
{
|
{
|
||||||
__stacks.push_back(sk);
|
__stacks.push_back(stk);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
delete sk;
|
delete stk;
|
||||||
return ERR_STACK_NOT_INITIALIZED;
|
return ERR_STACK_NOT_INITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +99,15 @@ ERR engine_stack_run(int stack_id)
|
||||||
{
|
{
|
||||||
if(!__initialized) return ERR_ENGINE_NOT_INITIALIZED;
|
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 */
|
/* 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;
|
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 */
|
/* shutdown downs all stacks */
|
||||||
|
@ -116,8 +135,10 @@ ERR engine_stack_shutdown_all(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find stack by id*/
|
/* 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();
|
std::list<PSTACK>::iterator iter = __stacks.begin();
|
||||||
iter = std::find_if( iter, __stacks.end(), std::bind2nd( pred_stack_find_by_id(), stack_id ) );
|
iter = std::find_if( iter, __stacks.end(), std::bind2nd( pred_stack_find_by_id(), stack_id ) );
|
||||||
if(iter != __stacks.end())
|
if(iter != __stacks.end())
|
||||||
|
@ -128,17 +149,12 @@ stack* engine_stack_find(int stack_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* engine callback*/
|
/* engine callback*/
|
||||||
void engine_callback(nua_event_t event,
|
void engine_callback(nua_event_t event, int status, char const *phrase,
|
||||||
int status,
|
nua_t *nua, nua_magic_t *magic, nua_handle_t *nh,
|
||||||
char const *phrase,
|
nua_hmagic_t *hmagic, sip_t const *sip, tagi_t tags[])
|
||||||
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
|
#undef PSTACK
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
#include "pref.h"
|
#include "pref.h"
|
||||||
#include "api_errors.h"
|
#include "api_errors.h"
|
||||||
#include "api_stack.h"
|
|
||||||
|
|
||||||
PREF_NAMESPACE_START
|
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(int stack_id);
|
||||||
DOUBANGO_API_C ERR engine_stack_shutdown_all(void);
|
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
|
PREF_NAMESPACE_END
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,13 @@ typedef enum tag_ERR
|
||||||
ERR_ENGINE_NOT_INITIALIZED, /* engine not initialized or initialization failed*/
|
ERR_ENGINE_NOT_INITIALIZED, /* engine not initialized or initialization failed*/
|
||||||
ERR_ENGINE_ALREADY_INITIALIZED, /* engine have been already initialized */
|
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 */
|
/* 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_NOT_INITIALIZED, /* stack not initialized or initialization failed*/
|
||||||
ERR_STACK_IS_INVALID, /* stack is in an invalide state (NULL, destroyed, locked, ...) */
|
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 */
|
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"
|
#include "api_stack.h"
|
||||||
|
|
||||||
|
#define DEFAULT_USER_AGENT "IM-client/OMA1.0"
|
||||||
|
|
||||||
PREF_NAMESPACE_START
|
PREF_NAMESPACE_START
|
||||||
|
|
||||||
/* stack constructor */
|
/* 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
|
// initialize memory handling
|
||||||
if( su_home_init(this->home) ) return;
|
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
|
// initialize root object
|
||||||
this->root = su_root_create(this);
|
this->root = su_root_create(this);
|
||||||
if(!this->root)
|
if(!this->root)
|
||||||
|
@ -17,7 +97,9 @@ stack::stack(int _id, nua_callback_f callback): id(_id), initialized(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// create NUA stack
|
// 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 ...*/
|
/* tags as necessary ...*/
|
||||||
TAG_NULL());
|
TAG_NULL());
|
||||||
if (!this->nua)
|
if (!this->nua)
|
||||||
|
@ -27,43 +109,55 @@ stack::stack(int _id, nua_callback_f callback): id(_id), initialized(false)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set necessary parameters
|
// FIXME
|
||||||
nua_set_params(this->nua,
|
this->running = true;
|
||||||
/* tags as necessary ...*/
|
|
||||||
TAG_NULL());
|
|
||||||
|
|
||||||
// enter main loop for processing of messages
|
// enter main loop for processing of messages
|
||||||
su_root_run(this->root);
|
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 */
|
#ifdef WIN32
|
||||||
stack::~stack()
|
/* 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
|
PREF_NAMESPACE_END
|
|
@ -2,28 +2,146 @@
|
||||||
#define __DOUBANGO_STACK_H__
|
#define __DOUBANGO_STACK_H__
|
||||||
|
|
||||||
#include "pref.h"
|
#include "pref.h"
|
||||||
|
#include "api_errors.h"
|
||||||
|
#include "sip_dialog.h"
|
||||||
#include <sofia-sip/nua.h>
|
#include <sofia-sip/nua.h>
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
PREF_NAMESPACE_START
|
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
|
class DOUBANGO_API stack
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
stack(int id, nua_callback_f callback);
|
stack(int id, nua_callback_f callback);
|
||||||
~stack();
|
~stack();
|
||||||
|
|
||||||
inline int get_id() const;
|
inline ERR run();
|
||||||
inline bool get_initialized() const;
|
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:
|
private:
|
||||||
int id;
|
int id;
|
||||||
bool initialized;
|
bool initialized;
|
||||||
|
bool running;
|
||||||
|
|
||||||
|
nua_callback_f callback;
|
||||||
|
void* thread;
|
||||||
|
|
||||||
|
std::list<sip_dialog*>dialogs;
|
||||||
|
|
||||||
su_home_t home[1]; /* memory home */
|
su_home_t home[1]; /* memory home */
|
||||||
su_root_t *root; /* root object */
|
su_root_t *root; /* root object */
|
||||||
nua_t *nua; /* NUA stack 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
|
PREF_NAMESPACE_END
|
||||||
|
|
||||||
#endif /* __DOUBANGO_STACK_H__ */
|
#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"
|
extern "C"
|
||||||
{
|
{
|
||||||
#include "api_engine.h"
|
#include "api_engine.h"
|
||||||
|
#include "api_sip.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* __DOUBANGO_DOUBANGO_H__ */
|
#endif /* __DOUBANGO_DOUBANGO_H__ */
|
|
@ -47,7 +47,7 @@
|
||||||
|
|
||||||
/* disable warnings */
|
/* disable warnings */
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#pragma warning( disable : 4132 4100 4127 4152 4355 4996)
|
#pragma warning( disable : 4132 4100 4127 4152 4355 4996 4251)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* namespace definition*/
|
/* namespace definition*/
|
||||||
|
|
|
@ -29,8 +29,10 @@
|
||||||
PREF_NAMESPACE_START
|
PREF_NAMESPACE_START
|
||||||
|
|
||||||
/* sip_dialog constructor */
|
/* sip_dialog constructor */
|
||||||
sip_dialog::sip_dialog()
|
sip_dialog::sip_dialog(stack* _stk)
|
||||||
{
|
{
|
||||||
|
this->handle = NULL;
|
||||||
|
this->stk = _stk;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sip_dialog destructor*/
|
/* 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
|
PREF_NAMESPACE_END
|
|
@ -29,14 +29,46 @@
|
||||||
#define __DOUBANGO_DIALOG_SM_H__
|
#define __DOUBANGO_DIALOG_SM_H__
|
||||||
|
|
||||||
#include "pref.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
|
PREF_NAMESPACE_START
|
||||||
|
|
||||||
class sip_dialog
|
class stack;
|
||||||
|
|
||||||
|
class DOUBANGO_API sip_dialog
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
sip_dialog();
|
sip_dialog(stack* stk);
|
||||||
~sip_dialog();
|
~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
|
PREF_NAMESPACE_END
|
||||||
|
|
|
@ -29,8 +29,8 @@
|
||||||
PREF_NAMESPACE_START
|
PREF_NAMESPACE_START
|
||||||
|
|
||||||
/* sip_dialog_info constructor*/
|
/* sip_dialog_info constructor*/
|
||||||
sip_dialog_info::sip_dialog_info()
|
sip_dialog_info::sip_dialog_info(stack* stk)
|
||||||
:sm_ctx(*this)
|
:sip_dialog(stk), sm_ctx(*this)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ PREF_NAMESPACE_START
|
||||||
class sip_dialog_info : public sip_dialog
|
class sip_dialog_info : public sip_dialog
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
sip_dialog_info();
|
sip_dialog_info(stack* stk);
|
||||||
~sip_dialog_info();
|
~sip_dialog_info();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -29,8 +29,8 @@
|
||||||
PREF_NAMESPACE_START
|
PREF_NAMESPACE_START
|
||||||
|
|
||||||
/* sip_dialog_invite constructor*/
|
/* sip_dialog_invite constructor*/
|
||||||
sip_dialog_invite::sip_dialog_invite()
|
sip_dialog_invite::sip_dialog_invite(stack* stk)
|
||||||
:sm_ctx(*this)
|
:sip_dialog(stk),sm_ctx(*this)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ PREF_NAMESPACE_START
|
||||||
class sip_dialog_invite : public sip_dialog
|
class sip_dialog_invite : public sip_dialog
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
sip_dialog_invite();
|
sip_dialog_invite(stack* stk);
|
||||||
~sip_dialog_invite();
|
~sip_dialog_invite();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -25,18 +25,99 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#include "sip_dialog_message.h"
|
#include "sip_dialog_message.h"
|
||||||
|
#include "api_stack.h"
|
||||||
|
|
||||||
PREF_NAMESPACE_START
|
PREF_NAMESPACE_START
|
||||||
|
|
||||||
/* sip_dialog_message constructor*/
|
/* sip_dialog_message constructor*/
|
||||||
sip_dialog_message::sip_dialog_message()
|
sip_dialog_message::sip_dialog_message(stack* stk, const char* _dest_address, const char* _content_type, const char* _content)
|
||||||
:sm_ctx(*this)
|
: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 destructor */
|
||||||
sip_dialog_message::~sip_dialog_message()
|
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
|
PREF_NAMESPACE_END
|
|
@ -35,14 +35,31 @@
|
||||||
PREF_NAMESPACE_START
|
PREF_NAMESPACE_START
|
||||||
|
|
||||||
/* MESSAGE */
|
/* MESSAGE */
|
||||||
class sip_dialog_message : public sip_dialog
|
class DOUBANGO_API sip_dialog_message : public sip_dialog
|
||||||
{
|
{
|
||||||
public:
|
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_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:
|
private:
|
||||||
sip_dialog_messageContext sm_ctx;
|
sip_dialog_messageContext sm_ctx;
|
||||||
|
|
||||||
|
char* dest_address;
|
||||||
|
char* content_type;
|
||||||
|
char* content;
|
||||||
};
|
};
|
||||||
|
|
||||||
PREF_NAMESPACE_END
|
PREF_NAMESPACE_END
|
||||||
|
|
|
@ -30,8 +30,8 @@
|
||||||
PREF_NAMESPACE_START
|
PREF_NAMESPACE_START
|
||||||
|
|
||||||
/* sip_dialog_message constructor*/
|
/* sip_dialog_message constructor*/
|
||||||
sip_dialog_options::sip_dialog_options()
|
sip_dialog_options::sip_dialog_options(stack* stk)
|
||||||
:sm_ctx(*this)
|
:sip_dialog(stk),sm_ctx(*this)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ PREF_NAMESPACE_START
|
||||||
class sip_dialog_options : public sip_dialog
|
class sip_dialog_options : public sip_dialog
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
sip_dialog_options();
|
sip_dialog_options(stack* stk);
|
||||||
~sip_dialog_options();
|
~sip_dialog_options();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -29,8 +29,8 @@
|
||||||
PREF_NAMESPACE_START
|
PREF_NAMESPACE_START
|
||||||
|
|
||||||
/* sip_dialog_publish constructor*/
|
/* sip_dialog_publish constructor*/
|
||||||
sip_dialog_publish::sip_dialog_publish()
|
sip_dialog_publish::sip_dialog_publish(stack* stk)
|
||||||
:sm_ctx(*this)
|
:sip_dialog(stk),sm_ctx(*this)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ PREF_NAMESPACE_START
|
||||||
class sip_dialog_publish : public sip_dialog
|
class sip_dialog_publish : public sip_dialog
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
sip_dialog_publish();
|
sip_dialog_publish(stack* stk);
|
||||||
~sip_dialog_publish();
|
~sip_dialog_publish();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -25,18 +25,116 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#include "sip_dialog_register.h"
|
#include "sip_dialog_register.h"
|
||||||
|
#include "api_stack.h"
|
||||||
|
|
||||||
PREF_NAMESPACE_START
|
PREF_NAMESPACE_START
|
||||||
|
|
||||||
/* sip_dialog_register constructor*/
|
/* sip_dialog_register constructor*/
|
||||||
sip_dialog_register::sip_dialog_register()
|
sip_dialog_register::sip_dialog_register(stack* stk)
|
||||||
:sm_ctx(*this)
|
:sip_dialog(stk),sm_ctx(*this)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sip_dialog_register destructor */
|
/* sip_dialog_register destructor */
|
||||||
sip_dialog_register::~sip_dialog_register()
|
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
|
PREF_NAMESPACE_END
|
|
@ -35,14 +35,32 @@
|
||||||
PREF_NAMESPACE_START
|
PREF_NAMESPACE_START
|
||||||
|
|
||||||
/* REGISTER */
|
/* REGISTER */
|
||||||
class sip_dialog_register : public sip_dialog
|
class DOUBANGO_API sip_dialog_register : public sip_dialog
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
sip_dialog_register();
|
sip_dialog_register(stack* stk);
|
||||||
~sip_dialog_register();
|
~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:
|
private:
|
||||||
sip_dialog_registerContext sm_ctx;
|
sip_dialog_registerContext sm_ctx;
|
||||||
|
bool registering;
|
||||||
};
|
};
|
||||||
|
|
||||||
PREF_NAMESPACE_END
|
PREF_NAMESPACE_END
|
||||||
|
|
|
@ -29,8 +29,8 @@
|
||||||
PREF_NAMESPACE_START
|
PREF_NAMESPACE_START
|
||||||
|
|
||||||
/* sip_dialog_subscribe constructor*/
|
/* sip_dialog_subscribe constructor*/
|
||||||
sip_dialog_subscribe::sip_dialog_subscribe()
|
sip_dialog_subscribe::sip_dialog_subscribe(stack* stk)
|
||||||
:sm_ctx(*this)
|
:sip_dialog(stk),sm_ctx(*this)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ PREF_NAMESPACE_START
|
||||||
class sip_dialog_subscribe : public sip_dialog
|
class sip_dialog_subscribe : public sip_dialog
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
sip_dialog_subscribe();
|
sip_dialog_subscribe(stack* stk);
|
||||||
~sip_dialog_subscribe();
|
~sip_dialog_subscribe();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -43,11 +43,151 @@ namespace dgo
|
||||||
{
|
{
|
||||||
// Static class declarations.
|
// Static class declarations.
|
||||||
map_dialog_message_Initialized map_dialog_message::Initialized("map_dialog_message::Initialized", 0);
|
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)
|
void sip_dialog_messageState::Default(sip_dialog_messageContext& context)
|
||||||
{
|
{
|
||||||
assert(1==0);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,9 @@ namespace dgo
|
||||||
// Forward declarations.
|
// Forward declarations.
|
||||||
class map_dialog_message;
|
class map_dialog_message;
|
||||||
class map_dialog_message_Initialized;
|
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 map_dialog_message_Default;
|
||||||
class sip_dialog_messageState;
|
class sip_dialog_messageState;
|
||||||
class sip_dialog_messageContext;
|
class sip_dialog_messageContext;
|
||||||
|
@ -37,6 +40,11 @@ namespace dgo
|
||||||
virtual void Entry(sip_dialog_messageContext&) {};
|
virtual void Entry(sip_dialog_messageContext&) {};
|
||||||
virtual void Exit(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:
|
protected:
|
||||||
|
|
||||||
|
@ -48,6 +56,9 @@ namespace dgo
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static map_dialog_message_Initialized Initialized;
|
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 :
|
class map_dialog_message_Default :
|
||||||
|
@ -59,6 +70,8 @@ namespace dgo
|
||||||
: sip_dialog_messageState(name, stateId)
|
: 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 :
|
class map_dialog_message_Initialized :
|
||||||
|
@ -69,6 +82,46 @@ namespace dgo
|
||||||
: map_dialog_message_Default(name, stateId)
|
: 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 :
|
class sip_dialog_messageContext :
|
||||||
|
@ -107,6 +160,31 @@ namespace dgo
|
||||||
return (dynamic_cast<sip_dialog_messageState&>(*_state));
|
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:
|
private:
|
||||||
|
|
||||||
sip_dialog_message& _owner;
|
sip_dialog_message& _owner;
|
||||||
|
|
|
@ -43,11 +43,213 @@ namespace dgo
|
||||||
{
|
{
|
||||||
// Static class declarations.
|
// Static class declarations.
|
||||||
map_dialog_register_Initialized map_dialog_register::Initialized("map_dialog_register::Initialized", 0);
|
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)
|
void sip_dialog_registerState::Default(sip_dialog_registerContext& context)
|
||||||
{
|
{
|
||||||
assert(1==0);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,10 @@ namespace dgo
|
||||||
// Forward declarations.
|
// Forward declarations.
|
||||||
class map_dialog_register;
|
class map_dialog_register;
|
||||||
class map_dialog_register_Initialized;
|
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 map_dialog_register_Default;
|
||||||
class sip_dialog_registerState;
|
class sip_dialog_registerState;
|
||||||
class sip_dialog_registerContext;
|
class sip_dialog_registerContext;
|
||||||
|
@ -37,6 +41,12 @@ namespace dgo
|
||||||
virtual void Entry(sip_dialog_registerContext&) {};
|
virtual void Entry(sip_dialog_registerContext&) {};
|
||||||
virtual void Exit(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:
|
protected:
|
||||||
|
|
||||||
|
@ -48,6 +58,10 @@ namespace dgo
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static map_dialog_register_Initialized Initialized;
|
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 :
|
class map_dialog_register_Default :
|
||||||
|
@ -59,6 +73,8 @@ namespace dgo
|
||||||
: sip_dialog_registerState(name, stateId)
|
: 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 :
|
class map_dialog_register_Initialized :
|
||||||
|
@ -69,6 +85,58 @@ namespace dgo
|
||||||
: map_dialog_register_Default(name, stateId)
|
: 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 :
|
class sip_dialog_registerContext :
|
||||||
|
@ -107,6 +175,36 @@ namespace dgo
|
||||||
return (dynamic_cast<sip_dialog_registerState&>(*_state));
|
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:
|
private:
|
||||||
|
|
||||||
sip_dialog_register& _owner;
|
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 "stdafx.h"
|
||||||
#include <doubango.h>
|
#include <doubango.h>
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#define STACK_ID 1234
|
#define STACK_ID 1234
|
||||||
|
|
||||||
int _tmain(int argc, _TCHAR* argv[])
|
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_create(STACK_ID)) );
|
||||||
assert( ERR_SUCCEED(dgo::engine_stack_run(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()) );
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue