Sipdroid实现SIP(三): 消息接收处理

本文详细解析了SIP协议中注册回调与来电回调的处理流程,介绍了RegisterAgent类如何实现TransactionClientListener接口,并解释了TransactionClient类在处理SIPProvider回调中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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()方法将被调用.

 

转载于:https://www.cnblogs.com/elsarong/p/6177892.html

### 如何使用 Keil5 Hex 文件 对于仅拥有已编译好的 hex 文件而无源文件的情况,在 Keil V5 平台上直接hex 文件至单片机(如华大单片机)需采取特定的方法,因为直接调用该平台进行此类操作不可行[^1]。 #### 设置 Output 路径 进入 Keil 的 output 设置界面,指定要录的 hex 文件的具体位置。确保在路径输入框中填完整的 hex 文件名称并附带 `.hex` 扩展名;缺少此扩展名可能导致系统继续尝试录先前编译的结果而非所选的 hex 文件[^3]。 #### 配置 Flash 工具选项 针对不同类型的微控制器(MCU),可能还需调整 flash 下载工具的相关配置参数以匹配目标设备的要求。这一步骤通常涉及选择合适的编程算法以及设定通信接口等细节[^2]。 #### 启动下载过程 完成上述准备工作之后,可以通过点击调试窗口内的 “Download” 或者快捷菜单里的相应命令来启动实际的程序入流程。如果一切顺利的话,软件会自动连接硬件并将选定的 hex 数据传输到 MCU 中存储起来[^4]。 ```python # Python 示例代码用于说明自动化脚本概念 (并非真实实现) def download_hex_to_mcu(hex_file_path, mcu_type): """ 自定义函数模拟将 HEX 文件下载到指定型号的 MCU 上 参数: hex_file_path -- 完整路径字符串指向待上传的 .hex 文件 mcu_type -- 字符串表示的目标单片机类型标识符 返回值: 成功则返回 True ,失败抛出异常信息 """ try: configure_output_settings(hex_file_path) # 设定输出设置 select_flash_tool(mcu_type) # 挑选适合的闪存工具 execute_download_command() # 发送下载指令 return True # 表明成功结束 except Exception as e: raise RuntimeError(f"Failed to upload {hex_file_path}: {e}") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值