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

📄 sipua.c

📁 这是HPOC SIP栈的SIPUA
💻 C
📖 第 1 页 / 共 4 页
字号:
/* @@ WARNING: This example is automatically included in the user
   @@ documentation. (Note: The lines containing '@@' are removed
   @@ automatically). */

/*    
 *                        WARNING
 *
 * This sample application uses the sleep() system call
 * in callback routines, for the sake of simplicity. This
 * allows simple coding of the sample, to introcuce user
 * delays or call duration.
 *
 * BUT, a real-world application should never stop during 
 * a callback routine. During the processing of a callback, 
 * no other indications can be delivered, incoming SIP 
 * messages are stored in the SIP stack and cause congestion.
 *
 * If you need to stop or wait for I/O before answering the 
 * request, you must return from the callback and trigger
 * an asynchronous mechanisn (threads, timers, ...) to answer
 * the request at a later time.
 */

 /*    
 *                        WARNING
 *
*这个例子在回调例程中使用了sleep()系统调用,这是出于简单性的考虑
*这使此例子简单化,来说明用户延时或呼叫延时。
*
*
*
 *但是,在真实的应用中,不应该在回调例程中停止。在回调的处理中,
 *没有其他indications可以传递,入SIP消息将存储在SIP栈中,(如果此时停止)这将引起拥塞。
*
*
*
*
*如果你需要停止或等待I/O,之后才应答此请求,你必须从回调
*中返回,并触发异步机制(线程,定时器。。。)来在以后应答请求
 */


#include <string.h>
#include <stdio.h>
#include <sys/signal.h>
#include <pthread.h>
#include <arpa/inet.h>

#include "sip_api.h"

sip_bool_t     sip_exit               = SIP_FALSE;
sip_bool_t     interactive            = SIP_FALSE;
sip_bool_t     no_bye                 = SIP_FALSE;
sip_bool_t     no_delay               = SIP_FALSE;
sip_bool_t     auto_exit              = SIP_TRUE;
int            cancel_delay           = 0;
int            uas_bye_delay          = 0;
int            uas_invite_delay       = 0;
char         * subscribe_event_name   = NULL;
int            unscuscribe_counter    = 0;
/*
 * FACILITY:
 *
 *      sip_call_on_initiate
 *
 * ABSTRACT:
 *
 *      The SIP call initiate reception callback
 *
 * FORMAL PARAMETERS:
 *
 *      instance      : The SIP call instance
 *      call          : The call identifier
 *      dialog        : The dialog identifier
 *      transaction   : The transaction identifier
 *      request_uri   : The request URI to forward the INVITE
 *      from          : The from header
 *      to            : The to header
 *      contact       : The contact header
 *      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_initiate
 (
    sip_call_inst_t               instance,
    sip_call_t                    call,
    sip_dialog_t                  dialog,
    sip_trans_t                   transaction,
    sip_msg_uri_t               * request_uri,
    sip_msg_header_t            * from,
    sip_msg_header_t            * to,
    sip_msg_header_t            * contact,
    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;
  char from_string[255];

  if(sip_msg_print_header(from, from_string, 255, SIP_FALSE, NULL) > 0) {
    printf("Call received, %s.\n",from_string);
  }/*此函数在parser中出现,功能为编码SIP头结构为包含等价SIP头的字符串*/
  
  if(uas_invite_delay) {
    printf("Adding a %d sec delay before answering 180 Ringing\n",
	   uas_invite_delay);  
          sleep(uas_invite_delay);
  }

  /* We first reply with a 180 ringing */
  sip_status = sip_call_progress(instance,
                                 call,
                                 dialog,
                                 transaction,
                                 180,
                                 "Ringing",
                                 NULL,
                                 NULL,
                                 SIP_FALSE,/*不需要可靠性*/
                                 NULL);/*此例程允许用户发送临时响应(1XX响应)。如果响应需要可靠性,SIPcallhandling级等待从远端的PRACK请求,之后才允许更多的响应被发送。此例程仅仅支持INVITE请求。*/
  if (sip_status != SIP_NORMAL)
  {
    printf("Error %d in sending a call in progress\n", sip_status);
    return SIP_NORMAL;
  }

  if(!no_delay) {
    printf("Waiting 3 seconds before accepting the call...\n");
    sleep(3);
  }

  contact_response = sip_msg_new_contact_header
    (request_uri, NULL, -1, -1, NULL, NULL);
/*此例程用给定的参数建造一个新的SIPContact头,或更改一个存在的Contact头的参数*/

  if(!contact_response) {
    printf("Unable to build the Contact: header\n");
    exit(1);
  }
  
  if(!body) {// 1
    sip_msg_body_t     * sdp_body;
    sdp_announcement_t * sdp;

    sdp = sdp_new_announcement(0, 
                               "media", 
                               "user1", 
                               "12341234", 
                               "2",
                               "IN",
                               "IP4",
                               "127.0.0.2",
                               NULL);/*创建新的SDP announcement.*/
	/*此例程在parser内说明,用给定的参数来创建新的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,
                                    SIP_FALSE, NULL);
/*此例程在parser内说明,此例程创建新的SDP体*/
/*建造新的包含一个SDP announcement的sip msg body t结构。作为一个参数给出的SDP announcement将不被复制(新的body仅仅指向源SDP announcement)*/
	
    /* Then send a 200 OK */
    sip_status = sip_call_accept(instance,
                                 call,
                                 dialog,
                                 transaction,
                                 200,
                                 "OK",
                                 contact_response,
                                 NULL,
                                 sdp_body,
                                 NULL);/*此例程允许用户发送实际的,最终的响应(2XX响应)给远端。*/

    sip_msg_free_body(sdp_body);/*此例程在parser内说明,删除一个体*/
/*	此例程递归地删除SIP体结构和它所有部分(SDP announcement等等),当引用计数器的值大于1时,减少它的值*/


  } else {// 1

    /* Then send a 200 OK */
    sip_status = sip_call_accept(instance,
                                 call,
                                 dialog,
                                 transaction,
                                 200,
                                 "OK",
                                 contact_response,
                                 NULL,
                                 body,
                                 NULL);/*此例程允许用户发送实际的,最终的响应(2XX响应)给远端。*/

  }// end 1

  if (sip_status != SIP_NORMAL)
  {
    printf("The call can't be accepted, rc = %d.\n", sip_status);
  } else {
    printf("Call accepted...\n");
  }

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

  return SIP_NORMAL;
}

