zoukankan      html  css  js  c++  java
  • Sipdroid实现SIP(三): 消息接收处理

    I. 注册回调

    RegisterAgent类

    在TransactionClient Fail/Success的回调中, 调用RegisterAgentListener的Register Fail/Sucess接口

    public class RegisterAgent implements TransactionClientListener, SubscriberDialogListener {
        
      RegisterAgentListener listener;
    public RegisterAgent(...RegisterAgentListener listener, ...) {} public void onTransSuccessResponse(TransactionClient ransaction, Message resp) { listener.onUaRegistrationSuccess(this, target, contact, result); } public void onTransFailureResponse(TransactionClient, Message resp) { listener.onUaRegistrationFailure(this, target, contact, result); } public void onTransTimeout(TransactionClient transaction) { listener.onUaRegistrationFailure(this, target, contac, "Timeout"); listener.onUaRegistrationSuccess(this, target, contac, "Timeout"); } }

    TransactionClient类/--->SipProviderListener

    1. extends Transaction

    public abstract class Transaction implements SipProviderListener, TimerListener {
        public void onReceivedMessage(SipProvider provider, Message msg){}
    }

    2. TransactionClient类

    在Transaction Fail/Success(实际的SipProvider回调)的回调中, 调用TransactionClient的 Fail/Sucess接口

    public class TransactionClient extends Transaction {
        TransactionClientListener transaction_listener;
    
        public TransactionClient(SipProvider sip_provider, Message req, TransactionClientListener listener) {
            super(sip_provider);
            request = new Message(req);
            init(listener, request.getTransactionId()); //this.transaction_listener = listener;
        }
        //实际上的SipProvider回调
    public void onReceivedMessage(SipProvider provider, Message msg) { transaction_listener.onTransSuccessResponse(this, msg); transaction_listener.onTransFailureResponse(this, msg); } pulic void onTimeout(Timer to) { //和超时相关的transaction_listener回调 } }

    所以, SipProviderListener又是哪个对象触发的呢?


    II. 来电回调

    我真的太机智了, Sipdroid回调嵌套得很深, 从回调处理顺藤摸瓜找到回调触发很复杂, 找着找着就迷失在代码里. 倒不如来个crash, Boom! Runtime Exception blablabla... 然后系统就寄几把函数调用堆栈打印出来了蛤蛤蛤~

    12-19 10:43:03.284 26271-26297/com.hik.visapp I/System.out: UA: onCallAccepted()
    12-19 10:43:03.284 26271-26297/com.hik.visapp I/System.out: UA: ACCEPTED/CALL
    12-19 10:43:03.284 26271-26297/com.hik.visapp I/System.out: SipProvider: WARNING: Error handling a new incoming message
    12-19 10:43:03.285 26271-26297/com.hik.visapp W/System.err: java.lang.RuntimeException: Tried to costruct a new Parser with a null String
    12-19 10:43:03.285 26271-26297/com.hik.visapp W/System.err:     at org.zoolu.tools.Parser.<init>(Parser.java:64)
    12-19 10:43:03.285 26271-26297/com.hik.visapp W/System.err:     at org.zoolu.sdp.SdpParser.<init>(SdpParser.java:39)
    12-19 10:43:03.285 26271-26297/com.hik.visapp W/System.err:     at org.zoolu.sdp.SessionDescriptor.<init>(SessionDescriptor.java:205)
    12-19 10:43:03.285 26271-26297/com.hik.visapp W/System.err:     at org.sipdroid.sipua.UserAgent.launchMediaApplication(UserAgent.java:430)
    12-19 10:43:03.285 26271-26297/com.hik.visapp W/System.err:     at org.sipdroid.sipua.UserAgent.onCallAccepted(UserAgent.java:626)
    12-19 10:43:03.285 26271-26297/com.hik.visapp W/System.err:     at org.zoolu.sip.call.Call.onDlgInviteSuccessResponse(Call.java:312)
    12-19 10:43:03.285 26271-26297/com.hik.visapp W/System.err:     at org.zoolu.sip.dialog.InviteDialog.onTransSuccessResponse(InviteDialog.java:792)
    12-19 10:43:03.285 26271-26297/com.hik.visapp W/System.err:     at org.zoolu.sip.dialog.ExtendedInviteDialog.onTransSuccessResponse(ExtendedInviteDialog.java:322)
    12-19 10:43:03.285 26271-26297/com.hik.visapp W/System.err:     at org.zoolu.sip.transaction.InviteTransactionClient.onReceivedMessage(InviteTransactionClient.java:145)
    12-19 10:43:03.285 26271-26297/com.hik.visapp W/System.err:     at org.zoolu.sip.provider.SipProvider.processReceivedMessage(SipProvider.java:1076)
    12-19 10:43:03.285 26271-26297/com.hik.visapp W/System.err:     at org.zoolu.sip.provider.SipProvider.onReceivedMessage(SipProvider.java:1206)
    12-19 10:43:03.285 26271-26297/com.hik.visapp W/System.err:     at org.zoolu.sip.provider.UdpTransport.onReceivedPacket(UdpTransport.java:122)
    12-19 10:43:03.286 26271-26297/com.hik.visapp W/System.err:     at org.zoolu.net.UdpProvider.run(UdpProvider.java:189)
    12-19 10:43:03.286 26271-26297/com.hik.visapp W/System.err: Error handling a new incoming message

    传输层通知SipProvider偏向底层, 现在先跳过. SipProvider是怎样通知到Transaction的呢?

    Version:0.9 StartHTML:-1 EndHTML:-1 StartFragment:0000000111 EndFragment:0000007686

    /**
    * SipProvider implements the SIP transport layer, that is the layer responsable
    * for sending and receiving SIP messages. Messages are received by the callback
    * function defined in the interface SipProviderListener.
    * <p>
    * SipProvider implements also multiplexing/demultiplexing service through the
    * use of SIP interface identifiers and <i>onReceivedMessage()<i/> callback
    * function of specific SipProviderListener.
    * <p>
    * A SipProviderListener can be added to a SipProvider through the
    * addSipProviderListener(id,listener) method, where: <b> - <i>id<i/> is the
    * SIP interface identifier the listener has to be bound to, <b> - <i>listener<i/>
    * is the SipProviderListener that received messages are passed to. <p/> The SIP
    * interface identifier specifies the type of messages the listener is going to
    * receive for. Together with the specific SipProvider, it represents the
    * complete SIP Service Access Point (SAP) address/identifier used for
    * demultiplexing SIP messages at receiving side. <p/> The identifier can be of
    * one of the three following types: transaction_id, dialog_id, or method_id.
    * These types of identifiers characterize respectively: <br> - messages within
    * a specific transaction, <br> - messages within a specific dialog, <br> -
    * messages related to a specific SIP method. It is also possible to use the the
    * identifier ANY to specify <br> - all messages that are out of any
    * transactions, dialogs, or already specified method types.
    * <p>
    * When receiving a message, the SipProvider first tries to look for a matching
    * transaction, then looks for a matching dialog, then for a matching method
    * type, and finally for a default listener (i.e. that with identifier ANY). For
    * the matched SipProviderListener, the method <i>onReceivedMessage()</i> is
    * fired.
    */

    译: SipProvider继承了SIP传输层的接口, 用来响应SIP消息的收/发. 消息的接收由SipProviderListener回调接口实现. 通过SIP接口标识和onReceivedMessage()回调函数(调用)指定的SipProvider监听器, SipProvider还继承了multiplexing/demultiplexing的复用服务功能. 一个SipProvider监听器可以通过addSipProviderListener(id,listener)方法添加到SipProvider的监听表, id是SIP接口标识, listener是收到的msg对应的监听者. SIP接口会根据msg类型区分不同的监听者. msg+指定监听者+指定SipProvider, 代表了一个接收处理方完整的SIP服务访问点(SIP SAP)地址/id. Identification有以下三类:(1)transaction_id; (2)dialog_id; (3)method_id. 这三种标识分别代表了: 包含指定transaction_id的msg; 包含指定dialog_id的msg; 包含指定method_id的msg. 当然也可以通过标识"ANY"来区分: 表示所有msg都不属于以上三类. 每当接收到一个msg时, SipProvider寻找id匹配的顺序是: transaction->dialog->method->default listener(ANY). 如果匹配, 对应的SipProviderListener的onReceivedMessage()方法将被调用.

  • 相关阅读:
    Python的object和type理解及主要对象层次结构
    【译】Matplotlib:plotting
    random
    【译】itertools
    VBA笔记
    Python Function
    Outlook API
    VB参考
    类方法:绑定或无绑定
    【摘录】数据库连接参数
  • 原文地址:https://www.cnblogs.com/elsarong/p/6177892.html
Copyright © 2011-2022 走看看