Commit 2da61556 authored by Pekka Pessi's avatar Pekka Pessi

nua: added nua_handle_make_replaces(), nua_handle_by_replaces().

darcs-hash:20061004160757-65a35-86caf182e27b4a77ef3dc86d3d4337930435eb22.gz
parent eabc0a73
......@@ -1166,3 +1166,88 @@ void nua_destroy_event(nua_saved_event_t saved[1])
su_msg_destroy(saved);
}
}
/* ---------------------------------------------------------------------- */
struct nua_stack_handle_make_replaces_args {
sip_replaces_t *retval;
nua_handle_t *nh;
su_home_t *home;
int early_only;
};
static int nua_stack_handle_make_replaces_call(void *arg)
{
struct nua_stack_handle_make_replaces_args *a = arg;
a->retval = nua_stack_handle_make_replaces(a->nh, a->home, a->early_only);
return 0;
}
/**Generate a @Replaces header for handle.
*
* @since New in @VERSION_1_12_4.
*
* @sa nua_handle_by_replaces(), @Replaces, @RFC3891, nua_refer(),
* nua_i_refer(), @ReferTo, nta_leg_make_replaces()
*/
sip_replaces_t *nua_handle_make_replaces(nua_handle_t *nh,
su_home_t *home,
int early_only)
{
if (nh && nh->nh_valid && nh->nh_nua) {
struct nua_stack_handle_make_replaces_args a = { NULL, nh, home, early_only };
if (su_task_execute(nh->nh_nua->nua_server,
nua_stack_handle_make_replaces_call, (void *)&a,
NULL) == 0) {
return a.retval;
}
}
return NULL;
}
struct nua_stack_handle_by_replaces_args {
nua_handle_t *retval;
nua_t *nua;
sip_replaces_t const *r;
};
static int nua_stack_handle_by_replaces_call(void *arg)
{
struct nua_stack_handle_by_replaces_args *a = arg;
a->retval = nua_stack_handle_by_replaces(a->nua, a->r);
return 0;
}
/** Obtain a new reference to an existing handle based on @Replaces header.
*
* @since New in @VERSION_1_12_4.
*
* @note
* You should release the reference with nua_handle_unref() when you are
* done with handle.
*
* @sa nua_handle_make_replaces(), @Replaces, @RFC3891, nua_refer(),
* nua_i_refer(), @ReferTo, nta_leg_by_replaces()
*/
nua_handle_t *nua_handle_by_replaces(nua_t *nua, sip_replaces_t const *r)
{
if (nua) {
struct nua_stack_handle_by_replaces_args a = { NULL, nua, r };
if (su_task_execute(nua->nua_server,
nua_stack_handle_by_replaces_call, (void *)&a,
NULL) == 0) {
nua_handle_t *nh = a.retval;
if (nh && !NH_IS_DEFAULT(nh) && nh->nh_valid)
return nua_handle_ref(nh);
}
}
return NULL;
}
......@@ -831,6 +831,28 @@ int nua_stack_set_handle_special(nua_handle_t *nh,
return 0;
}
sip_replaces_t *nua_stack_handle_make_replaces(nua_handle_t *nh,
su_home_t *home,
int early_only)
{
if (nh && nh->nh_ds && nh->nh_ds->ds_leg)
return nta_leg_make_replaces(nh->nh_ds->ds_leg, home, early_only);
else
return NULL;
}
nua_handle_t *nua_stack_handle_by_replaces(nua_t *nua,
sip_replaces_t const *r)
{
if (nua) {
nta_leg_t *leg = nta_leg_by_replaces(nua->nua_nta, r);
if (leg)
return nta_leg_magic(leg, nua_stack_process_request);
}
return NULL;
}
/** @internal Add authorization data */
int nh_authorize(nua_handle_t *nh, tag_type_t tag, tag_value_t value, ...)
{
......
......@@ -423,6 +423,15 @@ void nh_destroy(nua_t *nua, nua_handle_t *nh);
nua_handle_t *nh_validate(nua_t *nua, nua_handle_t *maybe);
sip_replaces_t *nua_stack_handle_make_replaces(nua_handle_t *handle,
su_home_t *home,
int early_only);
nua_handle_t *nua_stack_handle_by_replaces(nua_t *nua,
sip_replaces_t const *r);
/* ---------------------------------------------------------------------- */
int nua_stack_set_defaults(nua_handle_t *nh, nua_handle_preferences_t *nhp);
int nua_stack_set_from(nua_t *, int initial, tagi_t const *tags);
......
......@@ -354,6 +354,14 @@ SOFIAPUBFUN msg_t *nua_saved_event_request(nua_saved_event_t const *saved);
/** Get current request message. */
SOFIAPUBFUN msg_t *nua_current_request(nua_t const *nua);
SOFIAPUBFUN sip_replaces_t *nua_handle_make_replaces(nua_handle_t *nh,
su_home_t *home,
int early_only);
SOFIAPUBFUN nua_handle_t *nua_handle_by_replaces(nua_t *nua,
sip_replaces_t const *rp);
SOFIA_END_DECLS
#endif
......@@ -156,6 +156,9 @@ int test_basic_call_1(struct context *ctx)
struct endpoint *a = &ctx->a, *b = &ctx->b;
struct call *a_call = a->call, *b_call = b->call;
struct event *e;
sip_t *sip;
sip_replaces_t *repa, *repb;
nua_handle_t *nh;
if (print_headings)
printf("TEST NUA-3.1: Basic call\n");
......@@ -175,6 +178,22 @@ int test_basic_call_1(struct context *ctx)
run_ab_until(ctx, -1, until_ready, -1, accept_call);
TEST_1(repa = nua_handle_make_replaces(a_call->nh, nua_handle_home(a_call->nh), 0));
TEST_1(repb = nua_handle_make_replaces(b_call->nh, nua_handle_home(b_call->nh), 0));
TEST_S(repa->rp_call_id, repb->rp_call_id);
TEST_1(!nua_handle_by_replaces(a->nua, repa));
TEST_1(!nua_handle_by_replaces(b->nua, repb));
TEST_1(nh = nua_handle_by_replaces(a->nua, repb));
TEST(nh, a_call->nh);
nua_handle_unref(nh);
TEST_1(nh = nua_handle_by_replaces(b->nua, repa));
TEST(nh, b_call->nh);
nua_handle_unref(nh);
/* Client transitions:
INIT -(C1)-> CALLING: nua_invite(), nua_i_state
CALLING -(C2)-> PROCEEDING: nua_r_invite, nua_i_state
......@@ -185,6 +204,10 @@ int test_basic_call_1(struct context *ctx)
TEST_1(is_offer_sent(e->data->e_tags));
TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
TEST(e->data->e_status, 180);
TEST_1(sip = sip_object(e->data->e_msg));
TEST_S(sip->sip_call_id->i_id, repb->rp_call_id);
TEST_S(sip->sip_from->a_tag, repb->rp_to_tag);
TEST_S(sip->sip_to->a_tag, repb->rp_from_tag);
TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
TEST(callstate(e->data->e_tags), nua_callstate_proceeding); /* PROCEEDING */
TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
......@@ -216,6 +239,10 @@ int test_basic_call_1(struct context *ctx)
TEST(callstate(e->data->e_tags), nua_callstate_completed); /* COMPLETED */
TEST_1(is_answer_sent(e->data->e_tags));
TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_ack);
TEST_1(sip = sip_object(e->data->e_msg));
TEST_S(sip->sip_call_id->i_id, repa->rp_call_id);
TEST_S(sip->sip_from->a_tag, repa->rp_from_tag);
TEST_S(sip->sip_to->a_tag, repa->rp_to_tag);
TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
TEST_1(!e->next);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment