/** * 一个使用了 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 ; } |