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