add support for SIP SUBSCRIBE method

This commit is contained in:
imsframework 2009-10-16 00:59:16 +00:00
parent 4a0129b4ca
commit f21d586b92
15 changed files with 1006 additions and 31 deletions

View File

@ -38,15 +38,65 @@
//-------------------------------------------------------------------------------------
// Initialized
//-------------------------------------------------------------------------------------
Initialized
Entry
{
}
Exit
{
}
//
{
}
Initialized Entry { OnStateChanged(SS_SUBSCRIBE_INITIALIZED); }
{
sm_subscribeSent() Trying { }
}
Trying Entry { OnStateChanged(SS_SUBSCRIBE_TRYING); }
{
sm_1xx_response() nil {}
sm_2xx_response(unsub: bool) [unsub == true] Terminated {}
sm_2xx_response(unsub: bool) [unsub == false] Established {}
sm_3xx_response() Terminated {}
sm_401_407_421_494_response() Authentifying {}
sm_4xx_response() Terminated {}
sm_5xx_response() Terminated {}
sm_6xx_response() Terminated {}
sm_xxx_response() Terminated {}
sm_notify_response(term: bool) [term == true] Terminated { OnStateChanged(SS_SUBSCRIBE_NOTIFIED); }
sm_notify_response(term: bool) [term == false] nil { OnStateChanged(SS_SUBSCRIBE_NOTIFIED); }
sm_cancelSent() Terminated {}
Default nil {}
}
Established Entry { OnStateChanged(SS_SUBSCRIBE_ESTABLISHED); }
{
sm_1xx_response() nil {}
sm_2xx_response(unsub: bool) [unsub == true] Terminated {}
sm_2xx_response(unsub: bool) [unsub == false] nil {}
sm_401_407_421_494_response() Authentifying {}
sm_unsubscribeSent() Trying { }
sm_xxx_response() Terminated {}
sm_notify_response(term: bool) [term == true] Terminated { OnStateChanged(SS_SUBSCRIBE_NOTIFIED);}
sm_notify_response(term: bool) [term == false] nil { OnStateChanged(SS_SUBSCRIBE_NOTIFIED); }
Default nil {}
}
Authentifying Entry { OnStateChanged(SS_SUBSCRIBE_AUTHENTIFYING); }
{
sm_1xx_response() nil {}
sm_2xx_response(unsub: bool) [unsub == true] Terminated {}
sm_2xx_response(unsub: bool) [unsub == false] Established {}
sm_xxx_response() Terminated {}
sm_authentificationSent() Trying {}
Default nil {}
}
Terminated Entry { OnStateChanged(SS_SUBSCRIBE_TERMINATED); }
{
Default nil {}
}
Default Entry { OnStateChanged(SS_SUBSCRIBE_UNKNOWN); }
{
sm_401_407_421_494_response() Authentifying {}
sm_3xx_response() nil {}
sm_4xx_response() nil {}
sm_5xx_response() nil {}
sm_6xx_response() nil {}
sm_xxx_response() nil {}
Default nil {}
}
%%

View File

