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

📄 sipua.c

📁 这是HPOC SIP栈的SIPUA
💻 C
📖 第 1 页 / 共 4 页
字号:

  /* Then send a call accept */
  sip_status = sip_call_evt_accept(instance,
				   call,
				   dialog,
				   transaction,
				   subscription,
				   200,
				   "OK",
				   contact_response,
				   expires_response,
				   NULL,
				   body,/*对一个subscription请求发送一个最终的,实际的响应*/
				   NULL);/*此例程允许用户发送实际的,最终的响应(2XX响应)给关于特殊subscription的远端*/
  
  if (sip_status != SIP_NORMAL) {
    printf("The subscription can't be accepted, rc = %d.\n", sip_status);
  } else {
    printf("Subscription accepted...\n");
  }
  
  sip_msg_free_header(contact_response);/*此例程递归删除一个头和他的所有部分(URIs,参数,等等),如果引用计数器的值大于1,则减少引用计数器的值*/
  sip_msg_free_header(expires_response);
  
  for(index = 0; index < 5; index ++) {

    char value[10];
    sip_trans_t new_transaction;

    sprintf(value, "value_%d", index);

    subscription_state = sip_msg_new_subscription_state_header
      (value, NULL, -1, -1, NULL, NULL);/*没找到相应的资料*/
    
    sleep(1);

    sip_status = sip_call_evt_notify(instance,
				     call,
				     dialog,
				     &new_transaction,
				     subscription,
				     subscription_state,
				     NULL,
				     body,
				     NULL);/*此例程发送NOTIFY请求*/
    
    if (sip_status != SIP_NORMAL) {
      printf("Notification can't be sent, rc = %d.\n", sip_status);
    } else {
      printf("Notify sent with status '%s'.\n", value);
    }

    sip_msg_free_header(subscription_state);/*此例程递归删除一个头和他的所有部分(URIs,参数,等等),如果引用计数器的值大于1,则减少引用计数器的值*/
  }

  return SIP_NORMAL;
}

/*
 * FACILITY:
 *
 *      The SIP call notify reception callback
 *
 * FORMAL PARAMETERS:
 *
 *      instance           : The SIP call instance
 *      call               : The call identifier
 *      dialog             : The dialog identifier
 *      transaction        : The transaction identifier
 *      subscription       : The subscription identifier
 *      subscription state : The state of the recieved event
 *      request            : Additional headers in the INVITE
 *      body               : The INVITE body
 *      user_info          : The user info
 *
 * RETURN VALUE:
 *
 *      SIP_NORMAL : successful completion
 *
 */

sip_status_t sip_call_on_evt_notify
  (
    sip_call_inst_t               instance,
    sip_call_t                    call,
    sip_dialog_t                  dialog,
    sip_trans_t                   transaction,
    sip_subs_t                    subscription,
    sip_msg_uri_t               * request_uri,
    sip_msg_header_t            * event,
    sip_msg_header_t            * subscription_state,
    sip_msg_header_vector_t     * request,
    sip_msg_body_t              * body,
    sip_user_info_t             * user_info
)
{
  sip_status_t       sip_status;
  sip_msg_header_t * contact_response;

  printf("NOTIFY received with status '%s' for event '%s'...",
	 subscription_state -> structured_header -> 
	 content.subscription_state.value,
	 event -> structured_header -> content.event.event_type);
  fflush(stdout);
  
  /* Then send a 200 OK */
  sip_status = sip_call_reply(instance,
			      call,
			      dialog,
			      transaction,
			      subscription,
			      200,
			      NULL,
			      NULL,
			      NULL,
			      SIP_FALSE,
			      NULL);/*对入请求,发送一个回复*/
 /*  此例程允许用户回复入OPTIONS, EXTENSION, INFO,或 re-INVITE请求。*/
  
  if (sip_status != SIP_NORMAL) {
    printf("\nError sending the NOTIFY 200 OK, rc = %d.\n", sip_status);
  } else {
    printf(" 200 OK sent.\n");
  }
  
  if (unscuscribe_counter) {
    unscuscribe_counter--;

    if(!unscuscribe_counter) {
      sip_msg_header_t * event;
      sip_subs_t subscription_id;
      
      sip_status = sip_call_evt_unsubscribe
	(instance,
	 call,
	 dialog,
	 &transaction,
	 subscription,
	 SIP_CALL_RELEASE_GRACEFUL,/*从SIP角度看,正常释放。释放subscription 事件回调被调用*/
	 NULL,
	 NULL,
	 NULL);/*此例程发送SUBSCRIBE请求,对SUBSCRIBE消息创建的subscription,expire值为0。这将unsubscribe与此subscription相关的事件。否则,将仅仅释放本地资源*/
      
      if(sip_status != SIP_NORMAL) {
	printf("Error %d returned from sip_call_evt_unsubscribe\n", sip_status);
	return(1);
      } else {
	printf("SUBSCRIBE(expires=0) = unsubscription sent...\n");
      } 
    }
  }

  return SIP_NORMAL;
}
  
