Android平台GB28181设备接入端本地SIP端口被占用或屏蔽怎么办?

2022-10-04 01:03:06 浏览数 (1)

好多开发者或厂商,对Android平台GB28181接入模块的定位,大多是IPC国标流程打通模拟,基于这个目的,很难按照标准SPEC规范实现Android平台GB28181设备接入,我们在跟第三方国标平台厂商对接时发现,部分公司,尽管参与了标准的制定或审校,自身实现,细节仍不尽人意。

除了作为IPC国标模拟工具,Android平台GB28181设备接入没有实现价值吗?实际上,Android平台GB28181设备接入的用途非常广泛,通过实现不具备国标音视频能力的 Android终端,平台注册接入到现有的GB/T28181—2016服务,可用于如智能监控、智慧零售、智慧教育、远程办公、生产运输、智慧交通、车载或执法记录仪等场景。

Android平台GB28181接入终端除支持常规的音视频数据接入外,还需要支持移动设备位置(MobilePosition)订阅和通知、语音广播和语音对讲。

我们在实现Android平台GB28181设备接入端的时候,有个选项是设置本地SIP端口:

代码语言:javascript复制
GBSIPAgent     gb28181_agent_             = null;
private int    gb28181_sip_local_port_base_  = 5060;
private String gb28181_sip_server_id_     = "34020000002000000001";
private String gb28181_sip_domain_        =  "3402000000";
private String gb28181_sip_server_addr_   = "192.168.2.154";
private int    gb28181_sip_server_port_   = 15060;

private String gb28181_sip_user_agent_filed_  = "DN(daniusdk.com) GB28181 User Agent V1.3";
private String gb28181_sip_username_   = "31011500991320000078";
private String gb28181_sip_password_   = "12345678";

private int gb28181_reg_expired_           = 3600; // 注册有效期时间最小3600秒
private int gb28181_heartbeat_interval_    = 20; // 心跳间隔GB28181默认是60, 目前调整到20秒
private int gb28181_heartbeat_count_       = 3; // 心跳间隔3次失败,表示和服务器断开了
private int gb28181_sip_trans_protocol_    = 0; // 0表示信令用UDP传输, 1表示信令用TCP传输

private long gb28181_rtp_sender_handle_ = 0;
private int  gb28181_rtp_payload_type_  = 96;
private String gb28181_rtp_encoding_name_ = "PS";

设置本地SIP端口的时候,SIP端口有可能被占用(比如大多都是设置5060)或被网络屏蔽,网上常规的做法是设置个看似不常用的端口,比如5061、5062等,虽然能解决绝大多数场景的问题,作为个通用的模块来说,未免过于粗糙,或者说治标不治本。

我们的做法是:设置本地SIP端口的时候,设置个base_local_port, 然后,根据设定的端口,在有效端口范围内,做绑定尝试,如果成功,提示bind local port OK, 然后做其他操作即可,这样可以最大限度的规避端口分配失败。

具体代码如下:

代码语言:javascript复制
int try_end_port = gb28181_sip_local_port_base_   5000;
try_end_port = try_end_port > 65536 ?65536: try_end_port;

for (int i = gb28181_sip_local_port_base_; i < try_end_port;   i) {
	if (gb28181_agent_.bindLocalPort(i)) {
		is_bind_local_port_ok = true;
		break;
	}
}

if (!is_bind_local_port_ok) {
	gb28181_agent_.releaseSipStack();
	gb28181_agent_ = null;
	Log.e(TAG, "initGB28181Agent gb28181_agent_.bindLocalPort failed.");
	return  false;
}

感兴趣的开发者,可以做下尝试。

0 人点赞