eXosip用戶手冊:1.2 如何初始化、修改或終止呼叫

    eXosip2提供靈活的API,以幫助用戶控制呼叫。

1.2.1 初始化呼叫

    要啓動一個呼出,用戶通常需要一些eXosip2用到的頭部,以建立默認的INVITE請求。以下的代碼用於啓動一個呼叫:

    osip_message_t *invite;
    int i;

    i = eXosip_call_build_initial_invite (&invite, 
                                        "<sip:[email protected]>",
                                        "<sip:[email protected]>",
                                        NULL, // optional route header
                                        "This is a call for a conversation");
    if (i != 0)
    {
        return -1;
    }

    osip_message_set_supported (invite, "100rel");

    {
        char tmp[4096];
        char localip[128];

        eXosip_guess_localip (AF_INET, localip, 128); // 獲取本地IP
        
        // 格式化SDP信息體
        snprintf (tmp, 4096,
                 "v=0\r\n"                           // SDP版本
                 "o=josua 0 0 IN IP4 %s\r\n"         // 用戶名、ID、版本、網絡類型、地址類型、IP地址
                 "s=conversation\r\n"                // 會話名稱
                 "c=IN IP4 %s\r\n"
                 "t=0 0\r\n"                         // 開始時間、結束時間。此處不需要設置
                 "m=audio %s RTP/AVP 0 8 101\r\n"    // 音頻、傳輸端口、傳輸類型、格式列表
                 "a=rtpmap:0 PCMU/8000\r\n"          // 以下爲具體描述格式列表中的
                 "a=rtpmap:8 PCMA/8000\r\n"
                 "a=rtpmap:101 telephone-event/8000\r\n"
                 "a=fmtp:101 0-11\r\n", localip, localip, port);
                  
        osip_message_set_body (invite, tmp, strlen (tmp));
        osip_message_set_content_type (invite, "application/sdp");
    }

    eXosip_lock ();
    i = eXosip_call_send_initial_invite (invite); // 發送INVITE請求
    
    if (i > 0)
    {
        eXosip_call_set_reference (i, reference); 

    }
    
    eXosip_unlock ();
    return i;

    
       上面代碼使用eXosip_call_build_initial_invite函數爲新的呼叫建立一個默認的SIP INVITE請求。用戶需要插入SDP信息體,以指示RTP流的音頻參數。
       同時上述代碼演示了eXosip2 API的靈活性,它允許您插入額外的頭部,比如:"Supported: 100rel"(宣佈支持SIP擴展)。因此,您可以完全的控制SIP請求的創建。    
       eXosip_call_send_initial_invite函數的返回值爲呼叫標識(call identifier),該標識可以用於發送CANCEL請求。之後的事件中(除了100 Trying),用戶可以獲得會話標識(dialog identifier),該標識用於控制已建立的呼叫。  
      eXosip_call_set_reference函數將用戶自己的環境(context)與呼叫聯繫起來,這樣用戶可以從eXosip_event取回指針。
   
1.2.2 應答呼叫 
      下面的代碼教您如何應答一個到來的呼叫。當接收到SIP INVITE請求後,用戶通常需要發送一個 "180 Ringing" SIP應答。

    eXosip_lock ();
    eXosip_call_send_answer (ca->tid, 180, NULL);
    eXosip_unlock ();

 
       上述代碼表明,協議棧有時只需要一個API函數就可以建立和發送默認的SIP消息。
       然後,當用戶想要回復呼叫時,需要發送“200 OK”,同時在回覆中插入SDP信息體:

    osip_message_t *answer = NULL;

    eXosip_lock ();
    i = eXosip_call_build_answer (ca->tid, 200, &answer);// 建立200 OK應答
    
    if (i != 0)
    {
        eXosip_call_send_answer (ca->tid, 400, NULL);
    }
    else
    {
        i = sdp_complete_200ok (ca->did, answer); // 僞代碼,需要用戶自己實現
        
        if (i != 0)
        {
            osip_message_free (answer);
            eXosip_call_send_answer (ca->tid, 415, NULL);
        }
        else
            eXosip_call_send_answer (ca->tid, 200, answer); // 發送200 OK應答
    }
    
    eXosip_unlock ();

    
       注1:上述代碼中,注意到給請求發送應答時用到了傳送標識(transaction identifier)(不是呼叫標識,也不是會話標識)。
       注2:爲了發送“200 OK”,通常需要在回覆中插入SDP信息體,而且是在回覆前插入,目的是爲了協商支持的參數和編碼。在test tool目錄下,eXosip2提供的josua應用程序中,可以找到一個非常基本的SDP協商操作。
   
1.2.3 發送其他請求  
      呼叫控制API允許發送和接收REFER、UPDATE、INFO、OPTIONS、NOTIFY、INVITE。當回覆其他請求時,仍然存在一些限制,但可以發送任何類型的請求。    
      以下的代碼是發送INFO請求,用於在不同信號層發送不同信道的dtmf。 

    osip_message_t *info;
    char dtmf_body[1000];
    int i;

    eXosip_lock ();
    i = eXosip_call_build_info (ca->did, &info);
    
    if (i == 0)
    {
        snprintf (dtmf_body, 999, "Signal=%c\r\nDuration=250\r\n", c);
        
        osip_message_set_content_type (info, "application/dtmf-relay");
        osip_message_set_body (info, dtmf_body, strlen (dtmf_body));
        
        i = eXosip_call_send_request (ca->did, info);
    }
    
    eXosip_unlock ();    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章