⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 check_session.c

📁 Sofia SIP is an open-source SIP User-Agent library, compliant with the IETF RFC3261 specification.
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * 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"#include "check_nua.h"#include "test_s2.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_tag_io.h>#include <stdlib.h>#include <string.h>#include <assert.h>/* ====================================================================== *//* Call cases */static nua_t *nua;static soa_session_t *soa = NULL;static struct dialog *dialog = NULL;#define CRLF "\r\n"static void call_setup(void){  s2_case("0.1.1", "Setup for Call Tests", "");  nua = s2_nua_setup(TAG_END());  soa = soa_create(NULL, s2->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_teardown(void){  s2_case("0.1.2", "Teardown Call Test Setup", "");  mark_point();  s2_register_teardown();  nua_shutdown(nua);  fail_unless(s2_check_event(nua_r_shutdown, 200));  s2_nua_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 voidrespond_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_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 voidrequest_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_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_wait_for_request(SIP_METHOD_INVITE);}static struct message *respond_with_100rel(struct message *invite,		    struct dialog *d,		    int sdp,		    int status, char const *phrase,		    tag_type_t tag, tag_value_t value, ...){  struct message *prack;  ta_list ta;  static uint32_t rseq;  sip_rseq_t rs[1];  assert(100 < status && status < 200);  sip_rseq_init(rs);  rs->rs_response = ++rseq;  ta_start(ta, tag, value);  if (sdp) {    respond_with_sdp(      invite, dialog, status, phrase,      SIPTAG_REQUIRE_STR("100rel"),      SIPTAG_RSEQ(rs),      ta_tags(ta));  }  else {    s2_respond_to(      invite, dialog, status, phrase,      SIPTAG_REQUIRE_STR("100rel"),      SIPTAG_RSEQ(rs),      ta_tags(ta));  }  ta_end(ta);  fail_unless(s2_check_event(nua_r_invite, status));  prack = s2_wait_for_request(SIP_METHOD_PRACK);  /* Assumes auto-prack, so there is no offer in prack */  s2_respond_to(prack, dialog, SIP_200_OK, TAG_END());  return prack;}static voidinvite_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, SOATAG_USER_SDP_STR("m=audio 5004 RTP/AVP 0 8"),    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(s2_check_event(nua_r_invite, 180));  fail_unless(s2_check_callstate(nua_callstate_proceeding));  respond_with_sdp(invite, dialog, SIP_200_OK, TAG_END());  s2_free_message(invite);  fail_unless(s2_check_event(nua_r_invite, 200));  fail_unless(s2_check_callstate(nua_callstate_ready));  fail_unless(s2_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;  sip_cseq_t cseq[1];  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);  sip_cseq_init(cseq);  cseq->cs_method = sip_method_ack;  cseq->cs_method_name = "ACK";  cseq->cs_seq = sip_object(invite->data->e_msg)->sip_cseq->cs_seq;  s2_free_event(invite);  response = s2_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_wait_for_response(180, SIP_METHOD_INVITE);  fail_if(!response);  s2_update_dialog(dialog, response);  process_answer(response);  s2_free_message(response);  nua_respond(nh, SIP_200_OK, TAG_END());  fail_unless(s2_check_callstate(nua_callstate_completed));  response = s2_wait_for_response(200, SIP_METHOD_INVITE);  fail_if(!response);  s2_update_dialog(dialog, response);  s2_free_message(response);  fail_if(s2_request_to(dialog, SIP_METHOD_ACK, NULL,			SIPTAG_CSEQ(cseq), TAG_END()));  fail_unless(s2_check_event(nua_i_ack, 200));  fail_unless(s2_check_callstate(nua_callstate_ready));  return nh;}static voidbye_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_wait_for_request(SIP_METHOD_BYE);  fail_if(!bye);  s2_respond_to(bye, dialog, SIP_200_OK, TAG_END());  s2_free_message(bye);  fail_unless(s2_check_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_wait_for_request(SIP_METHOD_BYE);  fail_if(!bye);  s2_respond_to(bye, dialog, SIP_407_PROXY_AUTH_REQUIRED,		SIPTAG_PROXY_AUTHENTICATE_STR(s2_auth_digest_str),		TAG_END());  s2_free_message(bye);  fail_unless(s2_check_event(nua_r_bye, 407));  nua_authenticate(nh, NUTAG_AUTH("Digest:\"s2test\":abc:abc"), TAG_END());  bye = s2_wait_for_request(SIP_METHOD_BYE);  fail_if(!bye);  s2_respond_to(bye, dialog, SIP_200_OK, TAG_END());  s2_free_message(bye);  fail_unless(s2_check_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_wait_for_request(SIP_METHOD_CANCEL);  fail_if(!cancel);  s2_respond_to(cancel, dialog, SIP_200_OK, TAG_END());  s2_free_message(cancel);  fail_unless(s2_check_event(nua_r_cancel, 200));  s2_respond_to(invite, dialog, SIP_487_REQUEST_CANCELLED, TAG_END());  fail_unless(s2_check_request(SIP_METHOD_ACK));  fail_unless(s2_check_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_request_to(dialog, SIP_METHOD_BYE, NULL, ta_tags(ta)));  ta_end(ta);  fail_unless(s2_check_event(nua_i_bye, 200));  fail_unless(s2_check_callstate(nua_callstate_terminated));  fail_unless(s2_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(s2->local), TAG_END());  invite_by_nua(nh, TAG_END());  bye_by_nua(nh, TAG_END());  nua_handle_destroy(nh);}END_TESTSTART_TEST(call_2_1_2){  nua_handle_t *nh;  s2_case("2.1.2", "Basic call",	  "NUA sends INVITE, NUA receives BYE");  nh = nua_handle(nua, NULL, SIPTAG_TO(s2->local), TAG_END());  invite_by_nua(nh, TAG_END());  bye_to_nua(nh, TAG_END());  nua_handle_destroy(nh);}END_TESTSTART_TEST(call_2_1_3){  nua_handle_t *nh;  s2_case("2.1.3", "Incoming call",	  "NUA receives INVITE and BYE");  nh = invite_to_nua(TAG_END());  bye_to_nua(nh, TAG_END());  nua_handle_destroy(nh);}END_TESTSTART_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_TESTSTART_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_TESTSTART_TEST(call_2_1_6){  nua_handle_t *nh;  struct message *bye;  struct event *invite;  struct message *response;  sip_cseq_t cseq[1];  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);  sip_cseq_init(cseq);  cseq->cs_method = sip_method_ack;  cseq->cs_method_name = "ACK";  cseq->cs_seq = sip_object(invite->data->e_msg)->sip_cseq->cs_seq;  s2_free_event(invite);  response = s2_wait_for_response(100, SIP_METHOD_INVITE);  fail_if(!response);  nua_respond(nh, SIP_180_RINGING,	      /* Dialog-specific proxy is saved */	      NUTAG_PROXY(s2->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_wait_for_response(180, SIP_METHOD_INVITE);  fail_if(!response);  s2_update_dialog(dialog, response);  process_answer(response);  s2_free_message(response);  nua_respond(nh, SIP_200_OK, TAG_END());  fail_unless(s2_check_callstate(nua_callstate_completed));  response = s2_wait_for_response(200, SIP_METHOD_INVITE);  fail_if(!response);  s2_update_dialog(dialog, response);  s2_free_message(response);  fail_if(s2_request_to(dialog, SIP_METHOD_ACK, NULL,			SIPTAG_CSEQ(cseq), TAG_END()));  fail_unless(s2_check_event(nua_i_ack, 200));  fail_unless(s2_check_callstate(nua_callstate_ready));  nua_bye(nh, TAG_END());  bye = s2_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_respond_to(bye, dialog, SIP_200_OK, TAG_END());  s2_free_message(bye);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -