天天看点

Onvif修改设备属性

算下来,断断续续的接触Onvif有近两个多星期了,刚开始实在不好懂,尤其它基于soap协议而来,之前对这个协议也没怎么了解,让我进度缓慢。 不过幸好有google大神在,帮助良多。闲扯了,由于项目需要,需要对摄像头模组(符合ONVIF的)的一些属性进行修改,比如网络配置、视频参数配置等。 OK,刚接到这个需求,就开始无穷的google,发现网上多是搜索设备的例子,涉及修改设备属性的帖子不多。 还好让我找到些类似的,再配合官方白皮书说明,终于把这个东西解决了。

/*
* endpoint: 操作ONVIF设备地址   如"http://192.168.1.100/onvif/device_service"
* ip_dst:   这是我用的全局变量,就是ip地址了
*/
int onvif_DeviceSetNetworkInterfaces(char *endpoint)
{
    int result = SOAP_ERR;
    if( endpoint == NULL ||  == strlen(endpoint) )
    {
        printf("[%s][%d]\n", __func__, __LINE__);
        return result;
    }
    if( endpoint != NULL &&  != strlen(endpoint) )
    {
        struct soap soap;
        soap_init(&soap);
        struct _tds__SetNetworkInterfaces req;
        struct _tds__SetNetworkInterfacesResponse rsp;

        rsp.RebootNeeded = ;//设置后重启

        char interface[] = "NetworkInterfaceToken_1";
        req.InterfaceToken = interface;//要设置的设备网络接口
        //char ipaddr[16] = "10.0.0.232";
        //xsd__boolean dhcp = xsd__boolean__true_;
        struct tt__NetworkInterfaceSetConfiguration network;
        soap_default_tt__NetworkInterfaceSetConfiguration(&soap, &network);

        //network.Enabled = 1;
        enum xsd__boolean netEnable = xsd__boolean__true_;
        enum xsd__boolean ipv4Enable = xsd__boolean__true_;
        enum xsd__boolean DHCP = xsd__boolean__false_;
        network.Enabled = &netEnable;

        struct tt__IPv4NetworkInterfaceSetConfiguration tt_ipv4;
        soap_default_tt__IPv4NetworkInterfaceSetConfiguration(&soap, &tt_ipv4);
        struct tt__PrefixedIPv4Address  tt_prefAddr;
        soap_default_tt__PrefixedIPv4Address(&soap, &tt_prefAddr);
        tt_prefAddr.Address = ip_dst;//modify ipaddr
        tt_prefAddr.PrefixLength = ;
        tt_ipv4.Manual = &tt_prefAddr;
        tt_ipv4.__sizeManual = ;//must understand  这里坑我最久,后面会说

        tt_ipv4.DHCP = &DHCP;
        tt_ipv4.Enabled = &ipv4Enable;
        network.IPv4 = &tt_ipv4;

        int mtuLen = ;
        network.MTU = &mtuLen;

        printf("%d\n", network.IPv4->Manual->PrefixLength);
        printf("%s\n", network.IPv4->Manual->Address);
        req.NetworkInterface = &network;

        result = soap_call___tds__SetNetworkInterfaces(&soap,endpoint, NULL, &req, &rsp);
        if(result == SOAP_OK)
        {
            printf("====================setNetworkInterfaces successful============================\n");
        }
        soap_destroy(&soap);
        soap_end(&soap);
        soap_done(&soap);
    }
    return result;
}
           

下面回顾一下我的调试经过:

1、 代码一开始一直报段错误,原因是有些结构体的成员赋值类型不对。 举个例子:tt__NetworkInterfaceSetConfiguration结构体里Enabled成员为xsd__boolean *, 那么就必须用这个类型来给值,不能直接用1或0。

2、soap_call___tds__SetNetworkInterfaces一直设置失败,后来通过wireshark去抓包发现别人工具(Onvif device Manager)发出的SetNetworkInterfaces命令,里面的InterfaceToken为”NetworkInterfaceToken_1”, 我之前一直用的是”lo”或“eth0”,后来修改好后,发现就能设置部分信息了,比如DHCP、MTU那些信息, 并且设置后模组能够自行重启。 但IP仍无法正常修改。

抓包如下:

Onvif修改设备属性

3、后来在网上找寻答案无果,回来看看DEBUG信息,发现我的SENT.log如下

再对比一下Onvif device Manager设置OK的命令,抓包下来可以看到:

<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SetNetworkInterfaces xmlns="http://www.onvif.org/ver10/device/wsdl">
<InterfaceToken>NetworkInterfaceToken_1</InterfaceToken>
<NetworkInterface>
<Enabled xmlns="http://www.onvif.org/ver10/schema">true</Enabled>
<MTU xmlns="http://www.onvif.org/ver10/schema">16436</MTU>
<IPv4 xmlns="http://www.onvif.org/ver10/schema">
<Enabled>true</Enabled>
<Manual><Address>10.0.0.231</Address><PrefixLength>24</PrefixLength></Manual>
<DHCP>false</DHCP>
</IPv4>
</NetworkInterface>
</SetNetworkInterfaces>
</s:Body>
           

难怪我的IP修改设置总不成功,soap都没把我的修改ip信息加上,里面没有找到Manual段,Manual段包括了地址信息的修改。

最后的最后,发现是自己没有设置tt__IPv4NetworkInterfaceSetConfiguration结构体的__sizeManual成员,少了设置Manual的size,soap不知道这个大小,所以没有将信息发送上。 所以我设置成1后,就全部work了,哈哈。 下面为成功后的SENT.log信息

最后说明一下,我操作的设备是摄像头模组,可能代码里面有些跟你们用的设备信息不一样,这个需要根据实际情况进行修改。

需要工程的话,见下载链接: http://download.csdn.net/download/nszjh/8618129

参考

继续阅读