1 /*
2 * This file is part of the Sofia-SIP package
3 *
4 * Copyright (C) 2008 Nokia Corporation.
5 *
6 * Contact: Pekka Pessi <pekka.pessi@nokia.com>
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 *
23 */
24
25 /**@CFILE check_events.c
26 *
27 * @brief NUA module tests for SIP events
28 *
29 * @author Pekka Pessi <Pekka.Pessi@nokia.com>
30 *
31 * @copyright (C) 2008 Nokia Corporation.
32 */
33
34 #include "config.h"
35
36 #undef NDEBUG
37
38 #include "check_nua.h"
39
40 #include <sofia-sip/sip_status.h>
41 #include <sofia-sip/sip_header.h>
42 #include <sofia-sip/soa.h>
43 #include <sofia-sip/su_tagarg.h>
44 #include <sofia-sip/su_string.h>
45 #include <sofia-sip/su_tag_io.h>
46
47 #include <stdlib.h>
48 #include <string.h>
49 #include <assert.h>
50
51 /* define XXX as 1 in order to see all failing test cases */
52 #ifndef XXX
53 #define XXX (0)
54 #endif
55
56 /* ====================================================================== */
57
58 static nua_t *nua;
59 static struct dialog *dialog = NULL;
60
61 #define CRLF "\r\n"
62
s2_dialog_setup(void)63 void s2_dialog_setup(void)
64 {
65 nua = s2_nua_setup("simple",
66 SIPTAG_ORGANIZATION_STR("Pussy Galore's Flying Circus"),
67 NUTAG_OUTBOUND("no-options-keepalive, no-validate"),
68 TAG_END());
69
70 dialog = su_home_new(sizeof *dialog); fail_if(!dialog);
71
72 s2_register_setup();
73 }
74
s2_dialog_teardown(void)75 void s2_dialog_teardown(void)
76 {
77 s2_teardown_started("simple");
78
79 s2_register_teardown();
80
81 nua_shutdown(nua);
82
83 fail_unless_event(nua_r_shutdown, 200);
84
85 s2_nua_teardown();
86 }
87
simple_thread_setup(void)88 static void simple_thread_setup(void)
89 {
90 s2_nua_thread = 1;
91 s2_dialog_setup();
92 }
93
simple_threadless_setup(void)94 static void simple_threadless_setup(void)
95 {
96 s2_nua_thread = 0;
97 s2_dialog_setup();
98 }
99
simple_teardown(void)100 static void simple_teardown(void)
101 {
102 s2_dialog_teardown();
103 }
104
105 static char const presence_open[] =
106 "<?xml version='1.0' encoding='UTF-8'?>\n"
107 "<presence xmlns='urn:ietf:params:xml:ns:cpim-pidf' \n"
108 " entity='pres:bob@example.org'>\n"
109 " <tuple id='ksac9udshce'>\n"
110 " <status><basic>open</basic></status>\n"
111 " <contact priority='1.0'>sip:bob@example.org</contact>\n"
112 " </tuple>\n"
113 "</presence>\n";
114
115 static char const presence_closed[] =
116 "<?xml version='1.0' encoding='UTF-8'?>\n"
117 "<presence xmlns='urn:ietf:params:xml:ns:cpim-pidf' \n"
118 " entity='pres:bob@example.org'>\n"
119 " <tuple id='ksac9udshce'>\n"
120 " <status><basic>closed</basic></status>\n"
121 " </tuple>\n"
122 "</presence>\n";
123
124 static char const *event_type = "presence";
125 static char const *event_mime_type = "application/pidf+xml";
126 static char const *event_state = presence_open;
127 static char const *subscription_state = "active;expires=600";
128
129 static struct event *
respond_to_subscribe(struct message * subscribe,nua_event_t expect_event,enum nua_substate expect_substate,int status,char const * phrase,tag_type_t tag,tag_value_t value,...)130 respond_to_subscribe(struct message *subscribe,
131 nua_event_t expect_event,
132 enum nua_substate expect_substate,
133 int status, char const *phrase,
134 tag_type_t tag, tag_value_t value, ...)
135 {
136 struct event *event;
137 ta_list ta;
138
139 ta_start(ta, tag, value);
140 s2_sip_respond_to(subscribe, dialog, status, phrase,
141 ta_tags(ta));
142 ta_end(ta);
143
144 event = s2_wait_for_event(expect_event, status); fail_if(!event);
145 fail_unless(s2_check_substate(event, expect_substate));
146 return event;
147 }
148
149 static struct event *
notify_to_nua(enum nua_substate expect_substate,tag_type_t tag,tag_value_t value,...)150 notify_to_nua(enum nua_substate expect_substate,
151 tag_type_t tag, tag_value_t value, ...)
152 {
153 struct event *event;
154 struct message *response;
155 ta_list ta;
156
157 ta_start(ta, tag, value);
158 fail_if(s2_sip_request_to(dialog, SIP_METHOD_NOTIFY, NULL,
159 SIPTAG_CONTENT_TYPE_STR(event_mime_type),
160 SIPTAG_PAYLOAD_STR(event_state),
161 ta_tags(ta)));
162 ta_end(ta);
163
164 response = s2_sip_wait_for_response(200, SIP_METHOD_NOTIFY);
165 fail_if(!response);
166 s2_sip_free_message(response);
167
168 event = s2_wait_for_event(nua_i_notify, 200); fail_if(!event);
169 fail_unless(s2_check_substate(event, expect_substate));
170
171 return event;
172 }
173
174 static int send_notify_before_response = 0;
175
176 static struct event *
subscription_by_nua(nua_handle_t * nh,enum nua_substate current,tag_type_t tag,tag_value_t value,...)177 subscription_by_nua(nua_handle_t *nh,
178 enum nua_substate current,
179 tag_type_t tag, tag_value_t value, ...)
180 {
181 struct message *subscribe;
182 struct event *notify, *event;
183 ta_list ta;
184 enum nua_substate substate = nua_substate_active;
185 char const *substate_str = subscription_state;
186 char const *expires = "600";
187
188 subscribe = s2_sip_wait_for_request(SIP_METHOD_SUBSCRIBE);
189 if (event_type)
190 fail_if(!subscribe->sip->sip_event ||
191 strcmp(event_type, subscribe->sip->sip_event->o_type));
192
193 if (subscribe->sip->sip_expires && subscribe->sip->sip_expires->ex_delta == 0) {
194 substate = nua_substate_terminated;
195 substate_str = "terminated;reason=timeout";
196 expires = "0";
197 }
198
199 ta_start(ta, tag, value);
200
201 if (send_notify_before_response) {
202 s2_sip_save_uas_dialog(dialog, subscribe->sip);
203 notify = notify_to_nua(substate,
204 SIPTAG_EVENT(subscribe->sip->sip_event),
205 SIPTAG_SUBSCRIPTION_STATE_STR(substate_str),
206 ta_tags(ta));
207 event = respond_to_subscribe(subscribe, nua_r_subscribe, substate,
208 SIP_200_OK,
209 SIPTAG_EXPIRES_STR(expires),
210 TAG_END());
211 s2_free_event(event);
212 }
213 else {
214 event = respond_to_subscribe(subscribe, nua_r_subscribe, current,
215 SIP_202_ACCEPTED,
216 SIPTAG_EXPIRES_STR(expires),
217 TAG_END());
218 s2_free_event(event);
219 notify = notify_to_nua(substate,
220 SIPTAG_EVENT(subscribe->sip->sip_event),
221 SIPTAG_SUBSCRIPTION_STATE_STR(substate_str),
222 ta_tags(ta));
223 }
224
225 s2_sip_free_message(subscribe);
226
227 return notify;
228 }
229
230 static void
unsubscribe_by_nua(nua_handle_t * nh,tag_type_t tag,tag_value_t value,...)231 unsubscribe_by_nua(nua_handle_t *nh, tag_type_t tag, tag_value_t value, ...)
232 {
233 struct message *subscribe, *response;
234 struct event *event;
235
236 nua_unsubscribe(nh, TAG_END());
237 subscribe = s2_sip_wait_for_request(SIP_METHOD_SUBSCRIBE);
238
239 s2_sip_respond_to(subscribe, dialog, SIP_200_OK, SIPTAG_EXPIRES_STR("0"), TAG_END());
240
241 event = s2_wait_for_event(nua_r_unsubscribe, 200); fail_if(!event);
242 fail_unless(s2_check_substate(event, nua_substate_active));
243 s2_free_event(event);
244
245 fail_if(s2_sip_request_to(dialog, SIP_METHOD_NOTIFY, NULL,
246 SIPTAG_EVENT(subscribe->sip->sip_event),
247 SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=tiemout"),
248 SIPTAG_CONTENT_TYPE_STR(event_mime_type),
249 SIPTAG_PAYLOAD_STR(event_state),
250 TAG_END()));
251
252 event = s2_wait_for_event(nua_i_notify, 200); fail_if(!event);
253 fail_unless(s2_check_substate(event, nua_substate_terminated));
254 s2_free_event(event);
255
256 response = s2_sip_wait_for_response(200, SIP_METHOD_NOTIFY);
257 fail_if(!response);
258 s2_sip_free_message(response); s2_sip_free_message(subscribe);
259 }
260
261 /* ====================================================================== */
262 /* 6 - Subscribe/notify */
263
START_TEST(subscribe_6_1_1)264 START_TEST(subscribe_6_1_1)
265 {
266 nua_handle_t *nh;
267 struct event *notify;
268 S2_CASE("6.1.1", "Basic subscription",
269 "NUA sends SUBSCRIBE, waits for NOTIFY, sends un-SUBSCRIBE");
270
271 nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor), TAG_END());
272 nua_subscribe(nh, SIPTAG_EVENT_STR(event_type), TAG_END());
273 notify = subscription_by_nua(nh, nua_substate_embryonic, TAG_END());
274 s2_free_event(notify);
275 unsubscribe_by_nua(nh, TAG_END());
276 nua_handle_destroy(nh);
277 }
278 END_TEST
279
START_TEST(subscribe_6_1_2)280 START_TEST(subscribe_6_1_2)
281 {
282 nua_handle_t *nh;
283 struct message *subscribe, *response;
284 struct event *notify, *event;
285
286 S2_CASE("6.1.2", "Basic subscription with refresh",
287 "NUA sends SUBSCRIBE, waits for NOTIFY, "
288 "sends re-SUBSCRIBE, waits for NOTIFY, "
289 "sends un-SUBSCRIBE");
290
291 send_notify_before_response = 1;
292
293 nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor), TAG_END());
294 nua_subscribe(nh, SIPTAG_EVENT_STR(event_type), TAG_END());
295 notify = subscription_by_nua(nh, nua_substate_embryonic, TAG_END());
296 s2_free_event(notify);
297
298 /* Wait for refresh */
299 s2_nua_fast_forward(600, s2base->root);
300 subscribe = s2_sip_wait_for_request(SIP_METHOD_SUBSCRIBE);
301 s2_sip_respond_to(subscribe, dialog, SIP_200_OK,
302 SIPTAG_EXPIRES_STR("600"),
303 TAG_END());
304
305 event = s2_wait_for_event(nua_r_subscribe, 200); fail_if(!event);
306 fail_unless(s2_check_substate(event, nua_substate_active));
307 s2_free_event(event);
308
309 fail_if(s2_sip_request_to(dialog, SIP_METHOD_NOTIFY, NULL,
310 SIPTAG_EVENT(subscribe->sip->sip_event),
311 SIPTAG_SUBSCRIPTION_STATE_STR("active;expires=600"),
312 SIPTAG_CONTENT_TYPE_STR(event_mime_type),
313 SIPTAG_PAYLOAD_STR(event_state),
314 TAG_END()));
315 event = s2_wait_for_event(nua_i_notify, 200); fail_if(!event);
316 fail_unless(s2_check_substate(event, nua_substate_active));
317 s2_free_event(event);
318 response = s2_sip_wait_for_response(200, SIP_METHOD_NOTIFY);
319 fail_if(!response);
320 s2_sip_free_message(response);
321
322 unsubscribe_by_nua(nh, TAG_END());
323
324 nua_handle_destroy(nh);
325 }
326 END_TEST
327
START_TEST(subscribe_6_1_3)328 START_TEST(subscribe_6_1_3)
329 {
330 nua_handle_t *nh;
331 struct message *response;
332 struct event *notify, *event;
333
334 S2_CASE("6.1.3", "Subscription terminated by notifier",
335 "NUA sends SUBSCRIBE, waits for NOTIFY, "
336 "gets NOTIFY terminating the subscription,");
337
338 nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor), TAG_END());
339 nua_subscribe(nh, SIPTAG_EVENT_STR(event_type), TAG_END());
340 notify = subscription_by_nua(nh, nua_substate_embryonic, TAG_END());
341 s2_free_event(notify);
342
343 fail_if(s2_sip_request_to(dialog, SIP_METHOD_NOTIFY, NULL,
344 SIPTAG_EVENT_STR(event_type),
345 SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"),
346 TAG_END()));
347 event = s2_wait_for_event(nua_i_notify, 200); fail_if(!event);
348 fail_unless(s2_check_substate(event, nua_substate_terminated));
349 s2_free_event(event);
350 response = s2_sip_wait_for_response(200, SIP_METHOD_NOTIFY);
351 fail_if(!response);
352 s2_sip_free_message(response);
353
354 nua_handle_destroy(nh);
355 }
356 END_TEST
357
START_TEST(subscribe_6_1_4)358 START_TEST(subscribe_6_1_4)
359 {
360 nua_handle_t *nh;
361 struct message *response;
362 struct event *notify, *event;
363
364 S2_CASE("6.1.4", "Subscription terminated by notifier, re-established",
365 "NUA sends SUBSCRIBE, waits for NOTIFY, "
366 "gets NOTIFY terminating the subscription,");
367
368 nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor), TAG_END());
369 nua_subscribe(nh, SIPTAG_EVENT_STR(event_type), TAG_END());
370 notify = subscription_by_nua(nh, nua_substate_embryonic, TAG_END());
371 s2_free_event(notify);
372
373 fail_if(s2_sip_request_to(dialog, SIP_METHOD_NOTIFY, NULL,
374 SIPTAG_EVENT_STR(event_type),
375 SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=deactivated"),
376 TAG_END()));
377 event = s2_wait_for_event(nua_i_notify, 200); fail_if(!event);
378 fail_unless(s2_check_substate(event, nua_substate_embryonic));
379 s2_free_event(event);
380 response = s2_sip_wait_for_response(200, SIP_METHOD_NOTIFY);
381 fail_if(!response);
382 s2_sip_free_message(response);
383
384 su_home_unref((void *)dialog), dialog = su_home_new(sizeof *dialog); fail_if(!dialog);
385
386 s2_nua_fast_forward(5, s2base->root);
387 /* nua re-establishes the subscription */
388 notify = subscription_by_nua(nh, nua_substate_embryonic, TAG_END());
389 s2_free_event(notify);
390
391 /* Unsubscribe with nua_subscribe() Expires: 0 */
392 nua_subscribe(nh, SIPTAG_EVENT_STR(event_type), SIPTAG_EXPIRES_STR("0"), TAG_END());
393 notify = subscription_by_nua(nh, nua_substate_active, TAG_END());
394 s2_free_event(notify);
395
396 nua_handle_destroy(nh);
397 }
398 END_TEST
399
subscribe_tcase(int threading)400 TCase *subscribe_tcase(int threading)
401 {
402 TCase *tc = tcase_create("6.1 - Basic SUBSCRIBE_");
403 void (*simple_setup)(void);
404
405 simple_setup = threading ? simple_thread_setup : simple_threadless_setup;
406 tcase_add_checked_fixture(tc, simple_setup, simple_teardown);
407
408 {
409 tcase_add_test(tc, subscribe_6_1_1);
410 tcase_add_test(tc, subscribe_6_1_2);
411 tcase_add_test(tc, subscribe_6_1_3);
412 tcase_add_test(tc, subscribe_6_1_4);
413 }
414 return tc;
415 }
416
START_TEST(fetch_6_2_1)417 START_TEST(fetch_6_2_1)
418 {
419 nua_handle_t *nh;
420 struct event *notify;
421
422 S2_CASE("6.2.1", "Event fetch - NOTIFY after 202",
423 "NUA sends SUBSCRIBE with Expires 0, waits for NOTIFY");
424
425 nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor), TAG_END());
426 nua_subscribe(nh, SIPTAG_EVENT_STR(event_type), SIPTAG_EXPIRES_STR("0"), TAG_END());
427 notify = subscription_by_nua(nh, nua_substate_embryonic, TAG_END());
428 s2_check_substate(notify, nua_substate_terminated);
429 s2_free_event(notify);
430 nua_handle_destroy(nh);
431 }
432 END_TEST
433
START_TEST(fetch_6_2_2)434 START_TEST(fetch_6_2_2)
435 {
436 nua_handle_t *nh;
437 struct event *notify;
438
439 S2_CASE("6.2.2", "Event fetch - NOTIFY before 200",
440 "NUA sends SUBSCRIBE with Expires 0, waits for NOTIFY");
441
442 send_notify_before_response = 1;
443
444 nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor), TAG_END());
445 nua_subscribe(nh, SIPTAG_EVENT_STR(event_type), SIPTAG_EXPIRES_STR("0"), TAG_END());
446 notify = subscription_by_nua(nh, nua_substate_embryonic, TAG_END());
447 s2_check_substate(notify, nua_substate_terminated);
448 s2_free_event(notify);
449 nua_handle_destroy(nh);
450 }
451 END_TEST
452
START_TEST(fetch_6_2_3)453 START_TEST(fetch_6_2_3)
454 {
455 nua_handle_t *nh;
456 struct message *subscribe;
457 struct event *event;
458
459 S2_CASE("6.2.3", "Event fetch - no NOTIFY",
460 "NUA sends SUBSCRIBE with Expires 0, waits for NOTIFY, times out");
461
462 nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor), TAG_END());
463 nua_subscribe(nh, SIPTAG_EVENT_STR(event_type), SIPTAG_EXPIRES_STR("0"), TAG_END());
464 subscribe = s2_sip_wait_for_request(SIP_METHOD_SUBSCRIBE);
465 s2_sip_respond_to(subscribe, dialog, SIP_202_ACCEPTED,
466 SIPTAG_EXPIRES_STR("0"), TAG_END());
467 s2_sip_free_message(subscribe);
468
469 event = s2_wait_for_event(nua_r_subscribe, 202); fail_if(!event);
470 fail_unless(s2_check_substate(event, nua_substate_embryonic));
471 s2_free_event(event);
472
473 s2_nua_fast_forward(600, s2base->root);
474
475 event = s2_wait_for_event(nua_i_notify, 408); fail_if(!event);
476 fail_unless(s2_check_substate(event, nua_substate_terminated));
477 s2_free_event(event);
478
479 nua_handle_destroy(nh);
480 }
481 END_TEST
482
483
fetch_tcase(int threading)484 TCase *fetch_tcase(int threading)
485 {
486 TCase *tc = tcase_create("6.2 - Event fetch");
487 void (*simple_setup)(void);
488
489 simple_setup = threading ? simple_thread_setup : simple_threadless_setup;
490 tcase_add_checked_fixture(tc, simple_setup, simple_teardown);
491
492 {
493 tcase_add_test(tc, fetch_6_2_1);
494 tcase_add_test(tc, fetch_6_2_2);
495 tcase_add_test(tc, fetch_6_2_3);
496 }
497 return tc;
498 }
499
500 nua_handle_t *
subscribe_to_nua(char const * event,tag_type_t tag,tag_value_t value,...)501 subscribe_to_nua(char const *event,
502 tag_type_t tag, tag_value_t value, ...)
503 {
504 ta_list ta;
505 struct event *subscribe;
506 struct message *response;
507 nua_handle_t *nh;
508
509 nua_set_params(nua, NUTAG_APPL_METHOD("SUBSCRIBE"),
510 SIPTAG_ALLOW_EVENTS_STR(event),
511 TAG_END());
512 fail_unless_event(nua_r_set_params, 200);
513
514 ta_start(ta, tag, value);
515 s2_sip_request_to(dialog, SIP_METHOD_SUBSCRIBE, NULL,
516 SIPTAG_EVENT_STR(event),
517 ta_tags(ta));
518 ta_end(ta);
519
520 subscribe = s2_wait_for_event(nua_i_subscribe, 100);
521 nh = subscribe->nh;
522 nua_respond(nh, SIP_202_ACCEPTED,
523 NUTAG_WITH_SAVED(subscribe->event),
524 TAG_END());
525 s2_free_event(subscribe);
526
527 response = s2_sip_wait_for_response(202, SIP_METHOD_SUBSCRIBE);
528 s2_sip_update_dialog(dialog, response);
529 fail_unless(response->sip->sip_expires != NULL);
530 s2_sip_free_message(response);
531
532 return nh;
533 }
534
START_TEST(notify_6_3_1)535 START_TEST(notify_6_3_1)
536 {
537 nua_handle_t *nh;
538 struct event *subscribe;
539 struct message *notify, *response;
540 sip_t *sip;
541
542 S2_CASE("6.3.1", "Basic NOTIFY server",
543 "NUA receives SUBSCRIBE, sends 202 and NOTIFY. "
544 "First NOTIFY terminates subscription. ");
545
546 s2_sip_request_to(dialog, SIP_METHOD_SUBSCRIBE, NULL,
547 SIPTAG_EVENT_STR("presence"),
548 TAG_END());
549 /* 489 Bad Event by default */
550 s2_sip_check_response(489, SIP_METHOD_SUBSCRIBE);
551
552 nua_set_params(nua, NUTAG_APPL_METHOD("SUBSCRIBE"), TAG_END());
553 fail_unless_event(nua_r_set_params, 200);
554
555 s2_sip_request_to(dialog, SIP_METHOD_SUBSCRIBE, NULL,
556 SIPTAG_EVENT_STR("presence"),
557 TAG_END());
558 s2_sip_check_response(489, SIP_METHOD_SUBSCRIBE);
559
560 nua_set_params(nua, SIPTAG_ALLOW_EVENTS_STR("presence"), TAG_END());
561 fail_unless_event(nua_r_set_params, 200);
562
563 s2_sip_request_to(dialog, SIP_METHOD_SUBSCRIBE, NULL,
564 SIPTAG_EVENT_STR("presence"),
565 TAG_END());
566 subscribe = s2_wait_for_event(nua_i_subscribe, 100);
567 nh = subscribe->nh;
568 nua_respond(nh, SIP_403_FORBIDDEN,
569 NUTAG_WITH_SAVED(subscribe->event),
570 TAG_END());
571 s2_free_event(subscribe);
572
573 s2_sip_check_response(403, SIP_METHOD_SUBSCRIBE);
574
575 nua_handle_destroy(nh);
576
577 s2_sip_request_to(dialog, SIP_METHOD_SUBSCRIBE, NULL,
578 SIPTAG_EVENT_STR("presence"),
579 TAG_END());
580 subscribe = s2_wait_for_event(nua_i_subscribe, 100);
581 nh = subscribe->nh;
582 nua_respond(nh, SIP_202_ACCEPTED,
583 NUTAG_WITH_SAVED(subscribe->event),
584 TAG_END());
585 s2_free_event(subscribe);
586
587 response = s2_sip_wait_for_response(202, SIP_METHOD_SUBSCRIBE);
588 s2_sip_update_dialog(dialog, response);
589 fail_unless(response->sip->sip_expires != NULL);
590 s2_sip_free_message(response);
591
592 nua_notify(nh,
593 NUTAG_SUBSTATE(nua_substate_terminated),
594 SIPTAG_PAYLOAD_STR(presence_closed),
595 TAG_END());
596 notify = s2_sip_wait_for_request(SIP_METHOD_NOTIFY);
597 fail_unless(notify != NULL);
598 sip = notify->sip;
599 fail_unless(sip->sip_subscription_state != NULL);
600 fail_unless(su_strmatch(sip->sip_subscription_state->ss_substate,
601 "terminated"));
602 s2_sip_respond_to(notify, dialog, SIP_200_OK, TAG_END());
603
604 fail_unless_event(nua_r_notify, 200);
605 nua_handle_destroy(nh);
606 }
607 END_TEST
608
START_TEST(notify_6_3_2)609 START_TEST(notify_6_3_2)
610 {
611 nua_handle_t *nh;
612 struct message *notify;
613 sip_t *sip;
614
615 S2_CASE("6.3.2", "NOTIFY server - automatic subscription termination",
616 "NUA receives SUBSCRIBE, sends 202 and NOTIFY. "
617 "The subscription terminates with timeout. ");
618
619 nh = subscribe_to_nua("presence", SIPTAG_EXPIRES_STR("300"), TAG_END());
620
621 nua_notify(nh,
622 NUTAG_SUBSTATE(nua_substate_active),
623 SIPTAG_PAYLOAD_STR(presence_closed),
624 TAG_END());
625 notify = s2_sip_wait_for_request(SIP_METHOD_NOTIFY);
626 fail_unless(notify != NULL);
627 sip = notify->sip;
628 fail_unless(sip->sip_subscription_state != NULL);
629 fail_unless(su_strmatch(sip->sip_subscription_state->ss_substate,
630 "active"));
631 s2_sip_respond_to(notify, dialog, SIP_200_OK, TAG_END());
632 fail_unless_event(nua_r_notify, 200);
633
634 s2_nua_fast_forward(300, s2base->root);
635
636 notify = s2_sip_wait_for_request(SIP_METHOD_NOTIFY);
637 fail_unless(notify != NULL);
638 sip = notify->sip;
639 fail_unless(sip->sip_subscription_state != NULL);
640 fail_unless(su_strmatch(sip->sip_subscription_state->ss_substate,
641 "terminated"));
642 s2_sip_respond_to(notify, dialog, SIP_200_OK, TAG_END());
643 fail_unless_event(nua_r_notify, 200);
644
645 nua_handle_destroy(nh);
646 }
647 END_TEST
648
649 static int
s2_event_substate(struct event * event)650 s2_event_substate(struct event *event)
651 {
652 if (event) {
653 tagi_t const *t = tl_find(event->data->e_tags, nutag_substate);
654 if (t)
655 return t->t_value;
656 }
657 return -1;
658 }
659
START_TEST(notify_6_3_3)660 START_TEST(notify_6_3_3)
661 {
662 nua_handle_t *nh;
663 struct message *notify;
664 struct event *response;
665 sip_t *sip;
666
667 S2_CASE("6.3.3", "NOTIFY server - terminate with error response to NOTIFY",
668 "NUA receives SUBSCRIBE, sends 202 and NOTIFY. "
669 "The subscription terminates when watcher "
670 "returns 481 to second NOTIFY.");
671
672 nh = subscribe_to_nua("presence", SIPTAG_EXPIRES_STR("300"), TAG_END());
673
674 nua_notify(nh,
675 NUTAG_SUBSTATE(nua_substate_active),
676 SIPTAG_PAYLOAD_STR(presence_closed),
677 TAG_END());
678 notify = s2_sip_wait_for_request(SIP_METHOD_NOTIFY);
679 fail_unless(notify != NULL);
680 sip = notify->sip;
681 fail_unless(sip->sip_subscription_state != NULL);
682 fail_unless(su_strmatch(sip->sip_subscription_state->ss_substate,
683 "active"));
684 s2_sip_respond_to(notify, dialog, SIP_200_OK, TAG_END());
685 fail_unless_event(nua_r_notify, 200);
686
687 nua_notify(nh,
688 NUTAG_SUBSTATE(nua_substate_active),
689 SIPTAG_PAYLOAD_STR(presence_closed),
690 TAG_END());
691 notify = s2_sip_wait_for_request(SIP_METHOD_NOTIFY);
692 fail_unless(notify != NULL);
693 sip = notify->sip;
694 fail_unless(sip->sip_subscription_state != NULL);
695 fail_unless(su_strmatch(sip->sip_subscription_state->ss_substate,
696 "active"));
697 s2_sip_respond_to(notify, dialog, SIP_481_NO_TRANSACTION, TAG_END());
698 response = s2_wait_for_event(nua_r_notify, 481);
699 fail_unless(s2_event_substate(response) == nua_substate_terminated);
700
701 nua_handle_destroy(nh);
702 }
703 END_TEST
704
START_TEST(notify_6_3_4)705 START_TEST(notify_6_3_4)
706 {
707 nua_handle_t *nh;
708 struct message *notify;
709 struct event *response;
710 sip_t *sip;
711
712 S2_CASE("6.3.4", "NOTIFY server - terminate with error response to NOTIFY",
713 "NUA receives SUBSCRIBE, sends 202 and NOTIFY. "
714 "The subscription terminates when watcher "
715 "returns 481 to second NOTIFY. The queued 3rd NOTIFY gets "
716 "responded by stack.");
717
718 nh = subscribe_to_nua("presence", SIPTAG_EXPIRES_STR("300"), TAG_END());
719
720 nua_notify(nh,
721 NUTAG_SUBSTATE(nua_substate_active),
722 SIPTAG_PAYLOAD_STR(presence_closed),
723 TAG_END());
724 notify = s2_sip_wait_for_request(SIP_METHOD_NOTIFY);
725 fail_unless(notify != NULL);
726 sip = notify->sip;
727 fail_unless(sip->sip_subscription_state != NULL);
728 fail_unless(su_strmatch(sip->sip_subscription_state->ss_substate,
729 "active"));
730 s2_sip_respond_to(notify, dialog, SIP_200_OK, TAG_END());
731 fail_unless_event(nua_r_notify, 200);
732
733 nua_notify(nh,
734 NUTAG_SUBSTATE(nua_substate_active),
735 SIPTAG_PAYLOAD_STR(presence_open),
736 TAG_END());
737 nua_notify(nh,
738 NUTAG_SUBSTATE(nua_substate_active),
739 SIPTAG_PAYLOAD_STR(presence_closed),
740 TAG_END());
741 notify = s2_sip_wait_for_request(SIP_METHOD_NOTIFY);
742 fail_unless(notify != NULL);
743 sip = notify->sip;
744 fail_unless(sip->sip_subscription_state != NULL);
745 fail_unless(su_strmatch(sip->sip_subscription_state->ss_substate,
746 "active"));
747 s2_sip_respond_to(notify, dialog, SIP_481_NO_TRANSACTION, TAG_END());
748 response = s2_wait_for_event(nua_r_notify, 481);
749 fail_unless(s2_event_substate(response) == nua_substate_terminated);
750 response = s2_wait_for_event(nua_r_notify, 481);
751 fail_unless(s2_event_substate(response) == nua_substate_terminated);
752
753 nua_handle_destroy(nh);
754 }
755 END_TEST
756
START_TEST(notify_6_3_5)757 START_TEST(notify_6_3_5)
758 {
759 nua_handle_t *nh;
760 struct message *notify;
761 struct event *response;
762 sip_t *sip;
763
764 S2_CASE("6.3.4", "NOTIFY server - terminate with error response to NOTIFY",
765 "NUA receives SUBSCRIBE, sends 202 and NOTIFY. "
766 "The subscription terminates when watcher "
767 "returns 481 to NOTIFY.");
768
769 nh = subscribe_to_nua("presence", SIPTAG_EXPIRES_STR("300"), TAG_END());
770
771 nua_notify(nh,
772 SIPTAG_SUBSCRIPTION_STATE_STR("active"),
773 SIPTAG_PAYLOAD_STR(presence_closed),
774 TAG_END());
775 notify = s2_sip_wait_for_request(SIP_METHOD_NOTIFY);
776 fail_unless(notify != NULL);
777 sip = notify->sip;
778 fail_unless(sip->sip_subscription_state != NULL);
779 fail_unless(su_strmatch(sip->sip_subscription_state->ss_substate,
780 "active"));
781 s2_sip_respond_to(notify, dialog, SIP_200_OK, TAG_END());
782 fail_unless_event(nua_r_notify, 200);
783
784 nua_notify(nh,
785 SIPTAG_SUBSCRIPTION_STATE_STR("active"),
786 SIPTAG_PAYLOAD_STR(presence_open),
787 TAG_END());
788 notify = s2_sip_wait_for_request(SIP_METHOD_NOTIFY);
789 fail_unless(notify != NULL);
790 sip = notify->sip;
791 fail_unless(sip->sip_subscription_state != NULL);
792 fail_unless(su_strmatch(sip->sip_subscription_state->ss_substate,
793 "active"));
794
795 nua_notify(nh,
796 NUTAG_NEWSUB(1),
797 SIPTAG_SUBSCRIPTION_STATE_STR("active"),
798 SIPTAG_PAYLOAD_STR(presence_open),
799 TAG_END());
800
801 s2_sip_respond_to(notify, dialog, SIP_481_NO_TRANSACTION, TAG_END());
802 response = s2_wait_for_event(nua_r_notify, 481);
803 fail_unless(s2_event_substate(response) == nua_substate_terminated);
804
805 notify = s2_sip_wait_for_request(SIP_METHOD_NOTIFY);
806 s2_sip_respond_to(notify, dialog, SIP_481_NO_TRANSACTION, TAG_END());
807 response = s2_wait_for_event(nua_r_notify, 481);
808 fail_unless(s2_event_substate(response) == nua_substate_terminated);
809
810 nua_handle_destroy(nh);
811 }
812 END_TEST
813
notifier_tcase(int threading)814 TCase *notifier_tcase(int threading)
815 {
816 TCase *tc = tcase_create("6.3 - Basic event server with NOTIFY ");
817 void (*simple_setup)(void);
818
819 simple_setup = threading ? simple_thread_setup : simple_threadless_setup;
820 tcase_add_checked_fixture(tc, simple_setup, simple_teardown);
821
822 {
823 tcase_add_test(tc, notify_6_3_1);
824 tcase_add_test(tc, notify_6_3_2);
825 tcase_add_test(tc, notify_6_3_3);
826 tcase_add_test(tc, notify_6_3_4);
827 tcase_add_test(tc, notify_6_3_5);
828 }
829 return tc;
830 }
831
832 /* ====================================================================== */
833
834 /* Test case template */
835
START_TEST(empty)836 START_TEST(empty)
837 {
838 S2_CASE("0.0.0", "Empty test case",
839 "Detailed explanation for empty test case.");
840
841 tport_set_params(s2sip->master, TPTAG_LOG(1), TAG_END());
842 s2_setup_logs(7);
843 s2_setup_logs(0);
844 tport_set_params(s2sip->master, TPTAG_LOG(0), TAG_END());
845 }
846
847 END_TEST
848
empty_tcase(int threading)849 static TCase *empty_tcase(int threading)
850 {
851 TCase *tc = tcase_create("0 - Empty");
852 void (*simple_setup)(void);
853
854 simple_setup = threading ? simple_thread_setup : simple_threadless_setup;
855 tcase_add_checked_fixture(tc, simple_setup, simple_teardown);
856
857 tcase_add_test(tc, empty);
858
859 return tc;
860 }
861
862 /* ====================================================================== */
863
check_simple_cases(Suite * suite,int threading)864 void check_simple_cases(Suite *suite, int threading)
865 {
866 suite_add_tcase(suite, subscribe_tcase(threading));
867 suite_add_tcase(suite, fetch_tcase(threading));
868 suite_add_tcase(suite, notifier_tcase(threading));
869
870 if (0) /* Template */
871 suite_add_tcase(suite, empty_tcase(threading));
872 }
873
874