/*
 * FACILITY:
 *
 *      sip_call_on_connect
 *
 * ABSTRACT:
 *
 *      The SIP call connect reception callback
 *
 * FORMAL PARAMETERS:
 *
 *      instance      : The SIP call handling instance
 *      call          : The call identifier
 *      dialog        : The dialog identifier
 *      transaction   : The transaction identifier
 *      request_uri   : The request URI to forward the INVITE
 *      request       : The request headers
 *      body          : The message body
 *      user_info     : The user info
 *
 * RETURN VALUE:
 *
 *      SIP_NORMAL : successful completion
 *
 */

sip_status_t sip_call_on_connect
  (
    sip_call_inst_t               instance,
    sip_call_t                    call,
    sip_dialog_t                  dialog,
    sip_trans_t                   transaction,
    sip_msg_uri_t               * request_uri,
    sip_msg_header_vector_t     * request,
    sip_msg_body_t              * body,
    sip_user_info_t             * user_info
  )
{
  printf("The call is established\n");

  if(uas_bye_delay) {// 2
    sip_trans_t new_trans;

    printf("Waiting %d second before releasing the call\n",
	   uas_bye_delay);
    sleep(uas_bye_delay);
    
    printf("Releasing the call.\n");

    /* send a CANCEL request *//*依靠呼叫状态,SIPcallhandling级处理用户请求也不尽相同*/
	/*为什么这里就一定肯定为发送CANCEL呢*/
    sip_call_release(instance,
		     call,
		     dialog,
		     &new_trans,
		     NULL,
		     NULL,
		     SIP_CALL_RELEASE_AUTOMATIC,/*从SIP角度看,正常释放。释放呼叫事件回调不被调用*/
                     user_info);/*释放特定呼叫,此例程较复杂,可查看自己的读书笔记*/
  }// end 2

  return SIP_NORMAL;
}

/*
 * FACILITY:
 *
 *      sip_call_on_progress
 *
 * ABSTRACT:
 *
 *      The SIP call Ringing reception callback
 *
 * FORMAL PARAMETERS:
 *
 *      instance      : The SIP call instance
 *      call          : The call identifier
 *      dialog        : The dialog identifier
 *      transaction   : The transaction identifier
 *      status_code   : The status code (1xx) received in the response 
 *      reason_phrase : The character string in the received status line
 *      response      : Additional headers in the response
 *      body          : The received body
 *      user_info     : The user info
 *
 * RETURN VALUE:
 *
 *      SIP_NORMAL : successful completion
 *
 */

sip_status_t sip_call_on_progress
  (
    sip_call_inst_t               instance,
    sip_call_t                    call,
    sip_dialog_t                  dialog,
    sip_trans_t                   transaction,
    sip_uint32_t                  status_code,
    char                        * reason_phrase,
    sip_msg_header_vector_t     * response,
    sip_msg_body_t              * body,
    sip_user_info_t             * user_info
  )
{
  printf("Progressing: %s...\n", reason_phrase);

  return SIP_NORMAL;
}

/*
 * FACILITY:
 *
 *      sip_call_on_accept
 *
 * ABSTRACT:
 *
 *      The SIP call accept reception callback
 *
 * FORMAL PARAMETERS:
 *
 *      instance      : The SIP call instance
 *      call          : The call identifier
 *      dialog        : The dialog identifier
 *      transaction   : The transaction identifier
 *      status_code   : The status code (200) received in the response 
 *      reason_phrase : The character string in the received status line
 *      response      : Additional headers in the response
 *      body          : The received body
 *      user_info     : The user info
 *
 * RETURN VALUE:
 *
 *      SIP_NORMAL : successful completion
 *
 */

sip_status_t sip_call_on_accept
  (
    sip_call_inst_t               instance,
    sip_call_t                    call,
    sip_dialog_t                  dialog,
    sip_trans_t                   transaction,
    sip_uint32_t                  status_code,
    char                        * reason_phrase,
    sip_msg_header_vector_t     * response,
    sip_msg_body_t              * body,
    sip_user_info_t             * user_info
  )
{
  sip_trans_t new_trans;

  printf("The call has been accepted\n");

  /* send ACK request */
  sip_call_connect(instance,
                   call,
                   dialog,
                   transaction,
                   NULL,
                   NULL,
                   NULL);/*在接收了最终的成功响应后,发送ACK请求*/
  /*此例程仅支持INVITE请求*/

  if(!no_bye) {// 3

    printf("Waiting 3 seconds before releasing the call...\n");

⌨️ 快捷键说明

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