2
0

check_simple.c 25 KB

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