/*
 * FACILITY:
 *
 *      The SIP call event reception callback
 *
 * FORMAL PARAMETERS:
 *
 *      instance      : The SIP call handling instance
 *      call          : The call identifier
 *      dialog        : The dialog identifier
 *      event         : The call event
 *      user_info     : The user info
 *
 * RETURN VALUE:
 *
 *      SIP_NORMAL : successful completion
 *
 */

sip_status_t sip_call_on_event
  (
    sip_call_inst_t               instance,
    sip_call_t                    call,
    sip_dialog_t                  dialog,
    sip_call_event_t            * event,
    sip_user_info_t             * user_info
  )
{
  switch(event->type)
  {
    case SIP_CALL_EVENT_LOCAL_SRV_ERROR:
      printf("Local server error\n");
      return SIP_CALL_TRANSFAIL;

    case SIP_CALL_EVENT_ENUM_RES:
      printf("Enum resolution error\n");
      return SIP_CALL_TRANSFAIL;

    case SIP_CALL_EVENT_TRANSACTION_DELETED:
      printf("Transaction deleted\n");
      if ( event->parameters.transaction_deleted.status != SIP_NORMAL )
        return SIP_CALL_TRANSFAIL;
      break;

    case SIP_CALL_EVENT_DIALOG_DELETED:
      printf("Dialog deleted\n");
      if ( event->parameters.dialog_deleted.status != SIP_NORMAL )
        return SIP_CALL_TRANSFAIL;
      break;

    default:
      printf("Event type:%d received\n",event->type);
      break;
  }
  return SIP_NORMAL;
}

/*
 * FACILITY:
 *
 *      call_uri
 *
 * ABSTRACT:
 *
 *      The caller code, able to establish a call to the
 *      specified request URI.
 *
 * FORMAL PARAMETERS:
 *
 *      sip_called_uri    : The remote to call
 *      sip_ch_inst       : The call-handling instance 
 *      port              : The local port number (to build the 
 *                          calling URI for the From: and Contact:
 *                          headers.
 *
 * RETURN VALUE:
 *
 *      None
 *
 */

