Commit 69b0249d authored by Pekka Pessi's avatar Pekka Pessi

nua: refactored the client side.

Now each handle has a queue of client-side requests; if a request is
pending, a new request from API is added to the queue. After the request is
complete, it is removed from the queue and destroyed by the default. The
exception is the client requests bound to a dialog usage: they are saved and
re-used when the dialog usage is refreshed (and sometimes when they are
terminated).

The client request is subclassed and its behaviour modified using virtual
function table in nua_client_methods_t.

darcs-hash:20070102121444-65a35-f1fa4d836b95611cfbc6141ff491afcb8b789a74.gz
parent 1c53f4cc
......@@ -159,10 +159,12 @@ extern char const _NUA_HANDLE_DEBUG[];
static void nh_destructor(void *arg)
{
nua_handle_t *nh = arg;
SU_DEBUG_0(("nh_destructor(%p)\n", nh));
}
#undef nua_handle_ref
#undef nua_handle_unref
/** Make a new reference to handle.
*
* The handles use reference counting for memory management. In addition to
......@@ -180,7 +182,6 @@ nua_handle_t *nua_handle_ref(nua_handle_t *nh)
return (nua_handle_t *)su_home_ref(nh->nh_home);
}
/** Destroy reference to handle.
*
* The handles use reference counting for memory management. In addition to
......@@ -301,3 +302,34 @@ char const *nua_callstate_name(enum nua_callstate state)
default: return "UNKNOWN";
}
}
/** Return name of subscription state. @NEW_1_12_5. */
char const *nua_substate_name(enum nua_substate substate)
{
switch (substate) {
case nua_substate_embryonic:
/*FALLTHROUGH*/
case nua_substate_pending:
return "pending";
case nua_substate_terminated:
return "terminated";
case nua_substate_active:
/*FALLTHROUGH*/
default:
return "active";
}
}
/** Convert string to enum nua_substate. @NEW_1_12_5. */
enum nua_substate nua_substate_make(char const *sip_substate)
{
if (sip_substate == NULL)
return nua_substate_active;
else if (strcasecmp(sip_substate, "terminated") == 0)
return nua_substate_terminated;
else if (strcasecmp(sip_substate, "pending") == 0)
return nua_substate_pending;
else /* if (strcasecmp(sip_substate, "active") == 0) */
return nua_substate_active;
}
......@@ -345,6 +345,15 @@ void nua_dialog_usage_remove_at(nua_owner_t *own,
nua_client_request_t *cr, *cr_next;
nua_server_request_t *sr, *sr_next;
/* Destroy saved client request */
if (nua_client_is_bound(du->du_cr)) {
nua_client_bind(cr = du->du_cr, NULL);
if (!nua_client_is_queued(cr) &&
!nua_client_is_reporting(cr))
nua_client_request_destroy(cr);
}
/* Clean references from queued client requests */
for (cr = ds->ds_cr; cr; cr = cr_next) {
cr_next = cr->cr_next;
if (cr->cr_usage == du)
......@@ -365,7 +374,6 @@ void nua_dialog_usage_remove_at(nua_owner_t *own,
own, nua_dialog_usage_name(du),
o ? " with event " : "", o ? o->o_type :""));
du->du_class->usage_remove(own, ds, du);
msg_destroy(du->du_msg), du->du_msg = NULL;
su_home_unref(own);
su_free(own, du);
}
......@@ -524,7 +532,8 @@ void nua_dialog_usage_refresh_range(nua_dialog_usage_t *du,
/**@internal Do not refresh. */
void nua_dialog_usage_reset_refresh(nua_dialog_usage_t *du)
{
du->du_refresh = 0;
if (du)
du->du_refresh = 0;
}
/** @internal Refresh usage or shutdown usage if @a now is 0. */
......@@ -537,18 +546,26 @@ void nua_dialog_usage_refresh(nua_owner_t *owner,
du->du_refresh = 0;
if (now > 0) {
if (du->du_class->usage_refresh) {
du->du_class->usage_refresh(owner, ds, du, now);
return;
}
assert(du->du_class->usage_refresh);
du->du_class->usage_refresh(owner, ds, du, now);
}
else {
du->du_shutdown = 1;
if (du->du_class->usage_shutdown) {
du->du_class->usage_shutdown(owner, ds, du);
return;
}
assert(du->du_class->usage_shutdown);
du->du_class->usage_shutdown(owner, ds, du);
}
}
}
/** (Gracefully) terminate usage */
void nua_dialog_usage_terminate(nua_owner_t *owner,
nua_dialog_state_t *ds,
nua_dialog_usage_t *du)
{
if (du) {
du->du_refresh = 0;
du->du_shutdown = 1;
assert(du->du_class->usage_shutdown);
du->du_class->usage_shutdown(owner, ds, du);
}
}
This diff is collapsed.
......@@ -45,9 +45,6 @@
#include <sofia-sip/sip_status.h>
#include <sofia-sip/su_tagarg.h>
#define NTA_LEG_MAGIC_T struct nua_handle_s
#define NTA_OUTGOING_MAGIC_T struct nua_handle_s
#define NEA_SMAGIC_T struct nua_handle_s
#define NEA_EMAGIC_T struct nua_handle_s
......
......@@ -43,17 +43,8 @@
#include <sofia-sip/sip_protos.h>
#include <sofia-sip/sip_status.h>
#define NTA_LEG_MAGIC_T struct nua_handle_s
#define NTA_OUTGOING_MAGIC_T struct nua_handle_s
#include "nua_stack.h"
static int process_response_to_method(nua_handle_t *nh,
nta_outgoing_t *orq,
sip_t const *sip);
static void restart_method(nua_handle_t *nh, tagi_t *tags);
static int respond_to_method(nua_server_request_t *sr, tagi_t const *tags);
/** Send an extension request.
*
* Send an entension request message.
......@@ -78,32 +69,25 @@ static int respond_to_method(nua_server_request_t *sr, tagi_t const *tags);
* @since New in @VERSION_1_12_4.
*/
static nua_client_methods_t nua_method_client_methods = {
SIP_METHOD_UNKNOWN,
0,
{
/* create_dialog */ 0,
/* in_dialog */ 0,
/* target_refresh */ 0
},
/* nua_method_client_template */ NULL,
/* nua_method_client_init */ NULL,
/* nua_method_client_request */ NULL,
/* nua_method_client_check_restart */ NULL,
/* nua_method_client_response */ NULL
};
int
nua_stack_method(nua_t *nua, nua_handle_t *nh, nua_event_t e, tagi_t const *tags)
{
nua_client_request_t *cr = nh->nh_ds->ds_cr;
msg_t *msg;
if (cr->cr_orq)
return UA_EVENT2(e, 900, "Request already in progress");
nua_stack_init_handle(nua, nh, TAG_NEXT(tags));
msg = nua_creq_msg(nua, nh, cr, cr->cr_retry_count,
SIP_METHOD_UNKNOWN,
TAG_NEXT(tags));
if (msg)
cr->cr_orq = nta_outgoing_mcreate(nua->nua_nta,
process_response_to_method, nh, NULL,
msg,
SIPTAG_END(),
TAG_NEXT(tags));
if (!cr->cr_orq) {
msg_destroy(msg);
return UA_EVENT1(e, NUA_INTERNAL_ERROR);
}
return cr->cr_event = e;
return nua_client_create(nh, e, &nua_method_client_methods, tags);
}
/** @NUA_EVENT nua_r_method
......@@ -127,20 +111,6 @@ nua_stack_method(nua_t *nua, nua_handle_t *nh, nua_event_t e, tagi_t const *tags
* @END_NUA_EVENT
*/
static int process_response_to_method(nua_handle_t *nh,
nta_outgoing_t *orq,
sip_t const *sip)
{
if (nua_creq_check_restart(nh, nh->nh_ds->ds_cr, orq, sip, restart_method))
return 0;
return nua_stack_process_response(nh, nh->nh_ds->ds_cr, orq, sip, TAG_END());
}
void restart_method(nua_handle_t *nh, tagi_t *tags)
{
nua_creq_restart(nh, nh->nh_ds->ds_cr, process_response_to_method, tags);
}
/** @NUA_EVENT nua_i_method
*
* @brief Incoming extension request.
......@@ -165,6 +135,8 @@ void restart_method(nua_handle_t *nh, tagi_t *tags)
* @END_NUA_EVENT
*/
static int respond_to_method(nua_server_request_t *sr, tagi_t const *tags);
int nua_stack_process_method(nua_t *nua,
nua_handle_t *nh,
nta_incoming_t *irq,
......@@ -172,9 +144,7 @@ int nua_stack_process_method(nua_t *nua,
{
nua_server_request_t *sr, sr0[1];
sr = SR_INIT(sr0);
sr = nua_server_request(nua, nh, irq, sip, sr, sizeof *sr,
sr = nua_server_request(nua, nh, irq, sip, SR_INIT(sr0), sizeof sr0,
respond_to_method, 0);
return nua_stack_server_event(nua, sr, nua_i_method, TAG_END());
......@@ -185,20 +155,14 @@ int respond_to_method(nua_server_request_t *sr, tagi_t const *tags)
{
nua_handle_t *nh = sr->sr_owner;
nua_t *nua = nh->nh_nua;
msg_t *msg;
int status = sr->sr_status;
msg = nua_server_response(sr, sr->sr_status, sr->sr_phrase, TAG_NEXT(tags));
int final = nua_default_respond(sr, tags);
if (msg) {
nta_incoming_mreply(sr->sr_irq, msg);
}
else {
SR_STATUS1(sr, SIP_500_INTERNAL_SERVER_ERROR);
nta_incoming_treply(sr->sr_irq, sr->sr_status, sr->sr_phrase, TAG_END());
if (status != sr->sr_status)
nua_stack_event(nua, nh, NULL,
nua_i_error, 900, "Response to Extension Method Fails",
TAG_END());
}
return sr->sr_status >= 200 ? sr->sr_status : 0;
return final;
}
......@@ -43,9 +43,6 @@
#include <sofia-sip/sip_protos.h>
#include <sofia-sip/sip_status.h>
#define NTA_LEG_MAGIC_T struct nua_handle_s
#define NTA_OUTGOING_MAGIC_T struct nua_handle_s
#include "nua_stack.h"
/* ======================================================================== */
......@@ -72,48 +69,41 @@
* @sa #nua_i_message, @RFC3428
*/
static int process_response_to_message(nua_handle_t *nh,
nta_outgoing_t *orq,
sip_t const *sip);
static int nua_message_client_init(nua_client_request_t *cr,
msg_t *, sip_t *,
tagi_t const *tags);
static nua_client_methods_t nua_message_client_methods = {
SIP_METHOD_MESSAGE,
0,
{
/* create_dialog */ 0,
/* in_dialog */ 0,
/* target refresh */ 0
},
/* nua_message_client_template */ NULL,
nua_message_client_init,
/*nua_message_client_request*/ NULL,
/* nua_message_client_check_restart */ NULL,
/*nua_message_client_response*/ NULL
};
int
nua_stack_message(nua_t *nua, nua_handle_t *nh, nua_event_t e, tagi_t const *tags)
nua_stack_message(nua_t *nua,
nua_handle_t *nh,
nua_event_t e,
tagi_t const *tags)
{
nua_client_request_t *cr = nh->nh_ds->ds_cr;
msg_t *msg;
sip_t *sip;
if (nh_is_special(nh)) {
return UA_EVENT2(e, 900, "Invalid handle for MESSAGE");
}
else if (cr->cr_orq) {
return UA_EVENT2(e, 900, "Request already in progress");
}
nua_stack_init_handle(nua, nh, TAG_NEXT(tags));
msg = nua_creq_msg(nua, nh, cr, cr->cr_retry_count,
SIP_METHOD_MESSAGE,
NUTAG_ADD_CONTACT(NH_PGET(nh, win_messenger_enable)),
TAG_NEXT(tags));
sip = sip_object(msg);
if (sip)
cr->cr_orq = nta_outgoing_mcreate(nua->nua_nta,
process_response_to_message, nh, NULL,
msg,
SIPTAG_END(), TAG_NEXT(tags));
if (!cr->cr_orq) {
msg_destroy(msg);
return UA_EVENT1(e, NUA_INTERNAL_ERROR);
}
return cr->cr_event = e;
return nua_client_create(nh, e, &nua_message_client_methods, tags);
}
void restart_message(nua_handle_t *nh, tagi_t *tags)
static int nua_message_client_init(nua_client_request_t *cr,
msg_t *msg, sip_t *sip,
tagi_t const *tags)
{
nua_creq_restart(nh, nh->nh_ds->ds_cr, process_response_to_message, tags);
if (NH_PGET(cr->cr_owner, win_messenger_enable))
cr->cr_contactize = 1;
return 0;
}
/** @NUA_EVENT nua_r_message
......@@ -137,15 +127,6 @@ void restart_message(nua_handle_t *nh, tagi_t *tags)
* @END_NUA_EVENT
*/
static int process_response_to_message(nua_handle_t *nh,
nta_outgoing_t *orq,
sip_t const *sip)
{
if (nua_creq_check_restart(nh, nh->nh_ds->ds_cr, orq, sip, restart_message))
return 0;
return nua_stack_process_response(nh, nh->nh_ds->ds_cr, orq, sip, TAG_END());
}
/** @NUA_EVENT nua_i_message
*
* @brief Incoming @b MESSAGE request.
......@@ -173,27 +154,14 @@ int nua_stack_process_message(nua_t *nua,
nta_incoming_t *irq,
sip_t const *sip)
{
msg_t *msg;
if (nh
? !NH_PGET(nh, message_enable)
: !DNH_PGET(nua->nua_dhandle, message_enable))
return 403;
if (nh == NULL)
if (!(nh = nua_stack_incoming_handle(nua, irq, sip, 0)))
return 500; /* respond with 500 Internal Server Error */
msg = nta_incoming_getrequest(irq);
nua_server_request_t *sr, sr0[1];
nua_stack_event(nh->nh_nua, nh, msg, nua_i_message, SIP_200_OK, TAG_END());
sr = SR_INIT(sr0);
if (!NUA_PGET(nua, nh, message_enable))
SR_STATUS1(sr, SIP_403_FORBIDDEN);
#if 0 /* XXX */
if (nh->nh_nua->nua_messageRespond) {
nh->nh_irq = irq;
return 0;
}
#endif
sr = nua_server_request(nua, nh, irq, sip, sr, sizeof *sr, NULL, 0);
return 200;
return nua_stack_server_event(nua, sr, nua_i_message, TAG_END());
}
This diff is collapsed.
......@@ -45,9 +45,6 @@
#include <sofia-sip/sip_protos.h>
#include <sofia-sip/sip_status.h>
#define NTA_LEG_MAGIC_T struct nua_handle_s
#define NTA_OUTGOING_MAGIC_T struct nua_handle_s
#include "nua_stack.h"
/**@fn void nua_options(nua_handle_t *nh, tag_type_t tag, tag_value_t value, ...);
......@@ -69,46 +66,6 @@
* @sa #nua_i_options, @RFC3261 section 10
*/
static int process_response_to_options(nua_handle_t *nh,
nta_outgoing_t *orq,
sip_t const *sip);
int
nua_stack_options(nua_t *nua, nua_handle_t *nh, nua_event_t e, tagi_t const *tags)
{
nua_client_request_t *cr = nh->nh_ds->ds_cr;
msg_t *msg;
if (nh_is_special(nh)) {
return UA_EVENT2(e, 900, "Invalid handle for OPTIONS");
}
else if (cr->cr_orq) {
return UA_EVENT2(e, 900, "Request already in progress");
}
nua_stack_init_handle(nua, nh, TAG_NEXT(tags));
msg = nua_creq_msg(nua, nh, cr, cr->cr_retry_count,
SIP_METHOD_OPTIONS,
TAG_NEXT(tags));
cr->cr_orq = nta_outgoing_mcreate(nua->nua_nta,
process_response_to_options, nh, NULL,
msg,
SIPTAG_END(), TAG_NEXT(tags));
if (!cr->cr_orq) {
msg_destroy(msg);
return UA_EVENT1(e, NUA_INTERNAL_ERROR);
}
return cr->cr_event = e;
}
void restart_options(nua_handle_t *nh, tagi_t *tags)
{
nua_creq_restart(nh, nh->nh_ds->ds_cr, process_response_to_options, tags);
}
/** @NUA_EVENT nua_r_options
*
* Answer to outgoing OPTIONS.
......@@ -130,11 +87,25 @@ void restart_options(nua_handle_t *nh, tagi_t *tags)
* @END_NUA_EVENT
*/
static int process_response_to_options(nua_handle_t *nh,
nta_outgoing_t *orq,
sip_t const *sip)
{
if (nua_creq_check_restart(nh, nh->nh_ds->ds_cr, orq, sip, restart_options))
return 0;
return nua_stack_process_response(nh, nh->nh_ds->ds_cr, orq, sip, TAG_END());
static nua_client_methods_t nua_options_client_methods = {
SIP_METHOD_OPTIONS,
0,
{
/* create_dialog */ 0,
/* in_dialog */ 0,
/* target refresh */ 0
},
/*nua_options_client_template*/ NULL,
/*nua_options_client_init*/ NULL,
/*nua_options_client_request*/ NULL,
/* nua_options_client_check_restart */ NULL,
/*nua_options_client_response*/ NULL
};
int nua_stack_options(nua_t *nua,
nua_handle_t *nh,
nua_event_t e,
tagi_t const *tags)
{
return nua_client_create(nh, e, &nua_options_client_methods, tags);
}
......@@ -762,12 +762,6 @@ static int nhp_set_tags(su_home_t *home,
else if (tag == nutag_enablemessenger) {
NHP_SET(nhp, win_messenger_enable, value != 0);
}
#if 0
/* NUTAG_AUTORESPOND(autorespond) */
else if (tag == nutag_autorespond) {
NHP_SET(nhp, autorespond, value);
}
#endif
/* NUTAG_CALLEE_CAPS(callee_caps) */
else if (tag == nutag_callee_caps) {
NHP_SET(nhp, callee_caps, value != 0);
......@@ -1171,10 +1165,10 @@ int nua_handle_save_tags(nua_handle_t *nh, tagi_t *tags)
nh->nh_tags =
tl_filtered_tlist(nh->nh_home, tagfilter,
SIPTAG_FROM(p_from),
TAG_FILTER(nua_handle_tags_filter),
SIPTAG_TO(p_to),
TAG_FILTER(nua_handle_tags_filter),
TAG_IF(p_from != SIP_NONE, SIPTAG_FROM(p_from)),
TAG_IF(p_from != SIP_NONE, TAG_FILTER(nua_handle_tags_filter)),
TAG_IF(p_to != SIP_NONE, SIPTAG_TO(p_to)),
TAG_IF(p_to != SIP_NONE, TAG_FILTER(nua_handle_tags_filter)),
TAG_NEXT(tags));
nh->nh_ptags =
......@@ -1366,7 +1360,8 @@ int nua_stack_set_smime_params(nua_t *nua, tagi_t const *tags)
* application contact associated with the operation handle
* when responding to nua_get_hparams()
* @param sip NULL
* @param tags
* @param tags
* NUTAG_APPL_METHOD() \n
* NUTAG_AUTOACK() \n
* NUTAG_AUTOALERT() \n
* NUTAG_AUTOANSWER() \n
......@@ -1559,6 +1554,7 @@ int nua_stack_get_params(nua_t *nua, nua_handle_t *nh, nua_event_t e,
TIF_STR(SIPTAG_SUPPORTED_STR, supported),
TIF(SIPTAG_ALLOW, allow),
TIF_STR(SIPTAG_ALLOW_STR, allow),
TIF_STR(NUTAG_APPL_METHOD, appl_method),
TIF(SIPTAG_ALLOW_EVENTS, allow_events),
TIF_STR(SIPTAG_ALLOW_EVENTS_STR, allow_events),
TIF_SIP(SIPTAG_USER_AGENT, user_agent),
......
This diff is collapsed.
This diff is collapsed.
......@@ -44,8 +44,6 @@
#include <sofia-sip/sip_status.h>
#include <sofia-sip/sip_util.h>
#define NTA_LEG_MAGIC_T struct nua_handle_s
#define NTA_OUTGOING_MAGIC_T struct nua_handle_s
#define NTA_INCOMING_MAGIC_T struct nua_handle_s
#define NTA_RELIABLE_MAGIC_T struct nua_handle_s
......@@ -97,7 +95,7 @@ int nua_stack_process_register(nua_t *nua,
nua_server_request_t *sr, sr0[1];
sr = nua_server_request(nua, nh, irq, sip, SR_INIT(sr0), sizeof *sr,
nua_default_respond, 0);
NULL, 0);
return nua_stack_server_event(nua, sr, nua_i_register, TAG_END());
}
This diff is collapsed.
This diff is collapsed.
......@@ -103,6 +103,26 @@ typedef struct register_usage nua_registration_t;
TAG_IF((include) && (soa) && soa_is_remote_chat_active(soa) >= 0, \
SOATAG_ACTIVE_CHAT(soa_is_remote_chat_active(soa)))
#if HAVE_NUA_HANDLE_DEBUG
#define nua_handle_ref(nh) nua_handle_ref_by((nh), __func__)
#define nua_handle_unref(nh) nua_handle_unref_by((nh), __func__)
static inline nua_handle_t *nua_handle_ref_by(nua_handle_t *nh,
char const *by)
{
SU_DEBUG_0(("nua_handle_ref(%p) by %s\n", nh, by));
return (nua_handle_t *)su_home_ref((su_home_t *)nh);
}
static inline int nua_handle_unref_by(nua_handle_t *nh, char const *by)
{
SU_DEBUG_0(("nua_handle_unref(%p) by %s\n", nh, by));
return su_home_unref((su_home_t *)nh);
}
#endif
/** NUA handle.
*
*/
......@@ -349,48 +369,8 @@ int nua_stack_process_request(nua_handle_t *nh,
nta_incoming_t *irq,
sip_t const *sip);
int nua_stack_process_response(nua_handle_t *nh,
nua_client_request_t *cr,
nta_outgoing_t *orq,
sip_t const *sip,
tag_type_t tag, tag_value_t value, ...);
int nua_stack_launch_network_change_detector(nua_t *nua);
msg_t *nua_creq_msg(nua_t *nua, nua_handle_t *nh,
nua_client_request_t *cr,
int restart,
sip_method_t method, char const *name,
tag_type_t tag, tag_value_t value, ...);
int nua_tagis_have_contact_tag(tagi_t const *t);
int nua_creq_check_restart(nua_handle_t *nh,
nua_client_request_t *cr,
nta_outgoing_t *orq,
sip_t const *sip,
nua_creq_restart_f *f);
int nua_creq_restart_with(nua_handle_t *nh,
nua_client_request_t *cr,
nta_outgoing_t *orq,
int status, char const *phrase,
nua_creq_restart_f *f,
tag_type_t tag, tag_value_t value, ...);
int nua_creq_save_restart(nua_handle_t *nh,
nua_client_request_t *cr,
nta_outgoing_t *orq,
int status, char const *phrase,
nua_creq_restart_f *f);
int nua_creq_restart(nua_handle_t *nh,
nua_client_request_t *cr,
nta_response_f *cb,
tagi_t *tags);
void nua_creq_deinit(nua_client_request_t *cr, nta_outgoing_t *orq);
sip_contact_t const *nua_stack_get_contact(nua_registration_t const *nr);
int nua_registration_add_contact_to_request(nua_handle_t *nh,
......@@ -430,11 +410,7 @@ nua_stack_process_request_t nua_stack_process_unknown;
nua_stack_process_request_t nua_stack_process_register;
nua_stack_process_request_t nua_stack_process_method;
nua_client_request_t
*nua_client_request_pending(nua_client_request_t const *),
*nua_client_request_restarting(nua_client_request_t const *),
*nua_client_request_by_orq(nua_client_request_t const *cr,
nta_outgoing_t const *orq);
/* ---------------------------------------------------------------------- */
nua_server_request_t *nua_server_request(nua_t *nua,
nua_handle_t *nh,
......@@ -466,15 +442,6 @@ extern char const nua_application_sdp[];
#define NUTAG_ADD_CONTACT(v) _nutag_add_contact, tag_bool_v(v)
extern tag_typedef_t _nutag_add_contact;
#define NUTAG_ADD_CONTACT_REF(v) _nutag_add_contact_ref, tag_bool_vr(&v)
extern tag_typedef_t _nutag_add_contact_ref;
#define NUTAG_COPY(v) _nutag_copy, tag_bool_v(v)
extern tag_typedef_t _nutag_copy;
#define NUTAG_COPY_REF(v) _nutag_copy_ref, tag_bool_vr(&v)
extern tag_typedef_t _nutag_copy_ref;
/* ---------------------------------------------------------------------- */
typedef unsigned longlong ull;
......
This diff is collapsed.
......@@ -147,6 +147,3 @@ tag_typedef_t nutag_service_route_enable =
tag_typedef_t nutag_detect_network_updates = UINTTAG_TYPEDEF(detect_network_updates);
tag_typedef_t nutag_with = PTRTAG_TYPEDEF(with);
tag_typedef_t _nutag_add_contact = BOOLTAG_TYPEDEF(add_contact);
tag_typedef_t _nutag_copy = BOOLTAG_TYPEDEF(copy);
......@@ -262,6 +262,12 @@ SOFIAPUBFUN char const *nua_event_name(nua_event_t event);
/** Get name for NUA callstate. */
SOFIAPUBFUN char const *nua_callstate_name(enum nua_callstate state);
/** Return name of subscription state. @NEW_1_12_5. */
SOFIAPUBFUN char const *nua_substate_name(enum nua_substate substate);
/** Convert string to enum nua_substate. @NEW_1_12_5. */
SOFIAPUBFUN enum nua_substate nua_substate_make(char const *sip_substate);
/** Send SIP REGISTER request to the registrar. */
SOFIAPUBFUN void nua_register(nua_handle_t *nh, tag_type_t, tag_value_t, ...);
......
......@@ -1859,9 +1859,10 @@ enum nua_callstate {
/** Get name for NUA call state */
SOFIAPUBFUN char const *nua_callstate_name(enum nua_callstate state);
/** Subscription state
/**Subscription state.
*
* @par Used with
* #nua_notify() \n
* #nua_r_subscribe \n
* #nua_i_notify
*
......@@ -1874,11 +1875,10 @@ SOFIAPUBFUN char const *nua_callstate_name(enum nua_callstate state);
* @c nua_substate_active (2) \n
* @c nua_substate_terminated (3) \n
*
* see
* <a href="http://www.ietf.org/rfc/rfc3265.txt">RFC 3265</a>
* @sa @RFC3265
*
* Corresponding tag taking reference parameter is NUTAG_SUBSTATE_REF()
*/
*/
#define NUTAG_SUBSTATE(x) nutag_substate, tag_int_v(x)
SOFIAPUBVAR tag_typedef_t nutag_substate;
......@@ -1896,6 +1896,12 @@ enum nua_substate {
nua_substate_terminated = nea_terminated /**< Terminated subscription */
};
/** Return name of subscription state. @NEW_1_12_5. */
SOFIAPUBFUN char const *nua_substate_name(enum nua_substate substate);
/** Convert string to enum nua_substate. @NEW_1_12_5. */
SOFIAPUBFUN enum nua_substate nua_substate_make(char const *sip_substate);