166 lines
3.2 KiB
C++
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 |