读书人

一个基于 osip 库的 UAC 跟 UAS 的代码

发布时间: 2012-11-11 10:07:57 作者: rapoo

一个基于 osip 库的 UAC 和 UAS 的代码整理

来自:http://blog.chinaunix.net/uid-7684977-id-2569711.html

/** * 一个使用了 osip 和 eXosip 库的 UAS 代理服务端的演示程序 *  * - 只是简单的演示了使用了 osip 和 eXosip2 库的 UAS 代理服务端的如下几个功能: *  * 编 译:g++ -I/usr/local/include -L/usr/local/lib ua_server.cpp -o ua_server -leXosip2 -losip2 -losipparser2 -lpthread *  */#include <eXosip2/eXosip.h>#include <netinet/in.h>#include <sys/socket.h>#include <sys/types.h>#include <iostream>#include <fstream>#include <string>using namespace std;int main(){    eXosip_event_t *je = NULL;    osip_message_t *ack = NULL;    osip_message_t *invite = NULL;    osip_message_t *answer = NULL;    sdp_message_t *remote_sdp = NULL;    int call_id, dialog_id;    int i,j;    int id;    char *sour_call = "sip:136@133.37.55.136";    char *dest_call = "sip:136@133.37.55.136:5061"; //client ip/port    char command;    char tmp[4096];    char localip[128];    int pos = 0;    // 初始化 sip    i = eXosip_init ();    if (i != 0)    {        cerr << "\n\t--> Can't initialize eXosip!\n";        return -1;    }    else    {        cout << "\n\t--> eXosip_init successfully!\n";    }        i = eXosip_listen_addr (IPPROTO_UDP, NULL, 5060, AF_INET, 0);    if (i != 0)    {        eXosip_quit ();        cerr << "\n\t--> eXosip_listen_addr error! Couldn't initialize transport layer!\n";    }    for(;;)    {        // 侦听是否有消息到来        je = eXosip_event_wait (0, 50);         // 协议栈带有此语句,具体作用未知        eXosip_lock ();        eXosip_default_action (je);        eXosip_automatic_refresh ();        eXosip_unlock ();        if (je == NULL) // 没有接收到消息,继续        {            continue;        }        switch (je->type)        {        case EXOSIP_MESSAGE_NEW: // 新的消息到来            cout << "\n\t*** EXOSIP_MESSAGE_NEW!\n" << endl;            if (MSG_IS_MESSAGE (je->request)) // 如果接收到的消息类型是 MESSAGE            {                {                    osip_body_t *body;                    osip_message_get_body (je->request, 0, &body);                     cout << "I get the msg is: " << body->body << endl;                }                // 按照规则,需要回复 OK 信息                eXosip_message_build_answer (je->tid, 200, &answer);                eXosip_message_send_answer (je->tid, 200, answer);            }            break;        case EXOSIP_CALL_INVITE: // INVITE 请求消息            // 得到接收到消息的具体信息            cout << "\n\tReceived a INVITE msg from " << je->request->req_uri->host                  << " : " << je->request->req_uri->port                  << ", username is " << je->request->req_uri->username << endl;            // 得到消息体,认为该消息就是 SDP 格式.            remote_sdp = eXosip_get_remote_sdp (je->did);            call_id = je->cid;            dialog_id = je->did;                    eXosip_lock ();            eXosip_call_send_answer (je->tid, 180, NULL);            i = eXosip_call_build_answer (je->tid, 200, &answer);            if (i != 0)            {                cout << "\n\t--> This request msg is invalid! Cann't response!\n" << endl;                eXosip_call_send_answer (je->tid, 400, NULL);            }            else            {                snprintf (tmp, 4096,                    "v=0\r\n"                    "o=anonymous 0 0 IN IP4 0.0.0.0\r\n"                    "t=1 10\r\n"                    "a=username:rainfish\r\n"                    "a=password:123\r\n");                            // 设置回复的SDP消息体,下一步计划分析消息体                // 没有分析消息体,直接回复原来的消息,这一块做的不好。                osip_message_set_body (answer, tmp, strlen(tmp));                osip_message_set_content_type (answer, "application/sdp");                            eXosip_call_send_answer (je->tid, 200, answer);                cout << "\n\t--> send 200 over!" << endl;            }            eXosip_unlock ();                    // 显示出在 sdp 消息体中的 attribute 的内容,里面计划存放我们的信息            cout << "\n\t--> The INFO is :\n" ;            while (!osip_list_eol ( &(remote_sdp->a_attributes), pos))            {                sdp_attribute_t *at;                            //这里解释了为什么在SDP消息体中属性a里面存放必须是两列                at = (sdp_attribute_t *) osip_list_get ( &remote_sdp->a_attributes, pos);                cout << "\n\t" << at->a_att_field                      << " : " << at->a_att_value << endl;                            pos ++;            }            break;        case EXOSIP_CALL_ACK:            cout << "\n\t--> ACK recieved!\n" << endl;            // printf ("the cid is %s, did is %s\n", je->did, je->cid);             break;        case EXOSIP_CALL_CLOSED:            cout << "\n\t--> the remote hold the session!\n" << endl;            // eXosip_call_build_ack(dialog_id, &ack);            // eXosip_call_send_ack(dialog_id, ack);             i = eXosip_call_build_answer (je->tid, 200, &answer);            if (i != 0)            {                printf ("This request msg is invalid!Cann't response!\n");                eXosip_call_send_answer (je->tid, 400, NULL);            }            else            {                eXosip_call_send_answer (je->tid, 200, answer);                cout << "\n\t--> bye send 200 over!\n";            }             break;        case EXOSIP_CALL_MESSAGE_NEW:            cout << "\n\t*** EXOSIP_CALL_MESSAGE_NEW\n" << endl;            if (MSG_IS_INFO(je->request) ) // 如果传输的是 INFO 方法            {                eXosip_lock ();                i = eXosip_call_build_answer (je->tid, 200, &answer);                if (i == 0)                {                    eXosip_call_send_answer (je->tid, 200, answer);                }                eXosip_unlock ();                {                    osip_body_t *body;                    osip_message_get_body (je->request, 0, &body);                    cout << "the body is " << body->body << endl;                }            }            break;         default:            cout << "\n\t--> Could not parse the msg!\n" << endl;        }    }     return 0;}


读书人网 >操作系统

热点推荐