Commit 8e1435db authored by Pekka Pessi's avatar Pekka Pessi

nua: accept incoming SUBSCRIBE if the Event matches with nua Allow-Events.

Updated nua_notifier.c, test_simple.c.

Moved documentation of nua_notify() to nua_notifier.c from nua.c,
documentation of nua_i_subscribe and nua_r_notify to nua_notifier.c from
nua.docs.

darcs-hash:20061017165721-65a35-6a46a98604cb75be7c9ab15bcba9c3d32f24f39a.gz
parent 33945d39
......@@ -764,29 +764,14 @@ void nua_unsubscribe(nua_handle_t *nh, tag_type_t tag, tag_value_t value, ...)
NUA_SIGNAL(nh, nua_r_unsubscribe, tag, value);
}
/** Send a SIP NOTIFY request message.
*
* This function is used when the application implements itself
* the subscription state machine. The application must provide
* valid @b Subscription-State and @b Event headers using SIP tags.
*
* @param nh Pointer to operation handle
* @param tag, value, ... List of tagged parameters
*
* @return
* nothing
*
* @par Related Tags:
* Tags in <sip_tag.h>
*
* @par Events:
* #nua_r_notify
*/
/* Documented with nua_stack_notify() */
void nua_notify(nua_handle_t *nh, tag_type_t tag, tag_value_t value, ...)
{
NUA_SIGNAL(nh, nua_r_notify, tag, value);
}
/* nua_r_notify is documented with process_response_to_notify() */
/** Create an event server.
*
* This function create an event server taking care of sending NOTIFY
......
......@@ -2141,20 +2141,7 @@ NUTAG_AUTOANSWER(0) on B side, NUTAG_AUTOACK(0) on A side.
* NUTAG_REFER_WITH_ID().
*/
/** @var nua_event_e::nua_i_subscribe
*
* Incoming subscription request.
*
* Currently implemented only for refer events created by incoming REFER
* requests. The referrer can modify the subscription lifetime or terminate
* it with SUBSCRIBE requests.
*
* @param nh
* @param hmagic
* @param status statuscode of response sent automatically by stack
* @param sip
* @param tags
*/
/* nua_i_subscribe is documented with nua_stack_process_subscribe() */
/** @var nua_event_e::nua_i_subscription
*
......@@ -2209,19 +2196,7 @@ NUTAG_AUTOANSWER(0) on B side, NUTAG_AUTOACK(0) on A side.
* #SIPTAG_CONTENT_TYPE
*/
/** @var nua_event_e::nua_r_notify
*
* Answer to outgoing NOTIFY.
*
* The NOTIFY may be sent explicitly by nua_notify() or
* implicitly by NUA state machine.
*
* @param nh operation handle associated with the call
* @param hmagic operation magic associated with the call
* @param sip response to NOTIFY request or NULL upon an error
* (error code and message are in status an phrase parameters)
* @param tags empty
*/
/* nua_r_notify is documented with process_response_to_notify() */
/** @var nua_event_e::nua_r_options
*
......
This diff is collapsed.
......@@ -23,7 +23,7 @@
*/
/**@CFILE test_nua_simple.c
* @brief NUA-11: Test SIMPLE methods: MESSAGE and PUBLISH.
* @brief NUA-11: Test SIMPLE methods: MESSAGE, PUBLISH and SUBSCRIBE/NOTIFY.
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
* @author Martti Mela <Martti Mela@nokia.com>
......@@ -362,13 +362,271 @@ int test_publish(struct context *ctx)
END();
}
static char const presence_open[] =
"<?xml version='1.0' encoding='UTF-8'?>\n"
"<presence xmlns='urn:ietf:params:xml:ns:cpim-pidf' \n"
" entity='pres:bob@example.org'>\n"
" <tuple id='ksac9udshce'>\n"
" <status><basic>open</basic></status>\n"
" <contact priority='1.0'>sip:bob@example.org</contact>\n"
" </tuple>\n"
"</presence>\n";
static char const presence_closed[] =
"<?xml version='1.0' encoding='UTF-8'?>\n"
"<presence xmlns='urn:ietf:params:xml:ns:cpim-pidf' \n"
" entity='pres:bob@example.org'>\n"
" <tuple id='ksac9udshce'>\n"
" <status><basic>closed</basic></status>\n"
" </tuple>\n"
"</presence>\n";
int accept_and_notify(CONDITION_PARAMS)
{
msg_t *with = nua_current_request(nua);
if (!(check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR)))
return 0;
save_event_in_list(ctx, event, ep, call);
switch (event) {
case nua_i_subscribe:
if (status < 200) {
RESPOND(ep, call, nh, SIP_202_ACCEPTED,
NUTAG_WITH(with),
SIPTAG_EXPIRES_STR("360"),
TAG_END());
NOTIFY(ep, call, nh,
SIPTAG_EVENT(sip->sip_event),
SIPTAG_CONTENT_TYPE_STR("application/pidf+xml"),
SIPTAG_PAYLOAD_STR(presence_closed),
NUTAG_SUBSTATE(nua_substate_pending),
TAG_END());
}
return 0;
case nua_r_notify:
return status >= 200;
default:
return 0;
}
}
extern int save_until_notified_and_responded(CONDITION_PARAMS);
extern int save_until_notified(CONDITION_PARAMS);
int test_subscribe_notify(struct context *ctx)
{
BEGIN();
struct endpoint *a = &ctx->a, *b = &ctx->b;
struct call *a_call = a->call, *b_call = b->call;
struct event *e;
sip_t const *sip;
tagi_t const *n_tags, *r_tags;
if (print_headings)
printf("TEST NUA-11.4: establishing subscription without notifier\n");
TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
SUBSCRIBE(a, a_call, a_call->nh, NUTAG_URL(b->contact->m_url),
SIPTAG_EVENT_STR("presence"),
SIPTAG_ACCEPT_STR("application/xpidf, application/pidf+xml"),
TAG_END());
run_ab_until(ctx, -1, save_until_notified_and_responded,
-1, accept_and_notify);
/* Client events:
nua_subscribe(), nua_i_notify/nua_r_subscribe
*/
TEST_1(e = a->events->head);
if (e->data->e_event == nua_i_notify) {
TEST_E(e->data->e_event, nua_i_notify);
TEST_1(sip = sip_object(e->data->e_msg));
n_tags = e->data->e_tags;
TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_subscribe);
r_tags = e->data->e_tags;
TEST_1(tl_find(r_tags, nutag_substate));
TEST(tl_find(r_tags, nutag_substate)->t_value, nua_substate_pending);
}
else {
TEST_E(e->data->e_event, nua_r_subscribe);
TEST(e->data->e_status, 202);
r_tags = e->data->e_tags;
TEST_1(tl_find(r_tags, nutag_substate));
TEST(tl_find(r_tags, nutag_substate)->t_value, nua_substate_embryonic);
TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_notify);
TEST_1(sip = sip_object(e->data->e_msg));
n_tags = e->data->e_tags;
}
TEST_1(sip->sip_event); TEST_S(sip->sip_event->o_type, "presence");
TEST_1(sip->sip_content_type);
TEST_S(sip->sip_content_type->c_type, "application/pidf+xml");
TEST_1(sip->sip_subscription_state);
TEST_S(sip->sip_subscription_state->ss_substate, "pending");
TEST_1(sip->sip_subscription_state->ss_expires);
TEST_1(tl_find(n_tags, nutag_substate));
TEST(tl_find(n_tags, nutag_substate)->t_value, nua_substate_pending);
TEST_1(!e->next);
free_events_in_list(ctx, a->events);
/* Server events: nua_i_subscribe, nua_r_notify */
TEST_1(e = b->events->head);
TEST_E(e->data->e_event, nua_i_subscribe);
TEST_E(e->data->e_status, 100);
TEST_1(sip = sip_object(e->data->e_msg));
TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_notify);
r_tags = e->data->e_tags;
TEST_1(tl_find(r_tags, nutag_substate));
TEST(tl_find(r_tags, nutag_substate)->t_value, nua_substate_pending);
free_events_in_list(ctx, b->events);
if (print_headings)
printf("TEST NUA-11.4: PASSED\n");
/* ---------------------------------------------------------------------- */
/* NOTIFY with updated content
A B
| |
|<------NOTIFY-------|
|-------200 OK------>|
| |
*/
if (print_headings)
printf("TEST NUA-11.5: send NOTIFY\n");
/* Update presence data */
NOTIFY(b, b_call, b_call->nh,
NUTAG_SUBSTATE(nua_substate_active),
SIPTAG_EVENT_STR("presence"),
SIPTAG_CONTENT_TYPE_STR("application/pidf+xml"),
SIPTAG_PAYLOAD_STR(presence_open),
TAG_END());
run_ab_until(ctx, -1, save_until_notified,
-1, save_until_final_response);
/* subscriber events:
nua_i_notify
*/
TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_notify);
TEST_1(sip = sip_object(e->data->e_msg));
TEST_1(sip->sip_event); TEST_S(sip->sip_event->o_type, "presence");
TEST_1(sip->sip_content_type);
TEST_S(sip->sip_content_type->c_type, "application/pidf+xml");
TEST_1(sip->sip_subscription_state);
TEST_S(sip->sip_subscription_state->ss_substate, "active");
TEST_1(sip->sip_subscription_state->ss_expires);
n_tags = e->data->e_tags;
TEST_1(tl_find(n_tags, nutag_substate));
TEST(tl_find(n_tags, nutag_substate)->t_value, nua_substate_active);
TEST_1(!e->next);
free_events_in_list(ctx, a->events);
/* Notifier events: nua_r_notify */
TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_r_notify);
r_tags = e->data->e_tags;
TEST_1(tl_find(r_tags, nutag_substate));
TEST(tl_find(r_tags, nutag_substate)->t_value, nua_substate_active);
free_events_in_list(ctx, b->events);
if (print_headings)
printf("TEST NUA-11.5: PASSED\n");
/* ---------------------------------------------------------------------- */
/* un-SUBSCRIBE
A B
| |
|------SUBSCRIBE---->|
|<--------202--------|
|<------NOTIFY-------|
|-------200 OK------>|
| |
*/
if (print_headings)
printf("TEST NUA-11.6: un-SUBSCRIBE\n");
UNSUBSCRIBE(a, a_call, a_call->nh, TAG_END());
run_ab_until(ctx, -1, save_until_final_response,
-1, save_until_final_response);
/* Client events:
nua_unsubscribe(), nua_i_notify/nua_r_unsubscribe
*/
TEST_1(e = a->events->head);
if (e->data->e_event == nua_i_notify) {
TEST_E(e->data->e_event, nua_i_notify);
n_tags = e->data->e_tags;
TEST_1(sip = sip_object(e->data->e_msg));
TEST_1(sip->sip_event);
TEST_1(sip->sip_subscription_state);
TEST_S(sip->sip_subscription_state->ss_substate, "terminated");
TEST_1(!sip->sip_subscription_state->ss_expires);
TEST_1(tl_find(n_tags, nutag_substate));
TEST(tl_find(n_tags, nutag_substate)->t_value, nua_substate_terminated);
TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_unsubscribe);
TEST(e->data->e_status, 200);
r_tags = e->data->e_tags;
TEST_1(tl_find(r_tags, nutag_substate));
TEST(tl_find(r_tags, nutag_substate)->t_value, nua_substate_terminated);
}
else {
TEST_E(e->data->e_event, nua_r_unsubscribe);
TEST(e->data->e_status, 200);
r_tags = e->data->e_tags;
TEST_1(tl_find(r_tags, nutag_substate));
TEST(tl_find(r_tags, nutag_substate)->t_value, nua_substate_terminated);
}
TEST_1(!e->next);
free_events_in_list(ctx, a->events);
/* Notifier events: nua_r_notify */
TEST_1(e = b->events->head);
TEST_E(e->data->e_event, nua_i_subscribe);
TEST(e->data->e_status, 200);
TEST_1(sip = sip_object(e->data->e_msg));
TEST_1(tl_find(e->data->e_tags, nutag_substate));
TEST(tl_find(e->data->e_tags, nutag_substate)->t_value,
nua_substate_terminated);
TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_notify);
TEST_1(e->data->e_status >= 200);
r_tags = e->data->e_tags;
TEST_1(tl_find(r_tags, nutag_substate));
TEST(tl_find(r_tags, nutag_substate)->t_value, nua_substate_terminated);
free_events_in_list(ctx, b->events);
nua_handle_destroy(a_call->nh), a_call->nh = NULL;
nua_handle_destroy(b_call->nh), b_call->nh = NULL;
if (print_headings)
printf("TEST NUA-11.6: PASSED\n");
END();
}
/* ======================================================================== */
/* Test simple methods: MESSAGE and PUBLISH */
/* Test simple methods: MESSAGE, PUBLISH, SUBSCRIBE/NOTIFY */
int test_simple(struct context *ctx)
{
return
test_message(ctx)
|| test_publish(ctx)
|| test_subscribe_notify(ctx)
;
}
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