test_call_hold.c 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180
  1. /*
  2. * This file is part of the Sofia-SIP package
  3. *
  4. * Copyright (C) 2005 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 test_call_hold.c
  25. * @brief Test re-INVITE, call hold, un-hold.
  26. *
  27. * @author Pekka Pessi <Pekka.Pessi@nokia.com>
  28. * @author Martti Mela <Martti Mela@nokia.com>
  29. *
  30. * @date Created: Wed Aug 17 12:12:12 EEST 2005 ppessi
  31. */
  32. #include "config.h"
  33. #include "test_nua.h"
  34. #include <sofia-sip/su_tag_class.h>
  35. #if HAVE_FUNC
  36. #elif HAVE_FUNCTION
  37. #define __func__ __FUNCTION__
  38. #else
  39. #define __func__ "test_call_hold"
  40. #endif
  41. int complete_call(CONDITION_PARAMS);
  42. int until_complete(CONDITION_PARAMS);
  43. int invite_responded(CONDITION_PARAMS);
  44. static size_t remove_first_ack(void *_once, void *message, size_t len);
  45. /* ======================================================================== */
  46. /* test_call_hold message sequence looks like this:
  47. A B
  48. | |
  49. |-------INVITE------>|
  50. |<----100 Trying-----|
  51. | |
  52. |<----180 Ringing----|
  53. | |
  54. |<--------200--------|
  55. |---------ACK------->|
  56. : :
  57. |--INVITE(sendonly)->|
  58. |<---200(recvonly)---|
  59. |---------ACK------->|
  60. : :
  61. |<-INVITE(inactive)--|
  62. |----200(inactive)-->|
  63. |<--------ACK--------|
  64. : :
  65. |--INVITE(recvonly)->|
  66. |<---200(sendonly)---|
  67. |---------ACK------->|
  68. : :
  69. |<-INVITE(sendrecv)--|
  70. |----200(sendrecv)-->|
  71. |<--------ACK--------|
  72. : :
  73. |--------INFO------->|
  74. |<--------200--------|
  75. : :
  76. |---------BYE------->|
  77. |<--------200--------|
  78. */
  79. int test_call_hold(struct context *ctx)
  80. {
  81. BEGIN();
  82. struct endpoint *a = &ctx->a, *b = &ctx->b;
  83. struct call *a_call = a->call, *b_call = b->call;
  84. struct event *e;
  85. sip_t *sip;
  86. int zero = 0;
  87. struct nat_filter *f;
  88. a_call->sdp =
  89. "m=audio 5008 RTP/AVP 0 8\n"
  90. "m=video 6008 RTP/AVP 30\n";
  91. b_call->sdp =
  92. "m=audio 5010 RTP/AVP 8\n"
  93. "a=rtcp:5011\n"
  94. "m=video 6010 RTP/AVP 30\n"
  95. "a=rtcp:6011\n";
  96. TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
  97. INVITE(a, a_call, a_call->nh,
  98. TAG_IF(!ctx->proxy_tests, NUTAG_URL(b->contact->m_url)),
  99. SOATAG_USER_SDP_STR(a_call->sdp),
  100. TAG_END());
  101. run_ab_until(ctx, -1, until_ready, -1, accept_call);
  102. /*
  103. Client transitions:
  104. INIT -(C1)-> CALLING: nua_invite(), nua_i_state
  105. CALLING -(C2)-> PROCEEDING: nua_r_invite, nua_i_state
  106. PROCEEDING -(C3+C4)-> READY: nua_r_invite, nua_i_state
  107. */
  108. TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_state);
  109. TEST(callstate(e->data->e_tags), nua_callstate_calling); /* CALLING */
  110. TEST_1(is_offer_sent(e->data->e_tags));
  111. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
  112. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
  113. TEST(callstate(e->data->e_tags), nua_callstate_proceeding); /* PROCEEDING */
  114. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
  115. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
  116. TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
  117. TEST_1(is_answer_recv(e->data->e_tags));
  118. TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_SENDRECV);
  119. TEST_1(!e->next);
  120. free_events_in_list(ctx, a->events);
  121. TEST_1(nua_handle_has_active_call(a_call->nh));
  122. TEST_1(!nua_handle_has_call_on_hold(a_call->nh));
  123. /*
  124. Server transitions:
  125. INIT -(S1)-> RECEIVED: nua_i_invite, nua_i_state
  126. RECEIVED -(S2a)-> EARLY: nua_respond(), nua_i_state
  127. EARLY -(S3b)-> COMPLETED: nua_respond(), nua_i_state
  128. COMPLETED -(S4)-> READY: nua_i_ack, nua_i_state
  129. */
  130. TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_invite);
  131. TEST(e->data->e_status, 100);
  132. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
  133. TEST(callstate(e->data->e_tags), nua_callstate_received); /* RECEIVED */
  134. TEST_1(is_offer_recv(e->data->e_tags));
  135. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
  136. TEST(callstate(e->data->e_tags), nua_callstate_early); /* EARLY */
  137. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
  138. TEST(callstate(e->data->e_tags), nua_callstate_completed); /* COMPLETED */
  139. TEST_1(is_answer_sent(e->data->e_tags));
  140. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_ack);
  141. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
  142. TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
  143. TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_SENDRECV);
  144. TEST_1(!e->next);
  145. TEST_1(nua_handle_has_active_call(b_call->nh));
  146. TEST_1(!nua_handle_has_call_on_hold(b_call->nh));
  147. free_events_in_list(ctx, b->events);
  148. /*
  149. : :
  150. |--INVITE(sendonly)->|
  151. |<---200(recvonly)---|
  152. |---------ACK------->|
  153. : :
  154. */
  155. if (print_headings)
  156. printf("TEST NUA-7.1: put B on hold\n");
  157. /* Put B on hold */
  158. INVITE(a, a_call, a_call->nh, SOATAG_HOLD("audio"),
  159. SIPTAG_SUBJECT_STR("hold b"),
  160. TAG_END());
  161. run_ab_until(ctx, -1, until_ready, -1, until_ready);
  162. /* Client transitions:
  163. READY -(C1)-> CALLING: nua_invite(), nua_i_state
  164. CALLING -(C3a+C4)-> READY: nua_r_invite, nua_i_state
  165. */
  166. TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_state);
  167. TEST(callstate(e->data->e_tags), nua_callstate_calling); /* CALLING */
  168. TEST_1(is_offer_sent(e->data->e_tags));
  169. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
  170. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
  171. TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
  172. TEST_1(is_answer_recv(e->data->e_tags));
  173. TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_SENDONLY);
  174. TEST_1(!e->next);
  175. TEST_1(nua_handle_has_active_call(a_call->nh));
  176. TEST_1(nua_handle_has_call_on_hold(a_call->nh));
  177. free_events_in_list(ctx, a->events);
  178. /*
  179. Server transitions:
  180. READY -(S3a)-> COMPLETED: nua_i_invite, <auto-answer>, nua_i_state
  181. COMPLETED -(S4)-> READY: nua_i_ack, nua_i_state
  182. */
  183. TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_invite);
  184. TEST(e->data->e_status, 200);
  185. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
  186. TEST(callstate(e->data->e_tags), nua_callstate_completed); /* COMPLETED */
  187. TEST_1(is_answer_sent(e->data->e_tags));
  188. TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_RECVONLY);
  189. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_ack);
  190. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
  191. TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
  192. TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_RECVONLY);
  193. TEST_1(!e->next);
  194. TEST_1(nua_handle_has_active_call(b_call->nh));
  195. TEST_1(!nua_handle_has_call_on_hold(b_call->nh));
  196. free_events_in_list(ctx, b->events);
  197. if (print_headings)
  198. printf("TEST NUA-7.1: PASSED\n");
  199. /* ------------------------------------------------------------------------ */
  200. /*
  201. : :
  202. |<-INVITE(inactive)--|
  203. |----200(inactive)-->|
  204. |<--------ACK--------|
  205. : :
  206. */
  207. if (print_headings)
  208. printf("TEST NUA-7.2: put A on hold\n");
  209. /* Put A on hold, too. */
  210. INVITE(b, b_call, b_call->nh, SOATAG_HOLD("audio"),
  211. SIPTAG_SUBJECT_STR("hold a"),
  212. TAG_END());
  213. run_ab_until(ctx, -1, until_ready, -1, until_ready);
  214. /* Client transitions:
  215. READY -(C1)-> CALLING: nua_invite(), nua_i_state
  216. CALLING -(C3a+C4)-> READY: nua_r_invite, nua_i_state
  217. */
  218. TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_state);
  219. TEST(callstate(e->data->e_tags), nua_callstate_calling); /* CALLING */
  220. TEST_1(is_offer_sent(e->data->e_tags));
  221. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
  222. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
  223. TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
  224. TEST_1(is_answer_recv(e->data->e_tags));
  225. TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_INACTIVE);
  226. TEST(video_activity(e->data->e_tags), SOA_ACTIVE_SENDRECV);
  227. TEST_1(!e->next);
  228. TEST_1(nua_handle_has_active_call(b_call->nh));
  229. TEST_1(nua_handle_has_call_on_hold(b_call->nh));
  230. free_events_in_list(ctx, b->events);
  231. /*
  232. Server transitions:
  233. READY -(S3a)-> COMPLETED: nua_i_invite, <auto-answer>, nua_i_state
  234. COMPLETED -(S4)-> READY: nua_i_ack, nua_i_state
  235. */
  236. TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_invite);
  237. TEST(e->data->e_status, 200);
  238. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
  239. TEST(callstate(e->data->e_tags), nua_callstate_completed); /* COMPLETED */
  240. TEST_1(is_answer_sent(e->data->e_tags));
  241. TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_INACTIVE);
  242. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_ack);
  243. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
  244. TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
  245. TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_INACTIVE);
  246. TEST(video_activity(e->data->e_tags), SOA_ACTIVE_SENDRECV);
  247. TEST_1(!e->next);
  248. TEST_1(nua_handle_has_active_call(a_call->nh));
  249. TEST_1(nua_handle_has_call_on_hold(a_call->nh));
  250. free_events_in_list(ctx, a->events);
  251. if (print_headings)
  252. printf("TEST NUA-7.2: PASSED\n");
  253. /* ------------------------------------------------------------------------ */
  254. /*
  255. : :
  256. |--INVITE(recvonly)->|
  257. |<---200(sendonly)---|
  258. |---------ACK------->|
  259. : :
  260. */
  261. if (print_headings)
  262. printf("TEST NUA-7.3: resume B\n");
  263. /* Resume B from hold */
  264. INVITE(a, a_call, a_call->nh, SOATAG_HOLD(NULL),
  265. SIPTAG_SUBJECT_STR("resume b"),
  266. TAG_END());
  267. run_ab_until(ctx, -1, until_ready, -1, until_ready);
  268. /* Client transitions:
  269. READY -(C1)-> CALLING: nua_invite(), nua_i_state
  270. CALLING -(C3a+C4)-> READY: nua_r_invite, nua_i_state
  271. */
  272. TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_state);
  273. TEST(callstate(e->data->e_tags), nua_callstate_calling); /* CALLING */
  274. TEST_1(is_offer_sent(e->data->e_tags));
  275. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
  276. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
  277. TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
  278. TEST_1(is_answer_recv(e->data->e_tags));
  279. TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_RECVONLY);
  280. TEST(video_activity(e->data->e_tags), SOA_ACTIVE_SENDRECV);
  281. TEST_1(!e->next);
  282. free_events_in_list(ctx, a->events);
  283. TEST_1(nua_handle_has_active_call(a_call->nh));
  284. TEST_1(!nua_handle_has_call_on_hold(a_call->nh));
  285. /*
  286. Server transitions:
  287. READY -(S3a)-> COMPLETED: nua_i_invite, <auto-answer>, nua_i_state
  288. COMPLETED -(S4)-> READY: nua_i_ack, nua_i_state
  289. */
  290. TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_invite);
  291. TEST(e->data->e_status, 200);
  292. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
  293. TEST(callstate(e->data->e_tags), nua_callstate_completed); /* COMPLETED */
  294. TEST_1(is_answer_sent(e->data->e_tags));
  295. TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_SENDONLY);
  296. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_ack);
  297. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
  298. TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
  299. TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_SENDONLY);
  300. TEST(video_activity(e->data->e_tags), SOA_ACTIVE_SENDRECV);
  301. TEST_1(!e->next);
  302. TEST_1(nua_handle_has_active_call(b_call->nh));
  303. TEST_1(nua_handle_has_call_on_hold(b_call->nh));
  304. free_events_in_list(ctx, b->events);
  305. if (print_headings)
  306. printf("TEST NUA-7.3: PASSED\n");
  307. /* ------------------------------------------------------------------------ */
  308. /*
  309. : :
  310. |<-INVITE(sendrecv)--|
  311. |----200(sendrecv)-->|
  312. |<--------ACK--------|
  313. : :
  314. */
  315. if (print_headings)
  316. printf("TEST NUA-7.4: resume A\n");
  317. /* Resume A on hold, too. */
  318. INVITE(b, b_call, b_call->nh, SOATAG_HOLD(""),
  319. SIPTAG_SUBJECT_STR("TEST NUA-7.4: resume A"),
  320. TAG_END());
  321. run_ab_until(ctx, -1, until_ready, -1, until_ready);
  322. /* Client transitions:
  323. READY -(C1)-> CALLING: nua_invite(), nua_i_state
  324. CALLING -(C3a+C4)-> READY: nua_r_invite, nua_i_state
  325. */
  326. TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_state);
  327. TEST(callstate(e->data->e_tags), nua_callstate_calling); /* CALLING */
  328. TEST_1(is_offer_sent(e->data->e_tags));
  329. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
  330. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
  331. TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
  332. TEST_1(is_answer_recv(e->data->e_tags));
  333. TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_SENDRECV);
  334. TEST(video_activity(e->data->e_tags), SOA_ACTIVE_SENDRECV);
  335. TEST_1(!e->next);
  336. free_events_in_list(ctx, b->events);
  337. TEST_1(nua_handle_has_active_call(a_call->nh));
  338. TEST_1(!nua_handle_has_call_on_hold(a_call->nh));
  339. /*
  340. Server transitions:
  341. READY -(S3a)-> COMPLETED: nua_i_invite, <auto-answer>, nua_i_state
  342. COMPLETED -(S4)-> READY: nua_i_ack, nua_i_state
  343. */
  344. TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_invite);
  345. TEST(e->data->e_status, 200);
  346. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
  347. TEST(callstate(e->data->e_tags), nua_callstate_completed); /* COMPLETED */
  348. TEST_1(is_answer_sent(e->data->e_tags));
  349. TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_SENDRECV);
  350. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_ack);
  351. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
  352. TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
  353. TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_SENDRECV);
  354. TEST(video_activity(e->data->e_tags), SOA_ACTIVE_SENDRECV);
  355. TEST_1(!e->next);
  356. TEST_1(nua_handle_has_active_call(b_call->nh));
  357. TEST_1(!nua_handle_has_call_on_hold(b_call->nh));
  358. free_events_in_list(ctx, a->events);
  359. if (print_headings)
  360. printf("TEST NUA-7.4: PASSED\n");
  361. /* ---------------------------------------------------------------------- */
  362. /*
  363. A B
  364. |--------INFO------->|
  365. |<--------200--------|
  366. */
  367. if (print_headings)
  368. printf("TEST NUA-7.5: send INFO\n");
  369. INFO(a, a_call, a_call->nh, TAG_END());
  370. run_a_until(ctx, -1, save_until_final_response);
  371. /* XXX - B should get a nua_i_info event with 405 */
  372. /* A sent INFO, receives 405 */
  373. TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_r_info);
  374. TEST(e->data->e_status, 405);
  375. TEST_1(!e->next);
  376. free_events_in_list(ctx, a->events);
  377. #if 0 /* XXX */
  378. /* B received INFO */
  379. TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_info);
  380. TEST(e->data->e_status, 405);
  381. TEST_1(!e->next);
  382. free_events_in_list(ctx, b->events);
  383. #endif
  384. /* Add INFO to allowed methods */
  385. nua_set_hparams(b_call->nh, NUTAG_ALLOW("INFO, PUBLISH"), TAG_END());
  386. run_b_until(ctx, nua_r_set_params, until_final_response);
  387. INFO(a, a_call, a_call->nh, TAG_END());
  388. run_ab_until(ctx, -1, save_until_final_response, -1, save_until_received);
  389. /* A sent INFO, receives 200 */
  390. TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_r_info);
  391. TEST(e->data->e_status, 200);
  392. TEST_1(!e->next);
  393. free_events_in_list(ctx, a->events);
  394. /* B received INFO */
  395. TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_info);
  396. TEST(e->data->e_status, 200);
  397. TEST_1(!e->next);
  398. free_events_in_list(ctx, b->events);
  399. if (print_headings)
  400. printf("TEST NUA-7.5: PASSED\n");
  401. /* ------------------------------------------------------------------------ */
  402. /*
  403. : :
  404. |<------INVITE-------|
  405. |--------200-------->|
  406. |<--------ACK--------|
  407. : :
  408. */
  409. if (print_headings)
  410. printf("TEST NUA-7.6.1: re-INVITE without auto-ack\n");
  411. /* Turn off auto-ack */
  412. nua_set_hparams(b_call->nh, NUTAG_AUTOACK(0), TAG_END());
  413. run_b_until(ctx, nua_r_set_params, until_final_response);
  414. INVITE(b, b_call, b_call->nh, SOATAG_HOLD(""),
  415. SIPTAG_SUBJECT_STR("TEST NUA-7.6: re-INVITE without auto-ack"),
  416. TAG_END());
  417. run_ab_until(ctx, -1, until_complete, -1, complete_call);
  418. /* Client transitions:
  419. READY -(C1)-> CALLING: nua_invite(), nua_i_state
  420. CALLING -(C3a)-> COMPLETING: nua_r_invite, nua_i_state
  421. COMPLETING -(C4)-> READY: nua_ack(), nua_i_state
  422. */
  423. TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_state);
  424. TEST(callstate(e->data->e_tags), nua_callstate_calling); /* CALLING */
  425. TEST_1(is_offer_sent(e->data->e_tags));
  426. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
  427. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
  428. TEST(callstate(e->data->e_tags), nua_callstate_completing); /* COMPLETING */
  429. TEST_1(is_answer_recv(e->data->e_tags));
  430. TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_SENDRECV);
  431. TEST(video_activity(e->data->e_tags), SOA_ACTIVE_SENDRECV);
  432. TEST_1(!e->next);
  433. free_events_in_list(ctx, b->events);
  434. /*
  435. Server transitions:
  436. READY -(S3a)-> COMPLETED: nua_i_invite, <auto-answer>, nua_i_state
  437. COMPLETED -(S4)-> READY: nua_i_ack, nua_i_state
  438. */
  439. TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_invite);
  440. TEST(e->data->e_status, 200);
  441. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
  442. TEST(callstate(e->data->e_tags), nua_callstate_completed); /* COMPLETED */
  443. TEST_1(is_answer_sent(e->data->e_tags));
  444. TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_SENDRECV);
  445. TEST_1(!e->next);
  446. free_events_in_list(ctx, a->events);
  447. ACK(b, b_call, b_call->nh, TAG_END());
  448. run_ab_until(ctx, -1, until_ready, -1, until_ready);
  449. TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_state);
  450. TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
  451. TEST_1(!e->next);
  452. free_events_in_list(ctx, b->events);
  453. TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_ack);
  454. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
  455. TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
  456. TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_SENDRECV);
  457. TEST(video_activity(e->data->e_tags), SOA_ACTIVE_SENDRECV);
  458. TEST_1(!e->next);
  459. free_events_in_list(ctx, a->events);
  460. if (print_headings)
  461. printf("TEST NUA-7.6.1: PASSED\n");
  462. /* ------------------------------------------------------------------------ */
  463. /*
  464. : :
  465. |<------INVITE-------|
  466. |--------200-------->|
  467. |<--------ACK--------|
  468. : :
  469. */
  470. if (ctx->proxy_tests && ctx->nat) {
  471. if (print_headings)
  472. printf("TEST NUA-7.6.2: almost overlapping re-INVITE\n");
  473. /* Turn off auto-ack */
  474. nua_set_hparams(b_call->nh, NUTAG_AUTOACK(0), TAG_END());
  475. run_b_until(ctx, nua_r_set_params, until_final_response);
  476. INVITE(b, b_call, b_call->nh, SOATAG_HOLD("#"),
  477. SIPTAG_SUBJECT_STR("TEST NUA-7.6.2: re-INVITE"),
  478. TAG_END());
  479. run_ab_until(ctx, -1, until_complete, -1, complete_call);
  480. /* Client transitions:
  481. READY -(C1)-> CALLING: nua_invite(), nua_i_state
  482. CALLING -(C3a)-> COMPLETING: nua_r_invite, nua_i_state
  483. COMPLETING -(C4)-> READY: nua_ack(), nua_i_state
  484. */
  485. TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_state);
  486. TEST(callstate(e->data->e_tags), nua_callstate_calling); /* CALLING */
  487. TEST_1(is_offer_sent(e->data->e_tags));
  488. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
  489. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
  490. TEST(callstate(e->data->e_tags), nua_callstate_completing); /* COMPLETING */
  491. TEST_1(is_answer_recv(e->data->e_tags));
  492. TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_INACTIVE);
  493. TEST(video_activity(e->data->e_tags), SOA_ACTIVE_INACTIVE);
  494. TEST_1(!e->next);
  495. free_events_in_list(ctx, b->events);
  496. /*
  497. Server transitions:
  498. READY -(S3a)-> COMPLETED: nua_i_invite, <auto-answer>, nua_i_state
  499. COMPLETED -(S4)-> READY: nua_i_ack, nua_i_state
  500. */
  501. TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_invite);
  502. TEST(e->data->e_status, 200);
  503. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
  504. TEST(callstate(e->data->e_tags), nua_callstate_completed); /* COMPLETED */
  505. TEST_1(is_answer_sent(e->data->e_tags));
  506. TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_INACTIVE);
  507. TEST_1(!e->next);
  508. free_events_in_list(ctx, a->events);
  509. f = test_nat_add_filter(ctx->nat, remove_first_ack, &zero, nat_inbound);
  510. ACK(b, b_call, b_call->nh, TAG_END());
  511. INVITE(b, b_call, b_call->nh, SOATAG_HOLD("*"),
  512. SIPTAG_SUBJECT_STR("TEST NUA-7.6.2: almost overlapping re-INVITE"),
  513. NUTAG_AUTOACK(1),
  514. TAG_END());
  515. run_ab_until(ctx, -1, until_ready, -1, invite_responded);
  516. TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_state);
  517. TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
  518. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
  519. TEST(callstate(e->data->e_tags), nua_callstate_calling); /* CALLING */
  520. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
  521. TEST(e->data->e_status, 100);
  522. TEST_1(sip = sip_object(e->data->e_msg));
  523. TEST_1(sip->sip_retry_after);
  524. #if 1
  525. if (e->next) {
  526. free_events_in_list(ctx, b->events);
  527. free_events_in_list(ctx, a->events);
  528. goto passed; /* XXX - once in a while B *does* retry */
  529. }
  530. TEST_1(!e->next);
  531. #endif
  532. free_events_in_list(ctx, b->events);
  533. TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_ack);
  534. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
  535. TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
  536. TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_INACTIVE);
  537. TEST(video_activity(e->data->e_tags), SOA_ACTIVE_INACTIVE);
  538. TEST_1(!e->next);
  539. free_events_in_list(ctx, a->events);
  540. test_nat_remove_filter(ctx->nat, f);
  541. if (print_headings)
  542. printf("TEST NUA-7.6.2: PASSED\n");
  543. }
  544. /* ---------------------------------------------------------------------- */
  545. /*
  546. A B
  547. |---------BYE------->|
  548. |<--------200--------|
  549. */
  550. if (print_headings)
  551. printf("TEST NUA-7.6.3: terminate call\n");
  552. BYE(a, a_call, a_call->nh, TAG_END());
  553. run_ab_until(ctx, -1, until_terminated, -1, until_terminated);
  554. /*
  555. Transitions of A:
  556. READY --(T2)--> TERMINATING: nua_bye()
  557. TERMINATING --(T3)--> TERMINATED: nua_r_bye, nua_i_state
  558. */
  559. TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_r_bye);
  560. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
  561. TEST(callstate(e->data->e_tags), nua_callstate_terminated); /* TERMINATED */
  562. TEST_1(!e->next);
  563. free_events_in_list(ctx, a->events);
  564. /* Transitions of B:
  565. READY -(T1)-> TERMINATED: nua_i_bye, nua_i_state
  566. */
  567. TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_bye);
  568. TEST(e->data->e_status, 200);
  569. if (ctx->proxy_tests && ctx->nat) {
  570. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
  571. TEST(e->data->e_status, 481);
  572. }
  573. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
  574. TEST(callstate(e->data->e_tags), nua_callstate_terminated); /* TERMINATED */
  575. TEST_1(!e->next);
  576. free_events_in_list(ctx, b->events);
  577. passed:
  578. if (print_headings)
  579. printf("TEST NUA-7.6.3: PASSED\n");
  580. nua_handle_destroy(a_call->nh), a_call->nh = NULL;
  581. nua_handle_destroy(b_call->nh), b_call->nh = NULL;
  582. END();
  583. }
  584. /*
  585. INVITE without auto-ack
  586. X
  587. | |
  588. |-------INVITE------>|
  589. |<--------200--------|
  590. | |
  591. |---------ACK------->|
  592. */
  593. int complete_call(CONDITION_PARAMS)
  594. {
  595. if (!(check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR)))
  596. return 0;
  597. save_event_in_list(ctx, event, ep, call);
  598. switch (callstate(tags)) {
  599. case nua_callstate_completing:
  600. return 1;
  601. case nua_callstate_ready:
  602. return 1;
  603. case nua_callstate_terminated:
  604. if (call)
  605. nua_handle_destroy(call->nh), call->nh = NULL;
  606. return 1;
  607. default:
  608. return 0;
  609. }
  610. }
  611. /*
  612. X INVITE
  613. | |
  614. |-------INVITE------>|
  615. |<--------200--------|
  616. */
  617. int until_complete(CONDITION_PARAMS)
  618. {
  619. if (!(check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR)))
  620. return 0;
  621. save_event_in_list(ctx, event, ep, call);
  622. switch (callstate(tags)) {
  623. case nua_callstate_completed:
  624. case nua_callstate_ready:
  625. return 1;
  626. case nua_callstate_terminated:
  627. if (call)
  628. nua_handle_destroy(call->nh), call->nh = NULL;
  629. return 1;
  630. default:
  631. return 0;
  632. }
  633. }
  634. static size_t remove_first_ack(void *_once, void *message, size_t len)
  635. {
  636. int *once = _once;
  637. if (*once)
  638. return len;
  639. if (strncmp("ACK ", message, 4) == 0) {
  640. printf("FILTERING %.*s\n", strcspn(message, "\r\n"), (char *)message);
  641. *once = 1;
  642. return 0;
  643. }
  644. return len;
  645. }
  646. /* ======================================================================== */
  647. /* test_reinvite message sequence looks like this:
  648. A B
  649. | |
  650. |-------INVITE------>|
  651. |<----100 Trying-----|
  652. | |
  653. |<----180 Ringing----|
  654. | |
  655. |<--------200--------|
  656. |---------ACK------->|
  657. : :
  658. |<----re-INVITE------|
  659. |<-------BYE---------|
  660. |--------200-------->|
  661. |-----487-INVITE---->|
  662. |<--------ACK--------|
  663. */
  664. int accept_no_save(CONDITION_PARAMS);
  665. int ringing_until_terminated(CONDITION_PARAMS);
  666. int bye_when_ringing(CONDITION_PARAMS);
  667. int test_reinvite(struct context *ctx)
  668. {
  669. BEGIN();
  670. struct endpoint *a = &ctx->a, *b = &ctx->b;
  671. struct call *a_call = a->call, *b_call = b->call;
  672. if (print_headings)
  673. printf("TEST NUA-7.7: Test re-INVITE and BYE\n");
  674. a_call->sdp = "m=audio 5008 RTP/AVP 0 8\n";
  675. b_call->sdp = "m=audio 5010 RTP/AVP 8\n";
  676. TEST_1(a_call->nh =
  677. nua_handle(a->nua, a_call,
  678. SIPTAG_FROM_STR("Alice <sip:alice@example.com>"),
  679. SIPTAG_TO(b->to),
  680. NUTAG_AUTOANSWER(0),
  681. TAG_END()));
  682. INVITE(a, a_call, a_call->nh,
  683. TAG_IF(!ctx->proxy_tests, NUTAG_URL(b->contact->m_url)),
  684. SOATAG_USER_SDP_STR(a_call->sdp),
  685. TAG_END());
  686. run_ab_until(ctx, -1, accept_no_save, -1, accept_no_save);
  687. TEST_1(nua_handle_has_active_call(a_call->nh));
  688. TEST_1(nua_handle_has_active_call(b_call->nh));
  689. free_events_in_list(ctx, a->events);
  690. free_events_in_list(ctx, b->events);
  691. /*
  692. A B
  693. |<----re-INVITE------|
  694. |<------CANCEL-------|
  695. |<-------BYE---------|
  696. |-----200-CANCEL---->|
  697. |------200-BYE------>|
  698. |-----487-INVITE---->|
  699. |<--------ACK--------|
  700. */
  701. /* re-INVITE A, send BYE after receiving 180 */
  702. INVITE(b, b_call, b_call->nh,
  703. SIPTAG_SUBJECT_STR("re-INVITE"),
  704. TAG_END());
  705. /* Run until both a and b has terminated their call */
  706. run_ab_until(ctx, -1, ringing_until_terminated, -1, bye_when_ringing);
  707. #if notyet
  708. struct event *e;
  709. /* XXX - check events later - now we are happy that calls get terminated */
  710. /* Client events:
  711. READY -(C1)-> CALLING: nua_invite(), nua_i_state
  712. CALLING --(C2)--> PROCEEDING: nua_r_invite, nua_i_state, nua_bye()
  713. PROCEEDING--((C3a+C4)-> READY: nua_r_invite, nua_i_state
  714. READY --(T2)--> TERMINATING: nua_bye()
  715. TERMINATING --(T3)--> TERMINATED: nua_r_bye, nua_i_state
  716. */
  717. TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_state);
  718. TEST(callstate(e->data->e_tags), nua_callstate_calling); /* CALLING */
  719. TEST_1(is_offer_sent(e->data->e_tags));
  720. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
  721. TEST(e->data->e_status, 180);
  722. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
  723. TEST(callstate(e->data->e_tags), nua_callstate_terminating); /* READY */
  724. /* Now we can receive events, in any possible order */
  725. /* XXX */
  726. TEST_1(e = e->next);
  727. TEST_1(!nua_handle_has_active_call(a_call->nh));
  728. /*
  729. Server transitions:
  730. READY --(T2)--> CTERMINATING: nua_bye()
  731. TERMINATING --(T3)--> TERMINATED: nua_r_bye, nua_i_state
  732. READY -(S3a)-> COMPLETED: nua_i_invite, <auto-answer>, nua_i_state
  733. COMPLETED -(S4)-> READY: nua_i_ack, nua_i_state
  734. */
  735. TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_invite);
  736. TEST(e->data->e_status, 200);
  737. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
  738. TEST(callstate(e->data->e_tags), nua_callstate_completed); /* COMPLETED */
  739. TEST_1(is_answer_sent(e->data->e_tags));
  740. TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_RECVONLY);
  741. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_ack);
  742. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
  743. TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
  744. TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_RECVONLY);
  745. TEST_1(!e->next);
  746. TEST_1(nua_handle_has_active_call(b_call->nh));
  747. TEST_1(!nua_handle_has_call_on_hold(b_call->nh));
  748. #endif
  749. if (print_headings)
  750. printf("TEST NUA-7.7: PASSED\n");
  751. free_events_in_list(ctx, a->events);
  752. free_events_in_list(ctx, b->events);
  753. nua_handle_destroy(a_call->nh), a_call->nh = NULL;
  754. nua_handle_destroy(b_call->nh), b_call->nh = NULL;
  755. END();
  756. }
  757. /*
  758. Accept INVITE
  759. X
  760. | |
  761. |-------INVITE------>|
  762. |<--------200--------|
  763. | |
  764. |---------ACK------->|
  765. */
  766. int accept_no_save(CONDITION_PARAMS)
  767. {
  768. if (!(check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR)))
  769. return 0;
  770. switch (callstate(tags)) {
  771. case nua_callstate_received:
  772. RESPOND(ep, call, nh, SIP_200_OK,
  773. TAG_IF(call->sdp, SOATAG_USER_SDP_STR(call->sdp)),
  774. TAG_END());
  775. return 0;
  776. case nua_callstate_ready:
  777. return 1;
  778. case nua_callstate_terminated:
  779. if (call)
  780. nua_handle_destroy(call->nh), call->nh = NULL;
  781. return 1;
  782. default:
  783. return 0;
  784. }
  785. }
  786. int ringing_until_terminated(CONDITION_PARAMS)
  787. {
  788. if (!(check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR)))
  789. return 0;
  790. save_event_in_list(ctx, event, ep, call);
  791. switch (callstate(tags)) {
  792. case nua_callstate_received:
  793. RESPOND(ep, call, nh, SIP_180_RINGING, TAG_END());
  794. return 0;
  795. case nua_callstate_ready:
  796. return 0;
  797. case nua_callstate_terminated:
  798. if (call)
  799. nua_handle_destroy(call->nh), call->nh = NULL;
  800. return 1;
  801. default:
  802. return 0;
  803. }
  804. }
  805. /* ======================================================================== */
  806. int accept_and_attempt_reinvite(CONDITION_PARAMS);
  807. int until_ready2(CONDITION_PARAMS);
  808. /* test_reinvite2 message sequence looks like this:
  809. A B
  810. | |
  811. |-------INVITE------>|
  812. |<----100 Trying-----|
  813. | |
  814. |<----180 Ringing----|
  815. | |
  816. | /-INVITE-|
  817. | \---900->|
  818. | |
  819. |<--------200--------|
  820. |---------ACK------->|
  821. : :
  822. : queue INVITE :
  823. : :
  824. |-----re-INVITE----->|
  825. |<--------200--------|
  826. |---------ACK------->|
  827. |-----re-INVITE----->|
  828. |<--------200--------|
  829. |---------ACK------->|
  830. : :
  831. : glare :
  832. : :
  833. |-----re-INVITE----->|
  834. |<----re-INVITE------|
  835. |<--------491--------|
  836. |---------491------->|
  837. |---------ACK------->|
  838. |<--------ACK--------|
  839. : :
  840. |---------BYE------->|
  841. |<--------200--------|
  842. */
  843. int test_reinvite2(struct context *ctx)
  844. {
  845. BEGIN();
  846. struct endpoint *a = &ctx->a, *b = &ctx->b;
  847. struct call *a_call = a->call, *b_call = b->call;
  848. struct event *e;
  849. if (print_headings)
  850. printf("TEST NUA-7.8.1: Test re-INVITE glare\n");
  851. a_call->sdp = "m=audio 5008 RTP/AVP 0 8\n";
  852. b_call->sdp = "m=audio 5010 RTP/AVP 8\n";
  853. TEST_1(a_call->nh =
  854. nua_handle(a->nua, a_call,
  855. SIPTAG_FROM_STR("Alice <sip:alice@example.com>"),
  856. SIPTAG_TO(b->to),
  857. TAG_END()));
  858. INVITE(a, a_call, a_call->nh,
  859. TAG_IF(!ctx->proxy_tests, NUTAG_URL(b->contact->m_url)),
  860. SOATAG_USER_SDP_STR(a_call->sdp),
  861. TAG_END());
  862. run_ab_until(ctx, -1, until_ready, -1, accept_and_attempt_reinvite);
  863. TEST_1(nua_handle_has_active_call(a_call->nh));
  864. TEST_1(nua_handle_has_active_call(b_call->nh));
  865. free_events_in_list(ctx, a->events);
  866. free_events_in_list(ctx, b->events);
  867. /* Check that we can queue INVITEs */
  868. INVITE(a, a_call, a_call->nh, TAG_END());
  869. INVITE(a, a_call, a_call->nh, TAG_END());
  870. run_ab_until(ctx, -1, until_ready2, -1, until_ready2);
  871. free_events_in_list(ctx, a->events);
  872. free_events_in_list(ctx, b->events);
  873. /* Check that INVITE glare works */
  874. INVITE(a, a_call, a_call->nh, TAG_END());
  875. INVITE(b, b_call, b_call->nh, TAG_END());
  876. a->flags.n = 0, b->flags.n = 0;
  877. run_ab_until(ctx, -1, until_ready2, -1, until_ready2);
  878. free_events_in_list(ctx, a->events);
  879. free_events_in_list(ctx, b->events);
  880. if (print_headings)
  881. printf("TEST NUA-7.8.1: PASSED\n");
  882. /* ---------------------------------------------------------------------- */
  883. /*
  884. A B
  885. |---------BYE------->|
  886. |<--------200--------|
  887. */
  888. if (print_headings)
  889. printf("TEST NUA-7.8.2: terminate call\n");
  890. BYE(a, a_call, a_call->nh, TAG_END());
  891. run_ab_until(ctx, -1, until_terminated, -1, until_terminated);
  892. /*
  893. Transitions of A:
  894. READY --(T2)--> TERMINATING: nua_bye()
  895. TERMINATING --(T3)--> TERMINATED: nua_r_bye, nua_i_state
  896. */
  897. TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_r_bye);
  898. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
  899. TEST(callstate(e->data->e_tags), nua_callstate_terminated); /* TERMINATED */
  900. TEST_1(!e->next);
  901. free_events_in_list(ctx, a->events);
  902. /* Transitions of B:
  903. READY -(T1)-> TERMINATED: nua_i_bye, nua_i_state
  904. */
  905. TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_bye);
  906. TEST(e->data->e_status, 200);
  907. TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
  908. TEST(callstate(e->data->e_tags), nua_callstate_terminated); /* TERMINATED */
  909. TEST_1(!e->next);
  910. free_events_in_list(ctx, b->events);
  911. if (print_headings)
  912. printf("TEST NUA-7.8.2: PASSED\n");
  913. nua_handle_destroy(a_call->nh), a_call->nh = NULL;
  914. nua_handle_destroy(b_call->nh), b_call->nh = NULL;
  915. END();
  916. }
  917. int accept_and_attempt_reinvite(CONDITION_PARAMS)
  918. {
  919. if (!(check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR)))
  920. return 0;
  921. save_event_in_list(ctx, event, ep, call);
  922. if (event == nua_i_prack) {
  923. INVITE(ep, call, nh, TAG_END());
  924. RESPOND(ep, call, nh, SIP_200_OK,
  925. TAG_IF(call->sdp, SOATAG_USER_SDP_STR(call->sdp)),
  926. TAG_END());
  927. }
  928. else switch (callstate(tags)) {
  929. case nua_callstate_received:
  930. RESPOND(ep, call, nh, SIP_180_RINGING,
  931. SIPTAG_REQUIRE_STR("100rel"),
  932. TAG_END());
  933. return 0;
  934. case nua_callstate_early:
  935. return 0;
  936. case nua_callstate_ready:
  937. return 1;
  938. case nua_callstate_terminated:
  939. if (call)
  940. nua_handle_destroy(call->nh), call->nh = NULL;
  941. return 1;
  942. default:
  943. return 0;
  944. }
  945. return 0;
  946. }
  947. /*
  948. X INVITE
  949. | |
  950. |-------INVITE------>|
  951. |<--------200--------|
  952. |---------ACK------->|
  953. */
  954. int until_ready2(CONDITION_PARAMS)
  955. {
  956. if (!(check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR)))
  957. return 0;
  958. save_event_in_list(ctx, event, ep, call);
  959. if (event == nua_r_invite && status == 491) {
  960. if (ep == &ctx->a && ++ctx->b.flags.n >= 2) ctx->b.running = 0;
  961. if (ep == &ctx->b && ++ctx->a.flags.n >= 2) ctx->a.running = 0;
  962. }
  963. switch (callstate(tags)) {
  964. case nua_callstate_ready:
  965. return ++ep->flags.n >= 2;
  966. case nua_callstate_terminated:
  967. if (call)
  968. nua_handle_destroy(call->nh), call->nh = NULL;
  969. return 1;
  970. default:
  971. return 0;
  972. }
  973. }
  974. int invite_responded(CONDITION_PARAMS)
  975. {
  976. if (!(check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR)))
  977. return 0;
  978. save_event_in_list(ctx, event, ep, call);
  979. return event == nua_r_invite && status >= 100;
  980. }
  981. int test_reinvites(struct context *ctx)
  982. {
  983. int retval = 0;
  984. if (print_headings)
  985. printf("TEST NUA-7: Test call hold and re-INVITEs\n");
  986. retval = test_call_hold(ctx);
  987. if (retval == 0)
  988. retval = test_reinvite(ctx);
  989. if (retval == 0)
  990. retval = test_reinvite2(ctx);
  991. if (print_headings && retval == 0)
  992. printf("TEST NUA-7: PASSED\n");
  993. return retval;
  994. }