基于exosip编写呼叫流程实例2、复制如下代码⽣成UAC,该实例使⽤的是windows控制台程序,对于sdp的解析部分需修改⼀下
代码如下:
#include <eXosip2/eXosip.h>
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
int main(int argc, char *argv[])
{
struct eXosip_t *context_eXosip;
eXosip_event_t *je;
osip_message_t *reg = NULL;
osip_message_t *invite = NULL;
osip_message_t *ack = NULL;
osip_message_t *info = NULL;
osip_message_t *message = NULL;
int call_id, dialog_id;
int i, flag;
int flag1 = 1;
char*identity="sip:***********.0.115";//UAC1,端⼝是15060
char*registar="sip:***********.0.115:15061";//UAS,端⼝是15061
char*source_call="sip:***********.0.115";
char*dest_call="sip:***********.0.103:15061";
/
/identify和register这⼀组地址是和source和destination地址相同的
//在这个例⼦中,uac和uas通信,则source就是⾃⼰的地址,⽽⽬的地址就是uac1的地址
char command;
char tmp[4096];
printf("r 向服务器注册\n\n");
printf("c 取消注册\n\n");
printf("i 发起呼叫请求\n\n");
printf("h 挂断\n\n");
printf("q 推出程序\n\n");
printf("s 执⾏⽅法INFO\n\n");
printf("m 执⾏⽅法MESSAGE\n\n");
/
/初始化
struct eXosip_t *excontext;
excontext = eXosip_malloc();
i = eXosip_init(excontext);
if (i != 0)
{
printf("Couldn't initialize eXosip!\n");
osip_free(excontext);
return -1;
}
else
{
printf("eXosip_init successfully!\n");
}
//绑定uac⾃⼰的端⼝15060,并进⾏端⼝监听
i = eXosip_listen_addr(excontext, IPPROTO_UDP, NULL, 15060, AF_INET, 0);
if (i != 0)
{
eXosip_quit(excontext);
fprintf(stderr, "Couldn't initialize transport layer!\n");
osip_free(excontext);
return -1;
}
flag = 1;
while (flag)
{
//输⼊命令
printf("Please input the command:\n");
scanf_s("%c", &command);
getchar();
switch (command)
{
case 'r':
printf("This modal is not completed!\n");
break;
case 'i'://INVITE,发起呼叫请求
i = eXosip_call_build_initial_invite(excontext, &invite, dest_call, source_call, NULL, "This is a call for conversation"); if (i != 0)
{
printf("Initial INVITE failed!\n");
break;
}
//符合SDP格式,其中属性a是⾃定义格式,也就是说可以存放⾃⼰的信息,
//但是只能有两列,⽐如帐户信息
//但是经过测试,格式vot必不可少,原因未知,估计是协议栈在传输时需要检查的
_snprintf_s(tmp, 4096,
"v=0\r\n"
"o=anonymous 0 0 IN IP4 0.0.0.0\r\n"
"t=0 0\r\n"
"m=audio 62100 RTP/AVP 114 0 8 101\r\n"
"a=rtpmap:114 AMR/8000\r\n"
"a=fmtp:114 octet-align=1;mode-set=7,0\r\n"
"a=rtpmap:0 PCMU/8000\r\n"
"a=rtpmap:8 PCMA/8000\r\n"
"m=video 62102 RTP/AVP 102 99\r\n"
"a=rtpmap:102 H264/90000\r\n"
"a=rtpmap:99 MP4V-ES/90000\r\n"
);
osip_message_set_body(invite, tmp, strlen(tmp));
osip_message_set_content_type(invite, "application/sdp");
eXosip_lock(excontext);
i = eXosip_call_send_initial_invite(excontext, invite); //invite SIP INVITE message to send
eXosip_unlock(excontext);
//发送了INVITE消息,等待应答
flag1 = 1;
while (flag1)
{
je = eXosip_event_wait(excontext, 0, 200); //Wait for an eXosip event
//(超时时间秒,超时时间毫秒)
if (je == NULL)
{
printf("No response or the time is over!\n");
break;
}
switch (je->type) //可能会到来的事件类型
{
case EXOSIP_CALL_INVITE: //收到⼀个INVITE请求
printf("a new invite received!\n");
case EXOSIP_CALL_PROCEEDING: //收到100 trying消息,表⽰请求正在处理中
printf("proceeding!\n");
break;
case EXOSIP_CALL_RINGING: //收到180 Ringing应答,表⽰接收到INVITE请求的UAS正在向被叫⽤户振铃 printf("ringing!\n");
printf("call_id is %d,dialog_id is %d \n", je->cid, je->did);
break;
case EXOSIP_CALL_ANSWERED: //收到200 OK,表⽰请求已经被成功接受,⽤户应答
printf("ok!connected!\n");
call_id = je->cid;
dialog_id = je->did;
printf("call_id is %d,dialog_id is %d \n", je->cid, je->did);
//回送ack应答消息
eXosip_call_build_ack(excontext, je->did, &ack);
eXosip_call_send_ack(excontext, je->did, ack);
flag1 = 0; //推出While循环
break;
case EXOSIP_CALL_CLOSED: //a BYE was received for this call
printf("the other sid closed!\n");
break;
case EXOSIP_CALL_ACK: //ACK received for 200ok to INVITE
printf("ACK received!\n");
break;
default: //收到其他应答
printf("other response!\n");
break;
}
eXosip_event_free(je); //Free ressource in an eXosip event
}
break;
case 'h': //挂断
printf("Holded!\n");
eXosip_lock(excontext);
eXosip_call_terminate(excontext, call_id, dialog_id);
eXosip_unlock(excontext);
break;
case 'c':
printf("This modal is not commpleted!\n");
break;
case 's': //传输INFO⽅法
eXosip_call_build_info(excontext, dialog_id, &info);
_snprintf_s(tmp, 4096, "\nThis is a sip message(Method:INFO)");
osip_message_set_body(info, tmp, strlen(tmp));
//格式可以任意设定,text/plain代表⽂本信息;
osip_message_set_content_type(info, "text/plain");
eXosip_call_send_request(excontext, dialog_id, info);
break;
case 'm':
//传输MESSAGE⽅法,也就是即时消息,和INFO⽅法相⽐,我认为主要区别是:
//MESSAGE不⽤建⽴连接,直接传输信息,⽽INFO消息必须在建⽴INVITE的基础上传输
printf("the method : MESSAGE\n");
eXosip_message_build_request(excontext, &message, "MESSAGE", dest_call, source_call, NULL);
//内容,⽅法, to ,from ,route
_snprintf_s(tmp, 4096, "This is a sip message(Method:MESSAGE)");
osip_message_set_body(message, tmp, strlen(tmp));
//假设格式是xml
osip_message_set_content_type(message, "text/xml");
eXosip_message_send_request(excontext, message);
case 'q':
eXosip_quit(excontext);
printf("Exit the setup!\n");
flag = 0;
break;
}
}
osip_free(excontext);
return(0);
}
invite sdp 格式参照如下:
INVITEsip:***********.54.2:5060SIP/2.0
Via: SIP/2.0/UDP 10.4.46.1:49552;rport;branch=z9hG4bK2032385714
From:<sip:*********.46.1:49552>;tag=1798441523
To:<sip:***********.54.2:5060>
Call-ID: 3012165000
CSeq: 21 INVITE
Contact:<sip:*********.46.1:49552>
Proxy-Authorization: Digest username="8006", realm="BCC", nonce="0af1a282e6687dc7fe2442989bf23ea4",
uri="sip:***********.54.2:5060",response="51f136f0c58570397ba1b94c256d12b9",algorithm=MD5
Content-Type: application/sdp
Call-Info: <witen:609099>;type=videoupload;fmt=D1/CIF/QCIF;camera=1;user_confirm=0;mute=1
Max-Forwards: 70
User-Agent: #SDK Console 3.0
Subject: ## Dispatch Console!
Content-Length: 307
v=0
o=DConsole 1 1 IN IP4 10.4.46.1
s=##DConsole demo
c=IN IP4 10.4.46.1
t=0 0
m=audio 62100 RTP/AVP 114 0 8 101
a=rtpmap:114 AMR/8000
a=fmtp:114 octet-align=1;mode-set=7,0
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
m=video 62102 RTP/AVP 102 99
a=rtpmap:102 H264/90000
a=rtpmap:99 MP4V-ES/90000
3、复制如下代码⽣成UAS,该实例使⽤的是windows控制台程序,对于sdp的解析部分需修改⼀下,请参照⾳频的获取⽅式修改视频sdp 解析代码。
代码如下:
# include <eXosip2/eXosip.h>
# include <stdio.h>
# include <stdlib.h>
# include <Winsock2.h>
int main(int argc, char *argv[])
{
eXosip_event_t *je = NULL;
switch语句具体例子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:***********.0.115";
char*dest_call="sip:***********.0.115:15060";//clientip
char command;
char tmp[4096];
char localip[128];
int pos = 0;
//初始化sip
struct eXosip_t *excontext;
excontext = eXosip_malloc();
i = eXosip_init(excontext);
if (i != 0)
{
printf("Can't initialize eXosip!\n");
return -1;
}
else
{
printf("eXosip_init successfully!\n");
}
i = eXosip_listen_addr(excontext, IPPROTO_UDP, NULL, 15061, AF_INET, 0); if (i != 0)
{
eXosip_quit(excontext);
fprintf(stderr, "eXosip_listen_addr error!\nCouldn't initialize transport layer!\n"); }
for (;;)
{
//侦听是否有消息到来
je = eXosip_event_wait(excontext, 0, 50);
//协议栈带有此语句,具体作⽤未知
eXosip_lock(excontext);
eXosip_default_action(excontext, je);
//eXosip_automatic_refresh();
eXosip_automatic_action(excontext);
eXosip_unlock(excontext);
if (je == NULL)//没有接收到消息
continue;
// printf ("the cid is %s, did is %s/n", je->did, je->cid);
switch (je->type)
{
case EXOSIP_MESSAGE_NEW://新的消息到来
printf(" EXOSIP_MESSAGE_NEW!\n");
if (MSG_IS_MESSAGE(je->request))//如果接受到的消息类型是MESSAGE
{
{
osip_body_t *body;
osip_message_get_body(je->request, 0, &body);
printf("I get the msg is: %s\n", body->body);
//printf ("the cid is %s, did is %s/n", je->did, je->cid);
}
//按照规则,需要回复OK信息
eXosip_message_build_answer(excontext, je->tid, 200, &answer);
eXosip_message_send_answer(excontext, je->tid, 200, answer);
}
break;
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论