@ -64,6 +64,23 @@ ERR sip_unpublish(int stack_id)
return stk->sip_unpublish();
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// sip SUBSCRIBE
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/* send sip SUBSCRIBE */
DOUBANGO_API_C ERR sip_subscribe(int stack_id, const char* dest_address, const char* eventpackg, const char* allow, int eventlist, unsigned int* dialog_id)
{
GET_STACK(stack_id, stk);
return stk->sip_subscribe(dest_address, eventpackg, allow, eventlist, dialog_id);
}
/* send sip UNSUBSCRIBE */
DOUBANGO_API_C ERR sip_unsubscribe(int stack_id, unsigned int dialog_id)
{
GET_STACK(stack_id, stk);
return stk->sip_unsubscribe(dialog_id);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// authentication
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -23,6 +23,12 @@ DOUBANGO_API_C ERR sip_message(int stack_id, const char* dest_address, const cha
DOUBANGO_API_C ERR sip_publish(int stack_id);
DOUBANGO_API_C ERR sip_unpublish(int stack_id);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// sip SUBSCRIBE
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
DOUBANGO_API_C ERR sip_subscribe(int stack_id, const char* dest_address, const char* eventpackg, const char* allow, int eventlist, unsigned int* dialog_id);
DOUBANGO_API_C ERR sip_unsubscribe(int stack_id, unsigned int dialog_id);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// authentication
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -25,6 +25,15 @@ typedef enum tag_SIP_STATE
SS_PUBLISH_ESTABLISHED,
SS_PUBLISH_TERMINATED,
/* SUBSCRIBE */
SS_SUBSCRIBE_UNKNOWN,
SS_SUBSCRIBE_INITIALIZED,
SS_SUBSCRIBE_TRYING,
SS_SUBSCRIBE_AUTHENTIFYING,
SS_SUBSCRIBE_ESTABLISHED,
SS_SUBSCRIBE_NOTIFIED,
SS_SUBSCRIBE_TERMINATED,
/* MESSAGE */
SS_MESSAGE_UNKNOWN,
SS_MESSAGE_INITIALIZED,

View File

@ -16,6 +16,12 @@ PREF_NAMESPACE_START
inline type &get_##member(){ return this->##member; } \
inline void set_##member(type val){ this->##member = val; }
/* predicate: find dialog by id */
struct pred_dialog_find_by_id: public std::binary_function< sip_dialog*, unsigned int, bool > {
bool operator () ( const sip_dialog* dlg, unsigned int dialog_id ) const {
return dlg->get_dialog_id() == dialog_id;
}
};
/* 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 {
@ -35,17 +41,18 @@ struct pred_dialog_find_by_sipmethod: public std::binary_function< sip_dialog*,
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) \
/* get dialog by xxx */
#define GET_DIALOG_BY_XXX(dlg, predicate, xxx) \
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 ) ); \
std::list<sip_dialog*>::iterator iter = std::find_if( this->dialogs.begin(), this->dialogs.end(), std::bind2nd( predicate(), xxx ) ); \
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;
/* get dialog by sipmethod*/
#define GET_DIALOG_BY_SIPMETHOD(dlg, sipmethod) GET_DIALOG_BY_XXX(dlg, pred_dialog_find_by_sipmethod, sipmethod)
/* get dialog by handle */
#define GET_DIALOG_BY_HANDLE(dlg, handle) GET_DIALOG_BY_XXX(dlg, pred_dialog_find_by_handle, handle)
/* get dialog by id */
#define GET_DIALOG_BY_ID(dlg, dialog_id) GET_DIALOG_BY_XXX(dlg, pred_dialog_find_by_id, dialog_id)
class DOUBANGO_API stack
{
@ -73,6 +80,9 @@ public:
ERR sip_publish();
ERR sip_unpublish();
ERR sip_subscribe(const char* dest_address, const char* eventpackg, const char* allow, int eventlist, unsigned int* dialog_id);
ERR sip_unsubscribe(unsigned int dialog_id);
//
// Authentication
//

View File

@ -2,6 +2,7 @@
#include "sip_dialog_register.h"
#include "sip_dialog_message.h"
#include "sip_dialog_publish.h"
#include "sip_dialog_subscribe.h"
PREF_NAMESPACE_START
@ -61,4 +62,23 @@ ERR stack::sip_unpublish()
else return ERR_SIP_DIALOG_NOT_FOUND;
}
/* SIP SUBSCRIBE */
ERR stack::sip_subscribe(const char* dest_address, const char* eventpackg, const char* allow, int eventlist, unsigned int* dialog_id)
{
sip_dialog_subscribe* dlg_subscribe = new sip_dialog_subscribe(this, dest_address, eventpackg, allow, eventlist?true:false);
*dialog_id = dlg_subscribe->get_dialog_id();
this->dialogs.push_back(dlg_subscribe);
return dlg_subscribe->Start();
}
/* SIP UNSUBSCRIBE*/
ERR stack::sip_unsubscribe(unsigned int dialog_id)
{
GET_DIALOG_BY_ID(dlg, dialog_id);
if(dlg){
return dlg->Stop();
}
else return ERR_SIP_DIALOG_NOT_FOUND;
}
PREF_NAMESPACE_END

View File

@ -33,11 +33,14 @@
PREF_NAMESPACE_START
unsigned int sip_dialog::dialog_counter = 0;
/* sip_dialog constructor */
sip_dialog::sip_dialog(stack* _stk)
{
this->handle = NULL;
this->stk = _stk;
this->dialog_id = (++sip_dialog::dialog_counter);
}
/* sip_dialog destructor*/

View File

@ -51,6 +51,8 @@ public:
inline SIP_STATE get_state_current() const{ return this->state_current; }
inline void set_state_current(SIP_STATE s) { this->state_current = s; }
inline unsigned int get_dialog_id() const{ return this->dialog_id; }
virtual ERR Start() = 0;
virtual ERR Stop() = 0;
virtual void OnStateChanged(SIP_STATE state);
@ -71,6 +73,10 @@ protected:
nua_handle_t* handle;
stack* stk;
SIP_STATE state_current;
unsigned int dialog_id;
private:
static unsigned int dialog_counter;
};
PREF_NAMESPACE_END

View File

