Sipdroid源码初探(二):监听来电,通话建立流程
来源:互联网 发布:top域名不备案会怎么样 编辑:程序博客网 时间:2024/04/25 02:14
sip协议的相关背景知识
SIP协议是一个Client/Sever协议,因此SIP消息分两种:请求消息和响应消息。请求消息是SIP客户端为了激活特定操作而发给服务器端的消息。常用的SIP请求消息如下:
INVITE:表示主叫用户发起会话请求,邀请其他用户加入一个会话。也可以用在呼叫建立后用于更新会话(此时该INVITE又称为Re-invite)。
ACK:客户端向服务器端证实它已经收到了对INVITE请求的最终响应。
PRACK:表示对1xx响应消息的确认请求消息。
BYE:表示终止一个已经建立的呼叫。
CANCEL:表示在收到对请求的最终响应之前取消该请求,对于已完成的请求则无影响。
REGISTER:表示客户端向SIP服务器端注册列在To字段中的地址信息。
OPTIONS:表示查询被叫的相关信息和功能。SIP协议中的响应消息用于对请求消息进行响应,指示呼叫的成功或失败状态。
常用的一些响应消息:100试呼叫(Trying)
180振铃(Ringing)
181呼叫正在前转(Call is Being Forwarded)
200成功响应(OK)
302临时迁移(Moved Temporarily)
400错误请求(Bad Request)
401未授权(Unauthorized)
403禁止(Forbidden)
404用户不存在(Not Found)
408请求超时(Request Timeout)
480暂时无人接听(Temporarily Unavailable)
486线路忙(Busy Here)
504服务器超时(Server Time-out)
600全忙(Busy Everywhere)
以上背景知识在下面的代码分析中会用到。
开始
为了了解如何监听来电,我们从Sipdroid.StartEngine()开始,一步一步写出函数的调用过程。过程如下:
Sipdroid.StartEngine() -> Sipdroid.listen() -> UserAgent.listen() ->ExtendedCall.listen() -> ExtendedInviteDialog.listen() -> InviteTransactionServer.listen()
好戏从InviteTransactionServer.listen()开始,下面是代码:
public void listen() { printLog("start", LogLevel.LOW); if (statusIs(STATE_IDLE)) { changeStatus(STATE_WAITING); sip_provider.addSipProviderListener(new TransactionIdentifier( SipMethods.INVITE), this); sip_provider.addSipProviderListener(new TransactionIdentifier( SipMethods.OPTIONS), this); } }
大概得看上去,这里是给sip_provider添加了几个Listener,参数中寻找回调接口时发现了this,那就是在本类中了。寻找后发现回调方法就是这个了:
public void onReceivedMessage(SipProvider provider, Message msg) { if (msg.isRequest()) { String req_method = msg.getRequestLine().getMethod(); // invite 消息收到 if (req_method.equals(SipMethods.INVITE)) { if (statusIs(STATE_WAITING)) { request = new Message(msg); connection_id = request.getConnectionId(); transaction_id = request.getTransactionId(); sip_provider.addSipProviderListener(transaction_id, this); sip_provider .removeSipProviderListener(new TransactionIdentifier( SipMethods.INVITE)); changeStatus(STATE_TRYING); // automatically send "100 Tryng" response and go to // STATE_PROCEEDING //自动回复"100 Tryng"消息 if (auto_trying) { Message trying100 = MessageFactory.createResponse( request, 100, SipResponses.reasonOf(100), null); respondWith(trying100); // this method makes it going // automatically to // STATE_PROCEEDING } if (transaction_listener != null) transaction_listener.onTransRequest(this, msg); return; } if (statusIs(STATE_PROCEEDING) || statusIs(STATE_COMPLETED)) { // retransmission // of // the // last // response sip_provider.sendMessage(response, connection_id); return; } } //如果收到的是 OPTIONS 消息 if (req_method.equals(SipMethods.OPTIONS)) { Message ok200 = MessageFactory.createResponse(msg, 200, SipResponses.reasonOf(200), null); ok200.removeServerHeader(); ok200.addContactHeader(new ContactHeader(ok200.getToHeader().getNameAddress()), false); sip_provider.sendMessage(ok200, connection_id); return; } // ack received //如果收到的是 ack 消息 if (req_method.equals(SipMethods.ACK) && statusIs(STATE_COMPLETED)) { retransmission_to.halt(); end_to.halt(); changeStatus(STATE_CONFIRMED); if (transaction_listener != null) transaction_listener.onTransFailureAck(this, msg); clearing_to.start(); return; } } }
初看此方法,可以发现这里面的处理分为三种情况,收到 invite 消息时,收到options 消息时,收到 ack 消息时。本类的名字是InviteTransactionServer,意思是invite消息服务器,就是说这个类是专门用来处理invite消息的,对于其他的消息的处理就在其他的专门的类中了。
结合本文开篇的背景知识,我们就能知道这里实际上就是在对sip协议中的其中三种请求进行处理。根据sip协议,当一个用户想要拨打另一用户,代理服务器会首先将invite消息发给另一用户。在此方法中,我们只看见了对于invite消息进行回复100,根据sip协议,通话的建立是需要两个客户端进行几次握手的,这里仅仅是回复了一次消息,距离通话建立还有几步,不过这里好像就没有看到后续的操作了。
sipdroid的源码分层十分明显,从底层的网络数据接受发送到上层的呼叫的各种状态的建立(来电,接通,取消,挂断等等),每一层都用了单独的类。这里简单记录一下个类的分层情况(这里是仅考虑等待来电到接通电话,其他的代码还没看),从上往下是:
UserAgent(直接处理来电)
ExtendedCall (extends Call)
ExtendedInviteDialog (extends InviteDialog)
InviteTransactionServer
每一层通过回调接口相互联系。具体的流程十分的繁杂,文字叙述还真是很不方便。
- Sipdroid源码初探(二):监听来电,通话建立流程
- Android Sipdroid 对外通话建立过程分析,以及监听通话接通时刻
- Sipdroid会话邀请流程(二)
- Sipdroid会话邀请流程(二)
- Sipdroid中通话问题
- Sipdroid源码初探(一):用户注册(RegisterAgent)
- android源码开发之监听来电状态
- 来电监听
- 来电监听
- Android电话来电流程源码分析
- Android电话来电流程源码分析
- Android电话来电流程源码分析 .
- 远程来电流程分析---之二
- Android Sipdroid 语音通话项目简单使用
- Sipdroid数据发送流程
- Sipdroid数据发送流程
- sipdroid 拨号流程
- sipdroid 接听电话流程
- hadoop中使用MapReduce编程实例(转)
- 利用Google成为一个更好的程序员
- 抽象数据类型与类层次(一)
- 自己实现 一个MapReduce 示例
- POJ 1703 Find them, Catch them
- Sipdroid源码初探(二):监听来电,通话建立流程
- linux进程的后台运行、查看、关闭等命令
- C#设计模式05-建造者模式
- latex的数学符号式子(自用
- 忽略ssl使用httpclient访问阿里支付宝
- MapReduce经典案例分享
- 以前写的比较实用的mysql代码[1]
- xml
- 不同框架下相册及相机的使用权限