onvif学习笔记3:NTP命令实现的示例
来源:互联网 发布:2015网络歌曲排行榜 编辑:程序博客网 时间:2024/06/05 14:34
对于开始接触onvif的人,相信都会被其庞大的代码吓到。一般不建议上来就看代码,而是先去了解概念,然后去官网下载Spec来看。有一定概念后,再对照着wsdl命令描述、spec描述来阅读代码,这个时候就会比较清晰了。本文就按这个思路来讲解一下NTP的设置和获取命令。
1、SetNTP
首先看设置NTP命令SetNTP的描述,地址为:http://www.onvif.org/onvif/ver10/device/wsdl/devicemgmt.wsdl#op.SetNTP
如下图:
“Input”处定义了命令字段及解释。第一个字段为FromDHCP,如果为1,则表示NTP地址信息是从DHCP获取的。第二个字段为NTPManual,是手动设置NTP信息,其下又有类型Type(同时给出了枚举类型),还有IPv4或IPv6,等等。
再来看spec对SetNTP命令的描述,如下图:
对比上面两张图,可以看到,spec的字段不是太详细,但它给出了错误码Fault codes。有的错误码在代码里是需要设置的(下面的示例伪代码就使用到)。
伪代码示例如下:
SOAP_FMAC5 int SOAP_FMAC6 __tds__SetNTP(struct soap* soap, struct _tds__SetNTP *tds__SetNTP, struct _tds__SetNTPResponse *tds__SetNTPResponse){ onvif_debug(7, "--%s--\n", __func__); // 不支持FromDHCP,所以返回错误 if (tds__SetNTP->FromDHCP == TRUE) { onvif_fault(soap,"ter:NotSupported", "ter:SetDHCPNotAllowed"); return SOAP_FAULT; } // 不支持IPv6Address,所以返回错误 if (tds__SetNTP->NTPManual->IPv6Address != NULL) { onvif_fault(soap,"ter:NotSupported", "ter:IPv6AddressNotAllowed"); return SOAP_FAULT; } // 只支持IPv4Address if(tds__SetNTP->NTPManual->IPv4Address != NULL) { // 地址非法,返回错误 if(isValidIp4(tds__SetNTP->NTPManual->IPv4Address[0]) == 0) { onvif_fault(soap,"ter:InvalidArgVal", "ter:InvalidIPv4Address"); return SOAP_FAULT; } sa.sin_family = AF_INET; inet_aton(tds__SetNTP->NTPManual->IPv4Address[0], &sa.sin_addr.s_addr); s = getnameinfo(&sa, sizeof(sa), host, sizeof(host), service, sizeof(service), NI_NAMEREQD); //转换host // 如果host非法,返回错误 if(isValidHostname(host) == 0) { onvif_fault(soap,"ter:InvalidArgVal", "ter:InvalidDnsName"); return SOAP_FAULT; } // 这里设置设备的NTP服务器地址... } return SOAP_OK;}涉及到的结构体定义如下:
struct _tds__SetNTP{/// @brief Indicate if NTP address information is to be retrieved using DHCP./// Element FromDHCP of type xs:boolean. enum xsd__boolean FromDHCP 1; ///< Required element./// @brief Manual NTP settings./// Size of array of struct tt__NetworkHost* is 0..unbounded $int __sizeNTPManual 0;/// Array struct tt__NetworkHost* of length 0..unbounded struct tt__NetworkHost* NTPManual 0;};struct tt__NetworkHost{/// @brief Network host type: IPv4, IPv6 or DNS./// Element Type of type "http://www.onvif.org/ver10/schema":NetworkHostType. enum tt__NetworkHostType Type 1; ///< Required element./// @brief IPv4 address./// Element IPv4Address of type "http://www.onvif.org/ver10/schema":IPv4Address. tt__IPv4Address IPv4Address 0; ///< Optional element./// @brief IPv6 address./// Element IPv6Address of type "http://www.onvif.org/ver10/schema":IPv6Address. tt__IPv6Address IPv6Address 0; ///< Optional element./// @brief DNS name./// Element DNSname of type "http://www.onvif.org/ver10/schema":DNSName. tt__DNSName DNSname 0; ///< Optional element./// Element Extension of type "http://www.onvif.org/ver10/schema":NetworkHostExtension. struct tt__NetworkHostExtension* Extension 0; ///< Optional element./// <anyAttribute namespace="##any">/// TODO: Schema extensibility is user-definable./// Consult the protocol documentation to change or insert declarations./// Use wsdl2h option -x to remove this attribute./// Use wsdl2h option -d for xsd__anyAttribute DOM (soap_dom_attribute). @_XML __anyAttribute ; ///< A placeholder that has no effect: please see comment.};
小结:onvif的设置命令,基本套路的根据文档(建议同时看wsdl及spec)知道有哪些字段,然后结合实际情况填充(比如SetNTP,不支持的都返回错误码),在此过程可能要实现部分功能函数(如获取IP)。
2、GetNTP
onvif很多命令是成对出现的,有Set也有Get。这里介绍获取NTP命令GetNTP。按例上wsdl描述,地址为:http://www.onvif.org/onvif/ver10/device/wsdl/devicemgmt.wsdl#op.GetNTP。如图:
比较详细地规定各个字段名字、含义,是否是可选的。一般地Get和Set命令字段都是一一对应的。再来看看spec的定义:
同样地,spec也是大概地描述字段,没有很详细。
接下来看看SetNTP命令的代码实现,如下:
SOAP_FMAC5 int SOAP_FMAC6 __tds__GetNTP(struct soap* soap, struct _tds__GetNTP *tds__GetNTP, struct _tds__GetNTPResponse *tds__GetNTPResponse){ char *ip_address = getIPAddress(); // 获取IP地址; int dhcp_enable = getDhcpStatus(); // 获取dhcp使能标志 tds__GetNTPResponse->NTPInformation = (struct tt__NTPInformation*)soap_malloc(soap, sizeof(struct tt__NTPInformation)); tds__GetNTPResponse->NTPInformation->FromDHCP = dhcp_enable; if(dhcp_enable == 1) // NTPFromDHCP { tds__GetNTPResponse->NTPInformation->__sizeNTPFromDHCP = 1; // 开辟空间 tds__GetNTPResponse->NTPInformation->NTPFromDHCP = (struct tt__NetworkHost*)soap_malloc(soap, sizeof(struct tt__NetworkHost)); tds__GetNTPResponse->NTPInformation->NTPFromDHCP->Type = IPv4; // 枚举类型:enum { 'IPv4', 'IPv6', 'DNS' } tds__GetNTPResponse->NTPInformation->NTPFromDHCP->IPv4Address = (char **)soap_malloc(soap, sizeof(char *)); tds__GetNTPResponse->NTPInformation->NTPFromDHCP->IPv4Address[0] = (char *)soap_malloc(soap, sizeof(char) * 128); strcpy(tds__GetNTPResponse->NTPInformation->NTPFromDHCP->IPv4Address[0], ip_address); tds__GetNTPResponse->NTPInformation->NTPFromDHCP->IPv6Address = NULL; tds__GetNTPResponse->NTPInformation->NTPFromDHCP->DNSname = NULL; tds__GetNTPResponse->NTPInformation->NTPFromDHCP->Extension = NULL; tds__GetNTPResponse->NTPInformation->__sizeNTPManual = 0; tds__GetNTPResponse->NTPInformation->NTPManual = NULL; } else // 手动 { tds__GetNTPResponse->NTPInformation->__sizeNTPManual = 1; // 置为1 tds__GetNTPResponse->NTPInformation->NTPManual = ((struct tt__IPAddress *)soap_malloc(soap, sizeof(struct tt__IPAddress))); tds__GetNTPResponse->NTPInformation->NTPManual->Type = IPv4; tds__GetNTPResponse->NTPInformation->NTPManual->IPv4Address = (char **)soap_malloc(soap, sizeof(char *)); // 开辟存储IP地址空间 tds__GetNTPResponse->NTPInformation->NTPManual->IPv4Address[0] = (char *)soap_malloc(soap, sizeof(char) * 128); strcpy(tds__GetNTPResponse->NTPInformation->NTPManual->IPv4Address[0], ip_address); // 赋值 // 下面这些没有,置为NULL tds__GetNTPResponse->NTPInformation->NTPManual->IPv6Address = NULL; tds__GetNTPResponse->NTPInformation->NTPManual->DNSname = NULL; tds__GetNTPResponse->NTPInformation->NTPManual->Extension = NULL; tds__GetNTPResponse->NTPInformation->__sizeNTPFromDHCP = 0; tds__GetNTPResponse->NTPInformation->NTPFromDHCP = NULL; } return SOAP_OK;}小结:onvif的获取命令,套路和设置命令类似。要注意的是字段空间的申请,很多字段使用指针,如果需要使用这些字段,就是开辟空间。如果不留意,可能就会出现段错误。
3、参考
参考:
onvif 设备管理:http://www.onvif.org/onvif/ver10/device/wsdl/devicemgmt.wsdl
onvif最新(2015年)的核心规范:http://www.onvif.org/specs/DocMap-2.6.html
onvif规范(含profile、web serivce描述、设备测试规范):http://www.onvif.org/Documents/Specifications.aspx
李迟 2015.12.14 夜
- onvif学习笔记3:NTP命令实现的示例
- Onvif学习笔记3
- onvif学习笔记9:OSD命令学习
- onvif学习笔记6:onvif的OSD坐标小记
- onvif协议学习笔记
- Onvif学习笔记1
- Onvif学习笔记2
- onvif学习笔记2:了解onvif
- onvif学习笔记7:一个C++封装的onvif代码的阅读笔记
- openstack学习笔记 ---NTP
- onvif学习笔记8:最近写的一个ONVIF客户端的心得小结
- onvif学习笔记3:Windows环境使用gsoap生成onvif框架代码
- ONVIF学习理解(3)
- ONVIF学习之实现discovery
- ONVIF学习-设备搜索的实现(结合MFC)
- onvif学习笔记5:onvif框架代码初步了解
- onvif学习3-自发现功能实现(Discovery)
- linux设备上的Onvif 实现19:发现及鉴权示例程序
- 用广度优先遍历求有向带权图的最短路径
- 55.多线程第二章(常用的开启多线程方法)
- jQuery选择器总结
- 几种排序算法 觉得写得特别好
- QQ能上但是刷不出网页如何解决
- onvif学习笔记3:NTP命令实现的示例
- leetcode -- Group Anagrams -- 简单重点
- JVM内存分析以及Jconsole(一)
- 第十四周(项目一)--分块查找
- 爬爬爬之路:UI(十九) 多线程
- leetcode15---3Sum
- 五分钟理解一致性哈希算法(consistent hashing)
- [javase学习笔记]-5.5 数组常用操作(2)
- UIImage 与 base64 互转