@ -134,7 +134,9 @@ ERR sip_dialog_publish::sendUnpublish()
{
if(this->handle)
{
nua_unpublish(this->handle, TAG_END());
nua_publish(this->handle,
NUTAG_M_FEATURES("expires=0"),// FIXME
TAG_END());
this->sm_ctx.sm_unpublishSent();
return ERR_SUCCESS;

View File

@ -25,18 +25,170 @@
*
*/
#include "sip_dialog_subscribe.h"
#include "api_stack.h"
PREF_NAMESPACE_START
/* sip_dialog_subscribe constructor*/
sip_dialog_subscribe::sip_dialog_subscribe(stack* stk)
sip_dialog_subscribe::sip_dialog_subscribe(stack* stk, const char* _dest_address, const char* _eventpackg, const char* _allow, bool _eventlist)
:sip_dialog(stk),sm_ctx(*this)
{
this->dest_address = su_strdup(this->stk->get_home(), _dest_address);
this->eventpackg = su_strdup(this->stk->get_home(), _eventpackg);
this->allow = su_strdup(this->stk->get_home(), _allow);
this->eventlist = _eventlist;
}
/* sip_dialog_subscribe destructor */
sip_dialog_subscribe::~sip_dialog_subscribe()
{
// FIXME: destroy handle
su_free(this->stk->get_home(), this->dest_address);
su_free(this->stk->get_home(), this->eventpackg);
su_free(this->stk->get_home(), this->allow);
}
/* start */
ERR sip_dialog_subscribe::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;
}
return this->sendSubscribe();
}
/* stop */
ERR sip_dialog_subscribe::Stop()
{
ERR err = (this->state_current == SS_SUBSCRIBE_ESTABLISHED) ?
this->sendUnsubscribe() : this->sendCancel();
return err;
}
/* state changed */
void sip_dialog_subscribe::OnStateChanged(SIP_STATE state)
{
sip_dialog::OnStateChanged(state);
#if 1
if(this->get_terminated())
{
printf("SUBSCRIBE terminated\n");
}
#endif
}
/* sip method name */
inline const char* sip_dialog_subscribe::get_sipmethod()const
{
return "SUBSCRIBE";
}
/* returns true if terminated and false otherwise*/
inline bool sip_dialog_subscribe::get_terminated()const
{
return (this->state_current == SS_SUBSCRIBE_TERMINATED);
}
/* send SIP SUBSCRIBE request */
ERR sip_dialog_subscribe::sendSubscribe()
{
if(!this->handle) return ERR_SIP_DIALOG_UNKNOWN;
nua_subscribe(this->handle,
SIPTAG_PRIVACY_STR(this->stk->get_privacy()),
SIPTAG_FROM_STR(this->stk->get_public_id()),
SIPTAG_TO_STR(this->dest_address),
NUTAG_M_FEATURES("expires=200"),// FIXME
SIPTAG_ACCEPT_STR(this->allow),
TAG_IF(eventlist, SIPTAG_SUPPORTED_STR("eventlist")),
SIPTAG_EVENT_STR(this->eventpackg),
TAG_END());
this->sm_ctx.sm_subscribeSent();
return ERR_SUCCESS;
}
/* send SIP UNSUBSCRIBE request*/
ERR sip_dialog_subscribe::sendUnsubscribe()
{
if(this->handle)
{
nua_subscribe(this->handle,
NUTAG_M_FEATURES("expires=0"),// FIXME
TAG_END());
this->sm_ctx.sm_unsubscribeSent();
return ERR_SUCCESS;
}
else return ERR_SIP_DIALOG_UNKNOWN;
}
/* cancel request */
ERR sip_dialog_subscribe::sendCancel()
{
if(this->handle)
{
nua_cancel(this->handle, TAG_END());
this->sm_ctx.sm_cancelSent();
return ERR_SUCCESS;
}
else return ERR_SIP_DIALOG_UNKNOWN;
}
/* dialog callback function*/
void sip_dialog_subscribe::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_subscribe:
case nua_r_unsubscribe:
{
if(status <200) this->sm_ctx.sm_1xx_response();
else if(status <300) this->sm_ctx.sm_2xx_response( (_event==nua_r_unsubscribe) );
else if(status <400) this->sm_ctx.sm_3xx_response();
else if(status == 401 || status == 407 || status == 421 || status == 494)
{
this->sm_ctx.sm_401_407_421_494_response();
this->authenticate(nh, sip);
this->sm_ctx.sm_authentificationSent();
}
else if(status<500) this->sm_ctx.sm_4xx_response();
else if(status<600) this->sm_ctx.sm_5xx_response();
else if(status<700) this->sm_ctx.sm_6xx_response();
else this->sm_ctx.sm_xxx_response();
break;
}
case nua_i_notify:
{
// FIXME: handled by nea layer?
/*if(sip && sip->sip_subscription_state)
{
bool term = !stricmp(sip->sip_subscription_state->ss_substate, "terminated");
this->sm_ctx.sm_notify_response(term);
}*/
break;
}
default:
{
break;
}
}
}
PREF_NAMESPACE_END

View File

