v2: remove internal dialog/subscribe session manager

This commit is contained in:
tao3
2025-10-07 14:16:11 +08:00
parent 4a98d1a936
commit 1d82d258db
34 changed files with 340 additions and 669 deletions

View File

@@ -29,27 +29,27 @@ struct sip_uas_handler_t
/// @param[in] expires in seconds. if not provided, default equal to 60
int (*onregister)(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, const char* user, const char* location, int expires);
/// @param[in] dialog nil-new invite, not nil-reinvite
/// @param[out] session user-defined session-id(valid only code=2xx)
/// @param[in] redialog nil-new invite, not nil-reinvite
/// @return 0-ok, other-error
int (*oninvite)(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const void* data, int bytes, void** session);
int (*oninvite)(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, struct sip_dialog_t* redialog, const struct cstring_t* id, const void* data, int bytes);
/// @param[in] code 0-ok, other-sip status code
int (*onack)(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session, struct sip_dialog_t* dialog, int code, const void* data, int bytes);
int (*onack)(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const struct cstring_t* id, int code, const void* data, int bytes);
/// @param[in] session oninvite return value
int (*onprack)(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session, struct sip_dialog_t* dialog, const void* data, int bytes);
int (*onupdate)(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session, struct sip_dialog_t* dialog, const void* data, int bytes);
int (*oninfo)(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session, struct sip_dialog_t* dialog, const struct cstring_t* package, const void* data, int bytes);
int (*onprack)(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, const struct cstring_t* id, const void* data, int bytes);
int (*onupdate)(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, const struct cstring_t* id, const void* data, int bytes);
int (*oninfo)(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, const struct cstring_t* id, const struct cstring_t* package, const void* data, int bytes);
/// on terminating a session(dialog)
int (*onbye)(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session);
/// cancel a transaction(should be an invite transaction)
int (*oncancel)(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session);
int (*onbye)(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, const struct cstring_t* id);
/// cancel a transaction(should be an invite/subscribe transaction)
int (*oncancel)(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, const struct cstring_t* id);
int (*onsubscribe)(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, struct sip_subscribe_t* subscribe, void** sub);
int (*onnotify)(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* sub, const struct sip_event_t* event);
int (*onsubscribe)(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, struct sip_subscribe_t* subscribe, const struct cstring_t* id);
int (*onnotify)(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, const struct sip_event_t* event);
int (*onpublish)(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, const struct sip_event_t* event);
int (*onrefer)(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t);
int (*onmessage)(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session, const void* data, int bytes);
int (*onrefer)(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session);
/// @param[in] dialog nil-normal message, not nil-dialog message
int (*onmessage)(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, const void* data, int bytes);
};
struct sip_agent_t* sip_agent_create(struct sip_uas_handler_t* handler);

View File

@@ -37,10 +37,6 @@ struct sip_dialog_t
struct sip_uris_t routers;
// internal use only
void* session; // user-defined session
void (*ondestroy)(void* param);
void* ondestroyparam;
struct list_head link;
char* ptr;
int32_t ref;
};
@@ -48,7 +44,7 @@ struct sip_dialog_t
struct sip_dialog_t* sip_dialog_create(void);
int sip_dialog_release(struct sip_dialog_t* dialog);
int sip_dialog_addref(struct sip_dialog_t* dialog);
int sip_dialog_init_uac(struct sip_dialog_t* dialog, const struct sip_message_t* msg);
int sip_dialog_init_uas(struct sip_dialog_t* dialog, const struct sip_message_t* msg);
@@ -56,14 +52,8 @@ int sip_dialog_setlocaltag(struct sip_dialog_t* dialog, const struct cstring_t*
int sip_dialog_target_refresh(struct sip_dialog_t* dialog, const struct sip_message_t* msg);
int sip_dialog_set_local_target(struct sip_dialog_t* dialog, const struct sip_message_t* msg);
// dialog management
int sip_dialog_add(struct sip_agent_t* sip, struct sip_dialog_t* dialog);
int sip_dialog_remove(struct sip_agent_t* sip, struct sip_dialog_t* dialog);
/// call sip_dialog_release
struct sip_dialog_t* sip_dialog_fetch(struct sip_agent_t* sip, const struct cstring_t* callid, const struct cstring_t* local, const struct cstring_t* remote);
int sip_dialog_ondestroy(struct sip_dialog_t* dialog, void (*ondestroy)(void* param), void* param);
int sip_dialog_id(struct cstring_t* id, const struct sip_dialog_t* dialog, char* ptr, int len);
int sip_dialog_id_with_message(struct cstring_t* id, const struct sip_message_t* msg, char* ptr, int len);
#if defined(__cplusplus)
}

View File

@@ -33,29 +33,20 @@ struct sip_subscribe_t
uint64_t expires;
struct sip_event_t event;
char* ptr;
// internal use only
struct list_head link;
void* evtsession; // user-defined event session
char* ptr;
int32_t ref;
int newdiaolog; // flag for remote dialog from sip dialogs link
};
struct sip_subscribe_t* sip_subscribe_create(const struct sip_event_t* event);
int sip_subscribe_release(struct sip_subscribe_t* subscribe);
int sip_subscribe_addref(struct sip_subscribe_t* subscribe);
// subscribe management
int sip_subscribe_add(struct sip_agent_t* sip, struct sip_subscribe_t* subscribe);
int sip_subscribe_remove(struct sip_agent_t* sip, struct sip_subscribe_t* subscribe);
/// call sip_subscribe_release
struct sip_subscribe_t* sip_subscribe_fetch(struct sip_agent_t* sip, const struct cstring_t* callid, const struct cstring_t* local, const struct cstring_t* remote, const struct sip_event_t* event);
/// call sip_subscribe_release
struct sip_subscribe_t* sip_subscribe_internal_fetch(struct sip_agent_t* sip, const struct sip_message_t* msg, const struct sip_event_t* event, int uac, int* added);
struct sip_subscribe_t* sip_subscribe_internal_create(struct sip_agent_t* sip, const struct sip_message_t* msg, const struct sip_event_t* event, int uac);
int sip_subscribe_id(struct cstring_t* id, const struct sip_subscribe_t* subscribe, char* ptr, int len);
int sip_subscribe_id_with_message(struct cstring_t* id, const struct sip_message_t* msg, char* ptr, int len);
#if defined(__cplusplus)
}

View File

@@ -14,11 +14,11 @@ struct sip_uac_transaction_t;
/// call sip_uac_ack on 2xx only
/// @param[out] session user-defined session-id(only code=2xx)
/// @return 0-ok, other-error
typedef int (*sip_uac_oninvite)(void* param, const struct sip_message_t* reply, struct sip_uac_transaction_t* t, struct sip_dialog_t* dialog, int code, void** session);
typedef int (*sip_uac_oninvite)(void* param, const struct sip_message_t* reply, struct sip_uac_transaction_t* t, struct sip_dialog_t* dialog, const struct cstring_t* id, int code);
/// @param[in] subscribe MUST call sip_subscribe_remove on close
/// @param[out] session user-defined session-id(only code=2xx)
/// @return 0-ok, other-error
typedef int (*sip_uac_onsubscribe)(void* param, const struct sip_message_t* reply, struct sip_uac_transaction_t* t, struct sip_subscribe_t* subscribe, int code, void** session);
typedef int (*sip_uac_onsubscribe)(void* param, const struct sip_message_t* reply, struct sip_uac_transaction_t* t, struct sip_subscribe_t* subscribe, const struct cstring_t* id, int code);
/// @return 0-ok, other-error
typedef int (*sip_uac_onreply)(void* param, const struct sip_message_t* reply, struct sip_uac_transaction_t* t, int code);
/// @return <0-error, 0-udp, 1-tcp, other-reserved

View File

