libeXosip2(1-2) -- How-To initiate, modify or terminate calls.

How-To initiate, modify or terminate calls.

The eXtented eXosip stack

eXosip2 offers a flexible API to help you controling calls.

Initiate a call

To start an outgoing call, you typically need a few headers which will be used by eXosip2 to build a default SIP INVITE request. The code below is used to start a call:

osip_message_t *invite;

int cid;

int i;

i = eXosip_call_build_initial_invite (ctx, &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 (ctx, AF_INET, localip, 128);

snprintf (tmp, 4096,

"v=0\r\n"

"o=jack 0 0 IN IP4 %s\r\n"

"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 (ctx);

cid = eXosip_call_send_initial_invite (ctx, invite);

if (cid > 0)

{

eXosip_call_set_reference (ctx, i, reference);

}

eXosip_unlock (ctx);

return i;

The above code is using eXosip_call_build_initial_invite to build a default SIP INVITE request for a new call. You have to insert a SDP body announcing your audio parameter for the RTP stream.

The above code also show the flexibility of the eXosip2 API which allow you to insert additionnal headers such as "Supported: 100rel" (announcing support for a SIP extension). Thus you can enterely control the creation of SIP requests.

The returned element of eXosip_call_send_initial_invite is the cid (call identifier) that you can use to send a CANCEL. In future events other than 100 Trying, you‘ll also get the did (dialog identifier) that will also be needed to control established calls.

eXosip_call_set_reference is also a mean to attach one of your own context to a call so that you‘ll get your pointer back in eXosip_event.

Answer a call

The code below is another example that teach you how to answer an incoming call.

You‘ll usually need to send a "180 Ringing" SIP answer when receiving a SIP INVITE:

eXosip_lock (ctx);

eXosip_call_send_answer (ctx, evt->tid, 180, NULL);

eXosip_unlock (ctx);

Note: The above code also shows that the stack is sometimes able to build and send a default SIP messages with only one API call

Then, when the user wants to answer the call, you‘ll need to send a 200 ok and insert a SDP body in your SIP answer:

osip_message_t *answer = NULL;

eXosip_lock (ctx);

i = eXosip_call_build_answer (ctx, evt->tid, 200, &answer);

if (i != 0)

{

eXosip_call_send_answer (ctx, evt->tid, 400, NULL);

}

else

{

i = sdp_complete_200ok (evt->did, answer);

if (i != 0)

{

osip_message_free (answer);

eXosip_call_send_answer (ctx, evt->tid, 415, NULL);

}

else

eXosip_call_send_answer (ctx, evt->tid, 200, answer);

}

eXosip_unlock (ctx);

Note: In the above code, you can note that to send a response to a request, you have to use the tid (transaction identifier) and not a cid (call identifier) or a did (dialog identifier).

Note2: For sending a 200ok, you‘ll usually need to insert a SDP body in the answer and before this, to negotiate the parameters and codecs that you want to support. This is left to you! Once you have created the SDP, you add it in the answer using the following code:

osip_message_set_body (answer, tmp, strlen (tmp));

osip_message_set_content_type (answer, "application/sdp");

Terminate a Call

Simple API, no much to say about it! You can use it when you want: it will either send a CANCEL, a negative answer or a BYE depending on the call state.

eXosip_lock (ctx);

eXosip_call_terminate (ctx, cid, did);

eXosip_unlock (ctx);

Note: You can‘t stop a call where no 100 Trying has been received. In that case, you need to wait before sending a CANCEL or a BYE... This is per rfc3261.

Sending INFO, REFER, UPDATE, NOTIFY, OPTIONS request

The call control API allows you to send and receive REFER, UPDATE, INFO, OPTIONS, NOTIFY and INVITEs whitin calls.

Here you have a code sample to send an INFO requests used to send an out of band dtmf within the signalling layer. (not standard, but still used on some system!)

osip_message_t *info;

char dtmf_body[1000];

int i;

eXosip_lock (ctx);

i = eXosip_call_build_info (ctx, evt->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 (ctx, evt->did, info);

}

eXosip_unlock (ctx);

Sending any other request, with any header

You can in fact, send any kind of other request using eXosip2 API.

You will find many other API to build any kind of sip message. Using osip API, you can add any header or body in those message. eXosip2 will always prepare the minimal and technical stuff you need.

osip_message_t *message;

char body[1000];

int i;

eXosip_lock (ctx);

i = eXosip_call_build_request (ctx, evt->did, "PRIVATECOMMAND", &message);

if (i == 0)

{

snprintf (body, 999, "room=1;light=on\r\nroom=2;light=off\r\n");

osip_message_set_content_type (message, "application/antisip-domotic");

osip_message_set_body (message, body, strlen (body));

osip_message_set_header (invite, "P-MyCommand", "option=value");

i = eXosip_call_send_request (ctx, evt->did, message);

}

eXosip_unlock (ctx);



libeXosip2(1-2) -- How-To initiate, modify or terminate calls.

时间: 2024-10-11 17:53:30

libeXosip2(1-2) -- How-To initiate, modify or terminate calls.的相关文章

libeXosip2(1) -- Modules

Modules Here is a list of all modules: [detail level 12] The eXtented eXosip stack LibeXosip2 Version 4.0.0 How-To initialize libeXosip2. How-To initiate, modify or terminate calls. How-To send or update registrations. General purpose API. General pu

libeXosip2(1-3) -- How-To send or update registrations.

How-To send or update registrations. The eXtented eXosip stack Initiate a registration To start a registration, you need to build a default REGISTER request by providing several mandatory headers. You can start as many registration you want even in o

IMS Modify Call (2) receive request 收到视频升级请求

主要内容为MT收到视频升级的请求的过程,也是MT消息上传的过程. 流程图 可以看到信息上报跨了4个模块,没有经过service/Telecom 看关键log方便跟踪 06-19 19:05:41.437 3329-4362/com.android.phone V/ImsSenderRxr: Read packet: 24 bytes 06-19 19:05:41.437 3329-4362/com.android.phone V/ImsSenderRxr: processResponse[SUB

IMS Modify Call (1) send request 发出升级视频请求

upgrade/downgrade 升降级,其实就是ModifyCall 整体示意 图中有两种情况,一种是MT对收到的升级请求做出响应,一种是超时后服务器给双发发送消息. 一个完整的Modify call(upgrade)可以分为4个部分,本文主要讲第一部分发出升级请求. 流程图 界面入手 packages/apps/InCallUI packages/apps/InCallUI/src/com/android/incallui/CallButtonFragment.java CallButto

PHP错误Warning: Cannot modify header information - headers already sent by解决方法

这篇文章主要介绍了PHP错误Warning: Cannot modify header information - headers already sent by解决方法,需要的朋友可以参考下 今天在测试以下代码时遇到该错误: 复制代码代码如下: session_start();$_SESSION['username']=$username;echo "<script language='javascript'>location.href='../admin.php';</sc

出现Warning: Cannot modify header information - headers already sent by ..的解决办法

这个错误的出现,原因是: 出这个错误是因为 header('Content-Type:text/html;charset= UTF-8');发送头之前不能有任何输出. 检查了下我的输出,错误信息如下: Warning: Cannot modify header information - headers already sent by (output started at /data/home/qxu1084910324/htdocs/bw_feature.php:1) in /data/hom

Cannot modify header information问题的解决方法(php)

我做了一个统一的出错提示函数,在函数执行里面,先处理出错的地址写入cookie以方便用户登陆以后可以直接跳转到要执行的这个页面,可是发现在服务器上测试时,竟然提示本地没有出现的错误: Warning: Cannot modify header information - headers already sent by....这样的语句,很显然,造成这个原因是因为setcookie造成的,查了一下网上,有如下的解释: cookie本身在使用上有一些限制,例如:1.呼叫setcookie的敘述必須放

OJ2.0userInfo页面Modify逻辑bug修复,search功能逻辑实现

这周的主要任务:userInfo页面Modify逻辑bug修复,search功能逻辑实现. (一)Modify逻辑bug修复: 这里存在的bug就是在我们不重置密码的时候按照前面的逻辑是不能提交修改,这个逻辑是错误的,应该改为可以不修改密码也能提交,主要是if逻辑判断的修改 先看一下代码: def userInfo(request, user_id): try: user = User.objects.get(userID = request.session['userID']) except:

Demo_张仕传_结构体考试-modify

/* 题目: //声明一个结构体类型 struct _AdvTeacher { char *name; char *tile; int age; char *addr; char *p1; //系统预留成员域 char **p2;//系统预留成员域 }; 要求定义一个结构体数组(6个元素),要求从键盘输入数据,并按照名称大小进行排序:打印输出. 1. 打印结构体数组,需要单独封装成函数:10 2. 排序结构体数组,需要单独封装成函数(按照名称进行排序):50 3. main函数中编写业务测试模型