GB28181的设备端开发(二)接收发送xml格式的message信令

3 篇文章 4 订阅
2 篇文章 0 订阅

一、Message信令流程

在GB28181规定中,源设备(对我们来说就是sip服务器)向目标设备发送设备控制命令, 控制命令的类型包括球机/云台控制、 远程启动、 录像控制、报警布防/ 撤防、 报警复位、 强制关键帧、 拉框放大、 拉框缩小、 看守位控制、 设备配置等, 设备控制采用IETFRFC3428 中的Message 方法实现。

命令流程分为:
1.无应答命令流程
在这里插入图片描述
命令流程描述如下:
a ) 1 : 源设备向SIP 服务器发送设备控制命令, 设备控制命令采用Message 方法携带;
b ) 2 : SIP 服务器收到命令后返回200OK ;
c ) 3 : SIP 服务器向目标设备发送设备控制命令, 设备控制命令采用Message 方法携带;
d ) 4 : 目标设备收到命令后返回200OK 。

2.有应答命令流程
在这里插入图片描述
命令流程描述如下:
a ) 1 : 源设备向SIP 服务器发送设备控制命令, 设备控制命令采用Message 方法携带;
b ) 2 : SIP 服务器收到命令后返回200OK ;
c ) 3 : SIP 服务器向目标设备发送设备控制命令, 设备控制命令采用Message 方法携带;
d ) 4 : 目标设备收到命令后返回200OK ;
e ) 5 : 目标设备向SIP 服务器发送设备控制响应命令, 设备控制响应命令采用Message 方法携带;
f ) 6 : SIP 服务器收到命令后返回200OK ;
g ) 7 : SIP 服务器向源设备转发设备控制响应命令, 设备控制响应命令采用Message 方法携带;
h ) 8 : 源设备收到命令后返回200OK 。

看上去挺复杂,但实际上只有3、4、5、6是在和设备端通信的,4是由pjsip自动完成的的,我们只用关心3和5就行。

二、设备目录信息查询命令流程

接下来以设备目录信息查询(Catalog)为例,介绍一下Message信令的收发流程。之所以以Catalog为例进行讲解,是因为在向SIP服务器完成注册后,服务器会立马向设备发送一条Catalog的Message。Catalog是一条有应答命令,放上服务器记录的log,大家可以当做抓包来看,这里的设备端是我搞到的一台支持GB28181的网络摄像头。

3 : SIP 服务器向目标设备发送设备控制命令, 设备控制命令采用Message 方法携带;

MESSAGE sip:34020000002000000113@192.168.31.113 SIP/2.0
Via: SIP/2.0/UDP 192.168.31.103:15060;rport;branch=z9hG4bK792117068
From: <sip:34020000002000000001@3402000000>;tag=622117068
To: <sip:34020000002000000113@192.168.31.113>
Call-ID: 325117068
CSeq: 5 MESSAGE
Content-Type: Application/MANSCDP+xml
Max-Forwards: 70
User-Agent: LiveGBS v201123
Content-Length: 157

<?xml version="1.0" encoding="GB2312"?>
<Query>
  <CmdType>Catalog</CmdType>
  <SN>354117068</SN>
  <DeviceID>34020000002000000113</DeviceID>
</Query>

4 : 目标设备收到命令后返回200 OK ;

SIP/2.0 200 OK
Via: SIP/2.0/UDP 192.168.31.103:15060;rport=15060;received=192.168.31.103;branch=z9hG4bK792117068
Call-ID: 325117068
From: <sip:34020000002000000001@3402000000>;tag=622117068
To: <sip:34020000002000000113@192.168.31.113>;tag=z9hG4bK792117068
CSeq: 5 MESSAGE
Content-Length:  0

5 : 目标设备向SIP 服务器发送设备控制响应命令, 设备控制响应命令采用Message 方法携带;

MESSAGE sip:34020000002000000001@192.168.31.103:15060 SIP/2.0
Via: SIP/2.0/UDP 192.168.31.113:5060;rport;branch=z9hG4bKPj78yEWRJSrGA8PnksHhS2OHW4xuf29LZJ
Max-Forwards: 70
From: <sip:34020000002000000113@192.168.31.113>;tag=aMet8ZHT6HSTG.QdNpNGSTXxklKFuZth
To: <sip:34020000002000000001@192.168.31.103:15060>
Call-ID: gd98PDdY2I4lgYixMWrblWG14b9lRs.N
CSeq: 38630 MESSAGE
Contact: <sip:34020000002000000001@192.168.31.113:5060>
Content-Type: Application/MANSCDP+xml
Content-Length:   802