@@ -14,8 +14,6 @@ struct sip_agent_t* sip_agent_create(struct sip_uas_handler_t* handler)
locker_create(&sip->locker);
LIST_INIT_HEAD(&sip->uac);
LIST_INIT_HEAD(&sip->uas);
LIST_INIT_HEAD(&sip->dialogs);
LIST_INIT_HEAD(&sip->subscribes);
memcpy(&sip->handler, handler, sizeof(sip->handler));
return sip;
}
@@ -23,11 +21,6 @@ struct sip_agent_t* sip_agent_create(struct sip_uas_handler_t* handler)
int sip_agent_destroy(struct sip_agent_t* sip)
{
int32_t ref;
//struct list_head *pos, *next;
//struct sip_dialog_t* dialog;
//struct sip_subscribe_t* subscribe;
//struct sip_uac_transaction_t* uac;
//struct sip_uas_transaction_t* uas;
assert(sip->ref > 0);
ref = atomic_decrement32(&sip->ref);
@@ -36,31 +29,7 @@ int sip_agent_destroy(struct sip_agent_t* sip)
assert(list_empty(&sip->uac));
assert(list_empty(&sip->uas));
assert(list_empty(&sip->dialogs));
assert(list_empty(&sip->subscribes));
//list_for_each_safe(pos, next, &sip->uac)
//{
// uac = list_entry(pos, struct sip_uac_transaction_t, link);
// assert(uac->agent == sip);
// sip_uac_transaction_release(uac);
//}
//list_for_each_safe(pos, next, &sip->uas)
//{
// uas = list_entry(pos, struct sip_uas_transaction_t, link);
// assert(uas->agent == sip);
// sip_uac_transaction_release(uas);
//}
//list_for_each_safe(pos, next, &sip->dialogs)
//{
// dialog = list_entry(pos, struct sip_dialog_t, link);
// sip_dialog_release(dialog);
//}
//list_for_each_safe(pos, next, &sip->subscribes)
//{
// subscribe = list_entry(pos, struct sip_subscribe_t, link);
// sip_subscribe_release(subscribe);
//}
locker_destroy(&sip->locker);
free(sip);
return 0;

View File

@@ -22,7 +22,6 @@ struct sip_dialog_t* sip_dialog_create(void)
if (dialog)
{
dialog->ref = 1;
LIST_INIT_HEAD(&dialog->link);
dialog->state = DIALOG_ERALY;
dialog->ptr = (char*)(dialog + 1);
atomic_increment32(&s_gc.dialog);
@@ -118,9 +117,6 @@ int sip_dialog_release(struct sip_dialog_t* dialog)
if (0 != atomic_decrement32(&dialog->ref))
return 0;
if (dialog->ondestroy)
dialog->ondestroy(dialog->ondestroyparam);
sip_uri_free(&dialog->local.target);
sip_contact_free(&dialog->local.uri);
sip_uri_free(&dialog->remote.target);
@@ -139,13 +135,6 @@ int sip_dialog_addref(struct sip_dialog_t* dialog)
return r;
}
int sip_dialog_ondestroy(struct sip_dialog_t* dialog, void (*ondestroy)(void* param), void* param)
{
dialog->ondestroy = ondestroy;
dialog->ondestroyparam = param;
return 0;
}
int sip_dialog_setlocaltag(struct sip_dialog_t* dialog, const struct cstring_t* tag)
{
const char* end;
@@ -194,136 +183,24 @@ static int sip_dialog_match(const struct sip_dialog_t* dialog, const struct cstr
return cstreq(callid, &dialog->callid) && cstreq(local, &dialog->local.uri.tag) && cstreq(remote, &dialog->remote.uri.tag) ? 1 : 0;
}
static struct sip_dialog_t* sip_dialog_find(struct sip_agent_t* sip, const struct cstring_t* callid, const struct cstring_t* local, const struct cstring_t* remote)
int sip_dialog_id(struct cstring_t* id, const struct sip_dialog_t* dialog, char* ptr, int len)
{
struct list_head *pos, *next;
struct sip_dialog_t* dialog;
int r;
r = dialog ? snprintf(ptr, len, "%.*s@%.*s@%.*s", (int)dialog->callid.n, dialog->callid.p, (int)dialog->local.uri.tag.n, dialog->local.uri.tag.p, (int)dialog->remote.uri.tag.n, dialog->remote.uri.tag.p) : 0;
id->p = ptr;
id->n = r > 0 && r < sizeof(id) ? r : 0;
return r;
}
list_for_each_safe(pos, next, &sip->dialogs)
{
dialog = list_entry(pos, struct sip_dialog_t, link);
if (sip_dialog_match(dialog, callid, local, remote))
return dialog;
}
int sip_dialog_id_with_message(struct cstring_t *id, const struct sip_message_t* msg, char* ptr, int len)
{
int r;
if (msg->mode == SIP_MESSAGE_REQUEST)
r = snprintf(ptr, len, "%.*s@%.*s@%.*s", (int)msg->callid.n, msg->callid.p, (int)msg->to.tag.n, msg->to.tag.p, (int)msg->from.tag.n, msg->from.tag.p);
else
r = snprintf(ptr, len, "%.*s@%.*s@%.*s", (int)msg->callid.n, msg->callid.p, (int)msg->from.tag.n, msg->from.tag.p, (int)msg->to.tag.n, msg->to.tag.p);
return NULL;
}
struct sip_dialog_t* sip_dialog_fetch(struct sip_agent_t* sip, const struct cstring_t* callid, const struct cstring_t* local, const struct cstring_t* remote)
{
struct sip_dialog_t* dialog;
locker_lock(&sip->locker);
dialog = sip_dialog_find(sip, callid, local, remote);
if(dialog)
sip_dialog_addref(dialog);
locker_unlock(&sip->locker);
return dialog;
}
int sip_dialog_add(struct sip_agent_t* sip, struct sip_dialog_t* dialog)
{
locker_lock(&sip->locker);
if (NULL != sip_dialog_find(sip, &dialog->callid, &dialog->local.uri.tag, &dialog->remote.uri.tag))
{
assert(0);
locker_unlock(&sip->locker);
return -1; // exist
}
// link to tail
assert(1 == dialog->ref);
list_insert_after(&dialog->link, sip->dialogs.prev);
locker_unlock(&sip->locker);
sip_dialog_addref(dialog);
return 0;
}
int sip_dialog_remove(struct sip_agent_t* sip, struct sip_dialog_t* dialog)
{
// unlink dialog
locker_lock(&sip->locker);
//assert(1 == dialog->ref);
if (dialog->link.next == NULL)
{
// fix remove twice
locker_unlock(&sip->locker);
return -1;
}
list_remove(&dialog->link);
locker_unlock(&sip->locker);
sip_dialog_release(dialog);
return 0;
}
int sip_dialog_remove2(struct sip_agent_t* sip, const struct cstring_t* callid, const struct cstring_t* local, const struct cstring_t* remote)
{
struct sip_dialog_t* dialog;
locker_lock(&sip->locker);
dialog = sip_dialog_find(sip, callid, local, remote);
if (dialog && dialog->link.next)
list_remove(&dialog->link);
locker_unlock(&sip->locker);
if (dialog)
{
sip_dialog_release(dialog);
return 0;
}
return -1; // not found
}
int sip_dialog_remove_early(struct sip_agent_t* sip, const struct cstring_t* callid)
{
struct sip_dialog_t* early;
struct sip_dialog_t* dialog;
struct list_head *pos, *next;
early = NULL;
locker_lock(&sip->locker);
list_for_each_safe(pos, next, &sip->dialogs)
{
dialog = list_entry(pos, struct sip_dialog_t, link);
if (cstreq(callid, &dialog->callid) && DIALOG_ERALY == dialog->state)
{
//assert(0 == sip_contact_compare(&t->req->from, &dialog->local.uri));
list_remove(&dialog->link);
early = dialog;
break;
}
}
locker_unlock(&sip->locker);
if (early)
{
sip_dialog_release(early);
return 0;
}
return -1; // not found
}
// MUST ADD LOCK !!!!! internal use only !!!!!!!!!
struct sip_dialog_t* sip_dialog_internal_fetch(struct sip_agent_t* sip, const struct sip_message_t* msg, int uac, int* added)
{
struct sip_dialog_t* dialog;
*added = 0;
dialog = sip_dialog_find(sip, &msg->callid, uac ? &msg->from.tag : &msg->to.tag, uac ? &msg->to.tag : &msg->from.tag);
if (!dialog)
{
dialog = sip_dialog_create();
if (!dialog || 0 != (uac ? sip_dialog_init_uac(dialog, msg) : sip_dialog_init_uas(dialog, msg)))
{
sip_dialog_release(dialog);
return NULL;
}
// link to sip dialogs(add ref later)
list_insert_after(&dialog->link, sip->dialogs.prev);
assert(dialog->ref == 1);
*added = 1;
}
sip_dialog_addref(dialog); // for sip link dialog / fetch
return dialog;
id->p = ptr;
id->n = r > 0 && r < sizeof(id) ? r : 0;
return r;
}

View File

@@ -28,9 +28,6 @@ struct sip_agent_t
//struct sip_timer_t timer;
//void* timerptr;
struct list_head dialogs;
struct list_head subscribes;
struct list_head uac; // uac transactions
struct list_head uas; // uas transactions
struct sip_uas_handler_t handler;

View File

@@ -98,7 +98,6 @@ struct sip_subscribe_t* sip_subscribe_create(const struct sip_event_t* event)
if (s)
{
s->ref = 1;
LIST_INIT_HEAD(&s->link);
s->state = SUBSCRIBE_INIT;
s->ptr = (char*)(s + 1);
@@ -143,110 +142,44 @@ static int sip_subscribe_match(const struct sip_subscribe_t* subscribe, const st
return cstreq(callid, &subscribe->dialog->callid) && cstreq(local, &subscribe->dialog->local.uri.tag) && cstreq(remote, &subscribe->dialog->remote.uri.tag) && sip_event_equal(event, &subscribe->event) ? 1 : 0;
}
static struct sip_subscribe_t* sip_subscribe_find(struct sip_agent_t* sip, const struct cstring_t* callid, const struct cstring_t* local, const struct cstring_t* remote, const struct sip_event_t* event)
{
struct list_head *pos, *next;
struct sip_subscribe_t* subscribe;
list_for_each_safe(pos, next, &sip->subscribes)
{
subscribe = list_entry(pos, struct sip_subscribe_t, link);
if (sip_subscribe_match(subscribe, callid, local, remote, event))
return subscribe;
}
return NULL;
}
int sip_subscribe_add(struct sip_agent_t* sip, struct sip_subscribe_t* subscribe)
{
// TODO:
// the dialog of subscribe don't link to sip->dialogs, so so so...
assert(subscribe->dialog);
locker_lock(&sip->locker);
if (NULL != sip_subscribe_find(sip, &subscribe->dialog->callid, &subscribe->dialog->local.uri.tag, &subscribe->dialog->remote.uri.tag, &subscribe->event))
{
locker_unlock(&sip->locker);
return -1; // exist
}
// link to tail
assert(1 == subscribe->ref);
list_insert_after(&subscribe->link, sip->subscribes.prev);
locker_unlock(&sip->locker);
sip_subscribe_addref(subscribe);
return 0;
}
int sip_subscribe_remove(struct sip_agent_t* sip, struct sip_subscribe_t* subscribe)
{
// unlink dialog
locker_lock(&sip->locker);
if (subscribe->link.next == NULL)
{
// fix remove twice
locker_unlock(&sip->locker);
return 0;
}
//assert(1 == subscribe->ref);
if (subscribe->newdiaolog)
{
subscribe->newdiaolog = 0;
sip_dialog_remove(sip, subscribe->dialog);
}
list_remove(&subscribe->link);
locker_unlock(&sip->locker);
sip_subscribe_release(subscribe);
return 0;
}
struct sip_subscribe_t* sip_subscribe_fetch(struct sip_agent_t* sip, const struct cstring_t* callid, const struct cstring_t* local, const struct cstring_t* remote, const struct sip_event_t* event)
struct sip_subscribe_t* sip_subscribe_internal_create(struct sip_agent_t* sip, const struct sip_message_t* msg, const struct sip_event_t* event, int uac)
{
struct sip_subscribe_t* subscribe;
locker_lock(&sip->locker);
subscribe = sip_subscribe_find(sip, callid, local, remote, event);
if (subscribe)
sip_subscribe_addref(subscribe);
locker_unlock(&sip->locker);
subscribe = sip_subscribe_create(event);
if (!subscribe)
{
locker_unlock(&sip->locker);
return NULL; // exist
}
subscribe->dialog = sip_dialog_create();
if (!subscribe->dialog || 0 != (uac ? sip_dialog_init_uac(subscribe->dialog, msg) : sip_dialog_init_uas(subscribe->dialog, msg)))
{
sip_subscribe_release(subscribe);
return NULL;
}
subscribe->dialog->state = DIALOG_CONFIRMED; // confirm dialog
return subscribe;
}
struct sip_dialog_t* sip_dialog_internal_fetch(struct sip_agent_t* sip, const struct sip_message_t* msg, int uac, int* added);
// internal use only !!!!!!!!!
struct sip_subscribe_t* sip_subscribe_internal_fetch(struct sip_agent_t* sip, const struct sip_message_t* msg, const struct sip_event_t* event, int uac, int* added)
int sip_subscribe_id(struct cstring_t* id, const struct sip_subscribe_t* subscribe, char* ptr, int len)
{
struct sip_subscribe_t* subscribe;
*added = 0;
locker_lock(&sip->locker);
subscribe = sip_subscribe_find(sip, &msg->callid, uac ? &msg->from.tag : &msg->to.tag, uac ? &msg->to.tag : &msg->from.tag, event);
if (NULL == subscribe)
{
subscribe = sip_subscribe_create(event);
if (!subscribe)
{
locker_unlock(&sip->locker);
return NULL; // exist
}
subscribe->dialog = sip_dialog_internal_fetch(sip, msg, uac, &subscribe->newdiaolog);
if (!subscribe->dialog)
{
locker_unlock(&sip->locker);
sip_subscribe_release(subscribe);
return NULL; // exist
}
subscribe->dialog->state = DIALOG_CONFIRMED; // confirm dialog
// link to tail (add ref later)
list_insert_after(&subscribe->link, sip->subscribes.prev);
*added = 1;
}
assert(subscribe->dialog);
locker_unlock(&sip->locker);
sip_subscribe_addref(subscribe); // for sip link dialog / fetch
return subscribe;
int r;
r = subscribe ? snprintf(ptr, len, "%.*s@%.*s@%.*s@%.*s@%.*s", (int)subscribe->dialog->callid.n, subscribe->dialog->callid.p, (int)subscribe->dialog->local.uri.tag.n, subscribe->dialog->local.uri.tag.p, (int)subscribe->dialog->remote.uri.tag.n, subscribe->dialog->remote.uri.tag.p, (int)subscribe->event.event.n, subscribe->event.event.p, (int)subscribe->event.id.n, subscribe->event.id.p) : 0;
id->p = ptr;
id->n = r > 0 && r < sizeof(id) ? r : 0;
return r;
}
int sip_subscribe_id_with_message(struct cstring_t* id, const struct sip_message_t* msg, char* ptr, int len)
{
int r;
if (msg->mode == SIP_MESSAGE_REQUEST)
r = snprintf(ptr, len, "%.*s@%.*s@%.*s@%.*s@%.*s", (int)msg->callid.n, msg->callid.p, (int)msg->to.tag.n, msg->to.tag.p, (int)msg->from.tag.n, msg->from.tag.p, (int)msg->event.event.n, msg->event.event.p, (int)msg->event.id.n, msg->event.id.p);
else
r = snprintf(ptr, len, "%.*s@%.*s@%.*s@%.*s@%.*s", (int)msg->callid.n, msg->callid.p, (int)msg->from.tag.n, msg->from.tag.p, (int)msg->to.tag.n, msg->to.tag.p, (int)msg->event.event.n, msg->event.event.p, (int)msg->event.id.n, msg->event.id.p);
id->p = ptr;
id->n = r > 0 && r < sizeof(id) ? r : 0;
return r;
}

View File

@@ -3,38 +3,9 @@
#include "sip-message.h"
#include "sip-uac-transaction.h"
int sip_uac_onbye(struct sip_uac_transaction_t* t, int code)
{
struct sip_dialog_t* dialog;
//if ( (200 <= reply->u.s.code && reply->u.s.code < 300) || 481 == reply->u.s.code )
{
dialog = sip_dialog_fetch(t->agent, &t->req->callid, &t->req->from.tag, &t->req->to.tag);
if (dialog)
{
sip_dialog_remove(t->agent, dialog);
sip_dialog_release(dialog);
}
}
return 0;
}
struct sip_uac_transaction_t* sip_uac_dialog_custom(struct sip_agent_t* sip, const char* method, struct sip_dialog_t* dialog, sip_uac_onreply onreply, void* param);
struct sip_uac_transaction_t* sip_uac_bye(struct sip_agent_t* sip, struct sip_dialog_t* dialog, sip_uac_onreply onbye, void* param)
{
struct sip_message_t* req;
struct sip_uac_transaction_t* t;
++dialog->local.id;
req = sip_message_create(SIP_MESSAGE_REQUEST);
if (0 != sip_message_init2(req, SIP_METHOD_BYE, dialog))
{
--dialog->local.id;
sip_message_destroy(req);
return NULL;
}
t = sip_uac_transaction_create(sip, req);
t->onhandle = sip_uac_onbye;
t->onreply = onbye;
t->param = param;
return t;
return sip_uac_dialog_custom(sip, SIP_METHOD_BYE, dialog, onbye, param);
}

View File

@@ -6,21 +6,6 @@
#include <stdlib.h>
#include <string.h>
int sip_uac_oncancel(struct sip_uac_transaction_t* t, int code)
{
struct sip_dialog_t* dialog;
//if (200 <= reply->u.s.code && reply->u.s.code < 300)
{
dialog = sip_dialog_fetch(t->agent, &t->req->callid, &t->req->from.tag, &t->req->to.tag);
if (dialog)
{
sip_dialog_remove(t->agent, dialog);
sip_dialog_release(dialog);
}
}
return 0;
}
struct sip_uac_transaction_t* sip_uac_cancel(struct sip_agent_t* sip, struct sip_uac_transaction_t* invite, sip_uac_onreply oncancel, void* param)
{
char cseq[128];
@@ -46,7 +31,6 @@ struct sip_uac_transaction_t* sip_uac_cancel(struct sip_agent_t* sip, struct sip
memcpy(&req->u.c.method, &req->cseq.method, sizeof(req->u.c.method));
t = sip_uac_transaction_create(sip, req);
t->onhandle = sip_uac_oncancel;
t->onreply = oncancel;
t->param = param;
return t;

View File

@@ -10,8 +10,8 @@
int sip_uac_subscribe_onreply(struct sip_uac_transaction_t* t, const struct sip_message_t* reply)
{
int r;
int added;
const struct cstring_t *h;
char ptr[256];
struct cstring_t id;
struct sip_subscribe_t* subscribe;
if (reply->u.s.code < 200)
@@ -21,18 +21,20 @@ int sip_uac_subscribe_onreply(struct sip_uac_transaction_t* t, const struct sip_
subscribe = NULL;
if (200 <= reply->u.s.code && reply->u.s.code < 300)
{
subscribe = sip_subscribe_internal_fetch(t->agent, reply, &t->req->event, 1, &added);
subscribe = sip_subscribe_internal_create(t->agent, reply, &t->req->event, 1);
sip_subscribe_id(&id, subscribe, ptr, sizeof(ptr));
// call once only
//if (added)
r = t->onsubscribe(t->param, reply, t, subscribe, reply->u.s.code, &subscribe->evtsession);
r = t->onsubscribe(t->param, reply, t, subscribe, &id, reply->u.s.code);
}
else
{
// for subscribe expires 0, to sip_subscribe_remove
subscribe = sip_subscribe_fetch(t->agent, &t->req->callid, &t->req->from.tag, &t->req->to.tag, &t->req->event);
//subscribe = sip_subscribe_fetch(t->agent, &t->req->callid, &t->req->from.tag, &t->req->to.tag, &t->req->event);
sip_subscribe_id(&id, subscribe, ptr, sizeof(ptr));
r = t->onsubscribe(t->param, reply, t, subscribe, reply->u.s.code, subscribe ? &subscribe->evtsession : NULL);
r = t->onsubscribe(t->param, reply, t, subscribe, &id, reply->u.s.code);
}
if (subscribe)
@@ -55,17 +57,6 @@ int sip_uac_subscribe_onreply(struct sip_uac_transaction_t* t, const struct sip_
int sip_uac_notify_onreply(struct sip_uac_transaction_t* t, const struct sip_message_t* reply)
{
int r;
struct sip_subscribe_t* subscribe;
subscribe = sip_subscribe_fetch(t->agent, &reply->callid, &reply->from.tag, &reply->to.tag, &t->req->event);
if (!subscribe)
{
//return 0; // receive notify message before subscribe reply, discard it
// custom notify message ???
assert(t->req && !cstrvalid(&t->req->to.tag));
return t->onreply(t->param, reply, t, reply->u.s.code);
}
// NOTICE: ignore notify before subscribe created
r = t->onreply(t->param, reply, t, reply->u.s.code);
@@ -73,7 +64,6 @@ int sip_uac_notify_onreply(struct sip_uac_transaction_t* t, const struct sip_mes
//if (0 == cstrcmp(&reply->substate.state, SIP_SUBSCRIPTION_STATE_TERMINATED))
// sip_subscribe_remove(t->agent, subscribe);
sip_subscribe_release(subscribe);
return r;
}

View File

@@ -52,53 +52,53 @@
static int sip_uac_transaction_invite_proceeding(struct sip_uac_transaction_t* t, const struct sip_message_t* reply)
{
int r;
struct sip_dialog_t* dialog;
dialog = sip_dialog_fetch(t->agent, &reply->callid, &reply->from.tag, &reply->to.tag);
char ptr[256];
struct cstring_t id;
// TODO: add dialog locker here
if (!dialog && cstrvalid(&reply->to.tag))
if (!t->dialog && cstrvalid(&reply->to.tag))
{
// create early dialog
dialog = sip_dialog_create();
if (!dialog) return -1;
if (0 != sip_dialog_init_uac(dialog, reply) || 0 != sip_dialog_set_local_target(dialog, t->req) || 0 != sip_dialog_add(t->agent, dialog))
t->dialog = sip_dialog_create();
if (!t->dialog) return -1;
if (0 != sip_dialog_init_uac(t->dialog, reply) || 0 != sip_dialog_set_local_target(t->dialog, t->req))
{
assert(0);
sip_dialog_release(dialog);
dialog = NULL;
sip_dialog_release(t->dialog);
t->dialog = NULL;
return 0; // ignore
}
}
sip_dialog_id(&id, t->dialog, ptr, sizeof(ptr));
// 17.1.1.2 Formal Description (p126)
// the provisional response MUST be passed to the TU.
// Any further provisional responses MUST be passed up to the TU while in the "Proceeding" state.
r = t->oninvite(t->param, reply, t, dialog, reply->u.s.code, NULL); // ignore session
r = t->oninvite(t->param, reply, t, t->dialog, &id, reply->u.s.code); // ignore session
// reset timer b for proceeding too long
sip_uac_transaction_timeout(t, TIMER_B);
sip_dialog_release(dialog);
return r;
}
static int sip_uac_transaction_invite_completed(struct sip_uac_transaction_t* t, const struct sip_message_t* reply, int retransmissions)
{
int r;
struct sip_dialog_t* dialog;
dialog = sip_dialog_fetch(t->agent, &reply->callid, &reply->from.tag, &reply->to.tag);
assert(!dialog || DIALOG_ERALY == dialog->state);
char ptr[256];
struct cstring_t id;
r = 0;
assert(!t->dialog || DIALOG_ERALY == t->dialog->state);
if (!retransmissions)
{
sip_dialog_id(&id, t->dialog, ptr, sizeof(ptr));
// Any retransmissions of the final response that are received while in
// the "Completed" state MUST cause the ACK to be re-passed to the
// transport layer for retransmission, but the newly received response
// MUST NOT be passed up to the TU
assert(!dialog || NULL == dialog->session);
r = t->oninvite(t->param, reply, t, dialog, reply->u.s.code, NULL); // ignore session
r = t->oninvite(t->param, reply, t, t->dialog, &id, reply->u.s.code); // ignore session
}
else
{
@@ -109,7 +109,7 @@ static int sip_uac_transaction_invite_completed(struct sip_uac_transaction_t* t,
// 17.1.1.3 Construction of the ACK Request
// The ACK MUST be sent to the same address, port,
// and transport to which the original request was sent.
sip_uac_ack_3456xx(t, reply, dialog); // ignore ack transport layer error, retry send on retransmissions
sip_uac_ack_3456xx(t, reply, t->dialog); // ignore ack transport layer error, retry send on retransmissions
if (!retransmissions)
{
@@ -128,60 +128,51 @@ static int sip_uac_transaction_invite_completed(struct sip_uac_transaction_t* t,
sip_uac_transaction_timewait(t, t->reliable ? 1 : TIMER_D);
}
sip_dialog_release(dialog);
return r;
}
static int sip_uac_transaction_invite_accepted(struct sip_uac_transaction_t* t, const struct sip_message_t* reply, int retransmissions)
{
int r;
struct sip_dialog_t* dialog;
char ptr[256];
struct cstring_t id;
r = 0;
// TODO: add dialog locker here
dialog = sip_dialog_fetch(t->agent, &reply->callid, &reply->from.tag, &reply->to.tag);
// only create new dialog on first 2xx response
if (!dialog && cstrvalid(&reply->to.tag) && !retransmissions)
if (!t->dialog && cstrvalid(&reply->to.tag) && !retransmissions)
{
dialog = sip_dialog_create();
if (!dialog) return -1;
if (0 != sip_dialog_init_uac(dialog, reply) || 0 != sip_dialog_set_local_target(dialog, t->req) || 0 != sip_dialog_add(t->agent, dialog))
t->dialog = sip_dialog_create();
if (!t->dialog) return -1;
if (0 != sip_dialog_init_uac(t->dialog, reply) || 0 != sip_dialog_set_local_target(t->dialog, t->req))
{
sip_dialog_release(dialog);
dialog = NULL;
sip_dialog_release(t->dialog);
t->dialog = NULL;
return 0; // ignore
}
}
if (!dialog)
if (!t->dialog)
return 0; // ignore fork response
// update dialog target
assert(!t->dialog);
sip_dialog_target_refresh(dialog, reply);
if (!t->dialog)
{
sip_dialog_addref(dialog); // for t->dialog
t->dialog = dialog;
}
if (dialog->state == DIALOG_ERALY)
sip_dialog_target_refresh(t->dialog, reply);
if (t->dialog->state == DIALOG_ERALY)
{
assert(!retransmissions);
t->status = SIP_UAC_TRANSACTION_ACCEPTED_UNACK;
// transfer dialog state
dialog->state = DIALOG_CONFIRMED;
t->dialog->state = DIALOG_CONFIRMED;
// completed To tag
assert(cstrvalid(&dialog->remote.uri.tag));
assert(cstrvalid(&t->dialog->remote.uri.tag));
sip_dialog_id(&id, t->dialog, ptr, sizeof(ptr));
// receive and pass to the TU any retransmissions of the 2xx
// response or any additional 2xx responses from other branches of a
// downstream fork of the matching request.
assert(200 <= reply->u.s.code && reply->u.s.code < 300);
r = t->oninvite(t->param, reply, t, dialog, reply->u.s.code, &dialog->session);
r = t->oninvite(t->param, reply, t, t->dialog, &id, reply->u.s.code);
}
// 17.1.1.3 Construction of the ACK Request ==> 13.2.2.4 2xx Responses
@@ -201,7 +192,6 @@ static int sip_uac_transaction_invite_accepted(struct sip_uac_transaction_t* t,
sip_uac_transaction_timewait(t, TIMER_M);
}
sip_dialog_release(dialog);
return r;
}

View File

@@ -49,9 +49,6 @@
#include <string.h>
#include <assert.h>
int sip_uac_onbye(struct sip_uac_transaction_t* t, const struct sip_message_t* reply);
int sip_uac_oncancel(struct sip_uac_transaction_t* t, const struct sip_message_t* reply);
static int sip_uac_transaction_noninvite_proceeding(struct sip_uac_transaction_t* t, const struct sip_message_t* reply)
{
assert(SIP_UAC_TRANSACTION_TRYING == t->status || SIP_UAC_TRANSACTION_PROCEEDING == t->status);

View File

@@ -48,11 +48,7 @@ int sip_uac_transaction_release(struct sip_uac_transaction_t* t)
t->ondestroy(t->ondestroyparam);
}
if (t->dialog)
{
sip_dialog_release(t->dialog);
}
sip_dialog_release(t->dialog);
assert(NULL == t->onhandle);
sip_message_destroy(t->req);
locker_destroy(&t->locker);
@@ -142,9 +138,9 @@ static void sip_uac_transaction_ontimeout(void* usrptr)
// 8.1.3.1 Transaction Layer Errors (p42)
if (t->oninvite)
t->oninvite(t->param, NULL, t, NULL, 408/*Request Timeout*/, NULL);
t->oninvite(t->param, NULL, t, NULL, NULL, 408/*Request Timeout*/);
else if (t->onsubscribe)
t->onsubscribe(t->param, NULL, t, NULL, 408/*Request Timeout*/, NULL);
t->onsubscribe(t->param, NULL, t, NULL, NULL, 408/*Request Timeout*/);
else
t->onreply(t->param, NULL, t, 408/*Request Timeout*/);

View File

@@ -24,8 +24,8 @@ int sip_uac_link_transaction(struct sip_agent_t* sip, struct sip_uac_transaction
int sip_uac_unlink_transaction(struct sip_agent_t* sip, struct sip_uac_transaction_t* t)
{
struct sip_dialog_t* dialog;
struct list_head *pos, *next;
//struct sip_dialog_t* dialog;
//struct list_head *pos, *next;
assert(sip->ref > 0);
locker_lock(&sip->locker);
@@ -43,16 +43,16 @@ int sip_uac_unlink_transaction(struct sip_agent_t* sip, struct sip_uac_transacti
// Independent of the method, if a request outside of a dialog generates
// a non-2xx final response, any early dialogs created through
// provisional responses to that request are terminated.
list_for_each_safe(pos, next, &sip->dialogs)
{
dialog = list_entry(pos, struct sip_dialog_t, link);
if (cstreq(&t->req->callid, &dialog->callid) && DIALOG_ERALY == dialog->state)
{
//assert(0 == sip_contact_compare(&t->req->from, &dialog->local.uri));
sip_dialog_remove(sip, dialog); // TODO: release in locker
break;
}
}
//list_for_each_safe(pos, next, &sip->dialogs)
//{
// dialog = list_entry(pos, struct sip_dialog_t, link);
// if (cstreq(&t->req->callid, &dialog->callid) && DIALOG_ERALY == dialog->state)
// {
// //assert(0 == sip_contact_compare(&t->req->from, &dialog->local.uri));
// sip_dialog_remove(sip, dialog); // TODO: release in locker
// break;
// }
//}
locker_unlock(&sip->locker);
sip_uac_transaction_release(t);

View File

@@ -1,24 +1,21 @@
#include "sip-uas-transaction.h"
int sip_uas_onbye(struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const struct sip_message_t* req, void* param)
int sip_uas_onbye(struct sip_uas_transaction_t* t, const struct sip_message_t* req, void* param)
{
void* session;
//dialog = sip_dialog_find(&t->uas->dialogs, req);
if (!dialog)
{
// 481 Call/Transaction Does Not Exist
return sip_uas_transaction_noninvite_reply(t, 481, NULL, 0, param);
}
char ptr[256];
struct cstring_t id;
session = dialog ? dialog->session : NULL; // get session before dialog remove
if (0 != sip_dialog_remove(t->agent, dialog))
{
// 481 Call/Transaction Does Not Exist
return sip_uas_transaction_noninvite_reply(t, 481, NULL, 0, param);
}
sip_dialog_id_with_message(&id, req, ptr, sizeof(ptr));
//session = dialog ? dialog->session : NULL; // get session before dialog remove
//if (0 != sip_dialog_remove(t->agent, dialog))
//{
// // 481 Call/Transaction Does Not Exist
// return sip_uas_transaction_noninvite_reply(t, 481, NULL, 0, param);
//}
// The UAS MUST still respond to any pending requests received for that
// dialog. It is RECOMMENDED that a 487 (Request Terminated) response be
// generated to those pending requests.
return t->handler->onbye(param, req, t, session);
return t->handler->onbye(param, req, t, &id);
}

View File

@@ -1,10 +1,14 @@
#include "sip-uas-transaction.h"
int sip_uas_oncancel(struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const struct sip_message_t* req, void* param)
int sip_uas_oncancel(struct sip_uas_transaction_t* t, const struct sip_message_t* req, void* param)
{
int r;
char ptr[256];
struct cstring_t id;
struct sip_uas_transaction_t* origin;
sip_dialog_id_with_message(&id, req, ptr, sizeof(ptr));
// 487 Request Terminated
// CANCEL has no effect on a request to which a UAS has already given a final response
@@ -30,7 +34,7 @@ int sip_uas_oncancel(struct sip_uas_transaction_t* t, struct sip_dialog_t* dialo
// in the response to the original request SHOULD be the same.
t->reply->ptr.ptr = cstring_clone(t->reply->ptr.ptr, t->reply->ptr.end, &t->reply->to.tag, origin->reply->to.tag.p, origin->reply->to.tag.n);
r = t->handler->oncancel(param, req, t, dialog ? dialog->session : NULL);
r = t->handler->oncancel(param, req, t, &id);
}
sip_uas_transaction_release(t);

View File

@@ -1,9 +1,12 @@
#include "sip-uas-transaction.h"
int sip_uas_oninfo(struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const struct sip_message_t* req, void* param)
int sip_uas_oninfo(struct sip_uas_transaction_t* t, const struct sip_message_t* req, void* param)
{
int r;
assert(dialog);
char ptr[256];
struct cstring_t id;
sip_dialog_id_with_message(&id, req, ptr, sizeof(ptr));
// compatible rfc 2976 as "legacy INFO Usage"
// if(!cstrvalid(&req->info_package))
@@ -12,7 +15,7 @@ int sip_uas_oninfo(struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog,
// TODO: check Info-Package
if(t->handler->oninfo)
r = t->handler->oninfo(param, req, t, dialog ? dialog->session : NULL, dialog, &req->info_package, req->payload, req->size);
r = t->handler->oninfo(param, req, t, &id, &req->info_package, req->payload, req->size);
else
r = 0; // just ignore
return r;

View File

@@ -1,32 +1,28 @@
#include "sip-uas-transaction.h"
int sip_uas_onprack(struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const struct sip_message_t* req, void* param)
int sip_uas_onprack(struct sip_uas_transaction_t* t, const struct sip_message_t* req, void* param)
{
int r;
if (!dialog)
{
assert(0);
return 0; // discard
}
char ptr[256];
struct cstring_t id;
sip_dialog_id_with_message(&id, req, ptr, sizeof(ptr));
if (t->handler->onprack)
r = t->handler->onprack(param, req, t, dialog ? dialog->session : NULL, dialog, req->payload, req->size);
r = t->handler->onprack(param, req, t, &id, req->payload, req->size);
else
r = 0; // just ignore
return r;
}
int sip_uas_onupdate(struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const struct sip_message_t* req, void* param)
int sip_uas_onupdate(struct sip_uas_transaction_t* t, const struct sip_message_t* req, void* param)
{
int r;
if (!dialog)
{
assert(0);
return 0; // discard
}
char ptr[256];
struct cstring_t id;
sip_dialog_id_with_message(&id, req, ptr, sizeof(ptr));
if (t->handler->onupdate)
r = t->handler->onupdate(param, req, t, dialog ? dialog->session : NULL, dialog, req->payload, req->size);
r = t->handler->onupdate(param, req, t, &id, req->payload, req->size);
else
r = 0; // just ignore
return r;

View File

@@ -1,6 +1,6 @@
#include "sip-uas-transaction.h"
int sip_uas_onrefer(struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const struct sip_message_t* req, void* param)
int sip_uas_onrefer(struct sip_uas_transaction_t* t, const struct sip_message_t* req, void* param)
{
int r;
// An agent responding to a REFER method MUST return a 400 (Bad Request)
@@ -9,7 +9,7 @@ int sip_uas_onrefer(struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog
return sip_uas_reply(t, 400, NULL, 0, param);
if(t->handler->onrefer)
r = t->handler->onrefer(param, req, t, dialog ? dialog->session : NULL);
r = t->handler->onrefer(param, req, t);
else
r = 0; // just ignore
return r;

View File

@@ -1,18 +1,19 @@
#include "sip-uas-transaction.h"
#include "sip-subscribe.h"
int sip_uas_onsubscribe(struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const struct sip_message_t* req, void* param)
int sip_uas_onsubscribe(struct sip_uas_transaction_t* t, const struct sip_message_t* req, void* param)
{
int r, added;
int r;
char ptr[256];
struct cstring_t id;
const struct cstring_t *h;
struct sip_subscribe_t* subscribe;
r = 0;
subscribe = sip_subscribe_internal_fetch(t->agent, req, &req->event, 0, &added);
subscribe = sip_subscribe_internal_create(t->agent, req, &req->event, 0);
if (!subscribe)
return sip_uas_reply(t, 481, NULL, 0, param); // 481 Subscription does not exist
assert(!dialog || subscribe->dialog == dialog);
if (subscribe->dialog)
{
sip_dialog_setlocaltag(subscribe->dialog, &t->reply->to.tag);
@@ -24,7 +25,10 @@ int sip_uas_onsubscribe(struct sip_uas_transaction_t* t, struct sip_dialog_t* di
// call once only
if ( /*added &&*/ t->handler->onsubscribe)
r = t->handler->onsubscribe(param, req, t, subscribe, &subscribe->evtsession);
{
sip_subscribe_id(&id, subscribe, ptr, sizeof(ptr));
r = t->handler->onsubscribe(param, req, t, subscribe, &id);
}
if (subscribe)
{
@@ -64,22 +68,16 @@ int sip_uas_onsubscribe(struct sip_uas_transaction_t* t, struct sip_dialog_t* di
int sip_uas_onnotify(struct sip_uas_transaction_t* t, const struct sip_message_t* req, void* param)
{
int r;
struct sip_subscribe_t* subscribe;
subscribe = sip_subscribe_fetch(t->agent, &req->callid, &req->to.tag, &req->from.tag, &req->event);
//if (!subscribe)
// return sip_uas_reply(t, 481, NULL, 0, param); // 481 Subscription does not exist
// 489 Bad Event
if (t->handler->onnotify)
r = t->handler->onnotify(param, req, t, subscribe ? subscribe->evtsession : NULL, &req->event);
r = t->handler->onnotify(param, req, t, &req->event);
else
r = 0; // just ignore
//if (subscribe && 0 == cstrcmp(&req->substate.state, SIP_SUBSCRIPTION_STATE_TERMINATED))
// sip_subscribe_remove(t->agent, subscribe);
sip_subscribe_release(subscribe);
return r;
}

View File

@@ -83,35 +83,33 @@ static int sip_uas_transaction_inivte_change_state(struct sip_uas_transaction_t*
return t->status;
}
int sip_uas_transaction_invite_input(struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const struct sip_message_t* req, void* param)
int sip_uas_transaction_invite_input(struct sip_uas_transaction_t* t, const struct sip_message_t* req, void* param)
{
char ptr[256];
struct cstring_t id;
int r, status, oldstatus;
r = 0;
oldstatus = t->status;
status = sip_uas_transaction_inivte_change_state(t, req);
r = 0;
switch (status)
{
case SIP_UAS_TRANSACTION_INIT:
if (!dialog)
{
dialog = sip_uas_create_dialog(req);
if(!dialog) return 0;
}
else
{
sip_dialog_addref(dialog); // for t->dialog
}
t->dialog = sip_uas_create_dialog(req);
if(!t->dialog) return 0;
if (t->dialog->state == DIALOG_ERALY && req->to.tag.n > 0) // re-invite
t->dialog->state = DIALOG_CONFIRMED;
sip_dialog_id(&id, (t->dialog && t->dialog->state == DIALOG_CONFIRMED) ? t->dialog : NULL, ptr, sizeof(ptr));
//assert(t->param == t->initparam);
t->dialog = dialog;
// notify user
t->status = SIP_UAS_TRANSACTION_TRYING;
// re-invite: 488 (Not Acceptable Here)
r = t->handler->oninvite(param, req, t, (dialog && dialog->state == DIALOG_CONFIRMED) ? dialog : NULL, req->payload, req->size, &t->dialog->session);
r = t->handler->oninvite(param, req, t, (t->dialog && t->dialog->state == DIALOG_CONFIRMED) ? t->dialog : NULL, &id, req->payload, req->size);
// TODO: add timer here, send 100 trying
if (!t->dialog->session && SIP_UAS_TRANSACTION_TRYING == t->status)
if (0 != r && SIP_UAS_TRANSACTION_TRYING == t->status)
{
sip_uas_transaction_timewait(t, TIMER_H);
@@ -160,7 +158,6 @@ int sip_uas_transaction_invite_input(struct sip_uas_transaction_t* t, struct sip
break;
case SIP_UAS_TRANSACTION_CONFIRMED:
assert(!dialog || dialog == t->dialog);
if (oldstatus == SIP_UAS_TRANSACTION_ACCEPTED)
{
// update dialog target
@@ -168,7 +165,9 @@ int sip_uas_transaction_invite_input(struct sip_uas_transaction_t* t, struct sip
if(t->dialog->state == DIALOG_ERALY) // re-invite
t->dialog->state = DIALOG_CONFIRMED;
r = t->handler->onack(param, req, t, t->dialog->session, t->dialog, 200, req->payload, req->size);
sip_dialog_id(&id, t->dialog, ptr, sizeof(ptr));
r = t->handler->onack(param, req, t, t->dialog, &id, 200, req->payload, req->size);
// start timer I, wait for all inflight ACK
sip_uas_transaction_timewait(t, t->reliable ? 1 : TIMER_I);
@@ -198,7 +197,6 @@ int sip_uas_transaction_invite_input(struct sip_uas_transaction_t* t, struct sip
int sip_uas_transaction_invite_reply(struct sip_uas_transaction_t* t, int code, const void* data, int bytes, void* param)
{
int r;
// fix timeout(triggle by timer) before reply any code
assert(SIP_UAS_TRANSACTION_ACCEPTED != t->status && SIP_UAS_TRANSACTION_COMPLETED != t->status); // 200~700 reply once only
if (SIP_UAS_TRANSACTION_TRYING != t->status && SIP_UAS_TRANSACTION_PROCEEDING != t->status)
@@ -219,8 +217,6 @@ int sip_uas_transaction_invite_reply(struct sip_uas_transaction_t* t, int code,
assert(cstrvalid(&t->reply->to.tag));
sip_dialog_setlocaltag(t->dialog, &t->reply->to.tag);
sip_dialog_set_local_target(t->dialog, t->reply);
r = sip_dialog_add(t->agent, t->dialog);
assert(0 == r);
}
if (100 <= code && code < 200)

View File

@@ -46,14 +46,14 @@
#include "sip-uas-transaction.h"
// Figure 8: non-INVITE server transaction (p140)
int sip_uas_transaction_noninvite_input(struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const struct sip_message_t* req, void* param)
int sip_uas_transaction_noninvite_input(struct sip_uas_transaction_t* t, const struct sip_message_t* req, void* param)
{
int r;
switch (t->status)
{
case SIP_UAS_TRANSACTION_INIT:
t->status = SIP_UAS_TRANSACTION_TRYING;
r = sip_uas_transaction_handler(t, dialog, req, param);
r = sip_uas_transaction_handler(t, req, param);
if (0 != r && SIP_UAS_TRANSACTION_TRYING == t->status)
{
// user ignore/discard

View File

@@ -98,24 +98,28 @@ int sip_uas_transaction_addref(struct sip_uas_transaction_t* t)
// return sip_uas_transaction_release(t);
//}
int sip_uas_transaction_handler(struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const struct sip_message_t* req, void* param)
int sip_uas_transaction_handler(struct sip_uas_transaction_t* t, const struct sip_message_t* req, void* param)
{
//assert(t->param == t->initparam);
if (0 == cstrcasecmp(&req->u.c.method, SIP_METHOD_CANCEL))
{
return sip_uas_oncancel(t, dialog, req, param);
return sip_uas_oncancel(t, req, param);
}
else if (0 == cstrcasecmp(&req->u.c.method, SIP_METHOD_BYE))
{
return sip_uas_onbye(t, dialog, req, param);
return sip_uas_onbye(t, req, param);
}
else if (0 == cstrcasecmp(&req->u.c.method, SIP_METHOD_PRACK))
{
return sip_uas_onprack(t, dialog, req, param);
return sip_uas_onprack(t, req, param);
}
else if (0 == cstrcasecmp(&req->u.c.method, SIP_METHOD_UPDATE))
{
return sip_uas_onupdate(t, dialog, req, param);
return sip_uas_onupdate(t, req, param);
}
else if (0 == cstrcasecmp(&req->u.c.method, SIP_METHOD_INFO))
{
return sip_uas_oninfo(t, req, param);
}
else if (0 == cstrcasecmp(&req->u.c.method, SIP_METHOD_REGISTER))
{
@@ -127,7 +131,7 @@ int sip_uas_transaction_handler(struct sip_uas_transaction_t* t, struct sip_dial
}
else if (0 == cstrcasecmp(&req->u.c.method, SIP_METHOD_SUBSCRIBE))
{
return sip_uas_onsubscribe(t, dialog, req, param);
return sip_uas_onsubscribe(t, req, param);
}
else if (0 == cstrcasecmp(&req->u.c.method, SIP_METHOD_NOTIFY))
{
@@ -137,17 +141,13 @@ int sip_uas_transaction_handler(struct sip_uas_transaction_t* t, struct sip_dial
{
return sip_uas_onpublish(t, req, param);
}
else if (0 == cstrcasecmp(&req->u.c.method, SIP_METHOD_MESSAGE))
{
return t->handler->onmessage ? t->handler->onmessage(param, req, t, dialog ? dialog->session : NULL, req->payload, req->size) : 0;
}
else if (0 == cstrcasecmp(&req->u.c.method, SIP_METHOD_INFO))
{
return sip_uas_oninfo(t, dialog, req, param);
}
else if (0 == cstrcasecmp(&req->u.c.method, SIP_METHOD_REFER))
{
return sip_uas_onrefer(t, dialog, req, param);
return sip_uas_onrefer(t, req, param);
}
else if (0 == cstrcasecmp(&req->u.c.method, SIP_METHOD_MESSAGE))
{
return t->handler->onmessage ? t->handler->onmessage(param, req, t, req->payload, req->size) : 0;
}
else
{
@@ -192,6 +192,8 @@ int sip_uas_transaction_terminated(struct sip_uas_transaction_t* t)
void sip_uas_transaction_ontimeout(void* usrptr)
{
char ptr[256];
struct cstring_t id;
struct sip_uas_transaction_t* t;
t = (struct sip_uas_transaction_t*)usrptr;
locker_lock(&t->locker);
@@ -207,7 +209,10 @@ void sip_uas_transaction_ontimeout(void* usrptr)
// 8.1.3.1 Transaction Layer Errors (p42)
if (t->dialog)
t->handler->onack(t->initparam, NULL, t, t->dialog->session, (t->dialog && t->dialog->state == DIALOG_CONFIRMED) ? t->dialog : NULL, 408/*Invite Timeout*/, NULL, 0);
{
sip_dialog_id(&id, t->dialog, ptr, sizeof(ptr));
t->handler->onack(t->initparam, NULL, t, (t->dialog && t->dialog->state == DIALOG_CONFIRMED) ? t->dialog : NULL, (t->dialog && t->dialog->state == DIALOG_CONFIRMED) ? &id : NULL, 408/*Invite Timeout*/, NULL, 0);
}
}
locker_unlock(&t->locker);

View File

@@ -67,22 +67,22 @@ int sip_uas_transaction_timeout(struct sip_uas_transaction_t* t, int timeout);
int sip_uas_transaction_timewait(struct sip_uas_transaction_t* t, int timeout);
struct sip_uas_transaction_t* sip_uas_find_transaction(struct sip_agent_t* sip, const struct sip_message_t* req, int matchmethod);
int sip_uas_transaction_handler(struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const struct sip_message_t* req, void* param);
int sip_uas_transaction_handler(struct sip_uas_transaction_t* t, const struct sip_message_t* req, void* param);
int sip_uas_onregister(struct sip_uas_transaction_t* t, const struct sip_message_t* req, void* param);
int sip_uas_onoptions(struct sip_uas_transaction_t* t, const struct sip_message_t* req, void* param);
int sip_uas_oninfo(struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const struct sip_message_t* req, void* param);
int sip_uas_onrefer(struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const struct sip_message_t* req, void* param);
int sip_uas_oncancel(struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const struct sip_message_t* req, void* param);
int sip_uas_onbye(struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const struct sip_message_t* req, void* param);
int sip_uas_onprack(struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const struct sip_message_t* req, void* param);
int sip_uas_onupdate(struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const struct sip_message_t* req, void* param);
int sip_uas_onsubscribe(struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const struct sip_message_t* req, void* param);
int sip_uas_oninfo(struct sip_uas_transaction_t* t, const struct sip_message_t* req, void* param);
int sip_uas_oncancel(struct sip_uas_transaction_t* t, const struct sip_message_t* req, void* param);
int sip_uas_onbye(struct sip_uas_transaction_t* t, const struct sip_message_t* req, void* param);
int sip_uas_onprack(struct sip_uas_transaction_t* t, const struct sip_message_t* req, void* param);
int sip_uas_onupdate(struct sip_uas_transaction_t* t, const struct sip_message_t* req, void* param);
int sip_uas_onsubscribe(struct sip_uas_transaction_t* t, const struct sip_message_t* req, void* param);
int sip_uas_onnotify(struct sip_uas_transaction_t* t, const struct sip_message_t* req, void* param);
int sip_uas_onpublish(struct sip_uas_transaction_t* t, const struct sip_message_t* req, void* param);
int sip_uas_onrefer(struct sip_uas_transaction_t* t, const struct sip_message_t* req, void* param);
int sip_uas_transaction_invite_input(struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const struct sip_message_t* req, void* param);
int sip_uas_transaction_invite_input(struct sip_uas_transaction_t* t, const struct sip_message_t* req, void* param);
int sip_uas_transaction_invite_reply(struct sip_uas_transaction_t* t, int code, const void* data, int bytes, void* param);
int sip_uas_transaction_noninvite_input(struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const struct sip_message_t* req, void* param);
int sip_uas_transaction_noninvite_input(struct sip_uas_transaction_t* t, const struct sip_message_t* req, void* param);
int sip_uas_transaction_noninvite_reply(struct sip_uas_transaction_t* t, int code, const void* data, int bytes, void* param);
sip_timer_t sip_uas_start_timer(struct sip_agent_t* sip, struct sip_uas_transaction_t* t, int timeout, sip_timer_handle handler);

View File

@@ -54,8 +54,8 @@ int sip_uas_link_transaction(struct sip_agent_t* sip, struct sip_uas_transaction
int sip_uas_unlink_transaction(struct sip_agent_t* sip, struct sip_uas_transaction_t* t)
{
struct sip_dialog_t* dialog;
struct list_head *pos, *next;
//struct sip_dialog_t* dialog;
//struct list_head *pos, *next;
assert(sip->ref > 0);
locker_lock(&sip->locker);
@@ -73,16 +73,16 @@ int sip_uas_unlink_transaction(struct sip_agent_t* sip, struct sip_uas_transacti
// Independent of the method, if a request outside of a dialog generates
// a non-2xx final response, any early dialogs created through
// provisional responses to that request are terminated.
list_for_each_safe(pos, next, &sip->dialogs)
{
dialog = list_entry(pos, struct sip_dialog_t, link);
if (cstreq(&t->reply->callid, &dialog->callid) && DIALOG_ERALY == dialog->state)
{
//assert(0 == sip_contact_compare(&t->req->from, &dialog->local.uri));
sip_dialog_remove(sip, dialog); // TODO: release in locker
break;
}
}
//list_for_each_safe(pos, next, &sip->dialogs)
//{
// dialog = list_entry(pos, struct sip_dialog_t, link);
// if (cstreq(&t->reply->callid, &dialog->callid) && DIALOG_ERALY == dialog->state)
// {
// //assert(0 == sip_contact_compare(&t->req->from, &dialog->local.uri));
// sip_dialog_remove(sip, dialog); // TODO: release in locker
// break;
// }
//}
locker_unlock(&sip->locker);
sip_uas_transaction_release(t);
@@ -220,7 +220,7 @@ static int sip_uas_check_request(struct sip_agent_t* sip, struct sip_uas_transac
return 0;
}
static int sip_uas_input_with_transaction(struct sip_agent_t* sip, const struct sip_message_t* msg, struct sip_dialog_t* dialog, struct sip_uas_transaction_t* t, void* param)
static int sip_uas_input_with_transaction(struct sip_agent_t* sip, const struct sip_message_t* msg, struct sip_uas_transaction_t* t, void* param)
{
int r;
r = sip_uas_check_request(sip, t, msg, param);
@@ -231,9 +231,9 @@ static int sip_uas_input_with_transaction(struct sip_agent_t* sip, const struct
// 4. handle
if (sip_message_isinvite(msg) || sip_message_isack(msg))
r = sip_uas_transaction_invite_input(t, dialog, msg, param);
r = sip_uas_transaction_invite_input(t, msg, param);
else
r = sip_uas_transaction_noninvite_input(t, dialog, msg, param);
r = sip_uas_transaction_noninvite_input(t, msg, param);
// TODO:
// 1. A stateless UAS MUST NOT send provisional (1xx) responses.
@@ -245,7 +245,7 @@ static int sip_uas_input_with_transaction(struct sip_agent_t* sip, const struct
return r;
}
static int sip_uas_input_with_dialog(struct sip_agent_t* sip, const struct sip_message_t* msg, struct sip_dialog_t* dialog, void* param)
int sip_uas_input(struct sip_agent_t* sip, const struct sip_message_t* msg, void* param)
{
int r;
struct sip_uas_transaction_t* t;
@@ -261,7 +261,7 @@ static int sip_uas_input_with_dialog(struct sip_agent_t* sip, const struct sip_m
return 0; // invalid ack, discard, TODO: add log here
}
t = sip_uas_transaction_create(sip, msg, dialog, param);
t = sip_uas_transaction_create(sip, msg, NULL, param);
if (!t)
{
locker_unlock(&sip->locker);
@@ -271,24 +271,11 @@ static int sip_uas_input_with_dialog(struct sip_agent_t* sip, const struct sip_m
}
locker_unlock(&sip->locker);
r = sip_uas_input_with_transaction(sip, msg, dialog, t, param);
r = sip_uas_input_with_transaction(sip, msg, t, param);
sip_uas_transaction_release(t);
return r;
}
int sip_uas_input(struct sip_agent_t* sip, const struct sip_message_t* msg, void* param)
{
int r;
struct sip_dialog_t *dialog;
dialog = sip_dialog_fetch(sip, &msg->callid, &msg->to.tag, &msg->from.tag);
r = sip_uas_input_with_dialog(sip, msg, dialog, param);
sip_dialog_release(dialog);
return r;
}
int sip_uas_reply(struct sip_uas_transaction_t* t, int code, const void* data, int bytes, void* param)
{
int r;

View File

@@ -229,7 +229,7 @@ static void sip_uac_register_test(struct sip_task_t *task)
assert(0 == task->event.Wait());
}
static int sip_uac_oninvited(void* param, const struct sip_message_t* reply, struct sip_uac_transaction_t* t, struct sip_dialog_t* dialog, int code, void** session)
static int sip_uac_oninvited(void* param, const struct sip_message_t* reply, struct sip_uac_transaction_t* t, struct sip_dialog_t* dialog, const struct cstring_t* id, int code)
{
assert(code >= 100 && code < 700);
if (code >= 200 && code < 700)
@@ -238,10 +238,11 @@ static int sip_uac_oninvited(void* param, const struct sip_message_t* reply, str
task->success += (code >= 200 && code < 300);
task->failed += (code >= 300 && code < 700);
assert(task->dialog == NULL);
task->dialog = dialog;
if (200 <= code && code < 300)
{
*session = NULL;
assert(dialog);
sip_dialog_addref(dialog);
task->dialog = dialog;
sip_uac_ack(t, NULL, 0, NULL);
}
task->event.Signal();
@@ -265,8 +266,11 @@ static int sip_uac_onbye(void* param, const struct sip_message_t* reply, struct
task->success += (code >= 200 && code < 300);
task->failed += (code >= 300 && code < 700);
assert(task->dialog);
sip_dialog_release(task->dialog);
task->dialog = NULL;
if ((code >= 200 && code < 300) || 481 == code)
task->dialog = NULL;
{
}
else
printf("%s bye failed: %d\n", task->from, code);
task->event.Signal();
@@ -319,9 +323,8 @@ static void sip_uas_task_ondestroy(void* param)
assert(atomic_decrement32(&tu->count) >= 0);
}
static int sip_uas_oninvite(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const void* data, int bytes, void** session)
static int sip_uas_oninvite(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, struct sip_dialog_t* redialog, const struct cstring_t* id, const void* data, int bytes)
{
*session = t;
char contact[128];
struct sip_tu_t* tu = (struct sip_tu_t*)param;
atomic_increment32(&tu->count);
@@ -334,13 +337,13 @@ static int sip_uas_oninvite(void* param, const struct sip_message_t* req, struct
/// @param[in] code 0-ok, other-sip status code
/// @return 0-ok, other-error
static int sip_uas_onack(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session, struct sip_dialog_t* dialog, int code, const void* data, int bytes)
static int sip_uas_onack(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const struct cstring_t* id, int code, const void* data, int bytes)
{
return 0;
}
/// on terminating a session(dialog)
static int sip_uas_onbye(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session)
static int sip_uas_onbye(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, const struct cstring_t* id)
{
struct sip_tu_t* tu = (struct sip_tu_t*)param;
atomic_increment32(&tu->count);
@@ -349,7 +352,7 @@ static int sip_uas_onbye(void* param, const struct sip_message_t* req, struct si
}
/// cancel a transaction(should be an invite transaction)
static int sip_uas_oncancel(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session)
static int sip_uas_oncancel(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, const struct cstring_t* id)
{
struct sip_tu_t* tu = (struct sip_tu_t*)param;
atomic_increment32(&tu->count);
@@ -366,7 +369,7 @@ static int sip_uas_onregister(void* param, const struct sip_message_t* req, stru
return sip_uas_reply(t, 200, NULL, 0, param);
}
static int sip_uas_onmessage(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session, const void* payload, int bytes)
static int sip_uas_onmessage(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, const void* payload, int bytes)
{
struct sip_tu_t* tu = (struct sip_tu_t*)param;
atomic_increment32(&tu->count);

View File

@@ -22,7 +22,7 @@ struct sip_message_test_t
{
struct sip_agent_t* sip;
struct sip_transport_t udp;
struct sip_dialog_t* dialog;
//struct sip_dialog_t* dialog;
std::shared_ptr<struct sip_uas_transaction_t> st;
char buf[1024];
};
@@ -53,19 +53,18 @@ static struct sip_message_t* reply2sip(const char* reply)
return msg;
}
static int sip_uac_test_oninvite(void* param, const struct sip_message_t* reply, struct sip_uac_transaction_t* t, struct sip_dialog_t* dialog, int code, void** session)
static int sip_uac_test_oninvite(void* param, const struct sip_message_t* reply, struct sip_uac_transaction_t* t, struct sip_dialog_t* dialog, const struct cstring_t* id, int code)
{
struct sip_message_test_t* test = (struct sip_message_test_t*)param;
test->dialog = dialog;
//test->dialog = dialog;
if (200 <= code && code < 300)
{
*session = test;
sip_uac_ack(t, NULL, 0, NULL);
}
return 0;
}
static int sip_uac_test_onsubscribe(void* param, const struct sip_message_t* reply, struct sip_uac_transaction_t* t, struct sip_subscribe_t* subscribe, int code, void** session)
static int sip_uac_test_onsubscribe(void* param, const struct sip_message_t* reply, struct sip_uac_transaction_t* t, struct sip_subscribe_t* subscribe, const struct cstring_t* id, int code)
{
return 0;
}
@@ -621,18 +620,17 @@ static int sip_test_bye(struct sip_message_test_t* alice, struct sip_message_tes
return 0;
}
static int sip_uas_oninvite(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const void* data, int bytes, void** session)
static int sip_uas_oninvite(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const struct cstring_t* id, const void* data, int bytes)
{
struct sip_message_test_t* test = (struct sip_message_test_t*)param;
test->dialog = dialog;
//test->dialog = dialog;
sip_uas_transaction_addref(t);
test->st.reset(t, sip_uas_transaction_release);
*session = test;
return 0;
}
static int sip_uas_onack(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session, struct sip_dialog_t* dialog, int code, const void* data, int bytes)
static int sip_uas_onack(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const struct cstring_t* id, int code, const void* data, int bytes)
{
struct sip_message_test_t* test = (struct sip_message_test_t*)param;
sip_uas_transaction_addref(t);
@@ -640,7 +638,7 @@ static int sip_uas_onack(void* param, const struct sip_message_t* req, struct si
return 0;
}
static int sip_uas_onbye(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session)
static int sip_uas_onbye(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, const struct cstring_t* id)
{
struct sip_message_test_t* test = (struct sip_message_test_t*)param;
sip_uas_transaction_addref(t);
@@ -648,7 +646,7 @@ static int sip_uas_onbye(void* param, const struct sip_message_t* req, struct si
return 0;
}
static int sip_uas_oncancel(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session)
static int sip_uas_oncancel(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, const struct cstring_t* id)
{
struct sip_message_test_t* test = (struct sip_message_test_t*)param;
sip_uas_transaction_addref(t);
@@ -656,7 +654,7 @@ static int sip_uas_oncancel(void* param, const struct sip_message_t* req, struct
return 0;
}
static int sip_uas_onprack(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session, struct sip_dialog_t* dialog, const void* data, int bytes)
static int sip_uas_onprack(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, const struct cstring_t* id, const void* data, int bytes)
{
struct sip_message_test_t* test = (struct sip_message_test_t*)param;
sip_uas_transaction_addref(t);
@@ -664,7 +662,7 @@ static int sip_uas_onprack(void* param, const struct sip_message_t* req, struct
return 0;
}
static int sip_uas_onupdate(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session, struct sip_dialog_t* dialog, const void* data, int bytes)
static int sip_uas_onupdate(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, const struct cstring_t* id, const void* data, int bytes)
{
struct sip_message_test_t* test = (struct sip_message_test_t*)param;
sip_uas_transaction_addref(t);
@@ -672,7 +670,7 @@ static int sip_uas_onupdate(void* param, const struct sip_message_t* req, struct
return 0;
}
static int sip_uas_oninfo(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session, struct sip_dialog_t* dialog, const struct cstring_t* package, const void* data, int bytes)
static int sip_uas_oninfo(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, const struct cstring_t* id, const struct cstring_t* package, const void* data, int bytes)
{
struct sip_message_test_t* test = (struct sip_message_test_t*)param;
sip_uas_transaction_addref(t);
@@ -691,7 +689,7 @@ static int sip_uas_onregister(void* param, const struct sip_message_t* req, stru
return 0;
}
static int sip_uas_onmessage(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session, const void* payload, int bytes)
static int sip_uas_onmessage(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, const void* payload, int bytes)
{
struct sip_message_test_t* test = (struct sip_message_test_t*)param;
sip_uas_transaction_addref(t);
@@ -699,7 +697,7 @@ static int sip_uas_onmessage(void* param, const struct sip_message_t* req, struc
return 0;
}
static int sip_uas_onsubscribe(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, sip_subscribe_t* subscribe, void** sub)
static int sip_uas_onsubscribe(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, sip_subscribe_t* subscribe, const struct cstring_t* id)
{
struct sip_message_test_t* test = (struct sip_message_test_t*)param;
sip_uas_transaction_addref(t);
@@ -709,11 +707,10 @@ static int sip_uas_onsubscribe(void* param, const struct sip_message_t* req, str
//std::shared_ptr<sip_uac_transaction_t> notify(sip_uac_notify(test->sip, subscribe, "active", sip_uac_test_onreply, test), sip_uac_transaction_release);
//assert(0 == sip_uac_send(notify.get(), NULL, 0, &test->udp, test));
*sub = test;
return 0;
}
static int sip_uas_onnotify(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session, const struct sip_event_t* event)
static int sip_uas_onnotify(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, const struct sip_event_t* event)
{
struct sip_message_test_t* test = (struct sip_message_test_t*)param;
sip_uas_transaction_addref(t);
@@ -729,7 +726,7 @@ static int sip_uas_onpublish(void* param, const struct sip_message_t* req, struc
return 0;
}
static int sip_uas_onrefer(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session)
static int sip_uas_onrefer(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t)
{
struct sip_message_test_t* test = (struct sip_message_test_t*)param;
sip_uas_transaction_addref(t);
@@ -753,8 +750,8 @@ void sip_message_test(void)
sip_uas_onsubscribe,
sip_uas_onnotify,
sip_uas_onpublish,
sip_uas_onmessage,
sip_uas_onrefer,
sip_uas_onmessage,
};
struct sip_message_test_t alice, bob;

View File

@@ -3,6 +3,7 @@
#include "sip-uac.h"
#include "sip-message.h"
#include "sip-transport.h"
#include "sip-subscribe.h"
#include "port/ip-route.h"
#include "http-parser.h"
#include "uri-parse.h"
@@ -90,12 +91,13 @@ static int sip_uac_transport_send(void* transport, const void* data, size_t byte
// assert(sip_contact_write(&msg->from, p1, p1 + sizeof(p1)) > 0 && sip_contact_write(&req->from, p2, p2 + sizeof(p2)) > 0 && 0 == strcmp(p1, p2));
return 0;
}
static int sip_uac_message_oninvite(void* param, const struct sip_message_t* reply, struct sip_uac_transaction_t* t, struct sip_dialog_t* dialog, int code, void** session)
static int sip_uac_message_oninvite(void* param, const struct sip_message_t* reply, struct sip_uac_transaction_t* t, struct sip_dialog_t* dialog, const struct cstring_t* id, int code)
{
s_dialog = dialog;
assert(!s_dialog);
if (200 <= code && code < 300)
{
*session = NULL;
sip_dialog_addref(dialog);
s_dialog = dialog;
sip_uac_ack(t, NULL, 0, NULL);
}
return 0;
@@ -103,15 +105,23 @@ static int sip_uac_message_oninvite(void* param, const struct sip_message_t* rep
static int sip_uac_message_onbye(void* param, const struct sip_message_t* reply, struct sip_uac_transaction_t* t, int code)
{
assert(s_dialog);
sip_dialog_release(s_dialog);
s_dialog = NULL;
return 0;
}
static int sip_uac_message_onsubscribe(void* param, const struct sip_message_t* reply, struct sip_uac_transaction_t* t, struct sip_subscribe_t* subscribe, int code, void** session)
static int sip_uac_message_onsubscribe(void* param, const struct sip_message_t* reply, struct sip_uac_transaction_t* t, struct sip_subscribe_t* subscribe, const struct cstring_t* id, int code)
{
s_subscribe = subscribe;
char ptr[256];
struct cstring_t old;
sip_subscribe_id(&old, s_subscribe, ptr, sizeof(ptr));
assert(!s_subscribe || cstreq(&old, id));
if (200 <= code && code < 300)
{
*session = NULL;
sip_subscribe_release(s_subscribe);
sip_subscribe_addref(subscribe);
s_subscribe = subscribe;
}
return 0;
}

View File

@@ -217,11 +217,10 @@ static void sip_uac_message_test(struct sip_uac_test_t *test)
sip_uac_recv_reply(test);
}
static int sip_uac_oninvited(void* param, const struct sip_message_t* reply, struct sip_uac_transaction_t* t, struct sip_dialog_t* dialog, int code, void** session)
static int sip_uac_oninvited(void* param, const struct sip_message_t* reply, struct sip_uac_transaction_t* t, struct sip_dialog_t* dialog, const struct cstring_t* id, int code)
{
if (200 <= code && code < 300)
{
*session = NULL;
sip_uac_ack(t, NULL, 0, NULL);
}
return NULL;

View File

@@ -543,7 +543,7 @@ static int STDCALL sip_work_thread(void* param)
return 0;
}
static int sip_uas_oninvite_indialog(sip_uac_test2_t* ctx, sip_uac_test2_session_t* s, const struct sip_message_t* req, struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const void* data, int bytes, void** session)
static int sip_uas_oninvite_indialog(sip_uac_test2_t* ctx, sip_uac_test2_session_t* s, const struct sip_message_t* req, struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const struct cstring_t* id, const void* data, int bytes)
{
const char* pattern = "v=0\n"
"o=%s 0 0 IN IP4 %s\n"
@@ -572,7 +572,6 @@ static int sip_uas_oninvite_indialog(sip_uac_test2_t* ctx, sip_uac_test2_session
n += ice_transport_getsdp(s->avt, s->video.stream, reply + n, sizeof(reply) - n);
}
*session = s;
s->t = t;
sip_uas_add_header(t, "Content-Type", "application/sdp");
//sip_uas_add_header(s->t, "Contact", "sip:" SIP_USR "@" LOCAL_HOST);
@@ -580,7 +579,7 @@ static int sip_uas_oninvite_indialog(sip_uac_test2_t* ctx, sip_uac_test2_session
return 0;
}
static int sip_uas_oninvite(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const void* data, int bytes, void** session)
static int sip_uas_oninvite(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, struct sip_dialog_t* redialog, const struct cstring_t* id, const void* data, int bytes)
{
sip_uac_test2_t* ctx = (sip_uac_test2_t*)param;
@@ -599,13 +598,13 @@ static int sip_uas_oninvite(void* param, const struct sip_message_t* req, struct
it = ctx->sessions.find(s->from);
if (ctx->sessions.end() != it)
{
if(!dialog)
if(!redialog)
return 0; // ignore
// in dialog
return sip_uas_oninvite_indialog(ctx, it->second.get(), req, t, dialog, data, bytes, session);
return sip_uas_oninvite_indialog(ctx, it->second.get(), req, t, redialog, id, data, bytes);
}
ctx->sessions.insert(std::make_pair(s->from, s));
ctx->sessions.insert(std::make_pair(std::string(id->p, id->n), s));
}
struct ice_transport_handler_t handler = {
@@ -689,7 +688,6 @@ static int sip_uas_oninvite(void* param, const struct sip_message_t* req, struct
// s->pkts = pkts;
//s->source = source;
*session = s.get();
//sip_uas_add_header(t, "Content-Type", "application/sdp");
//sip_uas_add_header(t, "Contact", "sip:" SIP_USR "@" LOCAL_HOST);
// snprintf(reply, sizeof(reply), pattern, SIP_USR, LOCAL_HOST, LOCAL_HOST, s->audio.decoder?(char*)s->audio.sender.buffer:"", s->video.decoder?(char*)s->video.sender.buffer:"");
@@ -701,10 +699,14 @@ static int sip_uas_oninvite(void* param, const struct sip_message_t* req, struct
/// @param[in] code 0-ok, other-sip status code
/// @return 0-ok, other-error
static int sip_uas_onack(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session, struct sip_dialog_t* dialog, int code, const void* data, int bytes)
static int sip_uas_onack(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const struct cstring_t* id, int code, const void* data, int bytes)
{
struct sip_uac_test2_t* ctx = (struct sip_uac_test2_t*)param; assert(ctx);
sip_uac_test2_session_t* s = (sip_uac_test2_session_t*)session; assert(s);
AutoThreadLocker locker(ctx->locker);
auto it = ctx->sessions.find(std::string(id->p, id->n));
if (ctx->sessions.end() == it)
return 0;
sip_uac_test2_session_t* s = it->second.get(); assert(s);
printf("sip_uas_onack[%p]: %d\n", s, code);
if (200 <= code && code < 300)
@@ -726,16 +728,15 @@ static int sip_uas_onack(void* param, const struct sip_message_t* req, struct si
}
/// on terminating a session(dialog)
static int sip_uas_onbye(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session)
static int sip_uas_onbye(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, const struct cstring_t* id)
{
struct sip_uac_test2_t* ctx = (struct sip_uac_test2_t*)param;
sip_uac_test2_session_t* p = (sip_uac_test2_session_t*)session;
std::shared_ptr<sip_uac_test2_session_t> s;
sip_uac_test2_t::TSessions::iterator it;
{
AutoThreadLocker locker(ctx->locker);
it = ctx->sessions.find(p->from);
it = ctx->sessions.find(std::string(id->p, id->n));
if (it == ctx->sessions.end())
return sip_uas_reply(t, 481, NULL, 0, param);
@@ -751,7 +752,7 @@ static int sip_uas_onbye(void* param, const struct sip_message_t* req, struct si
}
/// cancel a transaction(should be an invite transaction)
static int sip_uas_oncancel(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session)
static int sip_uas_oncancel(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, const struct cstring_t* id)
{
return sip_uas_reply(t, 200, NULL, 0, param);
}
@@ -762,7 +763,7 @@ static int sip_uas_onregister(void* param, const struct sip_message_t* req, stru
return sip_uas_reply(t, 200, NULL, 0, param);
}
static int sip_uas_onmessage(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session, const void* payload, int bytes)
static int sip_uas_onmessage(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, const void* payload, int bytes)
{
return sip_uas_reply(t, 200, NULL, 0, param);
}
@@ -818,7 +819,7 @@ static void sip_uac_ice_transport_onbind(void* param, int code)
}
}
static int sip_uac_oninvited(void* param, const struct sip_message_t* reply, struct sip_uac_transaction_t* t, struct sip_dialog_t* dialog, int code, void** session)
static int sip_uac_oninvited(void* param, const struct sip_message_t* reply, struct sip_uac_transaction_t* t, struct sip_dialog_t* dialog, const struct cstring_t* id, int code)
{
const cstring_t* h;
std::shared_ptr<struct sip_uac_test2_session_t> s;
@@ -899,7 +900,6 @@ static int sip_uac_oninvited(void* param, const struct sip_message_t* reply, str
s->running = true;
thread_create(&s->th, sip_work_thread, s.get());
*session = s.get();
sip_uac_ack(t, NULL, 0, NULL);
return 0;
}
@@ -1112,11 +1112,11 @@ static int sip_uac_test_process(struct sip_uac_test2_t* test)
return 0;
}
static int sip_uas_onsubscribe(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, sip_subscribe_t* subscribe, void** sub)
static int sip_uas_onsubscribe(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, sip_subscribe_t* subscribe, const struct cstring_t* id)
{
return 0;
}
static int sip_uas_onnotify(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session, const struct sip_event_t* event)
static int sip_uas_onnotify(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, const struct sip_event_t* event)
{
return 0;
}
@@ -1125,22 +1125,22 @@ static int sip_uas_onpublish(void* param, const struct sip_message_t* req, struc
return 0;
}
static int sip_uas_onrefer(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session)
static int sip_uas_onrefer(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t)
{
return 0;
}
static int sip_uas_onprack(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session, struct sip_dialog_t* dialog, const void* data, int bytes)
static int sip_uas_onprack(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, const struct cstring_t* id, const void* data, int bytes)
{
return 0;
}
static int sip_uas_onupdate(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session, struct sip_dialog_t* dialog, const void* data, int bytes)
static int sip_uas_onupdate(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, const struct cstring_t* id, const void* data, int bytes)
{
return 0;
}
static int sip_uas_oninfo(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session, struct sip_dialog_t* dialog, const struct cstring_t* package, const void* data, int bytes)
static int sip_uas_oninfo(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, const struct cstring_t* id, const struct cstring_t* package, const void* data, int bytes)
{
return 0;
}
@@ -1151,6 +1151,7 @@ void sip_uac_test2(void)
sip_timer_init();
struct sip_uac_test2_t test;
memset(&test, 0, sizeof(test));
test.running = true;
test.callid[0] = 0;
struct sip_uas_handler_t handler = {
@@ -1166,8 +1167,8 @@ void sip_uac_test2(void)
sip_uas_onsubscribe,
sip_uas_onnotify,
sip_uas_onpublish,
sip_uas_onmessage,
sip_uas_onrefer,
sip_uas_onmessage,
};
assert(1 == sscanf(SIP_FROM, "sip:%[^@]", test.usr));

View File

@@ -197,14 +197,12 @@ static int sip_bye(struct sip_agent_t* sip)
struct sip_session_t
{
struct sip_uas_transaction_t* t;
struct sip_dialog_t* dialog;
};
static int sip_uas_oninvite(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const void* data, int bytes, void** ptr)
static int sip_uas_oninvite(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const struct cstring_t* id, const void* data, int bytes)
{
struct sip_session_t* session = new struct sip_session_t;
assert(NULL == dialog); // re-invite
// assert(NULL == dialog); // not re-invite
//sip_uas_add_header(t, "To", "Bob <sip:bob@biloxi.com>;tag=a6c85cf");
assert(0 == sip_uas_reply(t, 100, NULL, 0, param));
assert(0 == sip_uas_reply(t, 100, NULL, 0, param));
@@ -213,19 +211,16 @@ static int sip_uas_oninvite(void* param, const struct sip_message_t* req, struct
assert(0 == sip_uas_reply(t, 180, NULL, 0, param));
assert(0 == sip_uas_reply(t, 200, NULL, 0, param));
// assert(0 == sip_uas_reply(t, 200, NULL, 0, param));
session->t = t;
*ptr = session;
return 0;
}
static int sip_uas_onack(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session, struct sip_dialog_t* dialog, int code, const void* data, int bytes)
static int sip_uas_onack(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const struct cstring_t* id, int code, const void* data, int bytes)
{
char buf[1024];
const char* end = buf + sizeof(buf);
struct cstring_t ptr;
ptr.p = buf;
struct sip_session_t* s = (struct sip_session_t*)session;
struct sip_agent_t* uas = (struct sip_agent_t*)param;
assert(100 <= code && code < 700);
if (200 <= code && code < 300)
@@ -241,25 +236,21 @@ static int sip_uas_onack(void* param, const struct sip_message_t* req, struct si
assert(0 == cstrcmp(&ptr, "sip:alice@pc33.atlanta.com"));
assert(0 == cstrcmp(&dialog->callid, "a84b4c76e66710"));
assert(0 == sip_uris_count(&dialog->routers));
s->dialog = dialog;
}
else if (300 <= code && code < 700)
{
delete s;
}
return 0;
}
static int sip_uas_onbye(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session)
static int sip_uas_onbye(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, const struct cstring_t* id)
{
struct sip_session_t* s = (struct sip_session_t*)session;
struct sip_agent_t* uas = (struct sip_agent_t*)param;
assert(0 == sip_uas_reply(t, 200, NULL, 0, param));
if(s) delete s;
return 0;
}
static int sip_uas_oncancel(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session)
static int sip_uas_oncancel(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, const struct cstring_t* id)
{
assert(0);
return -1;
@@ -274,7 +265,7 @@ static int sip_uas_onregister(void* param, const struct sip_message_t* req, stru
return sip_uas_reply(t, 200, NULL, 0, param);
}
static int sip_uas_onmessage(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session, const void* payload, int bytes)
static int sip_uas_onmessage(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, const void* payload, int bytes)
{
return sip_uas_reply(t, 200, NULL, 0, param);
}

View File

@@ -38,7 +38,7 @@ static int sip_uas_transport_send(void* param, const struct cstring_t* /*protoco
return r == bytes ? 0 : -1;
}
static int sip_uas_oninvite(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const void* data, int bytes, void** session)
static int sip_uas_oninvite(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const struct cstring_t* id, const void* data, int bytes)
{
const char* ack = "v=0\n"
"o=34020000001320000001 0 0 IN IP4 192.168.128.1\n"
@@ -61,32 +61,30 @@ static int sip_uas_oninvite(void* param, const struct sip_message_t* req, struct
sip_uas_add_header(t, "Contact", "sip:34020000001320000001@192.168.154.1");
assert(0 == sip_uas_reply(t, 200, ack, strlen(ack), param));
sdp_destroy(sdp);
*session = t;
return 0;
}
else
{
assert(0);
*session = t;
return 0;
}
}
/// @param[in] code 0-ok, other-sip status code
/// @return 0-ok, other-error
static int sip_uas_onack(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session, struct sip_dialog_t* dialog, int code, const void* data, int bytes)
static int sip_uas_onack(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const struct cstring_t* id, int code, const void* data, int bytes)
{
return 0;
}
/// on terminating a session(dialog)
static int sip_uas_onbye(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session)
static int sip_uas_onbye(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, const struct cstring_t* id)
{
return 0;
}
/// cancel a transaction(should be an invite transaction)
static int sip_uas_oncancel(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session)
static int sip_uas_oncancel(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, const struct cstring_t* id)
{
return 0;
}

View File

@@ -49,6 +49,8 @@ struct sip_media_t
unsigned short port[2];
};
static std::map<std::string, struct sip_media_t*> s_sessions;
static int sip_uas_transport_send(void* param, const struct cstring_t* /*protocol*/, const struct cstring_t* /*url*/, const struct cstring_t* /*received*/, int /*rport*/, const void* data, int bytes)
{
struct sip_uas_test_t *test = (struct sip_uas_test_t *)param;
@@ -60,7 +62,7 @@ static int sip_uas_transport_send(void* param, const struct cstring_t* /*protoco
return r == bytes ? 0 : -1;
}
static int sip_uas_oninvite(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const void* data, int bytes, void** session)
static int sip_uas_oninvite(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const struct cstring_t* id, const void* data, int bytes)
{
const char* pattern = "v=0\n"
"o=- 0 0 IN IP4 %s\n"
@@ -93,7 +95,7 @@ static int sip_uas_oninvite(void* param, const struct sip_message_t* req, struct
sip_uas_add_header(t, "Contact", "sip:" NAME "@" HOST);
snprintf(reply, sizeof(reply), pattern, HOST, HOST, m->port[0]);
assert(0 == sip_uas_reply(t, 200, reply, strlen(reply), param));
*session = m;
s_sessions[std::string(id->p, id->n)] = m;
return 0;
}
else
@@ -118,10 +120,9 @@ static int STDCALL rtsp_play_thread(void* param)
/// @param[in] code 0-ok, other-sip status code
/// @return 0-ok, other-error
static int sip_uas_onack(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session, struct sip_dialog_t* dialog, int code, const void* data, int bytes)
static int sip_uas_onack(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const struct cstring_t* id, int code, const void* data, int bytes)
{
struct sip_media_t* m = (struct sip_media_t*)session;
struct sip_media_t* m = s_sessions[std::string(id->p, id->n)];
if (200 <= code && code < 300)
{
pthread_t th;
@@ -136,13 +137,13 @@ static int sip_uas_onack(void* param, const struct sip_message_t* req, struct si
}
/// on terminating a session(dialog)
static int sip_uas_onbye(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session)
static int sip_uas_onbye(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, const struct cstring_t* id)
{
return sip_uas_reply(t, 200, NULL, 0, param);
}
/// cancel a transaction(should be an invite transaction)
static int sip_uas_oncancel(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session)
static int sip_uas_oncancel(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, const struct cstring_t* id)
{
return sip_uas_reply(t, 200, NULL, 0, param);
}