想写一个开源的基于onvif协议的C++版本的搜索IPC rtsp地址的工具,希望大家参与
2 E币
成为会员,免费下载资料
文件大小:10.63 KB
上传者:ngswfx
时间:2016-07-10 03:36:38
下载量:69
本帖最后由 ngswfx 于 2016-7-10 05:04 编辑
主要是嫌弃onvif 使用soap方式搞出来的东西,太大,4.8M,即便压缩后,也占用flash约800K-1M(随压缩方法改变,有些差异),PC上没问题,嵌入式arm上有些紧张了。
准备开源,写好后,大家可以直接使用,但希望大家给点建议。
//////如果采用socket方式,直接建立连接,发送网络探测包,发送获取rtsp url关键步骤的几个数据包。由于仅仅获取得到url,这部分代码onvif协议估计不会变化太大,前端IPC变化也应该不会太快。很适合arm上使用,用于仅仅得到url流地址的场合。
返回的数据包,也只需重点过滤得到需要的信息即可。
把整个功能封装为一个独立的.so库当中,被其他程序调用,发现的结果通过回调送到应用层。能得到IPC的rtsp URL就是本so的主要目标。
/////////////由于代码部分只有linux网络等动作,以及一些提前准备好的string,我感觉产生的so应该可以控制在100K左右。
//////////////哪位搞过这个东西,给点建议。我感觉只要协议中是一次发送一个总包过去,就比较容易做,否则每次仅仅发送一个片段,还不停交互信息,就没有这么做的意义了,太繁琐了
我初步计划这样:
1、首先通过抓包工具,探测onvif一次性发出哪些数据包,然后,把这些包,弄成一个char[4096],我也抛给IPC。通过接收返回的数据包,得到设备的xaddr。也就是得到[url]http://192.168.2.22:8888/onvif[/url]这种地址。
2、接下来的几个步骤,还是通过抓包工具,获取每次发出的总数据包,直接保存为文件buff方式,放到代码里面,仿照onvif获取流地址的那几个步骤,也把这些包抛给IPC,直到得到rtsp url地址。
////////////////////////////进展:2016_7_4
//使用抓包工具,以及onvif manager tools等等,搜索设备以及走了一下几个关键的流程。还不错,虽然有些地方有些难度,但总的来说发送出去的是整体包,返回的也是一个个的整体包。
//应该还是可以做的。
感觉现在的难点主要集中在密码这方面:
1、通过搜索设备时probe的到设备的厂商或者型号信息,需要得到设备的默认用户名密码(有些IPC牌子,这个用户名密码可能必须填写正确,才能得到URL),至于海康这种暂不知道怎么弄,他的密码不是默认的,会比较麻烦(过几天再试试HK IPC)。对于其他厂商的,这个就比较好弄。因为这个用户名密码随后的命令里面要用到。
2、通过很onvif相同的方式,计算发出数据包里面密码相关的部分,进行替换。
//////////////
/////////2016_7_10
//编写验证程序,通过广播方式,向"239.255.255.250" 3702 发送2组整体探索包,仿照onvif client tools每种连续发2次,
[code]
char strFoundCMD_A[]={
"uuid:afbda84b-2c06-4e0f-9f9c-b73f3d11a0ab urn:schemas-xmlsoap-org:ws:2005:04:discovery http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe tds:Device "
};
char strFoundCMD_B[]={
"uuid:af1da4ae-26f2-49e6-aabc-ba8384185db9 urn:schemas-xmlsoap-org:ws:2005:04:discovery http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe dn:NetworkVideoTransmitter "
};
[/code]
//////////////已经可以收到类似于:XAddrs:[url]http://192.168.2.65/onvif/device_service[/url] 的地址。也就是说,设备搜索第一步已经完成,onvif client tools能搜索到的设备,这里也都搜索到了。到这里还比较顺利,接下来的GetServices暂准备先做不带验证的,先把整体结构框架弄出来,先避开带验证的难点
,不要一开始就把自己吓死了
第二交互命令GetService:
目标端口8899,发送479数据
[code]POST /onvif/device_service HTTP/1.1
Host: 192.168.2.127
Content-Type: application/soap+xml; charset=utf-8
Content-Length: 347
false [/code]
///////////////////////
很容易,直接就得到了[url]http://192.168.2.142:8899/onvif/Media[/url]地址
既然这么容易,干脆直接发送最后一个GetStreamUrl得了。
跳过第3交互命令getporfile
[code]POST /onvif/Media HTTP/1.1
Host: 192.168.2.142
Content-Type: application/soap+xml; charset=utf-8
Content-Length: 289
[/code]
////////////////第4交互命令请求stream url
[code]POST /onvif/Media HTTP/1.1
Host: 192.168.2.127
Content-Type: application/soap+xml; charset=utf-8
Content-Length: 523
RTP-Unicast RTSP 000 [/code]
/////////////////////通过检查返回的数据包,还真有rtsp地址:呵呵,XM的
SendBuff:640 rcv bk nbytes:3086
GetStreamUrl rtsp:://192.168.2.142:554/user=admin_password=tlJwpbo6_channel=1_ ......
/////////////到此,整个流程基本完毕。看来对于没有强制进行用户验证的设备来说,这种方式,获取rtsp地址,真的很容易。
//////////XM 端口8899的整个流程已经OK了,由于发送出的的包都是按照XM做的,这当然最容易了。
/////////ZW的端口80,GetServices 以及GetProfiles过程都很正常,GetStreamUrl返回异常,估计是发送出去的包不太一样。
///////HK的端口80,GetServices,在返回数据里面包含了设备型号以及需要认证的信息。看来需要按照提示做摘要认证才行。
///////HB的端口8888,没有返回数据,明显有验证流程
///////DH的端口80,GetServices GetProfiles 都正常,GetStreamUrl只要把profile token设置正确,RTSP地址已经得到。
///////////////其实对于特殊端口号而言,rtsp的URL我们其实是知道的,再把这些流程走一边,主要由于厂商可能会调整这个地址。
//////////经过简单的分析,发现不同厂家在描述profile token是不太一样,XM的是000 ,ZW的是MainStreamToken ,DH的是MediaProfile000,经过简单修改GetStreamUrl里面的实现,然后把组合包扔出去,返回数据包解析rtsp字眼。
目前可以成功获取的IPC的厂家有:DH XM ZW,呵呵,看来方法还可以呀,只需要分析出GetProfiles返回的内容中,关于profile token的值即可
做到这里,整个执行程序才30K大小(没有依赖任何onvif的库噢),呵呵,看来值得弄下去,流程思路还比较正确,这种方法应该可行,有完成的必要,这样看来,最后作完兼容性较好的so文件,估计能控制到200K以内。
///////////////接下来做支持认证的:不过这里有个难题,如果设备密码是默认的,我们可以尝试用默认厂商的密码,进行后面的过程,应该可以得到RTSP URL,但如果对于HK这种,就显的意义不是很大了。通过80端口,以及GetServices 和GetProfiles的返回信息,
已经足够定位这是HK的IPC了,由于密码变化范围太大,获取rtsp就显得没有必要了,说白了,我们已经知道了。对于HB设备而言,密码是固定的,做一下也无妨,最起码可以避免厂家中途改rtsp地址。
HK GetProfiles返回信息,提示需要认证,设备型号作为认证的realm了。做认证不难,难在不知道密码。呵呵。
[code]HTTP/1.1 401 Unauthorized
Date: Fri, 08 Jul 2016 01:16:29 GMT
Server: App-webs/
Content-Length: 218
Content-Type: text/html
Connection: close
WWW-Authenticate: Digest qop="auth", realm="DS-2CD2T25D-I5", nonce="4d6b524252"
Document Error: Unauthorized
[/code]
//////////////////附件中是一个nptl100编译的搜索测试程序(应该没啥关联库,启动后,拍一下键盘开始搜索,结果都在控制台,再拍键盘,继续搜索,ctrl+C强制退出)。代码太乱,都是验证代码,还没整理,暂拿不出手。:lol
///////等我把流程再处理一下,放到我的项目里面用一下先。
主要是嫌弃onvif 使用soap方式搞出来的东西,太大,4.8M,即便压缩后,也占用flash约800K-1M(随压缩方法改变,有些差异),PC上没问题,嵌入式arm上有些紧张了。
准备开源,写好后,大家可以直接使用,但希望大家给点建议。
//////如果采用socket方式,直接建立连接,发送网络探测包,发送获取rtsp url关键步骤的几个数据包。由于仅仅获取得到url,这部分代码onvif协议估计不会变化太大,前端IPC变化也应该不会太快。很适合arm上使用,用于仅仅得到url流地址的场合。
返回的数据包,也只需重点过滤得到需要的信息即可。
把整个功能封装为一个独立的.so库当中,被其他程序调用,发现的结果通过回调送到应用层。能得到IPC的rtsp URL就是本so的主要目标。
/////////////由于代码部分只有linux网络等动作,以及一些提前准备好的string,我感觉产生的so应该可以控制在100K左右。
//////////////哪位搞过这个东西,给点建议。我感觉只要协议中是一次发送一个总包过去,就比较容易做,否则每次仅仅发送一个片段,还不停交互信息,就没有这么做的意义了,太繁琐了
我初步计划这样:
1、首先通过抓包工具,探测onvif一次性发出哪些数据包,然后,把这些包,弄成一个char[4096],我也抛给IPC。通过接收返回的数据包,得到设备的xaddr。也就是得到[url]http://192.168.2.22:8888/onvif[/url]这种地址。
2、接下来的几个步骤,还是通过抓包工具,获取每次发出的总数据包,直接保存为文件buff方式,放到代码里面,仿照onvif获取流地址的那几个步骤,也把这些包抛给IPC,直到得到rtsp url地址。
////////////////////////////进展:2016_7_4
//使用抓包工具,以及onvif manager tools等等,搜索设备以及走了一下几个关键的流程。还不错,虽然有些地方有些难度,但总的来说发送出去的是整体包,返回的也是一个个的整体包。
//应该还是可以做的。
感觉现在的难点主要集中在密码这方面:
1、通过搜索设备时probe的到设备的厂商或者型号信息,需要得到设备的默认用户名密码(有些IPC牌子,这个用户名密码可能必须填写正确,才能得到URL),至于海康这种暂不知道怎么弄,他的密码不是默认的,会比较麻烦(过几天再试试HK IPC)。对于其他厂商的,这个就比较好弄。因为这个用户名密码随后的命令里面要用到。
2、通过很onvif相同的方式,计算发出数据包里面密码相关的部分,进行替换。
//////////////
/////////2016_7_10
//编写验证程序,通过广播方式,向"239.255.255.250" 3702 发送2组整体探索包,仿照onvif client tools每种连续发2次,
[code]
char strFoundCMD_A[]={
"
};
char strFoundCMD_B[]={
"
};
[/code]
//////////////已经可以收到类似于:XAddrs:[url]http://192.168.2.65/onvif/device_service[/url] 的地址。也就是说,设备搜索第一步已经完成,onvif client tools能搜索到的设备,这里也都搜索到了。到这里还比较顺利,接下来的GetServices暂准备先做不带验证的,先把整体结构框架弄出来,先避开带验证的难点
,不要一开始就把自己吓死了
第二交互命令GetService:
目标端口8899,发送479数据
[code]POST /onvif/device_service HTTP/1.1
Host: 192.168.2.127
Content-Type: application/soap+xml; charset=utf-8
Content-Length: 347
///////////////////////
很容易,直接就得到了[url]http://192.168.2.142:8899/onvif/Media[/url]地址
既然这么容易,干脆直接发送最后一个GetStreamUrl得了。
跳过第3交互命令getporfile
[code]POST /onvif/Media HTTP/1.1
Host: 192.168.2.142
Content-Type: application/soap+xml; charset=utf-8
Content-Length: 289
////////////////第4交互命令请求stream url
[code]POST /onvif/Media HTTP/1.1
Host: 192.168.2.127
Content-Type: application/soap+xml; charset=utf-8
Content-Length: 523
/////////////////////通过检查返回的数据包,还真有rtsp地址:呵呵,XM的
SendBuff:640 rcv bk nbytes:3086
GetStreamUrl rtsp:://192.168.2.142:554/user=admin_password=tlJwpbo6_channel=1_ ......
/////////////到此,整个流程基本完毕。看来对于没有强制进行用户验证的设备来说,这种方式,获取rtsp地址,真的很容易。
//////////XM 端口8899的整个流程已经OK了,由于发送出的的包都是按照XM做的,这当然最容易了。
/////////ZW的端口80,GetServices 以及GetProfiles过程都很正常,GetStreamUrl返回异常,估计是发送出去的包不太一样。
///////HK的端口80,GetServices,在返回数据里面包含了设备型号以及需要认证的信息。看来需要按照提示做摘要认证才行。
///////HB的端口8888,没有返回数据,明显有验证流程
///////DH的端口80,GetServices GetProfiles 都正常,GetStreamUrl只要把profile token设置正确,RTSP地址已经得到。
///////////////其实对于特殊端口号而言,rtsp的URL我们其实是知道的,再把这些流程走一边,主要由于厂商可能会调整这个地址。
//////////经过简单的分析,发现不同厂家在描述profile token是不太一样,XM的是000 ,ZW的是MainStreamToken ,DH的是MediaProfile000,经过简单修改GetStreamUrl里面的实现,然后把组合包扔出去,返回数据包解析rtsp字眼。
目前可以成功获取的IPC的厂家有:DH XM ZW,呵呵,看来方法还可以呀,只需要分析出GetProfiles返回的内容中,关于profile token的值即可
做到这里,整个执行程序才30K大小(没有依赖任何onvif的库噢),呵呵,看来值得弄下去,流程思路还比较正确,这种方法应该可行,有完成的必要,这样看来,最后作完兼容性较好的so文件,估计能控制到200K以内。
///////////////接下来做支持认证的:不过这里有个难题,如果设备密码是默认的,我们可以尝试用默认厂商的密码,进行后面的过程,应该可以得到RTSP URL,但如果对于HK这种,就显的意义不是很大了。通过80端口,以及GetServices 和GetProfiles的返回信息,
已经足够定位这是HK的IPC了,由于密码变化范围太大,获取rtsp就显得没有必要了,说白了,我们已经知道了。对于HB设备而言,密码是固定的,做一下也无妨,最起码可以避免厂家中途改rtsp地址。
HK GetProfiles返回信息,提示需要认证,设备型号作为认证的realm了。做认证不难,难在不知道密码。呵呵。
[code]HTTP/1.1 401 Unauthorized
Date: Fri, 08 Jul 2016 01:16:29 GMT
Server: App-webs/
Content-Length: 218
Content-Type: text/html
Connection: close
WWW-Authenticate: Digest qop="auth", realm="DS-2CD2T25D-I5", nonce="4d6b524252"
Access Error: 401 -- Unauthorized
Authentication Error: Access Denied! Authorization required.
[/code]
//////////////////附件中是一个nptl100编译的搜索测试程序(应该没啥关联库,启动后,拍一下键盘开始搜索,结果都在控制台,再拍键盘,继续搜索,ctrl+C强制退出)。代码太乱,都是验证代码,还没整理,暂拿不出手。:lol
///////等我把流程再处理一下,放到我的项目里面用一下先。
展开》
折叠》