<?xml version="1.0"?>
<Response>
<CmdType>Catalog</CmdType>
<SN>354117068</SN>
<DeviceID>34020000002000000113</DeviceID>
<SumNum>1</SumNum>
<DeviceList Num="1">
<Item>
<DeviceID>34020000002000000113</DeviceID>
<Name>Camera</Name>
<Manufacturer>IPC_Company</Manufacturer>
<Model>HI351X</Model>
<Owner>General</Owner>
<CivilCode>3402000000</CivilCode>
<Block>General</Block>
<Address>China</Address>
<Parental>0</Parental>
<ParentID>34020000002000000001</ParentID>
<SafetyWay>0</SafetyWay>
<RegisterWay>1</RegisterWay>
<Secrecy>0</Secrecy>
<IPAddress>192.168.31.113</IPAddress>
<Port>5060</Port>
<Status>ON</Status>
<Longitude>0.0</Longitude>
<Latitude>0.0</Latitude>
<Info>
<PTZType>3</PTZType>
<Resolution>6/5/4/2</Resolution>
</Info>
</Item>
</DeviceList>
</Response>

6 : SIP 服务器收到命令后返回200 OK ;

SIP/2.0 200 OK
Via: SIP/2.0/UDP 192.168.31.113:5060;rport=5060;received=192.168.31.113;branch=z9hG4bKPj78yEWRJSrGA8PnksHhS2OHW4xuf29LZJ
From: <sip:34020000002000000113@192.168.31.113>;tag=aMet8ZHT6HSTG.QdNpNGSTXxklKFuZth
To: <sip:34020000002000000001@192.168.31.103:15060>;tag=894117081
CSeq: 38630 MESSAGE
Call-ID: gd98PDdY2I4lgYixMWrblWG14b9lRs.N
User-Agent: LiveGBS v201123
Contact: <sip:34020000002000000001@192.168.31.103:15060>
Content-Length: 0

3、解析和生成xml格式信息

可以看出,message信令的body是xml格式的,为了解析和生成xml信息,我们需要一个xml的库,我用的是mini-xml。安装和使用方法可以参考下面链接。

Mini-XML(MXML)的交叉编译与使用

响应命令里DeviceList 元素的属性对应的就是青柿服务器里通道的个数了。
其他元素的含义在《GBT 28181-2016 公共安全视频监控联网系统信息传输、交换、控制技术要求》的附录A里都有详细的说明。

4、pjsip实现接收和发送Message信令

pjsip接收到message消息时可通过on_pager回调函数读取接收到的内容
函数原型:

https://www.pjsip.org/pjsip/docs/html/structpjsua__callback.htm

通过pjsua_im_send函数发送message消息
函数原型:

https://www.pjsip.org/pjsip/docs/html/group__PJSUA__LIB__BUDDY.htm

使用方法:

//在pjsua_init时修改回调函数
	pjsua_config cfg;
	pjsua_config_default(&cfg);
	cfg.cb.on_pager=&on_pager;
void on_pager (pjsua_call_id call_id, const pj_str_t *from, const pj_str_t *to, const pj_str_t *contact, const pj_str_t *mime_type, const pj_str_t *body)
{
	mxml_node_t *tree;	//新建xml节点
	int space;
	tree = mxmlLoadString(NULL,body->ptr,MXML_TEXT_CALLBACK);	//从字符串读取xml信息	
	mxml_node_t *CmdType = mxmlFindElement(tree, tree, "CmdType",NULL, NULL,MXML_DESCEND);	//查找CmdType元素
	if(strcmp("Catalog",mxmlGetText(CmdType, &space)) == 0)
	{
		mxml_node_t		*xml, *data;
		xml  = mxmlNewXML("1.0");
	  	mxml_node_t *Response = mxmlNewElement(xml, "Response");
		/************
		*处理接收到的信息,安装格式要求生成设备目录信息
		*************/
		#if 1	//通过whitespace_cb回调函数修改输出的格式
		char *buff = mxmlSaveAllocString ( xml, whitespace_cb );
		#else	//不调用回调函数(不插人任何空格,制表符,回车符和换行符)
		mxmlSetWrapMargin(0);		//控制输出的边距,默认为75以方便阅读
		char *buff = mxmlSaveAllocString ( xml, MXML_NO_CALLBACK );
		#endif
		if(buff==NULL)
			perror("mxmlSaveFile err:");
		pj_str_t to = pj_str("sip:34020000002000000001@3402000000");
		pj_str_t content = pj_str(buff);
		pj_str_t type = pj_str("Application/MANSCDP+xml");
		//响应catalog请求
		int status = pjsua_im_send(acc_id, &to, &type, &content , NULL, NULL);//acc_id为上一章设置SIP用户信息时生成的
		if (status != PJ_SUCCESS)
		{
			PJ_LOG(2, (__FILE__, "发送消息失败 %d",status));
		}
		free(buff);
		mxmlDelete(xml);	//释放内存
	}
	mxmlDelete(tree);	//释放内存
}
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值