int call_uri(char            * sip_called_uri,
             sip_call_inst_t   sip_ch_inst,
             int               port,
             sip_bool_t        do_body)/*很重要的函数*/
{/*此函数的流程,我的理解如下:
创建新的SIP URI结构
用给定的参数建立一个新的SIPFrom,Contact,To头
if (do_body){
用给定的参数来创建新的sdp_announcement_t结构
建造新的包含一个SDP announcement的sip msg body t结构
}
if(!subscribe_event_name) {
发送INVITE请求}else{
发送SUBSCRIBE请求}
 释放一些变量的内存
if (cancel_delay){
延时一段时间
发送CANCEL请求
}

*/
  sip_call_t   call;
  sip_dialog_t dialog;
  sip_trans_t  transaction;
  
  sip_msg_header_t * from;
  sip_msg_header_t * to;
  sip_msg_header_t * contact;

  sip_msg_uri_t * request_uri;
  sip_msg_uri_t * calling_uri;

  sip_status_t sip_rc;
  sip_msg_error_t error;

  sip_msg_body_t     * sdp_body = 0;
  sdp_announcement_t * sdp;
  
  char hostname[50];

  gethostname(hostname, 50);

  calling_uri = sip_msg_new_sip_url("user",
                                    hostname,
                                    port,
                                    NULL,
                                    NULL,
                                    SIP_MSG_NONE,/*缺省值,证明无METHOD*/
                                    NULL,
                                    -1,
                                    NULL,
                                    SIP_FALSE,
                                    NULL,
                                    NULL);/*此例程创建新的SIP URI结构,它包含了用给定的参数建造的"sip:" URL。此例程可以对存在的"sip:" URL更改参数*/
  if(!calling_uri) {
    sip_call_delete_instance(sip_ch_inst);/*此例程终止callhandling实例,并释放所有相关的对象(如呼叫)*/
    printf("Unable to build the calling uri");
    return(1);
  }

  if(interactive) {
    printf("Press enter to start the call...\n");
    getchar();
  }

  from = sip_msg_new_from_header(calling_uri, NULL, NULL, NULL, NULL);/*此例程用给定的参数建立一个新的SIPFrom头,或更改一个存在的头的参数*/
  if(!from) {
    printf("Unable to build the From: header\n");
    return(1);
  }

  contact = sip_msg_new_contact_header(calling_uri, NULL, -1, -1, NULL, NULL);/*此例程用给定的参数建造一个新的SIPContact头,或更改一个存在的Contact头的参数*/
  if(!contact) {
    sip_call_delete_instance(sip_ch_inst);/*此例程终止callhandling实例,并释放所有相关的对象(如呼叫)*/
    printf("Unable to build the Contact: header\n");
    return(1);
  }
  
  request_uri = sip_msg_parse_uri(sip_called_uri, &error);/*此例程解析包含SIP URI的字符串为sip msg uri t 结构*/
  if(!request_uri) {
    printf("Syntax error near token '%s' in request URI\n",
           error.unexpected_token);
    return(1);
  }
  
  to = sip_msg_new_to_header(request_uri, NULL, NULL, NULL, NULL);/*此例程用给定的参数建造一个新的SIP TO头,或更改存在的头的参数*/
  if(!to) {
    printf("Unable to build the To: header\n");
    return(1);
  }
  
  call = SIP_CALL_NO_CALL;
  dialog = SIP_CALL_NO_DIALOG;
  transaction = SIP_CALL_NO_TRANSACTION;
  
  if(do_body) {

    sdp = sdp_new_announcement(0, 
                               "media", 
                               "user1", 
                               "12341234", 
                               "2",
                               "IN",
                               "IP4",
                               "127.0.0.2",
                               NULL);/*用给定的参数来创建新的sdp_announcement_t结构。这些参数用于建立2个强制域(session_name and origin)*/
    
    if(!sdp) {
      printf("Unable to build SDP announcement\n");
      exit(1);
    }
    
    sdp_body = sip_msg_new_sdp_body(sdp,/*如果keep sdp参数为FALSE,此SDP announcement自动和sip msg body t结构同时被删除*/
                                    SIP_FALSE, NULL);/*此例程建造新的包含一个SDP announcement的sip msg body t结构。作为一个参数给出的SDP announcement将不被复制(新的body仅仅指向源SDP announcement)*/
  }

  if(!subscribe_event_name) {
    /* Normal INVITE case */

    sip_rc = sip_call_initiate(sip_ch_inst,
			       &call,
			       &dialog,
			       &transaction,
			       request_uri,
			       from,
			       to,
			       contact,
			       NULL,
			       sdp_body,
			       NULL);/*此例程发送INVITE请求,初始化出呼叫*/

    if(sip_rc != SIP_NORMAL) {
      printf("Error %d returned from sip_call_initiate\n", sip_rc);
      return(1);
    } else {
      printf("Initiate call ongoing...\n");
    }
  } else {
    /* SUBSCRIBE case */

    sip_msg_header_t * event;
    sip_subs_t subscription_id;

    event = sip_msg_new_event_header/*没找到相关资料*/
      (subscribe_event_name, NULL, NULL, NULL);

    if(!event) {
      printf("Error returned from sip_msg_new_event_header\n");
      return 1;
    }

⌨️ 快捷键说明

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