Add support for REGISTER & MESSAGE

This commit is contained in:
imsframework 2009-10-12 01:03:35 +00:00
parent 28745079d3
commit ef95a195a9
36 changed files with 1715 additions and 121 deletions

View File

@ -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

View File

@ -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 {}
}
%%

View File

@ -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 {}
}
%%

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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

View File

@ -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__ */

View File

@ -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

View File

@ -31,6 +31,7 @@
extern "C"
{
#include "api_engine.h"
#include "api_sip.h"
}
#endif /* __DOUBANGO_DOUBANGO_H__ */

View File

@ -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*/

View File

@ -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

View File

@ -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

View File

@ -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)
{
}

View File

@ -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:

View File

@ -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)
{
}

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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)
{
}

View File

@ -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:

View File

@ -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)
{
}

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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)
{
}

View File

@ -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:

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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;

55
trunk/rfcs.txt Normal file
View File

@ -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

View File

@ -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;
}