1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670 |
- /*
- * This file is part of the Sofia-SIP package
- *
- * Copyright (C) 2008 Nokia Corporation.
- *
- * Contact: Pekka Pessi <pekka.pessi@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
- /**@CFILE check_session.c
- *
- * @brief NUA module tests for SIP session handling
- *
- * @author Pekka Pessi <Pekka.Pessi@nokia.com>
- *
- * @copyright (C) 2008 Nokia Corporation.
- */
- #include "config.h"
- #undef NDEBUG
- #include "check_nua.h"
- #include <sofia-sip/sip_status.h>
- #include <sofia-sip/sip_header.h>
- #include <sofia-sip/soa.h>
- #include <sofia-sip/su_tagarg.h>
- #include <sofia-sip/su_string.h>
- #include <sofia-sip/su_tag_io.h>
- #include <stdlib.h>
- #include <string.h>
- #include <assert.h>
- /* define XXX as 1 in order to see all failing test cases */
- #ifndef XXX
- #define XXX (0)
- #endif
- /* ====================================================================== */
- static nua_t *nua;
- static soa_session_t *soa = NULL;
- static struct dialog *dialog = NULL;
- #define CRLF "\r\n"
- static void call_setup(void)
- {
- nua = s2_nua_setup("call",
- SIPTAG_ORGANIZATION_STR("Pussy Galore's Flying Circus"),
- NUTAG_OUTBOUND("no-options-keepalive, no-validate"),
- TAG_END());
- soa = soa_create(NULL, s2base->root, NULL);
- fail_if(!soa);
- soa_set_params(soa,
- SOATAG_USER_SDP_STR("m=audio 5008 RTP/AVP 8 0" CRLF
- "m=video 5010 RTP/AVP 34" CRLF),
- TAG_END());
- dialog = su_home_new(sizeof *dialog); fail_if(!dialog);
- s2_register_setup();
- }
- static void call_thread_setup(void)
- {
- s2_nua_thread = 1;
- call_setup();
- }
- static void call_teardown(void)
- {
- s2_teardown_started("call");
- mark_point();
- s2_register_teardown();
- if (s2->shutdown == 0) {
- mark_point();
- nua_shutdown(nua);
- fail_unless_event(nua_r_shutdown, 200);
- }
- mark_point();
- s2_nua_teardown();
- }
- static void
- add_call_fixtures(TCase *tc, int threading)
- {
- if (threading)
- tcase_add_checked_fixture(tc, call_thread_setup, call_teardown);
- else
- tcase_add_checked_fixture(tc, call_setup, call_teardown);
- }
- static void save_sdp_to_soa(struct message *message)
- {
- sip_payload_t *pl;
- char const *body;
- isize_t bodylen;
- fail_if(!message);
- fail_if(!message->sip->sip_content_length);
- fail_if(!message->sip->sip_content_type);
- fail_if(strcmp(message->sip->sip_content_type->c_type,
- "application/sdp"));
- fail_if(!message->sip->sip_payload);
- pl = message->sip->sip_payload;
- body = pl->pl_data, bodylen = pl->pl_len;
- fail_if(soa_set_remote_sdp(soa, NULL, body, (issize_t)bodylen) < 0);
- }
- static void process_offer(struct message *message)
- {
- save_sdp_to_soa(message);
- fail_if(soa_generate_answer(soa, NULL) < 0);
- }
- static void process_answer(struct message *message)
- {
- save_sdp_to_soa(message);
- fail_if(soa_process_answer(soa, NULL) < 0);
- }
- static void
- respond_with_sdp(struct message *request,
- struct dialog *dialog,
- int status, char const *phrase,
- tag_type_t tag, tag_value_t value, ...)
- {
- ta_list ta;
- char const *body;
- isize_t bodylen;
- fail_if(soa_get_local_sdp(soa, NULL, &body, &bodylen) != 1);
- ta_start(ta, tag, value);
- s2_sip_respond_to(request, dialog, status, phrase,
- SIPTAG_CONTENT_TYPE_STR("application/sdp"),
- SIPTAG_PAYLOAD_STR(body),
- SIPTAG_CONTENT_DISPOSITION_STR("session"),
- ta_tags(ta));
- ta_end(ta);
- }
- static void
- request_with_sdp(struct dialog *dialog,
- sip_method_t method, char const *name,
- tport_t *tport,
- tag_type_t tag, tag_value_t value, ...)
- {
- ta_list ta;
- char const *body;
- isize_t bodylen;
- fail_if(soa_get_local_sdp(soa, NULL, &body, &bodylen) != 1);
- ta_start(ta, tag, value);
- fail_if(
- s2_sip_request_to(dialog, method, name, tport,
- SIPTAG_CONTENT_TYPE_STR("application/sdp"),
- SIPTAG_PAYLOAD_STR(body),
- ta_tags(ta)));
- ta_end(ta);
- }
- static struct message *
- invite_sent_by_nua(nua_handle_t *nh,
- tag_type_t tag, tag_value_t value, ...)
- {
- ta_list ta;
- ta_start(ta, tag, value);
- nua_invite(nh, SOATAG_USER_SDP_STR("m=audio 5004 RTP/AVP 0 8"),
- ta_tags(ta));
- ta_end(ta);
- fail_unless(s2_check_callstate(nua_callstate_calling));
- return s2_sip_wait_for_request(SIP_METHOD_INVITE);
- }
- static uint32_t s2_rseq;
- static struct message *
- respond_with_100rel(struct message *invite,
- struct dialog *d,
- int with_sdp,
- int status, char const *phrase,
- tag_type_t tag, tag_value_t value, ...)
- {
- ta_list ta;
- sip_rseq_t rs[1];
- assert(100 < status && status < 200);
- sip_rseq_init(rs);
- rs->rs_response = ++s2_rseq;
- ta_start(ta, tag, value);
- if (with_sdp) {
- respond_with_sdp(
- invite, dialog, status, phrase,
- SIPTAG_REQUIRE_STR("100rel"),
- SIPTAG_RSEQ(rs),
- ta_tags(ta));
- }
- else {
- s2_sip_respond_to(
- invite, dialog, status, phrase,
- SIPTAG_REQUIRE_STR("100rel"),
- SIPTAG_RSEQ(rs),
- ta_tags(ta));
- }
- ta_end(ta);
- fail_unless_event(nua_r_invite, status);
- return s2_sip_wait_for_request(SIP_METHOD_PRACK);
- }
- static void
- invite_by_nua(nua_handle_t *nh,
- tag_type_t tag, tag_value_t value, ...)
- {
- struct message *invite;
- ta_list ta;
- ta_start(ta, tag, value);
- invite = invite_sent_by_nua(nh, ta_tags(ta));
- ta_end(ta);
- process_offer(invite);
- respond_with_sdp(
- invite, dialog, SIP_180_RINGING,
- SIPTAG_CONTENT_DISPOSITION_STR("session;handling=optional"),
- TAG_END());
- fail_unless_event(nua_r_invite, 180);
- fail_unless(s2_check_callstate(nua_callstate_proceeding));
- respond_with_sdp(invite, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(invite);
- fail_unless_event(nua_r_invite, 200);
- fail_unless(s2_check_callstate(nua_callstate_ready));
- fail_unless(s2_sip_check_request(SIP_METHOD_ACK));
- }
- static nua_handle_t *
- invite_to_nua(tag_type_t tag, tag_value_t value, ...)
- {
- ta_list ta;
- struct event *invite;
- struct message *response;
- nua_handle_t *nh;
- soa_generate_offer(soa, 1, NULL);
- ta_start(ta, tag, value);
- request_with_sdp(dialog, SIP_METHOD_INVITE, NULL, ta_tags(ta));
- ta_end(ta);
- invite = s2_wait_for_event(nua_i_invite, 100); fail_unless(invite != NULL);
- fail_unless(s2_check_callstate(nua_callstate_received));
- nh = invite->nh;
- fail_if(!nh);
- s2_free_event(invite);
- response = s2_sip_wait_for_response(100, SIP_METHOD_INVITE);
- fail_if(!response);
- nua_respond(nh, SIP_180_RINGING,
- SOATAG_USER_SDP_STR("m=audio 5004 RTP/AVP 0 8"),
- TAG_END());
- fail_unless(s2_check_callstate(nua_callstate_early));
- response = s2_sip_wait_for_response(180, SIP_METHOD_INVITE);
- fail_if(!response);
- s2_sip_update_dialog(dialog, response);
- process_answer(response);
- s2_sip_free_message(response);
- nua_respond(nh, SIP_200_OK, TAG_END());
- fail_unless(s2_check_callstate(nua_callstate_completed));
- response = s2_sip_wait_for_response(200, SIP_METHOD_INVITE);
- fail_if(!response);
- s2_sip_update_dialog(dialog, response);
- s2_sip_free_message(response);
- fail_if(s2_sip_request_to(dialog, SIP_METHOD_ACK, NULL, TAG_END()));
- fail_unless_event(nua_i_ack, 200);
- fail_unless(s2_check_callstate(nua_callstate_ready));
- return nh;
- }
- static void
- bye_by_nua(nua_handle_t *nh,
- tag_type_t tag, tag_value_t value, ...)
- {
- ta_list ta;
- struct message *bye;
- ta_start(ta, tag, value);
- nua_bye(nh, ta_tags(ta));
- ta_end(ta);
- bye = s2_sip_wait_for_request(SIP_METHOD_BYE);
- fail_if(!bye);
- s2_sip_respond_to(bye, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(bye);
- fail_unless_event(nua_r_bye, 200);
- fail_unless(s2_check_callstate(nua_callstate_terminated));
- }
- static void
- bye_by_nua_challenged(nua_handle_t *nh,
- tag_type_t tag, tag_value_t value, ...)
- {
- ta_list ta;
- struct message *bye;
- s2_flush_events();
- ta_start(ta, tag, value);
- nua_bye(nh, ta_tags(ta));
- ta_end(ta);
- bye = s2_sip_wait_for_request(SIP_METHOD_BYE);
- fail_if(!bye);
- s2_sip_respond_to(bye, dialog, SIP_407_PROXY_AUTH_REQUIRED,
- SIPTAG_PROXY_AUTHENTICATE_STR(s2_auth_digest_str),
- TAG_END());
- s2_sip_free_message(bye);
- fail_unless_event(nua_r_bye, 407);
- nua_authenticate(nh, NUTAG_AUTH("Digest:\"s2test\":abc:abc"), TAG_END());
- bye = s2_sip_wait_for_request(SIP_METHOD_BYE);
- fail_if(!bye);
- s2_sip_respond_to(bye, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(bye);
- fail_unless_event(nua_r_bye, 200);
- fail_unless(s2_check_callstate(nua_callstate_terminated));
- fail_if(s2->events);
- }
- static void
- cancel_by_nua(nua_handle_t *nh,
- struct message *invite,
- struct dialog *dialog,
- tag_type_t tag, tag_value_t value, ...)
- {
- ta_list ta;
- struct message *cancel;
- ta_start(ta, tag, value);
- nua_cancel(nh, ta_tags(ta));
- ta_end(ta);
- cancel = s2_sip_wait_for_request(SIP_METHOD_CANCEL);
- fail_if(!cancel);
- s2_sip_respond_to(cancel, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(cancel);
- fail_unless_event(nua_r_cancel, 200);
- s2_sip_respond_to(invite, dialog, SIP_487_REQUEST_CANCELLED, TAG_END());
- fail_unless(s2_sip_check_request(SIP_METHOD_ACK));
- fail_unless_event(nua_r_invite, 487);
- }
- static void
- bye_to_nua(nua_handle_t *nh,
- tag_type_t tag, tag_value_t value, ...)
- {
- ta_list ta;
- ta_start(ta, tag, value);
- fail_if(s2_sip_request_to(dialog, SIP_METHOD_BYE, NULL, ta_tags(ta)));
- ta_end(ta);
- fail_unless_event(nua_i_bye, 200);
- fail_unless(s2_check_callstate(nua_callstate_terminated));
- fail_unless(s2_sip_check_response(200, SIP_METHOD_BYE));
- }
- /* ====================================================================== */
- /* 2 - Call cases */
- /* 2.1 - Basic call cases */
- START_TEST(call_2_1_1)
- {
- nua_handle_t *nh;
- S2_CASE("2.1.1", "Basic call",
- "NUA sends INVITE, NUA sends BYE");
- nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor), TAG_END());
- invite_by_nua(nh, TAG_END());
- bye_by_nua(nh, TAG_END());
- nua_handle_destroy(nh);
- }
- END_TEST
- START_TEST(call_2_1_2_1)
- {
- nua_handle_t *nh;
- S2_CASE("2.1.2.1", "Basic call",
- "NUA sends INVITE, NUA receives BYE");
- nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor), TAG_END());
- invite_by_nua(nh, TAG_END());
- bye_to_nua(nh, TAG_END());
- nua_handle_destroy(nh);
- }
- END_TEST
- START_TEST(call_2_1_2_2)
- {
- nua_handle_t *nh;
- S2_CASE("2.1.2.2", "Basic call over TCP",
- "NUA sends INVITE, NUA receives BYE");
- nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor),
- TAG_END());
- invite_by_nua(nh,
- NUTAG_PROXY(s2sip->tcp.contact->m_url),
- TAG_END());
- bye_to_nua(nh, TAG_END());
- nua_handle_destroy(nh);
- }
- END_TEST
- START_TEST(call_2_1_3_1)
- {
- nua_handle_t *nh;
- S2_CASE("2.1.3.1", "Incoming call",
- "NUA receives INVITE and BYE");
- nh = invite_to_nua(TAG_END());
- bye_to_nua(nh, TAG_END());
- nua_handle_destroy(nh);
- }
- END_TEST
- START_TEST(call_2_1_3_2)
- {
- nua_handle_t *nh;
- S2_CASE("2.1.3.2", "Incoming call over TCP",
- "NUA receives INVITE and BYE");
- dialog->tport = s2sip->tcp.tport;
- nh = invite_to_nua(TAG_END());
- bye_to_nua(nh, TAG_END());
- nua_handle_destroy(nh);
- }
- END_TEST
- START_TEST(call_2_1_4)
- {
- nua_handle_t *nh;
- S2_CASE("2.1.4", "Incoming call",
- "NUA receives INVITE and sends BYE");
- nh = invite_to_nua(TAG_END());
- bye_by_nua(nh, TAG_END());
- nua_handle_destroy(nh);
- }
- END_TEST
- START_TEST(call_2_1_5)
- {
- nua_handle_t *nh;
- S2_CASE("2.1.5", "Incoming call",
- "NUA receives INVITE and sends BYE, BYE is challenged");
- nh = invite_to_nua(TAG_END());
- bye_by_nua_challenged(nh, TAG_END());
- nua_handle_destroy(nh);
- }
- END_TEST
- START_TEST(call_2_1_6)
- {
- nua_handle_t *nh;
- struct message *bye;
- struct event *invite;
- struct message *response;
- S2_CASE("2.1.6", "Basic call",
- "NUA received INVITE, "
- "NUA responds (and saves proxy for dialog), "
- "NUA sends BYE");
- soa_generate_offer(soa, 1, NULL);
- request_with_sdp(dialog, SIP_METHOD_INVITE, NULL, TAG_END());
- invite = s2_wait_for_event(nua_i_invite, 100); fail_unless(invite != NULL);
- fail_unless(s2_check_callstate(nua_callstate_received));
- nh = invite->nh;
- fail_if(!nh);
- s2_free_event(invite);
- response = s2_sip_wait_for_response(100, SIP_METHOD_INVITE);
- fail_if(!response);
- nua_respond(nh, SIP_180_RINGING,
- /* Dialog-specific proxy is saved */
- NUTAG_PROXY(s2sip->tcp.contact->m_url),
- SOATAG_USER_SDP_STR("m=audio 5004 RTP/AVP 0 8"),
- TAG_END());
- fail_unless(s2_check_callstate(nua_callstate_early));
- response = s2_sip_wait_for_response(180, SIP_METHOD_INVITE);
- fail_if(!response);
- s2_sip_update_dialog(dialog, response);
- process_answer(response);
- s2_sip_free_message(response);
- nua_respond(nh, SIP_200_OK, TAG_END());
- fail_unless(s2_check_callstate(nua_callstate_completed));
- response = s2_sip_wait_for_response(200, SIP_METHOD_INVITE);
- fail_if(!response);
- s2_sip_update_dialog(dialog, response);
- s2_sip_free_message(response);
- fail_if(s2_sip_request_to(dialog, SIP_METHOD_ACK, NULL, TAG_END()));
- fail_unless_event(nua_i_ack, 200);
- fail_unless(s2_check_callstate(nua_callstate_ready));
- nua_bye(nh, TAG_END());
- bye = s2_sip_wait_for_request(SIP_METHOD_BYE);
- fail_if(!bye);
- /* Check that NUA used dialog-specific proxy with BYE */
- fail_unless(tport_is_tcp(bye->tport));
- s2_sip_respond_to(bye, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(bye);
- fail_unless_event(nua_r_bye, 200);
- fail_unless(s2_check_callstate(nua_callstate_terminated));
- nua_handle_destroy(nh);
- }
- END_TEST
- START_TEST(call_2_1_7)
- {
- nua_handle_t *nh, *nh2;
- sip_replaces_t *replaces;
- S2_CASE("2.1.7", "Call lookup",
- "Test dialog and call-id lookup");
- nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor), TAG_END());
- invite_by_nua(nh, TAG_END());
- nh2 = nua_handle_by_call_id(nua, dialog->call_id->i_id);
- fail_if(!nh2); fail_if(nh != nh2); nua_handle_unref(nh2);
- replaces = sip_replaces_format(NULL, "%s;from-tag=%s;to-tag=%s",
- dialog->call_id->i_id,
- dialog->local->a_tag,
- dialog->remote->a_tag);
- fail_if(!replaces);
- nh2 = nua_handle_by_replaces(nua, replaces);
- fail_if(!nh2); fail_if(nh != nh2); nua_handle_unref(nh2);
- msg_header_free_all(NULL, (msg_header_t *)replaces);
- bye_by_nua(nh, TAG_END());
- nua_handle_destroy(nh);
- }
- END_TEST
- START_TEST(call_2_1_8)
- {
- nua_handle_t *nh;
- struct message *invite, *ack;
- S2_CASE("2.1.8", "Call using NUTAG_PROXY()",
- "Test handle-specific NUTAG_PROXY().");
- nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor), TAG_END());
- invite = invite_sent_by_nua(
- nh, SOATAG_USER_SDP_STR("m=audio 5004 RTP/AVP 0 8"),
- NUTAG_PROXY(s2sip->tcp.contact->m_url), TAG_END());
- process_offer(invite);
- respond_with_sdp(
- invite, dialog, SIP_180_RINGING,
- SIPTAG_CONTENT_DISPOSITION_STR("session;handling=optional"),
- TAG_END());
- fail_unless_event(nua_r_invite, 180);
- fail_unless(s2_check_callstate(nua_callstate_proceeding));
- respond_with_sdp(invite, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(invite);
- fail_unless_event(nua_r_invite, 200);
- fail_unless(s2_check_callstate(nua_callstate_ready));
- ack = s2_sip_wait_for_request(SIP_METHOD_ACK);
- fail_unless(ack && tport_is_tcp(ack->tport));
- bye_by_nua(nh, TAG_END());
- nua_handle_destroy(nh);
- }
- END_TEST
- TCase *invite_tcase(int threading)
- {
- TCase *tc = tcase_create("2.1 - Basic INVITE");
- add_call_fixtures(tc, threading);
- {
- tcase_add_test(tc, call_2_1_1);
- tcase_add_test(tc, call_2_1_2_1);
- tcase_add_test(tc, call_2_1_2_2);
- tcase_add_test(tc, call_2_1_3_1);
- tcase_add_test(tc, call_2_1_3_2);
- tcase_add_test(tc, call_2_1_4);
- tcase_add_test(tc, call_2_1_5);
- tcase_add_test(tc, call_2_1_6);
- tcase_add_test(tc, call_2_1_7);
- tcase_add_test(tc, call_2_1_8);
- }
- return tc;
- }
- /* ---------------------------------------------------------------------- */
- /* 2.2 - Call CANCEL cases */
- START_TEST(cancel_2_2_1)
- {
- nua_handle_t *nh;
- struct message *invite, *cancel;
- S2_CASE("2.2.1", "Cancel call",
- "NUA is caller, NUA sends CANCEL immediately");
- nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor), TAG_END());
- nua_invite(nh, SOATAG_USER_SDP_STR("m=audio 5004 RTP/AVP 0 8"),
- TAG_END());
- fail_unless(s2_check_callstate(nua_callstate_calling));
- nua_cancel(nh, TAG_END());
- invite = s2_sip_wait_for_request(SIP_METHOD_INVITE);
- fail_if(!invite);
- fail_if(s2sip->received != NULL);
- s2_sip_respond_to(invite, dialog, SIP_100_TRYING, TAG_END());
- cancel = s2_sip_wait_for_request(SIP_METHOD_CANCEL);
- fail_if(!cancel);
- s2_sip_respond_to(invite, dialog, SIP_487_REQUEST_CANCELLED, TAG_END());
- s2_sip_respond_to(cancel, dialog, SIP_200_OK, TAG_END());
- fail_unless(s2_sip_check_request(SIP_METHOD_ACK));
- fail_unless_event(nua_r_invite, 487);
- fail_unless(s2_check_callstate(nua_callstate_terminated));
- fail_unless_event(nua_r_cancel, 200);
- fail_if(s2->events != NULL);
- nua_handle_destroy(nh);
- }
- END_TEST
- START_TEST(cancel_2_2_2)
- {
- nua_handle_t *nh;
- struct message *invite;
- S2_CASE("2.2.2", "Canceled call",
- "NUA is caller, NUA sends CANCEL after receiving 100");
- nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor), TAG_END());
- nua_invite(nh, SOATAG_USER_SDP_STR("m=audio 5004 RTP/AVP 0 8"),
- TAG_END());
- fail_unless(s2_check_callstate(nua_callstate_calling));
- invite = s2_sip_wait_for_request(SIP_METHOD_INVITE);
- process_offer(invite);
- s2_sip_respond_to(invite, dialog, SIP_100_TRYING, TAG_END());
- cancel_by_nua(nh, invite, dialog, TAG_END());
- fail_unless(s2_check_callstate(nua_callstate_terminated));
- nua_handle_destroy(nh);
- }
- END_TEST
- START_TEST(cancel_2_2_3)
- {
- nua_handle_t *nh;
- struct message *invite;
- S2_CASE("2.2.3", "Canceled call",
- "NUA is caller, NUA sends CANCEL after receiving 180");
- nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor), TAG_END());
- nua_invite(nh, SOATAG_USER_SDP_STR("m=audio 5004 RTP/AVP 0 8"),
- TAG_END());
- fail_unless(s2_check_callstate(nua_callstate_calling));
- invite = s2_sip_wait_for_request(SIP_METHOD_INVITE);
- process_offer(invite);
- respond_with_sdp(
- invite, dialog, SIP_180_RINGING,
- SIPTAG_CONTENT_DISPOSITION_STR("session;handling=optional"),
- TAG_END());
- fail_unless_event(nua_r_invite, 180);
- fail_unless(s2_check_callstate(nua_callstate_proceeding));
- cancel_by_nua(nh, invite, dialog, TAG_END());
- fail_unless(s2_check_callstate(nua_callstate_terminated));
- nua_handle_destroy(nh);
- }
- END_TEST
- START_TEST(cancel_2_2_4)
- {
- nua_handle_t *nh;
- struct message *invite, *cancel;
- S2_CASE("2.2.4", "Cancel and 200 OK glare",
- "NUA is caller, NUA sends CANCEL after receiving 180 "
- "but UAS already sent 200 OK.");
- nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor), TAG_END());
- nua_invite(nh, SOATAG_USER_SDP_STR("m=audio 5004 RTP/AVP 0 8"),
- TAG_END());
- fail_unless(s2_check_callstate(nua_callstate_calling));
- invite = s2_sip_wait_for_request(SIP_METHOD_INVITE);
- process_offer(invite);
- respond_with_sdp(
- invite, dialog, SIP_180_RINGING,
- SIPTAG_CONTENT_DISPOSITION_STR("session;handling=optional"),
- TAG_END());
- fail_unless_event(nua_r_invite, 180);
- fail_unless(s2_check_callstate(nua_callstate_proceeding));
- nua_cancel(nh, TAG_END());
- cancel = s2_sip_wait_for_request(SIP_METHOD_CANCEL);
- fail_if(!cancel);
- respond_with_sdp(invite, dialog, SIP_200_OK, TAG_END());
- s2_sip_respond_to(cancel, dialog, SIP_481_NO_TRANSACTION, TAG_END());
- s2_sip_free_message(cancel);
- fail_unless_event(nua_r_cancel, 481);
- fail_unless(s2_sip_check_request(SIP_METHOD_ACK));
- fail_unless(s2_check_callstate(nua_callstate_ready));
- bye_by_nua(nh, TAG_END());
- nua_handle_destroy(nh);
- }
- END_TEST
- START_TEST(cancel_2_2_5)
- {
- nua_handle_t *nh;
- struct message *invite, *cancel, *bye;
- S2_CASE(
- "2.2.5", "Cancel and 200 OK glare",
- "NUA is caller, "
- "NUA uses nua_bye() to send CANCEL after receiving 180\n"
- "but UAS already sent 200 OK.\n"
- "Test case checks that NUA really sends BYE after nua_bye() is called\n");
- nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor), TAG_END());
- nua_invite(nh, SOATAG_USER_SDP_STR("m=audio 5004 RTP/AVP 0 8"),
- NUTAG_AUTOACK(0),
- TAG_END());
- fail_unless(s2_check_callstate(nua_callstate_calling));
- invite = s2_sip_wait_for_request(SIP_METHOD_INVITE);
- process_offer(invite);
- respond_with_sdp(
- invite, dialog, SIP_180_RINGING,
- SIPTAG_CONTENT_DISPOSITION_STR("session;handling=optional"),
- TAG_END());
- fail_unless_event(nua_r_invite, 180);
- fail_unless(s2_check_callstate(nua_callstate_proceeding));
- nua_bye(nh, TAG_END());
- cancel = s2_sip_wait_for_request(SIP_METHOD_CANCEL);
- fail_if(!cancel);
- respond_with_sdp(invite, dialog, SIP_200_OK, TAG_END());
- s2_sip_respond_to(cancel, dialog, SIP_481_NO_TRANSACTION, TAG_END());
- s2_sip_free_message(cancel);
- fail_unless_event(nua_r_cancel, 481);
- fail_unless(s2_sip_check_request(SIP_METHOD_ACK));
- fail_unless(s2_check_callstate(nua_callstate_terminating));
- bye = s2_sip_wait_for_request(SIP_METHOD_BYE);
- fail_if(!bye);
- s2_sip_respond_to(bye, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(bye);
- fail_unless_event(nua_r_bye, 200);
- fail_unless(s2_check_callstate(nua_callstate_terminated));
- nua_handle_destroy(nh);
- }
- END_TEST
- START_TEST(cancel_2_2_6)
- {
- nua_handle_t *nh;
- struct event *invite;
- struct message *response;
- S2_CASE("2.2.6", "Cancel call",
- "NUA is callee, sends 100, 180, INVITE gets canceled");
- soa_generate_offer(soa, 1, NULL);
- request_with_sdp(dialog, SIP_METHOD_INVITE, NULL, TAG_END());
- invite = s2_wait_for_event(nua_i_invite, 100); fail_unless(invite != NULL);
- fail_unless(s2_check_callstate(nua_callstate_received));
- nh = invite->nh; fail_if(!nh);
- s2_free_event(invite);
- response = s2_sip_wait_for_response(100, SIP_METHOD_INVITE);
- fail_if(!response);
- nua_respond(nh, SIP_180_RINGING,
- SOATAG_USER_SDP_STR("m=audio 5004 RTP/AVP 0 8"),
- TAG_END());
- fail_unless(s2_check_callstate(nua_callstate_early));
- response = s2_sip_wait_for_response(180, SIP_METHOD_INVITE);
- fail_if(!response);
- s2_sip_update_dialog(dialog, response);
- process_answer(response);
- s2_sip_free_message(response);
- fail_if(s2_sip_request_to(dialog, SIP_METHOD_CANCEL, NULL, TAG_END()));
- fail_unless_event(nua_i_cancel, 200);
- fail_unless(s2_check_callstate(nua_callstate_terminated));
- response = s2_sip_wait_for_response(200, SIP_METHOD_CANCEL);
- fail_if(!response);
- s2_sip_free_message(response);
- response = s2_sip_wait_for_response(487, SIP_METHOD_INVITE);
- fail_if(s2_sip_request_to(dialog, SIP_METHOD_ACK, NULL,
- SIPTAG_VIA(sip_object(dialog->invite)->sip_via),
- TAG_END()));
- nua_handle_destroy(nh);
- }
- END_TEST
- START_TEST(cancel_2_2_7)
- {
- nua_handle_t *nh;
- struct event *invite;
- struct message *response;
- char const *via = "SIP/2.0/UDP host.in.invalid;rport";
- S2_CASE("2.2.7", "Call gets canceled",
- "NUA is callee, sends 100, 180, INVITE gets canceled. "
- "Using RFC 2543 dialog and transaction matching.");
- soa_generate_offer(soa, 1, NULL);
- request_with_sdp(dialog, SIP_METHOD_INVITE, NULL,
- SIPTAG_VIA_STR(via),
- TAG_END());
- invite = s2_wait_for_event(nua_i_invite, 100); fail_unless(invite != NULL);
- fail_unless(s2_check_callstate(nua_callstate_received));
- nh = invite->nh; fail_if(!nh);
- s2_free_event(invite);
- response = s2_sip_wait_for_response(100, SIP_METHOD_INVITE);
- fail_if(!response);
- nua_respond(nh, SIP_180_RINGING,
- SOATAG_USER_SDP_STR("m=audio 5004 RTP/AVP 0 8"),
- TAG_END());
- fail_unless(s2_check_callstate(nua_callstate_early));
- response = s2_sip_wait_for_response(180, SIP_METHOD_INVITE);
- fail_if(!response);
- s2_sip_update_dialog(dialog, response);
- process_answer(response);
- s2_sip_free_message(response);
- fail_if(s2_sip_request_to(dialog, SIP_METHOD_CANCEL, NULL, TAG_END()));
- fail_unless_event(nua_i_cancel, 200);
- fail_unless(s2_check_callstate(nua_callstate_terminated));
- response = s2_sip_wait_for_response(200, SIP_METHOD_CANCEL);
- fail_if(!response);
- s2_sip_free_message(response);
- response = s2_sip_wait_for_response(487, SIP_METHOD_INVITE);
- fail_if(s2_sip_request_to(dialog, SIP_METHOD_ACK, NULL,
- SIPTAG_VIA(sip_object(dialog->invite)->sip_via),
- TAG_END()));
- nua_handle_destroy(nh);
- }
- END_TEST
- START_TEST(cancel_2_2_8)
- {
- nua_handle_t *nh;
- struct message *invite, *cancel;
- int timeout;
- S2_CASE("2.2.8", "CANCEL and INVITE times out",
- "NUA is caller, NUA sends CANCEL after receiving 180 "
- "but UAS never responds.");
- nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor), TAG_END());
- nua_invite(nh, SOATAG_USER_SDP_STR("m=audio 5004 RTP/AVP 0 8"),
- TAG_END());
- fail_unless(s2_check_callstate(nua_callstate_calling));
- invite = s2_sip_wait_for_request(SIP_METHOD_INVITE);
- process_offer(invite);
- respond_with_sdp(
- invite, dialog, SIP_180_RINGING,
- SIPTAG_CONTENT_DISPOSITION_STR("session;handling=optional"),
- TAG_END());
- fail_unless_event(nua_r_invite, 180);
- fail_unless(s2_check_callstate(nua_callstate_proceeding));
- nua_cancel(nh, TAG_END());
- cancel = s2_sip_wait_for_request(SIP_METHOD_CANCEL);
- s2_sip_free_message(cancel);
- fail_if(!cancel);
- /* Now, time out both CANCEL and INVITE */
- for (timeout = 0; timeout < 34; timeout++) {
- s2_nua_fast_forward(1, s2base->root);
- cancel = s2_sip_next_request(SIP_METHOD_CANCEL);
- if (cancel)
- s2_sip_free_message(cancel);
- }
- fail_unless_event(nua_r_cancel, 408);
- fail_unless_event(nua_r_invite, 408);
- fail_unless(s2_check_callstate(nua_callstate_terminated));
- nua_handle_destroy(nh);
- }
- END_TEST
- START_TEST(cancel_2_2_9)
- {
- nua_handle_t *nh;
- struct message *invite, *cancel;
- int timeout;
- S2_CASE("2.2.9", "CANCEL a RFC2543 UA",
- "NUA is caller, NUA sends CANCEL after receiving 180, "
- "UAS sends 200 OK to CANCEL but no response to INVITE.");
- nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor), TAG_END());
- nua_invite(nh, SOATAG_USER_SDP_STR("m=audio 5004 RTP/AVP 0 8"),
- TAG_END());
- fail_unless(s2_check_callstate(nua_callstate_calling));
- invite = s2_sip_wait_for_request(SIP_METHOD_INVITE);
- process_offer(invite);
- respond_with_sdp(
- invite, dialog, SIP_180_RINGING,
- SIPTAG_CONTENT_DISPOSITION_STR("session;handling=optional"),
- TAG_END());
- fail_unless_event(nua_r_invite, 180);
- fail_unless(s2_check_callstate(nua_callstate_proceeding));
- nua_cancel(nh, TAG_END());
- cancel = s2_sip_wait_for_request(SIP_METHOD_CANCEL);
- fail_if(!cancel);
- s2_sip_respond_to(cancel, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(cancel);
- /* Time out INVITE */
- for (timeout = 0; timeout < 34; timeout++) {
- s2_nua_fast_forward(1, s2base->root);
- }
- fail_unless_event(nua_r_invite, 408);
- fail_unless(s2_check_callstate(nua_callstate_terminated));
- nua_handle_destroy(nh);
- }
- END_TEST
- START_TEST(cancel_2_2_10)
- {
- nua_handle_t *nh;
- struct message *invite, *cancel;
- struct event *event;
- int timeout;
- S2_CASE("2.2.10", "CANCEL and INVITE times out",
- "NUA is caller, NUA sends CANCEL after receiving 180 "
- "but UAS never responds.");
- nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor), TAG_END());
- nua_invite(nh, SOATAG_USER_SDP_STR("m=audio 5004 RTP/AVP 0 8"),
- TAG_END());
- fail_unless(s2_check_callstate(nua_callstate_calling));
- invite = s2_sip_wait_for_request(SIP_METHOD_INVITE);
- process_offer(invite);
- respond_with_sdp(
- invite, dialog, SIP_180_RINGING,
- SIPTAG_CONTENT_DISPOSITION_STR("session;handling=optional"),
- TAG_END());
- fail_unless_event(nua_r_invite, 180);
- fail_unless(s2_check_callstate(nua_callstate_proceeding));
- nua_cancel(nh, TAG_END());
- cancel = s2_sip_wait_for_request(SIP_METHOD_CANCEL);
- s2_sip_free_message(cancel);
- fail_if(!cancel);
- nua_cancel(nh, TAG_END());
- cancel = s2_sip_wait_for_request(SIP_METHOD_CANCEL);
- fail_if(!cancel);
- s2_sip_respond_to(cancel, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(cancel);
- /* emulate network gone bad below
- zap registration handle here
- so that s2_register_teardown() does not hang
- */
- s2->registration->nh = NULL;
- nua_set_params(s2->nua, NUTAG_SHUTDOWN_EVENTS(1), TAG_END());
- fail_unless_event(nua_r_set_params, 200);
- nua_shutdown(s2->nua);
- event = s2_wait_for_event(nua_r_shutdown, 100);
- fail_unless(event != NULL);
- s2_free_event(event);
- /* Time out */
- for (timeout = 0; timeout < 34; timeout++) {
- s2_nua_fast_forward(5, s2base->root);
- nua_shutdown(s2->nua);
- event = s2_wait_for_event(nua_r_shutdown, 0);
- fail_unless(event != NULL);
- if (event->data->e_status >= 200)
- break;
- }
- s2->shutdown = 200;
- }
- END_TEST
- TCase *cancel_tcase(int threading)
- {
- TCase *tc = tcase_create("2.2 - CANCEL");
- add_call_fixtures(tc, threading);
- tcase_add_test(tc, cancel_2_2_1);
- tcase_add_test(tc, cancel_2_2_2);
- tcase_add_test(tc, cancel_2_2_3);
- tcase_add_test(tc, cancel_2_2_4);
- if (XXX) tcase_add_test(tc, cancel_2_2_5);
- tcase_add_test(tc, cancel_2_2_6);
- tcase_add_test(tc, cancel_2_2_7);
- tcase_add_test(tc, cancel_2_2_8);
- tcase_add_test(tc, cancel_2_2_9);
- tcase_add_test(tc, cancel_2_2_10);
- return tc;
- }
- /* ---------------------------------------------------------------------- */
- /* 2.3 - Session timers */
- /* Wait for invite from NUA */
- static struct message *
- invite_timer_round(nua_handle_t *nh,
- char const *session_expires,
- sip_record_route_t *rr)
- {
- struct message *invite, *ack;
- fail_unless(s2_check_callstate(nua_callstate_calling));
- invite = s2_sip_wait_for_request(SIP_METHOD_INVITE);
- process_offer(invite);
- /* Check that INVITE contains Session-Expires header with refresher=uac */
- fail_unless(invite->sip->sip_session_expires != NULL);
- fail_unless(su_casematch(invite->sip->sip_session_expires->x_refresher, "uac"));
- respond_with_sdp(
- invite, dialog, SIP_200_OK,
- SIPTAG_SESSION_EXPIRES_STR(session_expires),
- SIPTAG_REQUIRE_STR("timer"),
- SIPTAG_RECORD_ROUTE(rr),
- TAG_END());
- s2_sip_free_message(invite);
- fail_unless_event(nua_r_invite, 200);
- fail_unless(s2_check_callstate(nua_callstate_ready));
- ack = s2_sip_wait_for_request(SIP_METHOD_ACK);
- if (rr == NULL)
- s2_sip_free_message(ack);
- return ack;
- }
- START_TEST(call_2_3_1)
- {
- nua_handle_t *nh;
- sip_record_route_t rr[1];
- struct message *ack;
- sip_record_route_init(rr);
- *rr->r_url = *s2sip->contact->m_url;
- rr->r_url->url_user = "record";
- rr->r_url->url_params = "lr";
- S2_CASE("2.3.1", "Incoming call with call timers",
- "NUA receives INVITE, "
- "activates call timers, "
- "sends re-INVITE twice, "
- "sends BYE.");
- nh = invite_to_nua(
- SIPTAG_SESSION_EXPIRES_STR("300;refresher=uas"),
- SIPTAG_REQUIRE_STR("timer"),
- TAG_END());
- s2_nua_fast_forward(300, s2base->root);
- ack = invite_timer_round(nh, "300;refresher=uac", rr);
- fail_if(ack->sip->sip_route &&
- su_strmatch(ack->sip->sip_route->r_url->url_user, "record"));
- s2_nua_fast_forward(300, s2base->root);
- invite_timer_round(nh, "300;refresher=uac", NULL);
- bye_by_nua(nh, TAG_END());
- nua_handle_destroy(nh);
- }
- END_TEST
- START_TEST(call_2_3_2)
- {
- nua_handle_t *nh;
- S2_CASE("2.3.2", "Incoming call with call timers",
- "NUA receives INVITE, "
- "activates call timers, "
- "sends re-INVITE, "
- "sends BYE.");
- nh = invite_to_nua(
- SIPTAG_SESSION_EXPIRES_STR("300;refresher=uas"),
- SIPTAG_REQUIRE_STR("timer"),
- TAG_END());
- s2_nua_fast_forward(300, s2base->root);
- invite_timer_round(nh, "300;refresher=uac", NULL);
- s2_nua_fast_forward(300, s2base->root);
- invite_timer_round(nh, "300;refresher=uac", NULL);
- bye_by_nua(nh, TAG_END());
- nua_handle_destroy(nh);
- }
- END_TEST
- TCase *session_timer_tcase(int threading)
- {
- TCase *tc = tcase_create("2.3 - Session timers");
- add_call_fixtures(tc, threading);
- {
- tcase_add_test(tc, call_2_3_1);
- tcase_add_test(tc, call_2_3_2);
- }
- return tc;
- }
- /* ====================================================================== */
- /* 2.4 - 100rel */
- START_TEST(call_2_4_1)
- {
- nua_handle_t *nh;
- struct message *invite, *prack, *ack;
- int with_sdp;
- sip_record_route_t rr[1];
- S2_CASE("2.4.1", "Call with 100rel",
- "NUA sends INVITE, "
- "receives 183, sends PRACK, receives 200 for it, "
- "receives 180, sends PRACK, receives 200 for it, "
- "receives 200, send ACK.");
- sip_record_route_init(rr);
- *rr->r_url = *s2sip->contact->m_url;
- rr->r_url->url_user = "record";
- rr->r_url->url_params = "lr";
- nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor), TAG_END());
- invite = invite_sent_by_nua(
- nh, SOATAG_USER_SDP_STR("m=audio 5004 RTP/AVP 0 8"),
- TAG_END());
- process_offer(invite);
- prack = respond_with_100rel(invite, dialog, with_sdp = 1,
- SIP_183_SESSION_PROGRESS,
- SIPTAG_RECORD_ROUTE(rr),
- TAG_END());
- s2_sip_respond_to(prack, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(prack), prack = NULL;
- fail_unless(s2_check_callstate(nua_callstate_proceeding));
- fail_unless_event(nua_r_prack, 200);
- prack = respond_with_100rel(invite, dialog, with_sdp = 0,
- SIP_180_RINGING,
- TAG_END());
- fail_unless(prack->sip->sip_route != NULL);
- fail_unless(su_strmatch(prack->sip->sip_route->r_url->url_user, "record"));
- s2_sip_respond_to(prack, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(prack), prack = NULL;
- fail_unless(s2_check_callstate(nua_callstate_proceeding));
- fail_unless_event(nua_r_prack, 200);
- /* Change the record-route */
- rr->r_url->url_user = "record2";
- s2_sip_respond_to(invite, dialog, SIP_200_OK,
- SIPTAG_RECORD_ROUTE(rr),
- TAG_END());
- s2_sip_free_message(invite);
- fail_unless_event(nua_r_invite, 200);
- fail_unless(s2_check_callstate(nua_callstate_ready));
- ack = s2_sip_wait_for_request(SIP_METHOD_ACK);
- fail_if(!ack);
- fail_unless(su_strmatch(ack->sip->sip_route->r_url->url_user, "record2"));
- s2_sip_free_message(ack);
- bye_to_nua(nh, TAG_END());
- nua_handle_destroy(nh);
- }
- END_TEST
- START_TEST(call_2_4_2)
- {
- nua_handle_t *nh;
- struct message *invite, *prack;
- int with_sdp;
- S2_CASE("2.4.2", "Call with 100rel",
- "NUA sends INVITE, "
- "receives 183, sends PRACK, receives 200 for it, "
- "receives 180, sends PRACK, receives 200 for it, "
- "receives 200, send ACK.");
- nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor), TAG_END());
- invite = invite_sent_by_nua(
- nh,
- NUTAG_MEDIA_ENABLE(0),
- SIPTAG_CONTENT_TYPE_STR("application/sdp"),
- SIPTAG_PAYLOAD_STR(
- "v=0" CRLF
- "o=- 6805647540234172778 5821668777690722690 IN IP4 127.0.0.1" CRLF
- "s=-" CRLF
- "c=IN IP4 127.0.0.1" CRLF
- "m=audio 5004 RTP/AVP 0 8" CRLF),
- TAG_END());
- prack = respond_with_100rel(invite, dialog, with_sdp = 0,
- SIP_183_SESSION_PROGRESS,
- TAG_END());
- s2_sip_respond_to(prack, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(prack), prack = NULL;
- fail_unless(s2_check_callstate(nua_callstate_proceeding));
- fail_unless_event(nua_r_prack, 200);
- prack = respond_with_100rel(invite, dialog, with_sdp = 0,
- SIP_180_RINGING,
- TAG_END());
- s2_sip_respond_to(prack, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(prack), prack = NULL;
- fail_unless(s2_check_callstate(nua_callstate_proceeding));
- fail_unless_event(nua_r_prack, 200);
- s2_sip_respond_to(invite, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(invite);
- fail_unless_event(nua_r_invite, 200);
- fail_unless(s2_check_callstate(nua_callstate_ready));
- fail_unless(s2_sip_check_request(SIP_METHOD_ACK));
- bye_to_nua(nh, TAG_END());
- nua_handle_destroy(nh);
- }
- END_TEST
- START_TEST(call_2_4_3)
- {
- struct message *response;
- S2_CASE("2.4.3", "Call without 100rel",
- "NUA receives INVITE with Required: 100rel, "
- "rejects it with 420");
- nua_set_params(s2->nua,
- SIPTAG_SUPPORTED(SIP_NONE),
- SIPTAG_SUPPORTED_STR("timer"),
- TAG_END());
- fail_unless_event(nua_r_set_params, 200);
- soa_generate_offer(soa, 1, NULL);
- request_with_sdp(dialog, SIP_METHOD_INVITE, NULL,
- SIPTAG_REQUIRE_STR("100rel"),
- TAG_END());
- response = s2_sip_wait_for_response(420, SIP_METHOD_INVITE);
- fail_if(!response);
- fail_if(s2_sip_request_to(dialog, SIP_METHOD_ACK, NULL, TAG_END()));
- }
- END_TEST
- START_TEST(call_2_4_4)
- {
- nua_handle_t *nh;
- struct event *invite;
- struct message *response;
- S2_CASE("2.4.3", "Call without 100rel",
- "NUA receives INVITE with Supported: 100rel, "
- "proceeds normally");
- nua_set_params(s2->nua,
- SIPTAG_SUPPORTED(SIP_NONE),
- SIPTAG_SUPPORTED_STR("timer"),
- TAG_END());
- fail_unless_event(nua_r_set_params, 200);
- soa_generate_offer(soa, 1, NULL);
- request_with_sdp(dialog, SIP_METHOD_INVITE, NULL,
- SIPTAG_SUPPORTED_STR("100rel"),
- TAG_END());
- invite = s2_wait_for_event(nua_i_invite, 100); fail_unless(invite != NULL);
- fail_unless(s2_check_callstate(nua_callstate_received));
- nh = invite->nh; fail_if(!nh);
- s2_free_event(invite);
- response = s2_sip_wait_for_response(100, SIP_METHOD_INVITE);
- fail_if(!response);
- nua_respond(nh, SIP_183_SESSION_PROGRESS,
- SOATAG_USER_SDP_STR("m=audio 5004 RTP/AVP 0 8"),
- TAG_END());
- fail_unless(s2_check_callstate(nua_callstate_early));
- response = s2_sip_wait_for_response(183, SIP_METHOD_INVITE);
- fail_if(!response);
- fail_if(response->sip->sip_require);
- s2_sip_update_dialog(dialog, response);
- process_answer(response);
- s2_sip_free_message(response);
- nua_respond(nh, SIP_200_OK, TAG_END());
- fail_unless(s2_check_callstate(nua_callstate_completed));
- response = s2_sip_wait_for_response(200, SIP_METHOD_INVITE);
- fail_if(!response);
- s2_sip_update_dialog(dialog, response);
- s2_sip_free_message(response);
- fail_if(s2_sip_request_to(dialog, SIP_METHOD_ACK, NULL, TAG_END()));
- fail_unless_event(nua_i_ack, 200);
- fail_unless(s2_check_callstate(nua_callstate_ready));
- bye_to_nua(nh, TAG_END());
- nua_handle_destroy(nh);
- }
- END_TEST
- START_TEST(call_2_4_5)
- {
- nua_handle_t *nh;
- struct message *invite, *prack, *cancel;
- int i;
- int with_sdp;
- sip_from_t *branch1, *branch2;
- /* Testcase for bug FSCORE-338 -
- forked transactions getting canceled and terminated properly. */
- S2_CASE("2.4.5", "Destroy proceeding call with 100rel",
- "NUA sends INVITE, "
- "receives 183, sends PRACK, receives 200 for it, "
- "receives 180, sends PRACK, receives 200 for it, "
- "handle is destroyed.");
- nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor), TAG_END());
- invite = invite_sent_by_nua(
- nh,
- NUTAG_PROXY(s2sip->tcp.contact->m_url),
- NUTAG_MEDIA_ENABLE(0),
- NUTAG_AUTOACK(0),
- SIPTAG_CONTENT_TYPE_STR("application/sdp"),
- SIPTAG_PAYLOAD_STR(
- "v=0" CRLF
- "o=- 6805647540234172778 5821668777690722690 IN IP4 127.0.0.1" CRLF
- "s=-" CRLF
- "c=IN IP4 127.0.0.1" CRLF
- "m=audio 5004 RTP/AVP 0 8" CRLF),
- TAG_END());
- prack = respond_with_100rel(invite, dialog, with_sdp = 0,
- SIP_183_SESSION_PROGRESS,
- SIPTAG_CONTACT(s2sip->tcp.contact),
- TAG_END());
- s2_sip_respond_to(prack, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(prack), prack = NULL;
- fail_unless(s2_check_callstate(nua_callstate_proceeding));
- fail_unless_event(nua_r_prack, 200);
- prack = respond_with_100rel(invite, dialog, with_sdp = 0,
- SIP_180_RINGING,
- SIPTAG_CONTACT(s2sip->tcp.contact),
- TAG_END());
- s2_sip_respond_to(prack, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(prack), prack = NULL;
- fail_unless(s2_check_callstate(nua_callstate_proceeding));
- fail_unless_event(nua_r_prack, 200);
- branch1 = dialog->local;
- branch2 = dialog->local = sip_from_dup(dialog->home, invite->sip->sip_to);
- sip_from_tag(dialog->home, dialog->local, s2_sip_generate_tag(dialog->home));
- nua_handle_destroy(nh), nh = NULL;
- cancel = s2_sip_wait_for_request(SIP_METHOD_CANCEL);
- s2_sip_respond_to(cancel, dialog, SIP_200_OK, TAG_END());
- for (i = 1; i < 4; i++) {
- s2_nua_fast_forward(1, s2base->root);
- }
- s2_sip_respond_to(invite, dialog, SIP_487_REQUEST_CANCELLED, TAG_END());
- fail_unless(s2_sip_check_request(SIP_METHOD_ACK));
- /* Time out requests */
- for (i = 1; i < 128; i++) {
- s2_nua_fast_forward(1, s2base->root);
- }
- }
- END_TEST
- TCase *invite_100rel_tcase(int threading)
- {
- TCase *tc = tcase_create("2.4 - INVITE with 100rel");
- add_call_fixtures(tc, threading);
- {
- tcase_add_test(tc, call_2_4_1);
- tcase_add_test(tc, call_2_4_2);
- tcase_add_test(tc, call_2_4_3);
- tcase_add_test(tc, call_2_4_4);
- tcase_add_test(tc, call_2_4_5);
- }
- return tc;
- }
- /* ====================================================================== */
- /* 2.5 - Call with preconditions */
- START_TEST(call_2_5_1)
- {
- nua_handle_t *nh;
- struct message *invite, *prack, *update;
- int with_sdp;
- S2_CASE("2.5.1", "Call with preconditions",
- "NUA sends INVITE, "
- "receives 183, sends PRACK, receives 200 for it, "
- "sends UPDATE, receives 200 for it, "
- "receives 180, sends PRACK, receives 200 for it, "
- "receives 200, send ACK.");
- nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor), TAG_END());
- invite = invite_sent_by_nua(
- nh, SOATAG_USER_SDP_STR("m=audio 5004 RTP/AVP 0 8"),
- SIPTAG_REQUIRE_STR("precondition"),
- TAG_END());
- process_offer(invite);
- prack = respond_with_100rel(invite, dialog, with_sdp = 1,
- SIP_183_SESSION_PROGRESS,
- TAG_END());
- fail_unless(s2_check_callstate(nua_callstate_proceeding));
- process_offer(prack);
- respond_with_sdp(
- prack, dialog, SIP_200_OK,
- SIPTAG_REQUIRE_STR("100rel"),
- TAG_END());
- s2_sip_free_message(prack), prack = NULL;
- fail_unless_event(nua_r_prack, 200);
- fail_unless(s2_check_callstate(nua_callstate_proceeding));
- update = s2_sip_wait_for_request(SIP_METHOD_UPDATE);
- /* UPDATE sent by stack, stack sends event for it */
- fail_unless(s2_check_callstate(nua_callstate_proceeding));
- process_offer(update);
- respond_with_sdp(
- update, dialog, SIP_200_OK,
- TAG_END());
- s2_sip_free_message(update), update = NULL;
- fail_unless_event(nua_r_update, 200);
- fail_unless(s2_check_callstate(nua_callstate_proceeding));
- prack = respond_with_100rel(invite, dialog, with_sdp = 0,
- SIP_180_RINGING,
- TAG_END());
- s2_sip_respond_to(prack, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(prack), prack = NULL;
- fail_unless(s2_check_callstate(nua_callstate_proceeding));
- fail_unless_event(nua_r_prack, 200);
- s2_sip_respond_to(invite, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(invite);
- fail_unless_event(nua_r_invite, 200);
- fail_unless(s2_check_callstate(nua_callstate_ready));
- fail_unless(s2_sip_check_request(SIP_METHOD_ACK));
- bye_to_nua(nh, TAG_END());
- nua_handle_destroy(nh);
- }
- END_TEST
- START_TEST(call_2_5_2)
- {
- nua_handle_t *nh;
- struct message *invite, *prack, *update;
- sip_rseq_t rs[1];
- sip_rack_t rack[1];
- S2_CASE("2.5.2", "Call with preconditions - send 200 w/ ongoing PRACK ",
- "NUA sends INVITE, "
- "receives 183, sends PRACK, "
- "receives 200 to INVITE, "
- "receives 200 to PRACK, "
- "sends ACK, "
- "sends UPDATE, "
- "receives 200 to UPDATE.");
- nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor), TAG_END());
- invite = invite_sent_by_nua(
- nh,
- SOATAG_USER_SDP_STR("m=audio 5004 RTP/AVP 0 8"),
- SIPTAG_REQUIRE_STR("precondition"),
- NUTAG_APPL_METHOD("PRACK"),
- TAG_END());
- process_offer(invite);
- sip_rseq_init(rs)->rs_response = ++s2_rseq;
- respond_with_sdp(
- invite, dialog, SIP_183_SESSION_PROGRESS,
- SIPTAG_REQUIRE_STR("100rel"),
- SIPTAG_RSEQ(rs),
- TAG_END());
- fail_unless_event(nua_r_invite, 183);
- fail_unless(s2_check_callstate(nua_callstate_proceeding));
- sip_rack_init(rack)->ra_response = s2_rseq;
- rack->ra_cseq = invite->sip->sip_cseq->cs_seq;
- rack->ra_method = invite->sip->sip_cseq->cs_method;
- rack->ra_method_name = invite->sip->sip_cseq->cs_method_name;
- nua_prack(nh, SIPTAG_RACK(rack), TAG_END());
- prack = s2_sip_wait_for_request(SIP_METHOD_PRACK);
- process_offer(prack);
- s2_sip_respond_to(invite, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(invite);
- fail_unless_event(nua_r_invite, 200);
- fail_unless(s2_check_callstate(nua_callstate_completing));
- respond_with_sdp(
- prack, dialog, SIP_200_OK,
- TAG_END());
- s2_sip_free_message(prack), prack = NULL;
- fail_unless_event(nua_r_prack, 200);
- fail_unless(s2_check_callstate(nua_callstate_ready));
- fail_unless(s2_sip_check_request(SIP_METHOD_ACK));
- update = s2_sip_wait_for_request(SIP_METHOD_UPDATE);
- /* UPDATE sent by stack, stack sends event for it */
- fail_unless(s2_check_callstate(nua_callstate_calling));
- process_offer(update);
- respond_with_sdp(
- update, dialog, SIP_200_OK,
- TAG_END());
- s2_sip_free_message(update), update = NULL;
- fail_unless_event(nua_r_update, 200);
- fail_unless(s2_check_callstate(nua_callstate_ready));
- bye_to_nua(nh, TAG_END());
- nua_handle_destroy(nh);
- }
- END_TEST
- START_TEST(call_2_5_3)
- {
- nua_handle_t *nh;
- struct message *invite, *prack, *update;
- sip_rseq_t rs[1];
- sip_rack_t rack[1];
- S2_CASE("2.5.3", "Call with preconditions - send 200 w/ ongoing UPDATE ",
- "NUA sends INVITE, "
- "receives 183, sends PRACK, receives 200 to PRACK, "
- "sends UPDATE, "
- "receives 200 to INVITE, "
- "receives 200 to UPDATE, "
- "sends ACK.");
- nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor), TAG_END());
- invite = invite_sent_by_nua(
- nh,
- SOATAG_USER_SDP_STR("m=audio 5004 RTP/AVP 0 8"),
- SIPTAG_REQUIRE_STR("precondition"),
- NUTAG_APPL_METHOD("PRACK"),
- TAG_END());
- process_offer(invite);
- sip_rseq_init(rs)->rs_response = ++s2_rseq;
- respond_with_sdp(
- invite, dialog, SIP_183_SESSION_PROGRESS,
- SIPTAG_REQUIRE_STR("100rel"),
- SIPTAG_RSEQ(rs),
- TAG_END());
- fail_unless_event(nua_r_invite, 183);
- fail_unless(s2_check_callstate(nua_callstate_proceeding));
- sip_rack_init(rack)->ra_response = s2_rseq;
- rack->ra_cseq = invite->sip->sip_cseq->cs_seq;
- rack->ra_method = invite->sip->sip_cseq->cs_method;
- rack->ra_method_name = invite->sip->sip_cseq->cs_method_name;
- nua_prack(nh, SIPTAG_RACK(rack), TAG_END());
- prack = s2_sip_wait_for_request(SIP_METHOD_PRACK);
- process_offer(prack);
- respond_with_sdp(
- prack, dialog, SIP_200_OK,
- TAG_END());
- s2_sip_free_message(prack), prack = NULL;
- fail_unless_event(nua_r_prack, 200);
- fail_unless(s2_check_callstate(nua_callstate_proceeding));
- update = s2_sip_wait_for_request(SIP_METHOD_UPDATE);
- /* UPDATE sent by stack, stack sends event for it */
- fail_unless(s2_check_callstate(nua_callstate_proceeding));
- s2_sip_respond_to(invite, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(invite);
- fail_unless_event(nua_r_invite, 200);
- fail_unless(s2_check_callstate(nua_callstate_completing));
- process_offer(update);
- respond_with_sdp(
- update, dialog, SIP_200_OK,
- TAG_END());
- s2_sip_free_message(update), update = NULL;
- fail_unless_event(nua_r_update, 200);
- fail_unless(s2_check_callstate(nua_callstate_ready));
- fail_unless(s2_sip_check_request(SIP_METHOD_ACK));
- bye_to_nua(nh, TAG_END());
- nua_handle_destroy(nh);
- }
- END_TEST
- TCase *invite_precondition_tcase(int threading)
- {
- TCase *tc = tcase_create("2.5 - Call with preconditions");
- add_call_fixtures(tc, threading);
- {
- tcase_add_test(tc, call_2_5_1);
- tcase_add_test(tc, call_2_5_2);
- tcase_add_test(tc, call_2_5_3);
- }
- return tc;
- }
- /* ====================================================================== */
- /* 2.6 - Re-INVITEs */
- START_TEST(call_2_6_1)
- {
- nua_handle_t *nh;
- struct message *invite, *ack;
- int i;
- S2_CASE("2.6.1", "Queued re-INVITEs",
- "NUA receives INVITE, "
- "sends re-INVITE twice, "
- "sends BYE.");
- nh = invite_to_nua(TAG_END());
- nua_invite(nh, TAG_END());
- nua_invite(nh, TAG_END());
- for (i = 0; i < 2; i++) {
- fail_unless(s2_check_callstate(nua_callstate_calling));
- invite = s2_sip_wait_for_request(SIP_METHOD_INVITE);
- fail_if(!invite);
- process_offer(invite);
- respond_with_sdp(invite, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(invite);
- ack = s2_sip_wait_for_request(SIP_METHOD_ACK);
- fail_if(!ack);
- s2_sip_free_message(ack);
- fail_unless_event(nua_r_invite, 200);
- fail_unless(s2_check_callstate(nua_callstate_ready));
- }
- bye_by_nua(nh, TAG_END());
- nua_handle_destroy(nh);
- }
- END_TEST
- START_TEST(call_2_6_2)
- {
- nua_handle_t *nh;
- struct message *invite, *ack, *response;
- S2_CASE("2.6.2", "Re-INVITE glare",
- "NUA sends re-INVITE and then receives re-INVITE, "
- "sends BYE.");
- nh = invite_to_nua(TAG_END());
- nua_invite(nh, TAG_END());
- fail_unless(s2_check_callstate(nua_callstate_calling));
- soa_generate_offer(soa, 1, NULL);
- request_with_sdp(dialog, SIP_METHOD_INVITE, NULL, TAG_END());
- invite = s2_sip_wait_for_request(SIP_METHOD_INVITE);
- fail_if(!invite);
- s2_sip_respond_to(invite, dialog, SIP_500_INTERNAL_SERVER_ERROR,
- SIPTAG_RETRY_AFTER_STR("8"),
- TAG_END());
- s2_sip_free_message(invite);
- ack = s2_sip_wait_for_request(SIP_METHOD_ACK);
- fail_if(!ack);
- s2_sip_free_message(ack);
- response = s2_sip_wait_for_response(491, SIP_METHOD_INVITE);
- fail_if(!response);
- fail_if(s2_sip_request_to(dialog, SIP_METHOD_ACK, NULL,
- SIPTAG_VIA(sip_object(dialog->invite)->sip_via),
- TAG_END()));
- s2_sip_free_message(response);
- fail_if(soa_process_reject(soa, NULL) < 0);
- /* We get nua_r_invite with 100 trying (and 500 in sip->sip_status) */
- fail_unless_event(nua_r_invite, 100);
- s2_nua_fast_forward(10, s2base->root);
- fail_unless(s2_check_callstate(nua_callstate_calling));
- invite = s2_sip_wait_for_request(SIP_METHOD_INVITE);
- process_offer(invite);
- respond_with_sdp(invite, dialog, SIP_200_OK, TAG_END());
- fail_unless_event(nua_r_invite, 200);
- fail_unless(s2_check_callstate(nua_callstate_ready));
- ack = s2_sip_wait_for_request(SIP_METHOD_ACK);
- fail_if(!ack);
- s2_sip_free_message(ack);
- bye_by_nua(nh, TAG_END());
- nua_handle_destroy(nh);
- }
- END_TEST
- START_TEST(call_2_6_3)
- {
- nua_handle_t *nh;
- struct message *response;
- S2_CASE("2.6.3", "Handling re-INVITE without SDP gracefully",
- "NUA receives INVITE, "
- "re-INVITE without SDP (w/o NUTAG_REFRESH_WITHOUT_SDP(), "
- "re-INVITE without SDP (using NUTAG_REFRESH_WITHOUT_SDP(), "
- "sends BYE.");
- nh = invite_to_nua(
- TAG_END());
- s2_sip_request_to(dialog, SIP_METHOD_INVITE, NULL,
- SIPTAG_USER_AGENT_STR("evil (evil) evil"),
- TAG_END());
- nua_respond(nh, SIP_200_OK, TAG_END());
- fail_unless(s2_check_callstate(nua_callstate_completed));
- response = s2_sip_wait_for_response(200, SIP_METHOD_INVITE);
- fail_if(!response);
- s2_sip_update_dialog(dialog, response);
- fail_if(!response->sip->sip_content_type);
- s2_sip_free_message(response);
- fail_if(s2_sip_request_to(dialog, SIP_METHOD_ACK, NULL, TAG_END()));
- fail_unless_event(nua_i_ack, 200);
- fail_unless(s2_check_callstate(nua_callstate_ready));
- s2_nua_fast_forward(10, s2base->root);
- nua_set_hparams(nh, NUTAG_REFRESH_WITHOUT_SDP(1), TAG_END());
- fail_unless_event(nua_r_set_params, 200);
- s2_sip_request_to(dialog, SIP_METHOD_INVITE, NULL,
- SIPTAG_USER_AGENT_STR("evil (evil) evil"),
- TAG_END());
- nua_respond(nh, SIP_200_OK, TAG_END());
- fail_unless(s2_check_callstate(nua_callstate_completed));
- response = s2_sip_wait_for_response(200, SIP_METHOD_INVITE);
- fail_if(!response);
- s2_sip_update_dialog(dialog, response);
- fail_if(response->sip->sip_content_type);
- s2_sip_free_message(response);
- fail_if(s2_sip_request_to(dialog, SIP_METHOD_ACK, NULL, TAG_END()));
- fail_unless_event(nua_i_ack, 200);
- fail_unless(s2_check_callstate(nua_callstate_ready));
- bye_by_nua(nh, TAG_END());
- nua_handle_destroy(nh);
- }
- END_TEST
- START_TEST(call_2_6_4)
- {
- nua_handle_t *nh;
- struct message *invite, *ack;
- S2_CASE("2.6.4", "re-INVITEs w/o SDP",
- "NUA sends re-INVITE w/o SDP, "
- "receives SDP w/ offer, "
- "sends ACK w/ answer, "
- "sends BYE.");
- /* Bug reported by Liu Yang 2009-01-11 */
- nh = invite_to_nua(TAG_END());
- nua_invite(nh, SIPTAG_PAYLOAD_STR(""), TAG_END());
- fail_unless(s2_check_callstate(nua_callstate_calling));
- invite = s2_sip_wait_for_request(SIP_METHOD_INVITE);
- fail_if(!invite);
- fail_if(invite->sip->sip_content_type);
- soa_generate_offer(soa, 1, NULL);
- respond_with_sdp(invite, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(invite);
- ack = s2_sip_wait_for_request(SIP_METHOD_ACK);
- fail_if(!ack);
- process_answer(ack);
- s2_sip_free_message(ack);
- fail_unless_event(nua_r_invite, 200);
- fail_unless(s2_check_callstate(nua_callstate_ready));
- bye_by_nua(nh, TAG_END());
- nua_handle_destroy(nh);
- }
- END_TEST
- START_TEST(call_2_6_5)
- {
- nua_handle_t *nh;
- struct event *reinvite;
- struct message *invite, *ack, *response;
- /* Test case for FreeSwitch bugs #SFSIP-135, #SFSIP-137 */
- S2_CASE("2.6.5", "Re-INVITE glare and 500 Retry-After",
- "NUA receives re-INVITE, replies with 200, "
- "sends re-INVITE, gets 500, gets ACK, retrys INVITE,"
- "sends BYE.");
- nh = invite_to_nua(TAG_END());
- soa_generate_offer(soa, 1, NULL);
- request_with_sdp(dialog, SIP_METHOD_INVITE, NULL, TAG_END());
- reinvite = s2_wait_for_event(nua_i_invite, 200); fail_unless(reinvite != NULL);
- fail_unless(s2_check_callstate(nua_callstate_completed));
- response = s2_sip_wait_for_response(200, SIP_METHOD_INVITE);
- fail_if(!response);
- s2_sip_update_dialog(dialog, response);
- process_answer(response);
- s2_sip_free_message(response);
- nua_invite(nh, TAG_END());
- fail_unless(s2_check_callstate(nua_callstate_calling));
- invite = s2_sip_wait_for_request(SIP_METHOD_INVITE);
- fail_if(!invite);
- s2_sip_respond_to(invite, dialog, SIP_500_INTERNAL_SERVER_ERROR,
- SIPTAG_RETRY_AFTER_STR("7"),
- TAG_END());
- s2_sip_free_message(invite);
- ack = s2_sip_wait_for_request(SIP_METHOD_ACK);
- fail_if(!ack);
- s2_sip_free_message(ack);
- /* We get nua_r_invite with 100 trying (and 500 in sip->sip_status) */
- fail_unless_event(nua_r_invite, 100);
- fail_if(s2_sip_request_to(dialog, SIP_METHOD_ACK, NULL, TAG_END()));
- fail_unless_event(nua_i_ack, 200);
- fail_unless(s2_check_callstate(nua_callstate_ready));
- s2_nua_fast_forward(10, s2base->root);
- fail_unless(s2_check_callstate(nua_callstate_calling));
- invite = s2_sip_wait_for_request(SIP_METHOD_INVITE);
- process_offer(invite);
- respond_with_sdp(invite, dialog, SIP_200_OK, TAG_END());
- fail_unless_event(nua_r_invite, 200);
- fail_unless(s2_check_callstate(nua_callstate_ready));
- ack = s2_sip_wait_for_request(SIP_METHOD_ACK);
- fail_if(!ack);
- s2_sip_free_message(ack);
- bye_by_nua(nh, TAG_END());
- nua_handle_destroy(nh);
- }
- END_TEST
- TCase *reinvite_tcase(int threading)
- {
- TCase *tc = tcase_create("2.6 - re-INVITEs");
- add_call_fixtures(tc, threading);
- {
- tcase_add_test(tc, call_2_6_1);
- tcase_add_test(tc, call_2_6_2);
- tcase_add_test(tc, call_2_6_3);
- tcase_add_test(tc, call_2_6_4);
- tcase_add_test(tc, call_2_6_5);
- }
- return tc;
- }
- /* ====================================================================== */
- /* 3.1 - Call error cases */
- START_TEST(call_3_1_1)
- {
- nua_handle_t *nh;
- struct message *invite, *ack;
- S2_CASE("3.1.1", "Call failure", "Call fails with 403 response");
- nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor),
- TAG_END());
- nua_invite(nh, SOATAG_USER_SDP_STR("m=audio 5004 RTP/AVP 0 8"),
- TAG_END());
- fail_unless(s2_check_callstate(nua_callstate_calling));
- invite = s2_sip_wait_for_request(SIP_METHOD_INVITE);
- fail_if(!invite);
- s2_sip_respond_to(invite, NULL, SIP_403_FORBIDDEN,
- SIPTAG_TO_STR("UAS Changed <sip:To@Header.field.invalid>"),
- TAG_END());
- s2_sip_free_message(invite);
- ack = s2_sip_wait_for_request(SIP_METHOD_ACK);
- fail_if(!ack);
- fail_if(strcmp(ack->sip->sip_to->a_display, "UAS Changed"));
- s2_sip_free_message(ack);
- fail_unless_event(nua_r_invite, 403);
- fail_unless(s2_check_callstate(nua_callstate_terminated));
- nua_handle_destroy(nh);
- }
- END_TEST
- START_TEST(call_3_1_2)
- {
- nua_handle_t *nh;
- struct message *invite;
- int i;
- S2_CASE("3.1.2", "Call fails after too many retries",
- "Call fails after 4 times 500 Retry-After");
- nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor),
- NUTAG_RETRY_COUNT(3),
- TAG_END());
- nua_invite(nh, SOATAG_USER_SDP_STR("m=audio 5004 RTP/AVP 0 8"),
- TAG_END());
- for (i = 0;; i++) {
- fail_unless(s2_check_callstate(nua_callstate_calling));
- invite = s2_sip_wait_for_request(SIP_METHOD_INVITE);
- fail_if(!invite);
- s2_sip_respond_to(invite, NULL, SIP_500_INTERNAL_SERVER_ERROR,
- SIPTAG_RETRY_AFTER_STR("5"),
- TAG_END());
- s2_sip_free_message(invite);
- fail_unless(s2_sip_check_request(SIP_METHOD_ACK));
- if (i == 3)
- break;
- fail_unless_event(nua_r_invite, 100);
- s2_nua_fast_forward(5, s2base->root);
- }
- fail_unless_event(nua_r_invite, 500);
- fail_unless(s2_check_callstate(nua_callstate_terminated));
- nua_handle_destroy(nh);
- }
- END_TEST
- START_TEST(call_3_2_1)
- {
- nua_handle_t *nh;
- struct message *invite;
- S2_CASE("3.2.1", "Re-INVITE failure", "Re-INVITE fails with 403 response");
- nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor),
- TAG_END());
- invite_by_nua(nh, TAG_END());
- nua_invite(nh, TAG_END());
- fail_unless(s2_check_callstate(nua_callstate_calling));
- invite = s2_sip_wait_for_request(SIP_METHOD_INVITE);
- fail_if(!invite);
- s2_sip_respond_to(invite, NULL, SIP_403_FORBIDDEN, TAG_END());
- s2_sip_free_message(invite);
- fail_unless(s2_sip_check_request(SIP_METHOD_ACK));
- fail_unless_event(nua_r_invite, 403);
- /* Return to previous state */
- fail_unless(s2_check_callstate(nua_callstate_ready));
- bye_by_nua(nh, TAG_END());
- }
- END_TEST
- START_TEST(call_3_2_2)
- {
- nua_handle_t *nh;
- struct message *invite, *bye;
- int i;
- S2_CASE("3.2.2", "Re-INVITE fails after too many retries",
- "Call fails after 4 times 500 Retry-After");
- nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor),
- NUTAG_RETRY_COUNT(3),
- TAG_END());
- invite_by_nua(nh, TAG_END());
- nua_invite(nh, SOATAG_USER_SDP_STR("m=audio 5004 RTP/AVP 0 8"),
- TAG_END());
- for (i = 0;; i++) {
- fail_unless(s2_check_callstate(nua_callstate_calling));
- invite = s2_sip_wait_for_request(SIP_METHOD_INVITE);
- fail_if(!invite);
- s2_sip_respond_to(invite, NULL, SIP_500_INTERNAL_SERVER_ERROR,
- SIPTAG_RETRY_AFTER_STR("5"),
- TAG_END());
- s2_sip_free_message(invite);
- fail_unless(s2_sip_check_request(SIP_METHOD_ACK));
- if (i == 3)
- break;
- fail_unless_event(nua_r_invite, 100);
- s2_nua_fast_forward(5, s2base->root);
- }
- fail_unless_event(nua_r_invite, 500);
- /* Graceful termination */
- fail_unless(s2_check_callstate(nua_callstate_terminating));
- bye = s2_sip_wait_for_request(SIP_METHOD_BYE);
- fail_if(!bye);
- s2_sip_respond_to(bye, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(bye);
- fail_unless_event(nua_r_bye, 200);
- fail_unless(s2_check_callstate(nua_callstate_terminated));
- nua_handle_destroy(nh);
- }
- END_TEST
- START_TEST(call_3_2_3)
- {
- nua_handle_t *nh;
- struct message *invite;
- S2_CASE("3.2.3", "Re-INVITE failure", "Re-INVITE fails with 491 response");
- nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor),
- TAG_END());
- invite_by_nua(nh, TAG_END());
- nua_invite(nh, TAG_END());
- fail_unless(s2_check_callstate(nua_callstate_calling));
- invite = s2_sip_wait_for_request(SIP_METHOD_INVITE);
- fail_if(!invite);
- s2_sip_respond_to(invite, NULL, SIP_491_REQUEST_PENDING, TAG_END());
- s2_sip_free_message(invite);
- fail_unless(s2_sip_check_request(SIP_METHOD_ACK));
- fail_unless_event(nua_r_invite, 491);
- /* Return to previous state */
- fail_unless(s2_check_callstate(nua_callstate_ready));
- bye_by_nua(nh, TAG_END());
- }
- END_TEST
- TCase *invite_error_tcase(int threading)
- {
- TCase *tc = tcase_create("3 - Call Errors");
- add_call_fixtures(tc, threading);
- {
- tcase_add_test(tc, call_3_1_1);
- tcase_add_test(tc, call_3_1_2);
- tcase_add_test(tc, call_3_2_1);
- tcase_add_test(tc, call_3_2_2);
- tcase_add_test(tc, call_3_2_3);
- tcase_set_timeout(tc, 5);
- }
- return tc;
- }
- /* ====================================================================== */
- /* Weird call termination cases */
- START_TEST(bye_4_1_1)
- {
- nua_handle_t *nh;
- struct message *bye, *r481;
- S2_CASE("4.1.1", "Re-INVITE while terminating",
- "NUA sends BYE, "
- "BYE is challenged, "
- "and NUA is re-INVITEd at the same time.");
- nh = invite_to_nua(TAG_END());
- s2_flush_events();
- nua_bye(nh, TAG_END());
- bye = s2_sip_wait_for_request(SIP_METHOD_BYE);
- fail_if(!bye);
- s2_sip_respond_to(bye, dialog, SIP_407_PROXY_AUTH_REQUIRED,
- SIPTAG_PROXY_AUTHENTICATE_STR(s2_auth_digest_str),
- TAG_END());
- s2_sip_free_message(bye);
- fail_unless_event(nua_r_bye, 407);
- soa_generate_offer(soa, 1, NULL);
- request_with_sdp(dialog, SIP_METHOD_INVITE, NULL, TAG_END());
- do {
- r481 = s2_sip_wait_for_response(0, SIP_METHOD_INVITE);
- }
- while (r481->sip->sip_status->st_status < 200);
- s2_sip_update_dialog(dialog, r481); /* send ACK */
- fail_unless(s2_check_callstate(nua_callstate_terminated));
- nua_handle_destroy(nh);
- }
- END_TEST
- START_TEST(bye_4_1_2)
- {
- nua_handle_t *nh;
- struct message *bye, *r481;
- S2_CASE("4.1.2", "Re-INVITE while terminating",
- "NUA sends BYE, and gets re-INVITEd at same time");
- nh = invite_to_nua(TAG_END());
- s2_flush_events();
- nua_bye(nh, TAG_END());
- bye = s2_sip_wait_for_request(SIP_METHOD_BYE);
- fail_if(!bye);
- request_with_sdp(dialog, SIP_METHOD_INVITE, NULL, TAG_END());
- do {
- r481 = s2_sip_wait_for_response(0, SIP_METHOD_INVITE);
- }
- while (r481->sip->sip_status->st_status < 200);
- s2_sip_update_dialog(dialog, r481); /* send ACK */
- fail_unless(s2_check_callstate(nua_callstate_terminated));
- s2_sip_respond_to(bye, dialog, SIP_200_OK,
- TAG_END());
- s2_sip_free_message(bye);
- fail_unless_event(nua_r_bye, 200);
- nua_handle_destroy(nh);
- }
- END_TEST
- START_TEST(bye_4_1_3)
- {
- nua_handle_t *nh;
- struct message *bye;
- struct event *i_bye;
- S2_CASE("4.1.3", "BYE while terminating",
- "NUA sends BYE and receives BYE");
- nh = invite_to_nua(TAG_END());
- mark_point();
- nua_set_hparams(nh, NUTAG_APPL_METHOD("BYE"), TAG_END());
- fail_unless_event(nua_r_set_params, 200);
- s2_flush_events();
- nua_bye(nh, TAG_END());
- bye = s2_sip_wait_for_request(SIP_METHOD_BYE);
- fail_if(!bye);
- s2_sip_request_to(dialog, SIP_METHOD_BYE, NULL, TAG_END());
- i_bye = s2_wait_for_event(nua_i_bye, 100);
- fail_if(!i_bye);
- nua_respond(nh, 200, "OKOK", NUTAG_WITH(i_bye->data->e_msg), TAG_END());
- s2_sip_respond_to(bye, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(bye);
- fail_unless_event(nua_r_bye, 200);
- fail_unless(s2_check_callstate(nua_callstate_terminated));
- fail_unless(s2_sip_check_response(200, SIP_METHOD_BYE));
- nua_handle_destroy(nh);
- }
- END_TEST
- START_TEST(bye_4_1_4)
- {
- nua_handle_t *nh;
- struct message *bye;
- struct event *i_bye;
- S2_CASE("4.1.4", "Send BYE after BYE has been received",
- "NUA receives BYE, tries to send BYE at same time");
- nh = invite_to_nua(TAG_END());
- mark_point();
- nua_set_hparams(nh, NUTAG_APPL_METHOD("BYE"), TAG_END());
- fail_unless_event(nua_r_set_params, 200);
- s2_flush_events();
- s2_sip_request_to(dialog, SIP_METHOD_BYE, NULL, TAG_END());
- i_bye = s2_wait_for_event(nua_i_bye, 100);
- fail_if(!i_bye);
- nua_bye(nh, TAG_END());
- bye = s2_sip_wait_for_request(SIP_METHOD_BYE);
- fail_if(!bye);
- s2_sip_respond_to(bye, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(bye);
- fail_unless_event(nua_r_bye, 200);
- fail_unless(s2_check_callstate(nua_callstate_terminated));
- nua_respond(nh, 200, "OKOK", NUTAG_WITH(i_bye->data->e_msg), TAG_END());
- fail_unless(s2_sip_check_response(200, SIP_METHOD_BYE));
- nua_handle_destroy(nh);
- }
- END_TEST
- START_TEST(bye_4_1_5)
- {
- nua_handle_t *nh;
- struct message *bye;
- struct event *i_bye;
- S2_CASE("4.1.5", "Send BYE after BYE has been received",
- "NUA receives BYE, tries to send BYE at same time");
- nh = invite_to_nua(TAG_END());
- mark_point();
- nua_set_hparams(nh, NUTAG_APPL_METHOD("BYE"), TAG_END());
- fail_unless_event(nua_r_set_params, 200);
- s2_flush_events();
- s2_sip_request_to(dialog, SIP_METHOD_BYE, NULL, TAG_END());
- i_bye = s2_wait_for_event(nua_i_bye, 100);
- fail_if(!i_bye);
- nua_bye(nh, TAG_END());
- bye = s2_sip_wait_for_request(SIP_METHOD_BYE);
- fail_if(!bye);
- s2_sip_respond_to(bye, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(bye);
- fail_unless_event(nua_r_bye, 200);
- fail_unless(s2_check_callstate(nua_callstate_terminated));
- nua_handle_destroy(nh);
- fail_unless(s2_sip_check_response(200, SIP_METHOD_BYE));
- }
- END_TEST
- START_TEST(bye_4_1_6)
- {
- nua_handle_t *nh;
- struct message *bye, *r486;
- S2_CASE("4.1.6", "Send BYE after INVITE has been received",
- "NUA receives INVITE, sends BYE at same time");
- nh = invite_to_nua(TAG_END());
- nua_set_hparams(nh, NUTAG_AUTOANSWER(0), TAG_END());
- fail_unless_event(nua_r_set_params, 200);
- s2_flush_events();
- request_with_sdp(dialog, SIP_METHOD_INVITE, NULL, TAG_END());
- fail_unless(s2_sip_check_response(100, SIP_METHOD_INVITE));
- nua_bye(nh, TAG_END());
- fail_unless_event(nua_i_invite, 100);
- fail_unless(s2_check_callstate(nua_callstate_received));
- do {
- r486 = s2_sip_wait_for_response(0, SIP_METHOD_INVITE);
- }
- while (r486->sip->sip_status->st_status < 200);
- s2_sip_update_dialog(dialog, r486); /* send ACK */
- fail_unless(r486->sip->sip_status->st_status == 486);
- bye = s2_sip_wait_for_request(SIP_METHOD_BYE);
- fail_if(!bye);
- s2_sip_respond_to(bye, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(bye);
- nua_handle_destroy(nh);
- }
- END_TEST
- START_TEST(bye_4_1_7)
- {
- nua_handle_t *nh;
- struct message *bye, *r486;
- S2_CASE("4.1.7", "Send BYE after INVITE has been received",
- "NUA receives INVITE, sends BYE at same time");
- nh = invite_to_nua(TAG_END());
- nua_set_hparams(nh, NUTAG_AUTOANSWER(0), TAG_END());
- fail_unless_event(nua_r_set_params, 200);
- s2_flush_events();
- request_with_sdp(dialog, SIP_METHOD_INVITE, NULL, TAG_END());
- fail_unless(s2_sip_check_response(100, SIP_METHOD_INVITE));
- nua_bye(nh, TAG_END());
- fail_unless_event(nua_i_invite, 100);
- fail_unless(s2_check_callstate(nua_callstate_received));
- bye = s2_sip_wait_for_request(SIP_METHOD_BYE);
- fail_if(!bye);
- s2_sip_respond_to(bye, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(bye);
- do {
- r486 = s2_sip_wait_for_response(0, SIP_METHOD_INVITE);
- }
- while (r486->sip->sip_status->st_status < 200);
- s2_sip_update_dialog(dialog, r486); /* send ACK */
- fail_unless(r486->sip->sip_status->st_status == 486);
- nua_handle_destroy(nh);
- }
- END_TEST
- START_TEST(bye_4_1_8)
- {
- nua_handle_t *nh;
- struct message *bye, *r486;
- S2_CASE("4.1.8", "BYE followed by response to INVITE",
- "NUA receives INVITE, sends BYE at same time");
- nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor), TAG_END());
- invite_by_nua(nh, NUTAG_AUTOANSWER(0), TAG_END());
- s2_flush_events();
- request_with_sdp(dialog, SIP_METHOD_INVITE, NULL, TAG_END());
- fail_unless(s2_sip_check_response(100, SIP_METHOD_INVITE));
- nua_bye(nh, TAG_END());
- fail_unless_event(nua_i_invite, 100);
- fail_unless(s2_check_callstate(nua_callstate_received));
- nua_respond(nh, SIP_486_BUSY_HERE, TAG_END());
- do {
- r486 = s2_sip_wait_for_response(0, SIP_METHOD_INVITE);
- }
- while (r486->sip->sip_status->st_status < 200);
- s2_sip_update_dialog(dialog, r486); /* send ACK */
- fail_unless(r486->sip->sip_status->st_status == 486);
- bye = s2_sip_wait_for_request(SIP_METHOD_BYE);
- fail_if(!bye);
- s2_sip_respond_to(bye, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(bye);
- nua_handle_destroy(nh);
- }
- END_TEST
- START_TEST(bye_4_1_9)
- {
- nua_handle_t *nh;
- struct message *bye;
- struct event *i_bye;
- S2_CASE("4.1.6", "Send BYE, receive BYE, destroy",
- "NUA sends BYE, receives BYE and handle gets destroyed");
- nh = invite_to_nua(TAG_END());
- mark_point();
- s2_flush_events();
- nua_bye(nh, TAG_END());
- bye = s2_sip_wait_for_request(SIP_METHOD_BYE);
- fail_if(!bye);
- s2_sip_request_to(dialog, SIP_METHOD_BYE, NULL, TAG_END());
- i_bye = s2_wait_for_event(nua_i_bye, 200);
- fail_if(!i_bye);
- s2_free_event(i_bye), i_bye = NULL;
- fail_unless(s2_check_callstate(nua_callstate_terminated));
- fail_unless(s2_sip_check_response(200, SIP_METHOD_BYE));
- nua_handle_destroy(nh);
- mark_point();
- su_root_step(s2base->root, 10);
- su_root_step(s2base->root, 10);
- su_root_step(s2base->root, 10);
- mark_point();
- s2_sip_respond_to(bye, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(bye);
- mark_point();
- while (su_home_check_alloc((su_home_t *)nua, (void *)nh)) {
- su_root_step(s2base->root, 10);
- }
- }
- END_TEST
- START_TEST(bye_4_1_10)
- {
- nua_handle_t *nh;
- struct message *invite, *bye;
- struct event *i_bye;
- S2_CASE("4.1.6", "Send auto-BYE upon receiving 501, receive BYE, destroy",
- "NUA sends BYE, receives BYE and handle gets destroyed");
- nh = invite_to_nua(TAG_END());
- mark_point();
- s2_flush_events();
- nua_invite(nh, TAG_END());
- invite = s2_sip_wait_for_request(SIP_METHOD_INVITE);
- fail_if(!invite);
- s2_sip_respond_to(invite, dialog, SIP_501_NOT_IMPLEMENTED, TAG_END());
- s2_sip_free_message(invite);
- fail_unless(s2_sip_check_request(SIP_METHOD_ACK));
- bye = s2_sip_wait_for_request(SIP_METHOD_BYE);
- fail_if(!bye);
- fail_unless(s2_check_callstate(nua_callstate_calling));
- fail_unless_event(nua_r_invite, 501);
- fail_unless(s2_check_callstate(nua_callstate_terminating));
- s2_sip_request_to(dialog, SIP_METHOD_BYE, NULL, TAG_END());
- i_bye = s2_wait_for_event(nua_i_bye, 200);
- fail_if(!i_bye);
- s2_free_event(i_bye), i_bye = NULL;
- fail_unless(s2_check_callstate(nua_callstate_terminated));
- fail_unless(s2_sip_check_response(200, SIP_METHOD_BYE));
- nua_handle_destroy(nh);
- su_root_step(s2base->root, 10);
- su_root_step(s2base->root, 10);
- su_root_step(s2base->root, 10);
- s2_sip_respond_to(bye, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(bye);
- while (su_home_check_alloc((su_home_t *)nua, (void *)nh)) {
- su_root_step(s2base->root, 10);
- }
- }
- END_TEST
- START_TEST(bye_4_1_11)
- {
- nua_handle_t *nh;
- struct message *invite, *ack;
- struct event *i_bye;
- S2_CASE("4.1.11", "Receive BYE in completing state",
- "NUA sends INVITE, receives 200, receives BYE.");
- nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor), TAG_END());
- invite = invite_sent_by_nua(nh, NUTAG_AUTOACK(0), TAG_END());
- process_offer(invite);
- s2_sip_respond_to(invite, dialog, SIP_180_RINGING, TAG_END());
- fail_unless_event(nua_r_invite, 180);
- fail_unless(s2_check_callstate(nua_callstate_proceeding));
- respond_with_sdp(invite, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(invite);
- fail_unless_event(nua_r_invite, 200);
- fail_unless(s2_check_callstate(nua_callstate_completing));
- s2_sip_request_to(dialog, SIP_METHOD_BYE, NULL, TAG_END());
- i_bye = s2_wait_for_event(nua_i_bye, 200);
- fail_if(!i_bye);
- s2_free_event(i_bye), i_bye = NULL;
- fail_unless(s2_check_callstate(nua_callstate_terminated));
- fail_unless(s2_sip_check_response(200, SIP_METHOD_BYE));
- ack = s2_sip_wait_for_request(SIP_METHOD_ACK);
- fail_if(!ack);
- s2_sip_free_message(ack);
- nua_handle_destroy(nh);
- }
- END_TEST
- START_TEST(bye_4_2_1)
- {
- nua_handle_t *nh;
- struct message *bye;
- S2_CASE("4.2.1", "BYE in progress while call timer expires",
- "NUA receives INVITE, "
- "activates call timers, "
- "sends BYE, BYE challenged, "
- "waits until session expires.");
- nh = invite_to_nua(
- SIPTAG_SESSION_EXPIRES_STR("300;refresher=uas"),
- SIPTAG_REQUIRE_STR("timer"),
- TAG_END());
- s2_nua_fast_forward(300, s2base->root);
- invite_timer_round(nh, "300", NULL);
- nua_bye(nh, TAG_END());
- bye = s2_sip_wait_for_request(SIP_METHOD_BYE);
- fail_if(!bye);
- s2_sip_respond_to(bye, dialog, SIP_407_PROXY_AUTH_REQUIRED,
- SIPTAG_PROXY_AUTHENTICATE_STR(s2_auth_digest_str),
- TAG_END());
- s2_sip_free_message(bye);
- fail_unless_event(nua_r_bye, 407);
- s2_nua_fast_forward(300, s2base->root);
- nua_authenticate(nh, NUTAG_AUTH("Digest:\"s2test\":abc:abc"), TAG_END());
- bye = s2_sip_wait_for_request(SIP_METHOD_BYE);
- fail_if(!bye);
- s2_sip_respond_to(bye, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(bye);
- fail_unless_event(nua_r_bye, 200);
- fail_unless(s2_check_callstate(nua_callstate_terminated));
- fail_if(s2->events);
- nua_handle_destroy(nh);
- }
- END_TEST
- START_TEST(bye_4_2_2)
- {
- nua_handle_t *nh;
- struct message *bye;
- S2_CASE("4.2.2", "BYE in progress while call timer expires",
- "NUA receives INVITE, "
- "activates call timers, "
- "sends BYE, BYE challenged, "
- "waits until session expires.");
- nh = invite_to_nua(
- SIPTAG_SESSION_EXPIRES_STR("300;refresher=uas"),
- SIPTAG_REQUIRE_STR("timer"),
- TAG_END());
- s2_nua_fast_forward(300, s2base->root);
- invite_timer_round(nh, "300", NULL);
- s2_nua_fast_forward(140, s2base->root);
- nua_bye(nh, TAG_END());
- bye = s2_sip_wait_for_request(SIP_METHOD_BYE);
- fail_if(!bye);
- s2_sip_respond_to(bye, dialog, SIP_407_PROXY_AUTH_REQUIRED,
- SIPTAG_PROXY_AUTHENTICATE_STR(s2_auth_digest_str),
- TAG_END());
- s2_sip_free_message(bye);
- fail_unless_event(nua_r_bye, 407);
- s2_nua_fast_forward(160, s2base->root);
- nua_authenticate(nh, NUTAG_AUTH(s2_auth_credentials), TAG_END());
- bye = s2_sip_wait_for_request(SIP_METHOD_BYE);
- fail_if(!bye);
- s2_sip_respond_to(bye, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(bye);
- fail_unless_event(nua_r_bye, 200);
- fail_unless(s2_check_callstate(nua_callstate_terminated));
- fail_if(s2->events);
- nua_handle_destroy(nh);
- }
- END_TEST
- TCase *termination_tcase(int threading)
- {
- TCase *tc = tcase_create("4 - Call Termination");
- add_call_fixtures(tc, threading);
- {
- tcase_add_test(tc, bye_4_1_1);
- tcase_add_test(tc, bye_4_1_2);
- tcase_add_test(tc, bye_4_1_3);
- tcase_add_test(tc, bye_4_1_4);
- tcase_add_test(tc, bye_4_1_5);
- tcase_add_test(tc, bye_4_1_6);
- tcase_add_test(tc, bye_4_1_7);
- tcase_add_test(tc, bye_4_1_8);
- tcase_add_test(tc, bye_4_1_9);
- tcase_add_test(tc, bye_4_1_10);
- tcase_add_test(tc, bye_4_1_11);
- tcase_add_test(tc, bye_4_2_1);
- tcase_add_test(tc, bye_4_2_2);
- tcase_set_timeout(tc, 5);
- }
- return tc;
- }
- /* ====================================================================== */
- START_TEST(destroy_4_3_1)
- {
- nua_handle_t *nh;
- struct message *invite, *cancel;
- S2_CASE("4.3.1", "Destroy handle after INVITE sent",
- "NUA sends INVITE, handle gets destroyed.");
- nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor), TAG_END());
- invite = invite_sent_by_nua(nh, TAG_END());
- process_offer(invite);
- nua_handle_destroy(nh);
- s2_sip_respond_to(invite, dialog, SIP_100_TRYING, TAG_END());
- cancel = s2_sip_wait_for_request(SIP_METHOD_CANCEL);
- fail_if(!cancel);
- s2_sip_respond_to(invite, dialog, SIP_487_REQUEST_CANCELLED, TAG_END());
- s2_sip_free_message(invite);
- s2_sip_respond_to(cancel, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(cancel);
- }
- END_TEST
- START_TEST(destroy_4_3_2)
- {
- nua_handle_t *nh;
- struct message *invite, *cancel;
- S2_CASE("4.3.2", "Destroy handle in calling state",
- "NUA sends INVITE, receives 180, handle gets destroyed.");
- nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor), TAG_END());
- invite = invite_sent_by_nua(nh, TAG_END());
- process_offer(invite);
- s2_sip_respond_to(invite, dialog, SIP_180_RINGING, TAG_END());
- fail_unless_event(nua_r_invite, 180);
- fail_unless(s2_check_callstate(nua_callstate_proceeding));
- nua_handle_destroy(nh);
- cancel = s2_sip_wait_for_request(SIP_METHOD_CANCEL);
- fail_if(!cancel);
- s2_sip_respond_to(invite, dialog, SIP_487_REQUEST_CANCELLED, TAG_END());
- s2_sip_free_message(invite);
- s2_sip_respond_to(cancel, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(cancel);
- }
- END_TEST
- START_TEST(destroy_4_3_3)
- {
- nua_handle_t *nh;
- struct message *invite, *ack, *bye;
- S2_CASE("4.3.3", "Destroy handle in completing state",
- "NUA sends INVITE, receives 200, handle gets destroyed.");
- nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor), TAG_END());
- invite = invite_sent_by_nua(nh, NUTAG_AUTOACK(0), TAG_END());
- process_offer(invite);
- s2_sip_respond_to(invite, dialog, SIP_180_RINGING, TAG_END());
- fail_unless_event(nua_r_invite, 180);
- fail_unless(s2_check_callstate(nua_callstate_proceeding));
- respond_with_sdp(invite, dialog, SIP_200_OK, TAG_END());
- fail_unless_event(nua_r_invite, 200);
- fail_unless(s2_check_callstate(nua_callstate_completing));
- nua_handle_destroy(nh);
- ack = s2_sip_wait_for_request(SIP_METHOD_ACK);
- fail_if(!ack);
- s2_sip_free_message(ack);
- bye = s2_sip_wait_for_request(SIP_METHOD_BYE);
- fail_if(!bye);
- s2_sip_respond_to(bye, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(bye);
- s2_sip_free_message(invite);
- }
- END_TEST
- START_TEST(destroy_4_3_4)
- {
- nua_handle_t *nh;
- struct message *invite, *ack, *bye;
- S2_CASE("4.3.3", "Destroy handle in ready state ",
- "NUA sends INVITE, receives 200, handle gets destroyed.");
- nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor), TAG_END());
- invite = invite_sent_by_nua(nh, NUTAG_AUTOACK(0), TAG_END());
- process_offer(invite);
- s2_sip_respond_to(invite, dialog, SIP_180_RINGING, TAG_END());
- fail_unless_event(nua_r_invite, 180);
- fail_unless(s2_check_callstate(nua_callstate_proceeding));
- respond_with_sdp(invite, dialog, SIP_200_OK, TAG_END());
- fail_unless_event(nua_r_invite, 200);
- fail_unless(s2_check_callstate(nua_callstate_completing));
- nua_ack(nh, TAG_END());
- ack = s2_sip_wait_for_request(SIP_METHOD_ACK);
- fail_if(!ack);
- s2_sip_free_message(ack);
- fail_unless(s2_check_callstate(nua_callstate_ready));
- nua_handle_destroy(nh);
- bye = s2_sip_wait_for_request(SIP_METHOD_BYE);
- fail_if(!bye);
- s2_sip_respond_to(bye, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(bye);
- s2_sip_free_message(invite);
- }
- END_TEST
- START_TEST(destroy_4_3_5)
- {
- nua_handle_t *nh;
- struct message *invite, *cancel;
- S2_CASE("4.3.5", "Destroy handle in re-INVITE calling state",
- "NUA sends re-INVITE, handle gets destroyed.");
- nh = invite_to_nua(TAG_END());
- invite = invite_sent_by_nua(nh, TAG_END());
- process_offer(invite);
- nua_handle_destroy(nh);
- s2_sip_respond_to(invite, dialog, SIP_100_TRYING, TAG_END());
- cancel = s2_sip_wait_for_request(SIP_METHOD_CANCEL);
- fail_if(!cancel);
- s2_sip_respond_to(invite, dialog, SIP_487_REQUEST_CANCELLED, TAG_END());
- s2_sip_free_message(invite);
- s2_sip_respond_to(cancel, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(cancel);
- }
- END_TEST
- START_TEST(destroy_4_3_6)
- {
- nua_handle_t *nh;
- struct message *invite, *cancel;
- S2_CASE("4.3.6", "Destroy handle in calling state of re-INVITE",
- "NUA sends re-INVITE, receives 180, handle gets destroyed.");
- nh = invite_to_nua(TAG_END());
- invite = invite_sent_by_nua(nh, TAG_END());
- process_offer(invite);
- s2_sip_respond_to(invite, dialog, SIP_180_RINGING, TAG_END());
- fail_unless_event(nua_r_invite, 180);
- fail_unless(s2_check_callstate(nua_callstate_proceeding));
- nua_handle_destroy(nh);
- cancel = s2_sip_wait_for_request(SIP_METHOD_CANCEL);
- fail_if(!cancel);
- s2_sip_respond_to(invite, dialog, SIP_487_REQUEST_CANCELLED, TAG_END());
- s2_sip_free_message(invite);
- s2_sip_respond_to(cancel, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(cancel);
- }
- END_TEST
- START_TEST(destroy_4_3_7)
- {
- nua_handle_t *nh;
- struct message *invite, *ack, *bye;
- S2_CASE("4.3.7", "Destroy handle in completing state of re-INVITE",
- "NUA sends INVITE, receives 200, handle gets destroyed.");
- nh = invite_to_nua(TAG_END());
- invite = invite_sent_by_nua(nh, NUTAG_AUTOACK(0), TAG_END());
- process_offer(invite);
- s2_sip_respond_to(invite, dialog, SIP_180_RINGING, TAG_END());
- fail_unless_event(nua_r_invite, 180);
- fail_unless(s2_check_callstate(nua_callstate_proceeding));
- respond_with_sdp(invite, dialog, SIP_200_OK, TAG_END());
- fail_unless_event(nua_r_invite, 200);
- fail_unless(s2_check_callstate(nua_callstate_completing));
- nua_handle_destroy(nh);
- ack = s2_sip_wait_for_request(SIP_METHOD_ACK);
- fail_if(!ack);
- s2_sip_free_message(ack);
- bye = s2_sip_wait_for_request(SIP_METHOD_BYE);
- fail_if(!bye);
- s2_sip_respond_to(bye, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(bye);
- s2_sip_free_message(invite);
- }
- END_TEST
- START_TEST(destroy_4_3_8)
- {
- nua_handle_t *nh;
- struct message *invite, *ack, *bye;
- S2_CASE("4.3.8", "Destroy handle after INVITE sent",
- "NUA sends INVITE, handle gets destroyed, "
- "but remote end returns 200 OK. "
- "Make sure nua tries to release call properly.");
- nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor), TAG_END());
- invite = invite_sent_by_nua(nh, TAG_END());
- process_offer(invite);
- nua_handle_destroy(nh);
- respond_with_sdp(invite, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(invite);
- ack = s2_sip_wait_for_request(SIP_METHOD_ACK);
- fail_if(!ack);
- s2_sip_free_message(ack);
- bye = s2_sip_wait_for_request(SIP_METHOD_BYE);
- fail_if(!bye);
- s2_sip_respond_to(bye, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(bye);
- }
- END_TEST
- START_TEST(destroy_4_3_9)
- {
- nua_handle_t *nh;
- struct message *invite, *cancel, *ack, *bye;
- S2_CASE("4.3.9", "Destroy handle in calling state",
- "NUA sends INVITE, receives 180, handle gets destroyed, "
- "but remote end returns 200 OK. "
- "Make sure nua tries to release call properly.");
- nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor), TAG_END());
- invite = invite_sent_by_nua(nh, TAG_END());
- process_offer(invite);
- s2_sip_respond_to(invite, dialog, SIP_180_RINGING, TAG_END());
- fail_unless_event(nua_r_invite, 180);
- fail_unless(s2_check_callstate(nua_callstate_proceeding));
- nua_handle_destroy(nh);
- cancel = s2_sip_wait_for_request(SIP_METHOD_CANCEL);
- fail_if(!cancel);
- s2_sip_respond_to(cancel, dialog, SIP_481_NO_TRANSACTION, TAG_END());
- s2_sip_free_message(cancel);
- respond_with_sdp(invite, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(invite);
- ack = s2_sip_wait_for_request(SIP_METHOD_ACK);
- fail_if(!ack);
- s2_sip_free_message(ack);
- bye = s2_sip_wait_for_request(SIP_METHOD_BYE);
- fail_if(!bye);
- s2_sip_respond_to(bye, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(bye);
- }
- END_TEST
- START_TEST(destroy_4_4_1)
- {
- nua_handle_t *nh;
- struct event *invite;
- struct message *response;
- S2_CASE("4.4.1", "Destroy handle while call is on-going",
- "NUA is callee, sends 100, destroys handle");
- soa_generate_offer(soa, 1, NULL);
- request_with_sdp(dialog, SIP_METHOD_INVITE, NULL, TAG_END());
- invite = s2_wait_for_event(nua_i_invite, 100); fail_unless(invite != NULL);
- fail_unless(s2_check_callstate(nua_callstate_received));
- nh = invite->nh; fail_if(!nh);
- s2_free_event(invite);
- response = s2_sip_wait_for_response(100, SIP_METHOD_INVITE);
- fail_if(!response);
- s2_sip_free_message(response);
- nua_handle_destroy(nh);
- response = s2_sip_wait_for_response(480, SIP_METHOD_INVITE);
- fail_if(!response);
- fail_if(s2_sip_request_to(dialog, SIP_METHOD_ACK, NULL,
- SIPTAG_VIA(sip_object(dialog->invite)->sip_via),
- TAG_END()));
- s2_sip_free_message(response);
- }
- END_TEST
- START_TEST(destroy_4_4_2)
- {
- nua_handle_t *nh;
- struct event *invite;
- struct message *response;
- S2_CASE("4.4.1", "Destroy handle while call is on-going",
- "NUA is callee, sends 180, destroys handle");
- soa_generate_offer(soa, 1, NULL);
- request_with_sdp(dialog, SIP_METHOD_INVITE, NULL, TAG_END());
- invite = s2_wait_for_event(nua_i_invite, 100); fail_unless(invite != NULL);
- fail_unless(s2_check_callstate(nua_callstate_received));
- nh = invite->nh; fail_if(!nh);
- s2_free_event(invite);
- response = s2_sip_wait_for_response(100, SIP_METHOD_INVITE);
- fail_if(!response);
- s2_sip_free_message(response);
- nua_respond(nh, SIP_180_RINGING, TAG_END());
- response = s2_sip_wait_for_response(180, SIP_METHOD_INVITE);
- fail_if(!response);
- s2_sip_free_message(response);
- nua_handle_destroy(nh);
- response = s2_sip_wait_for_response(480, SIP_METHOD_INVITE);
- fail_if(!response);
- fail_if(s2_sip_request_to(dialog, SIP_METHOD_ACK, NULL,
- SIPTAG_VIA(sip_object(dialog->invite)->sip_via),
- TAG_END()));
- s2_sip_free_message(response);
- }
- END_TEST
- START_TEST(destroy_4_4_3_1)
- {
- nua_handle_t *nh;
- struct event *invite;
- struct message *response, *bye;
- S2_CASE("4.4.3.1", "Destroy handle while call is on-going",
- "NUA is callee, sends 200, destroys handle");
- soa_generate_offer(soa, 1, NULL);
- request_with_sdp(dialog, SIP_METHOD_INVITE, NULL, TAG_END());
- invite = s2_wait_for_event(nua_i_invite, 100); fail_unless(invite != NULL);
- fail_unless(s2_check_callstate(nua_callstate_received));
- nh = invite->nh; fail_if(!nh);
- s2_free_event(invite);
- response = s2_sip_wait_for_response(100, SIP_METHOD_INVITE);
- fail_if(!response);
- s2_sip_free_message(response);
- nua_respond(nh, SIP_180_RINGING,
- SOATAG_USER_SDP_STR("m=audio 5004 RTP/AVP 0 8"),
- TAG_END());
- response = s2_sip_wait_for_response(180, SIP_METHOD_INVITE);
- fail_if(!response);
- s2_sip_free_message(response);
- fail_unless(s2_check_callstate(nua_callstate_early));
- nua_respond(nh, SIP_200_OK, TAG_END());
- fail_unless(s2_check_callstate(nua_callstate_completed));
- response = s2_sip_wait_for_response(200, SIP_METHOD_INVITE);
- fail_if(!response);
- nua_handle_destroy(nh);
- fail_if(s2_sip_request_to(dialog, SIP_METHOD_ACK, NULL,
- SIPTAG_VIA(sip_object(dialog->invite)->sip_via),
- TAG_END()));
- s2_sip_free_message(response);
- bye = s2_sip_wait_for_request(SIP_METHOD_BYE);
- fail_if(!bye);
- s2_sip_respond_to(bye, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(bye);
- }
- END_TEST
- START_TEST(destroy_4_4_3_2)
- {
- nua_handle_t *nh;
- struct event *invite;
- struct message *response, *bye;
- S2_CASE("4.4.3.1", "Destroy handle while call is on-going",
- "NUA is callee, sends 200, destroys handle");
- soa_generate_offer(soa, 1, NULL);
- request_with_sdp(dialog, SIP_METHOD_INVITE, NULL, TAG_END());
- invite = s2_wait_for_event(nua_i_invite, 100); fail_unless(invite != NULL);
- fail_unless(s2_check_callstate(nua_callstate_received));
- nh = invite->nh; fail_if(!nh);
- s2_free_event(invite);
- response = s2_sip_wait_for_response(100, SIP_METHOD_INVITE);
- fail_if(!response);
- s2_sip_free_message(response);
- nua_respond(nh, SIP_180_RINGING,
- SOATAG_USER_SDP_STR("m=audio 5004 RTP/AVP 0 8"),
- TAG_END());
- response = s2_sip_wait_for_response(180, SIP_METHOD_INVITE);
- fail_if(!response);
- s2_sip_free_message(response);
- fail_unless(s2_check_callstate(nua_callstate_early));
- nua_respond(nh, SIP_200_OK, TAG_END());
- fail_unless(s2_check_callstate(nua_callstate_completed));
- response = s2_sip_wait_for_response(200, SIP_METHOD_INVITE);
- fail_if(!response);
- nua_handle_destroy(nh);
- bye = s2_sip_wait_for_request(SIP_METHOD_BYE);
- fail_if(!bye);
- s2_sip_respond_to(bye, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(bye);
- fail_if(s2_sip_request_to(dialog, SIP_METHOD_ACK, NULL,
- SIPTAG_VIA(sip_object(dialog->invite)->sip_via),
- TAG_END()));
- s2_sip_free_message(response);
- }
- END_TEST
- static TCase *destroy_tcase(int threading)
- {
- TCase *tc = tcase_create("4.3 - Destroying Handle");
- add_call_fixtures(tc, threading);
- {
- tcase_add_test(tc, destroy_4_3_1);
- tcase_add_test(tc, destroy_4_3_2);
- tcase_add_test(tc, destroy_4_3_3);
- tcase_add_test(tc, destroy_4_3_4);
- tcase_add_test(tc, destroy_4_3_5);
- tcase_add_test(tc, destroy_4_3_6);
- tcase_add_test(tc, destroy_4_3_7);
- if (XXX) {
- tcase_add_test(tc, destroy_4_3_8);
- tcase_add_test(tc, destroy_4_3_9);
- }
- tcase_add_test(tc, destroy_4_4_1);
- tcase_add_test(tc, destroy_4_4_2);
- tcase_add_test(tc, destroy_4_4_3_1);
- tcase_add_test(tc, destroy_4_4_3_2);
- tcase_set_timeout(tc, 5);
- }
- return tc;
- }
- /* ====================================================================== */
- static void options_setup(void), options_teardown(void);
- START_TEST(options_5_1_1)
- {
- struct event *options;
- nua_handle_t *nh;
- struct message *response;
- S2_CASE("5.1.1", "Test nua_respond() API",
- "Test nua_respond() API with OPTIONS.");
- s2_sip_request_to(dialog, SIP_METHOD_OPTIONS, NULL, TAG_END());
- options = s2_wait_for_event(nua_i_options, 200);
- fail_unless(options != NULL);
- nh = options->nh; fail_if(!nh);
- response = s2_sip_wait_for_response(200, SIP_METHOD_OPTIONS);
- fail_if(!response);
- s2_sip_free_message(response);
- nua_handle_destroy(nh);
- nua_set_params(nua, NUTAG_APPL_METHOD("OPTIONS"), TAG_END());
- fail_unless_event(nua_r_set_params, 200);
- s2_sip_request_to(dialog, SIP_METHOD_OPTIONS, NULL, TAG_END());
- options = s2_wait_for_event(nua_i_options, 100);
- fail_unless(options != NULL);
- nh = options->nh; fail_if(!nh);
- nua_respond(nh, 202, "okok", NUTAG_WITH_SAVED(options->event), TAG_END());
- response = s2_sip_wait_for_response(202, SIP_METHOD_OPTIONS);
- fail_if(!response);
- s2_sip_free_message(response);
- nua_handle_destroy(nh);
- }
- END_TEST
- #if HAVE_LIBPTHREAD
- #include <pthread.h>
- void *respond_to_options(void *arg)
- {
- struct event *options = (struct event *)arg;
- nua_respond(options->nh, 202, "ok ok",
- NUTAG_WITH_SAVED(options->event),
- TAG_END());
- pthread_exit(arg);
- return NULL;
- }
- START_TEST(options_5_1_2)
- {
- struct event *options;
- nua_handle_t *nh;
- struct message *response;
- pthread_t tid;
- void *thread_return = NULL;
- S2_CASE("5.1.2", "Test nua_respond() API with another thread",
- "Test multithreading nua_respond() API with OPTIONS.");
- nua_set_params(nua, NUTAG_APPL_METHOD("OPTIONS"), TAG_END());
- fail_unless_event(nua_r_set_params, 200);
- s2_sip_request_to(dialog, SIP_METHOD_OPTIONS, NULL, TAG_END());
- options = s2_wait_for_event(nua_i_options, 100);
- fail_unless(options != NULL);
- nh = options->nh; fail_if(!nh);
- fail_if(pthread_create(&tid, NULL, respond_to_options, (void *)options));
- pthread_join(tid, &thread_return);
- fail_unless(thread_return == (void *)options);
- response = s2_sip_wait_for_response(202, SIP_METHOD_OPTIONS);
- fail_if(!response);
- s2_sip_free_message(response);
- nua_handle_destroy(nh);
- }
- END_TEST
- #else
- START_TEST(options_5_1_2)
- {
- }
- END_TEST
- #endif
- TCase *options_tcase(int threading)
- {
- TCase *tc = tcase_create("5 - OPTIONS, etc");
- tcase_add_checked_fixture(tc, options_setup, options_teardown);
- tcase_add_test(tc, options_5_1_1);
- tcase_add_test(tc, options_5_1_2);
- return tc;
- }
- static void options_setup(void)
- {
- s2_nua_thread = 1;
- call_setup();
- }
- static void options_teardown(void)
- {
- s2_teardown_started("options");
- call_teardown();
- }
- /* ====================================================================== */
- /* Test cases for REFER */
- START_TEST(refer_5_2_1)
- {
- nua_handle_t *nh;
- sip_refer_to_t r[1];
- struct event *refer;
- struct message *notify;
- S2_CASE("5.2.1", "Receive REFER",
- "Make a call, receive REFER.");
- nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor), TAG_END());
- invite_by_nua(nh, TAG_END());
- *sip_refer_to_init(r)->r_url = *s2sip->aor->a_url;
- r->r_url->url_user = "bob2";
- s2_sip_request_to(dialog, SIP_METHOD_REFER, NULL,
- SIPTAG_REFER_TO(r),
- TAG_END());
- refer = s2_wait_for_event(nua_i_refer, 202);
- bye_by_nua(nh, TAG_END());
- nua_handle_destroy(nh);
- notify = s2_sip_wait_for_request(SIP_METHOD_NOTIFY);
- s2_sip_respond_to(notify, dialog, SIP_200_OK, TAG_END());
- }
- END_TEST
- START_TEST(refer_5_2_2)
- {
- nua_handle_t *nh, *nh2;
- sip_refer_to_t r[1];
- sip_referred_by_t by[1];
- struct event *refer, *notified;
- sip_t const *sip;
- sip_event_t const *refer_event = NULL;
- sip_subscription_state_t const *ss;
- struct message *invite;
- struct message *notify0, *notify1, *notify2;
- struct dialog *dialog1, *dialog2;
- S2_CASE("5.2.2", "Receive REFER",
- "Make a call, receive REFER, "
- "make another call with automatic NOTIFYs");
- dialog2 = su_home_new(sizeof *dialog2); fail_unless(dialog2 != NULL);
- nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor), TAG_END());
- invite_by_nua(nh, TAG_END());
- *sip_refer_to_init(r)->r_url = *s2sip->aor->a_url;
- r->r_url->url_user = "bob2";
- s2_sip_request_to(dialog, SIP_METHOD_REFER, NULL,
- SIPTAG_REFER_TO(r),
- TAG_END());
- refer = s2_wait_for_event(nua_i_refer, 202);
- sip = sip_object(refer->data->e_msg);
- fail_unless(sip && sip->sip_refer_to);
- bye_by_nua(nh, TAG_END());
- dialog1 = dialog, dialog = dialog2;
- *sip_referred_by_init(by)->b_url =
- *sip->sip_from->a_url;
- fail_unless(tl_gets(refer->data->e_tags,
- NUTAG_REFER_EVENT_REF(refer_event),
- TAG_END()) == 1);
- nua_notify(nh,
- SIPTAG_EVENT(refer_event),
- SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
- SIPTAG_PAYLOAD_STR("SIP/2.0 100 Trying\r\n"),
- NUTAG_SUBSTATE(nua_substate_active),
- TAG_END());
- notify0 = s2_sip_wait_for_request(SIP_METHOD_NOTIFY);
- fail_unless((ss = notify0->sip->sip_subscription_state) != NULL);
- fail_unless(su_casematch("active", ss->ss_substate));
- s2_sip_respond_to(notify0, dialog1, SIP_200_OK, TAG_END());
- notified = s2_wait_for_event(nua_r_notify, 200);
- nh2 = nua_handle(nua, NULL, NUTAG_URL(r->r_url), TAG_END());
- invite = invite_sent_by_nua(nh2,
- NUTAG_REFER_EVENT(refer_event),
- NUTAG_NOTIFY_REFER(nh),
- SIPTAG_REFERRED_BY(by),
- TAG_END());
- process_offer(invite);
- respond_with_sdp(
- invite, dialog, SIP_180_RINGING,
- SIPTAG_CONTENT_DISPOSITION_STR("session;handling=optional"),
- TAG_END());
- fail_unless_event(nua_r_invite, 180);
- fail_unless(s2_check_callstate(nua_callstate_proceeding));
- notify1 = s2_sip_wait_for_request(SIP_METHOD_NOTIFY);
- s2_sip_respond_to(notify1, dialog1, SIP_200_OK, TAG_END());
- respond_with_sdp(invite, dialog, SIP_200_OK, TAG_END());
- s2_sip_free_message(invite);
- fail_unless_event(nua_r_invite, 200);
- fail_unless(s2_check_callstate(nua_callstate_ready));
- fail_unless(s2_sip_check_request(SIP_METHOD_ACK));
- notify2 = s2_sip_wait_for_request(SIP_METHOD_NOTIFY);
- s2_sip_respond_to(notify2, dialog1, SIP_200_OK, TAG_END());
- fail_unless((ss = notify2->sip->sip_subscription_state) != NULL);
- fail_unless(su_casematch("terminated", ss->ss_substate));
- nua_handle_destroy(nh);
- bye_by_nua(nh2, TAG_END());
- nua_handle_destroy(nh2);
- }
- END_TEST
- TCase *refer_tcase(int threading)
- {
- TCase *tc = tcase_create("5.2 - Call Transfer");
- add_call_fixtures(tc, threading);
- tcase_add_test(tc, refer_5_2_1);
- tcase_add_test(tc, refer_5_2_2);
- return tc;
- }
- /* ====================================================================== */
- /* Test case template */
- START_TEST(empty)
- {
- S2_CASE("0.0.0", "Empty test case",
- "Detailed explanation for empty test case.");
- tport_set_params(s2sip->master, TPTAG_LOG(1), TAG_END());
- s2_setup_logs(7);
- s2_setup_logs(0);
- tport_set_params(s2sip->master, TPTAG_LOG(0), TAG_END());
- }
- END_TEST
- TCase *empty_tcase(int threading)
- {
- TCase *tc = tcase_create("0 - Empty");
- add_call_fixtures(tc, threading);
- tcase_add_test(tc, empty);
- return tc;
- }
- /* ====================================================================== */
- void check_session_cases(Suite *suite, int threading)
- {
- suite_add_tcase(suite, invite_tcase(threading));
- suite_add_tcase(suite, cancel_tcase(threading));
- suite_add_tcase(suite, session_timer_tcase(threading));
- suite_add_tcase(suite, invite_100rel_tcase(threading));
- suite_add_tcase(suite, invite_precondition_tcase(threading));
- suite_add_tcase(suite, reinvite_tcase(threading));
- suite_add_tcase(suite, invite_error_tcase(threading));
- suite_add_tcase(suite, termination_tcase(threading));
- suite_add_tcase(suite, destroy_tcase(threading));
- suite_add_tcase(suite, options_tcase(threading));
- suite_add_tcase(suite, refer_tcase(threading));
- if (0) /* Template */
- suite_add_tcase(suite, empty_tcase(threading));
- }
|