doubango/trunk/doubango/src/api_stack.cxx

166 lines
3.2 KiB
C++

#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)
{
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, early_ims = false;
/* Network */
pcscf = 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)
{
su_home_deinit(this->home);
return;
}
// create NUA stack
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)
{
su_root_destroy(this->root);
su_home_deinit(this->home);
return;
}
// FIXME
this->running = true;
// enter main loop for processing of messages
su_root_run(this->root);
// 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;
}
#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[])
{
GET_DIALOG_BY_HANDLE(dlg, nh);
if(dlg)
{
dlg->dialog_callback(_event, status, phrase, nua, magic,
nh, hmagic, sip, tags);
}
else
{
}
}
PREF_NAMESPACE_END