onvif学习笔记3:NTP命令实现的示例
2015-12-14 22:45
567 查看
对于开始接触onvif的人,相信都会被其庞大的代码吓到。一般不建议上来就看代码,而是先去了解概念,然后去官网下载Spec来看。有一定概念后,再对照着wsdl命令描述、spec描述来阅读代码,这个时候就会比较清晰了。本文就按这个思路来讲解一下NTP的设置和获取命令。
如下图:
“Input”处定义了命令字段及解释。第一个字段为FromDHCP,如果为1,则表示NTP地址信息是从DHCP获取的。第二个字段为NTPManual,是手动设置NTP信息,其下又有类型Type(同时给出了枚举类型),还有IPv4或IPv6,等等。
再来看spec对SetNTP命令的描述,如下图:
对比上面两张图,可以看到,spec的字段不是太详细,但它给出了错误码Fault codes。有的错误码在代码里是需要设置的(下面的示例伪代码就使用到)。
伪代码示例如下:
小结:onvif的设置命令,基本套路的根据文档(建议同时看wsdl及spec)知道有哪些字段,然后结合实际情况填充(比如SetNTP,不支持的都返回错误码),在此过程可能要实现部分功能函数(如获取IP)。
如图:
比较详细地规定各个字段名字、含义,是否是可选的。一般地Get和Set命令字段都是一一对应的。再来看看spec的定义:
同样地,spec也是大概地描述字段,没有很详细。
接下来看看SetNTP命令的代码实现,如下:
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 夜
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 夜
相关文章推荐
- ThinkPHP中的动态缓存(S方法)和快速缓存(F方法)
- A+B for Input-Output Practice (VIII)(没啥用,来凑数)
- 转】关于cgi、FastCGI、php-fpm、php-cgi
- php学习日记第三棒(虚拟目录)
- php优化
- php-简单计算器
- SMTP的响应码列表
- 安装php扩展
- PHP访问MySQL几种方法
- PHP安装与使用VLD查看opcode代码【PHP安装第三方扩展的方法】
- wget FTP下载问题
- WindowManager.LayoutParams.type属性
- PHP读取TXT中文乱码的解决方式
- php单例模式学习
- mac下配置matplotlib绘图
- ThinkPHP--多表查询之join和table的用法
- PHP防csrf攻击
- php代码下载文件转换成迅雷,快车,qq下载文件源代码
- 发送电子邮件模块smtplib
- EditPlus 注册码在线生成