@ -38,11 +38,33 @@ PREF_NAMESPACE_START
class sip_dialog_subscribe : public sip_dialog
{
public:
sip_dialog_subscribe(stack* stk);
sip_dialog_subscribe(stack* stk, const char* dest_address, const char* eventpackg, const char* allow, bool eventlist);
~sip_dialog_subscribe();
/* 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:
ERR sendSubscribe();
ERR sendUnsubscribe();
ERR sendCancel();
private:
sip_dialog_subscribeContext sm_ctx;
char* dest_address;
char* eventpackg;
char* allow;
bool eventlist;
};
PREF_NAMESPACE_END

View File

@ -43,11 +43,525 @@ namespace dgo
{
// Static class declarations.
map_dialog_subscribe_Initialized map_dialog_subscribe::Initialized("map_dialog_subscribe::Initialized", 0);
map_dialog_subscribe_Trying map_dialog_subscribe::Trying("map_dialog_subscribe::Trying", 1);
map_dialog_subscribe_Established map_dialog_subscribe::Established("map_dialog_subscribe::Established", 2);
map_dialog_subscribe_Authentifying map_dialog_subscribe::Authentifying("map_dialog_subscribe::Authentifying", 3);
map_dialog_subscribe_Terminated map_dialog_subscribe::Terminated("map_dialog_subscribe::Terminated", 4);
void sip_dialog_subscribeState::sm_1xx_response(sip_dialog_subscribeContext& context)
{
Default(context);
return;
}
void sip_dialog_subscribeState::sm_2xx_response(sip_dialog_subscribeContext& context, bool unsub)
{
Default(context);
return;
}
void sip_dialog_subscribeState::sm_3xx_response(sip_dialog_subscribeContext& context)
{
Default(context);
return;
}
void sip_dialog_subscribeState::sm_401_407_421_494_response(sip_dialog_subscribeContext& context)
{
Default(context);
return;
}
void sip_dialog_subscribeState::sm_4xx_response(sip_dialog_subscribeContext& context)
{
Default(context);
return;
}
void sip_dialog_subscribeState::sm_5xx_response(sip_dialog_subscribeContext& context)
{
Default(context);
return;
}
void sip_dialog_subscribeState::sm_6xx_response(sip_dialog_subscribeContext& context)
{
Default(context);
return;
}
void sip_dialog_subscribeState::sm_authentificationSent(sip_dialog_subscribeContext& context)
{
Default(context);
return;
}
void sip_dialog_subscribeState::sm_cancelSent(sip_dialog_subscribeContext& context)
{
Default(context);
return;
}
void sip_dialog_subscribeState::sm_notify_response(sip_dialog_subscribeContext& context, bool term)
{
Default(context);
return;
}
void sip_dialog_subscribeState::sm_subscribeSent(sip_dialog_subscribeContext& context)
{
Default(context);
return;
}
void sip_dialog_subscribeState::sm_unsubscribeSent(sip_dialog_subscribeContext& context)
{
Default(context);
return;
}
void sip_dialog_subscribeState::sm_xxx_response(sip_dialog_subscribeContext& context)
{
Default(context);
return;
}
void sip_dialog_subscribeState::Default(sip_dialog_subscribeContext& context)
{
assert(1==0);
return;
}
void map_dialog_subscribe_Default::sm_401_407_421_494_response(sip_dialog_subscribeContext& context)
{
(context.getState()).Exit(context);
context.setState(map_dialog_subscribe::Authentifying);
(context.getState()).Entry(context);
return;
}
void map_dialog_subscribe_Default::sm_3xx_response(sip_dialog_subscribeContext& context)
{
return;
}
void map_dialog_subscribe_Default::sm_4xx_response(sip_dialog_subscribeContext& context)
{
return;
}
void map_dialog_subscribe_Default::sm_5xx_response(sip_dialog_subscribeContext& context)
{
return;
}
void map_dialog_subscribe_Default::sm_6xx_response(sip_dialog_subscribeContext& context)
{
return;
}
void map_dialog_subscribe_Default::sm_xxx_response(sip_dialog_subscribeContext& context)
{
return;
}
void map_dialog_subscribe_Default::Default(sip_dialog_subscribeContext& context)
{
return;
}
void map_dialog_subscribe_Initialized::Entry(sip_dialog_subscribeContext& context)
{
sip_dialog_subscribe& ctxt(context.getOwner());
ctxt.OnStateChanged(SS_SUBSCRIBE_INITIALIZED);
return;
}
void map_dialog_subscribe_Initialized::sm_subscribeSent(sip_dialog_subscribeContext& context)
{
(context.getState()).Exit(context);
context.setState(map_dialog_subscribe::Trying);
(context.getState()).Entry(context);
return;
}
void map_dialog_subscribe_Trying::Entry(sip_dialog_subscribeContext& context)
{
sip_dialog_subscribe& ctxt(context.getOwner());
ctxt.OnStateChanged(SS_SUBSCRIBE_TRYING);
return;
}
void map_dialog_subscribe_Trying::Default(sip_dialog_subscribeContext& context)
{
return;
}
void map_dialog_subscribe_Trying::sm_1xx_response(sip_dialog_subscribeContext& context)
{
return;
}
void map_dialog_subscribe_Trying::sm_2xx_response(sip_dialog_subscribeContext& context, bool unsub)
{
if (unsub == true)
{
(context.getState()).Exit(context);
// No actions.
context.setState(map_dialog_subscribe::Terminated);
(context.getState()).Entry(context);
}
else if (unsub == false)
{
(context.getState()).Exit(context);
// No actions.
context.setState(map_dialog_subscribe::Established);
(context.getState()).Entry(context);
} else
{
map_dialog_subscribe_Default::sm_2xx_response(context, unsub);
}
return;
}
void map_dialog_subscribe_Trying::sm_3xx_response(sip_dialog_subscribeContext& context)
{
(context.getState()).Exit(context);
context.setState(map_dialog_subscribe::Terminated);
(context.getState()).Entry(context);
return;
}
void map_dialog_subscribe_Trying::sm_401_407_421_494_response(sip_dialog_subscribeContext& context)
{
(context.getState()).Exit(context);
context.setState(map_dialog_subscribe::Authentifying);
(context.getState()).Entry(context);
return;
}
void map_dialog_subscribe_Trying::sm_4xx_response(sip_dialog_subscribeContext& context)
{
(context.getState()).Exit(context);
context.setState(map_dialog_subscribe::Terminated);
(context.getState()).Entry(context);
return;
}
void map_dialog_subscribe_Trying::sm_5xx_response(sip_dialog_subscribeContext& context)
{
(context.getState()).Exit(context);
context.setState(map_dialog_subscribe::Terminated);
(context.getState()).Entry(context);
return;
}
void map_dialog_subscribe_Trying::sm_6xx_response(sip_dialog_subscribeContext& context)
{
(context.getState()).Exit(context);
context.setState(map_dialog_subscribe::Terminated);
(context.getState()).Entry(context);
return;
}
void map_dialog_subscribe_Trying::sm_cancelSent(sip_dialog_subscribeContext& context)
{
(context.getState()).Exit(context);
context.setState(map_dialog_subscribe::Terminated);
(context.getState()).Entry(context);
return;
}
void map_dialog_subscribe_Trying::sm_notify_response(sip_dialog_subscribeContext& context, bool term)
{
sip_dialog_subscribe& ctxt(context.getOwner());
if (term == true)
{
(context.getState()).Exit(context);
context.clearState();
try
{
ctxt.OnStateChanged(SS_SUBSCRIBE_NOTIFIED);
context.setState(map_dialog_subscribe::Terminated);
}
catch (...)
{
context.setState(map_dialog_subscribe::Terminated);
}
(context.getState()).Entry(context);
}
else if (term == false)
{
sip_dialog_subscribeState& endState = context.getState();
context.clearState();
try
{
ctxt.OnStateChanged(SS_SUBSCRIBE_NOTIFIED);
context.setState(endState);
}
catch (...)
{
context.setState(endState);
}
} else
{
map_dialog_subscribe_Default::sm_notify_response(context, term);
}
return;
}
void map_dialog_subscribe_Trying::sm_xxx_response(sip_dialog_subscribeContext& context)
{
(context.getState()).Exit(context);
context.setState(map_dialog_subscribe::Terminated);
(context.getState()).Entry(context);
return;
}
void map_dialog_subscribe_Established::Entry(sip_dialog_subscribeContext& context)
{
sip_dialog_subscribe& ctxt(context.getOwner());
ctxt.OnStateChanged(SS_SUBSCRIBE_ESTABLISHED);
return;
}
void map_dialog_subscribe_Established::Default(sip_dialog_subscribeContext& context)
{
return;
}
void map_dialog_subscribe_Established::sm_1xx_response(sip_dialog_subscribeContext& context)
{
return;
}
void map_dialog_subscribe_Established::sm_2xx_response(sip_dialog_subscribeContext& context, bool unsub)
{
if (unsub == true)
{
(context.getState()).Exit(context);
// No actions.
context.setState(map_dialog_subscribe::Terminated);
(context.getState()).Entry(context);
}
else if (unsub == false)
{
// No actions.
} else
{
map_dialog_subscribe_Default::sm_2xx_response(context, unsub);
}
return;
}
void map_dialog_subscribe_Established::sm_401_407_421_494_response(sip_dialog_subscribeContext& context)
{
(context.getState()).Exit(context);
context.setState(map_dialog_subscribe::Authentifying);
(context.getState()).Entry(context);
return;
}
void map_dialog_subscribe_Established::sm_notify_response(sip_dialog_subscribeContext& context, bool term)
{
sip_dialog_subscribe& ctxt(context.getOwner());
if (term == true)
{
(context.getState()).Exit(context);
context.clearState();
try
{
ctxt.OnStateChanged(SS_SUBSCRIBE_NOTIFIED);
context.setState(map_dialog_subscribe::Terminated);
}
catch (...)
{
context.setState(map_dialog_subscribe::Terminated);
}
(context.getState()).Entry(context);
}
else if (term == false)
{
sip_dialog_subscribeState& endState = context.getState();
context.clearState();
try
{
ctxt.OnStateChanged(SS_SUBSCRIBE_NOTIFIED);
context.setState(endState);
}
catch (...)
{
context.setState(endState);
}
} else
{
map_dialog_subscribe_Default::sm_notify_response(context, term);
}
return;
}
void map_dialog_subscribe_Established::sm_unsubscribeSent(sip_dialog_subscribeContext& context)
{
(context.getState()).Exit(context);
context.setState(map_dialog_subscribe::Trying);
(context.getState()).Entry(context);
return;
}
void map_dialog_subscribe_Established::sm_xxx_response(sip_dialog_subscribeContext& context)
{
(context.getState()).Exit(context);
context.setState(map_dialog_subscribe::Terminated);
(context.getState()).Entry(context);
return;
}
void map_dialog_subscribe_Authentifying::Entry(sip_dialog_subscribeContext& context)
{
sip_dialog_subscribe& ctxt(context.getOwner());
ctxt.OnStateChanged(SS_SUBSCRIBE_AUTHENTIFYING);
return;
}
void map_dialog_subscribe_Authentifying::Default(sip_dialog_subscribeContext& context)
{
return;
}
void map_dialog_subscribe_Authentifying::sm_1xx_response(sip_dialog_subscribeContext& context)
{
return;
}
void map_dialog_subscribe_Authentifying::sm_2xx_response(sip_dialog_subscribeContext& context, bool unsub)
{
if (unsub == true)
{
(context.getState()).Exit(context);
// No actions.
context.setState(map_dialog_subscribe::Terminated);
(context.getState()).Entry(context);
}
else if (unsub == false)
{
(context.getState()).Exit(context);
// No actions.
context.setState(map_dialog_subscribe::Established);
(context.getState()).Entry(context);
} else
{
map_dialog_subscribe_Default::sm_2xx_response(context, unsub);
}
return;
}
void map_dialog_subscribe_Authentifying::sm_authentificationSent(sip_dialog_subscribeContext& context)
{
(context.getState()).Exit(context);
context.setState(map_dialog_subscribe::Trying);
(context.getState()).Entry(context);
return;
}
void map_dialog_subscribe_Authentifying::sm_xxx_response(sip_dialog_subscribeContext& context)
{
(context.getState()).Exit(context);
context.setState(map_dialog_subscribe::Terminated);
(context.getState()).Entry(context);
return;
}
void map_dialog_subscribe_Terminated::Entry(sip_dialog_subscribeContext& context)
{
sip_dialog_subscribe& ctxt(context.getOwner());
ctxt.OnStateChanged(SS_SUBSCRIBE_TERMINATED);
return;
}
void map_dialog_subscribe_Terminated::Default(sip_dialog_subscribeContext& context)
{
return;
}
}

View File

@ -20,6 +20,10 @@ namespace dgo
// Forward declarations.
class map_dialog_subscribe;
class map_dialog_subscribe_Initialized;
class map_dialog_subscribe_Trying;
class map_dialog_subscribe_Established;
class map_dialog_subscribe_Authentifying;
class map_dialog_subscribe_Terminated;
class map_dialog_subscribe_Default;
class sip_dialog_subscribeState;
class sip_dialog_subscribeContext;
@ -37,6 +41,19 @@ namespace dgo
virtual void Entry(sip_dialog_subscribeContext&) {};
virtual void Exit(sip_dialog_subscribeContext&) {};
virtual void sm_1xx_response(sip_dialog_subscribeContext& context);
virtual void sm_2xx_response(sip_dialog_subscribeContext& context, bool unsub);
virtual void sm_3xx_response(sip_dialog_subscribeContext& context);
virtual void sm_401_407_421_494_response(sip_dialog_subscribeContext& context);
virtual void sm_4xx_response(sip_dialog_subscribeContext& context);
virtual void sm_5xx_response(sip_dialog_subscribeContext& context);
virtual void sm_6xx_response(sip_dialog_subscribeContext& context);
virtual void sm_authentificationSent(sip_dialog_subscribeContext& context);
virtual void sm_cancelSent(sip_dialog_subscribeContext& context);
virtual void sm_notify_response(sip_dialog_subscribeContext& context, bool term);
virtual void sm_subscribeSent(sip_dialog_subscribeContext& context);
virtual void sm_unsubscribeSent(sip_dialog_subscribeContext& context);
virtual void sm_xxx_response(sip_dialog_subscribeContext& context);
protected:
@ -48,6 +65,10 @@ namespace dgo
public:
static map_dialog_subscribe_Initialized Initialized;
static map_dialog_subscribe_Trying Trying;
static map_dialog_subscribe_Established Established;
static map_dialog_subscribe_Authentifying Authentifying;
static map_dialog_subscribe_Terminated Terminated;
};
class map_dialog_subscribe_Default :
@ -59,6 +80,13 @@ namespace dgo
: sip_dialog_subscribeState(name, stateId)
{};
virtual void sm_401_407_421_494_response(sip_dialog_subscribeContext& context);
virtual void sm_3xx_response(sip_dialog_subscribeContext& context);
virtual void sm_4xx_response(sip_dialog_subscribeContext& context);
virtual void sm_5xx_response(sip_dialog_subscribeContext& context);
virtual void sm_6xx_response(sip_dialog_subscribeContext& context);
virtual void sm_xxx_response(sip_dialog_subscribeContext& context);
virtual void Default(sip_dialog_subscribeContext& context);
};
class map_dialog_subscribe_Initialized :
@ -69,6 +97,76 @@ namespace dgo
: map_dialog_subscribe_Default(name, stateId)
{};
void Entry(sip_dialog_subscribeContext&);
void sm_subscribeSent(sip_dialog_subscribeContext& context);
};
class map_dialog_subscribe_Trying :
public map_dialog_subscribe_Default
{
public:
map_dialog_subscribe_Trying(const char *name, int stateId)
: map_dialog_subscribe_Default(name, stateId)
{};
void Entry(sip_dialog_subscribeContext&);
void Default(sip_dialog_subscribeContext& context);
void sm_1xx_response(sip_dialog_subscribeContext& context);
void sm_2xx_response(sip_dialog_subscribeContext& context, bool unsub);
void sm_3xx_response(sip_dialog_subscribeContext& context);
void sm_401_407_421_494_response(sip_dialog_subscribeContext& context);
void sm_4xx_response(sip_dialog_subscribeContext& context);
void sm_5xx_response(sip_dialog_subscribeContext& context);
void sm_6xx_response(sip_dialog_subscribeContext& context);
void sm_cancelSent(sip_dialog_subscribeContext& context);
void sm_notify_response(sip_dialog_subscribeContext& context, bool term);
void sm_xxx_response(sip_dialog_subscribeContext& context);
};
class map_dialog_subscribe_Established :
public map_dialog_subscribe_Default
{
public:
map_dialog_subscribe_Established(const char *name, int stateId)
: map_dialog_subscribe_Default(name, stateId)
{};
void Entry(sip_dialog_subscribeContext&);
void Default(sip_dialog_subscribeContext& context);
void sm_1xx_response(sip_dialog_subscribeContext& context);
void sm_2xx_response(sip_dialog_subscribeContext& context, bool unsub);
void sm_401_407_421_494_response(sip_dialog_subscribeContext& context);
void sm_notify_response(sip_dialog_subscribeContext& context, bool term);
void sm_unsubscribeSent(sip_dialog_subscribeContext& context);
void sm_xxx_response(sip_dialog_subscribeContext& context);
};
class map_dialog_subscribe_Authentifying :
public map_dialog_subscribe_Default
{
public:
map_dialog_subscribe_Authentifying(const char *name, int stateId)
: map_dialog_subscribe_Default(name, stateId)
{};
void Entry(sip_dialog_subscribeContext&);
void Default(sip_dialog_subscribeContext& context);
void sm_1xx_response(sip_dialog_subscribeContext& context);
void sm_2xx_response(sip_dialog_subscribeContext& context, bool unsub);
void sm_authentificationSent(sip_dialog_subscribeContext& context);
void sm_xxx_response(sip_dialog_subscribeContext& context);
};
class map_dialog_subscribe_Terminated :
public map_dialog_subscribe_Default
{
public:
map_dialog_subscribe_Terminated(const char *name, int stateId)
: map_dialog_subscribe_Default(name, stateId)
{};
void Entry(sip_dialog_subscribeContext&);
void Default(sip_dialog_subscribeContext& context);
};
class sip_dialog_subscribeContext :
@ -107,6 +205,71 @@ namespace dgo
return (dynamic_cast<sip_dialog_subscribeState&>(*_state));
};
void sm_1xx_response()
{
(getState()).sm_1xx_response(*this);
};
void sm_2xx_response(bool unsub)
{
(getState()).sm_2xx_response(*this, unsub);
};
void sm_3xx_response()
{
(getState()).sm_3xx_response(*this);
};
void sm_401_407_421_494_response()
{
(getState()).sm_401_407_421_494_response(*this);
};
void sm_4xx_response()
{
(getState()).sm_4xx_response(*this);
};
void sm_5xx_response()
{
(getState()).sm_5xx_response(*this);
};
void sm_6xx_response()
{
(getState()).sm_6xx_response(*this);
};
void sm_authentificationSent()
{
(getState()).sm_authentificationSent(*this);
};
void sm_cancelSent()
{
(getState()).sm_cancelSent(*this);
};
void sm_notify_response(bool term)
{
(getState()).sm_notify_response(*this, term);
};
void sm_subscribeSent()
{
(getState()).sm_subscribeSent(*this);
};
void sm_unsubscribeSent()
{
(getState()).sm_unsubscribeSent(*this);
};
void sm_xxx_response()
{
(getState()).sm_xxx_response(*this);
};
private:
sip_dialog_subscribe& _owner;

View File

@ -3,12 +3,12 @@ set SMC_HOME=%ROOT_DIR%\SMC_6_0_0
set SM_DIR=%ROOT_DIR%\doubango\sm
set SRC_DIR=%ROOT_DIR%\doubango\src
java -jar %SMC_HOME%\Smc.jar -c++ -suffix cxx -verbose -noex -d %SRC_DIR% %SM_DIR%\sm_dialog_info.sm
java -jar %SMC_HOME%\Smc.jar -c++ -suffix cxx -verbose -noex -d %SRC_DIR% %SM_DIR%\sm_dialog_invite.sm
java -jar %SMC_HOME%\Smc.jar -c++ -suffix cxx -verbose -noex -d %SRC_DIR% %SM_DIR%\sm_dialog_message.sm
java -jar %SMC_HOME%\Smc.jar -c++ -suffix cxx -verbose -noex -d %SRC_DIR% %SM_DIR%\sm_dialog_options.sm
java -jar %SMC_HOME%\Smc.jar -c++ -suffix cxx -verbose -noex -d %SRC_DIR% %SM_DIR%\sm_dialog_publish.sm
java -jar %SMC_HOME%\Smc.jar -c++ -suffix cxx -verbose -noex -d %SRC_DIR% %SM_DIR%\sm_dialog_register.sm
rem java -jar %SMC_HOME%\Smc.jar -c++ -suffix cxx -verbose -noex -d %SRC_DIR% %SM_DIR%\sm_dialog_info.sm
rem java -jar %SMC_HOME%\Smc.jar -c++ -suffix cxx -verbose -noex -d %SRC_DIR% %SM_DIR%\sm_dialog_invite.sm
rem java -jar %SMC_HOME%\Smc.jar -c++ -suffix cxx -verbose -noex -d %SRC_DIR% %SM_DIR%\sm_dialog_message.sm
rem java -jar %SMC_HOME%\Smc.jar -c++ -suffix cxx -verbose -noex -d %SRC_DIR% %SM_DIR%\sm_dialog_options.sm
rem java -jar %SMC_HOME%\Smc.jar -c++ -suffix cxx -verbose -noex -d %SRC_DIR% %SM_DIR%\sm_dialog_publish.sm
rem java -jar %SMC_HOME%\Smc.jar -c++ -suffix cxx -verbose -noex -d %SRC_DIR% %SM_DIR%\sm_dialog_register.sm
java -jar %SMC_HOME%\Smc.jar -c++ -suffix cxx -verbose -noex -d %SRC_DIR% %SM_DIR%\sm_dialog_subscribe.sm
pause

View File

@ -12,6 +12,8 @@
int _tmain(int argc, _TCHAR* argv[])
{
unsigned int sub_reg_dialog_id;
assert( ERR_SUCCEED(dgo::engine_initialize()) );
assert( ERR_SUCCEED(dgo::engine_stack_create(STACK_ID)) );
@ -23,12 +25,13 @@ int _tmain(int argc, _TCHAR* argv[])
assert( ERR_SUCCEED(dgo::auth_set(STACK_ID, "sip:doubango@wonderland.net", "doubango@wonderland.net", "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::network_set_pcscf(STACK_ID, "192.168.0.14", 4060)) );
assert( ERR_SUCCEED(dgo::sip_register(STACK_ID)) );
Sleep(5000);
assert( ERR_SUCCEED(dgo::sip_subscribe(STACK_ID, "sip:doubango@wonderland.net", "reg", "application/reginfo+xml", false, &sub_reg_dialog_id)) );
assert( ERR_SUCCEED(dgo::sip_publish(STACK_ID)) );
//assert( ERR_SUCCEED(dgo::sip_message(STACK_ID, "sip:toto@wonderland.net", "text/plain", "test")) );
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);
@ -36,8 +39,6 @@ int _tmain(int argc, _TCHAR* argv[])
assert( ERR_SUCCEED(dgo::engine_deinitialize()) );
Sleep(5000);
//http://sofia-sip.sourceforge.net/refdocs/iptsec/index.html
// 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;
}