ONVIF客户端开发

在使用 gSoap 框架生成代码之后, 得到文件:

 soapC.c 
 soapClient.c
 stdsoap2.c stdsoap2.h
 duration.c
 wsdd.h

我们利用现有的soapClient, 调用API构建Onvif请求(包括XML, HTTP Client). 开发前需要了解一下Onvif官网文档指导: Onvif 2.0 Service Operation Index;该文档列举了ONVIF的各个模块下的各种方法. 再回到gSoap框架, 同样, 它的文档说明也比较详细.

gSoap 框架API

  • 创建初始化Soap对象
    在stdsoap2.h文件中,有如下定义
//创建各种soap
#define soap_new() soap_new1(SOAP_IO_DEFAULT)
#define soap_new1(mode) soap_new2(mode, mode)
#define soap_new2(imode, omode) soap_versioning(soap_new)(imode, omode)
//初始化各种soap
#define soap_init(soap) soap_init1(soap, SOAP_IO_DEFAULT)
#define soap_init1(soap, mode) soap_init2(soap, mode, mode)
#define soap_init2(soap, imode, omode) soap_versioning(soap_init)(soap, imode, omode)
  • 申请内存模块打Soap中
//该函数soap_done函数调用的时候释放, 无需调用free函数
soap_malloc(struct soap *soap, size_t n)
  • 结束释放Soap
//释放临时Cache
soap_end(struct soap *soap)

//释放所以内存模块和关闭socket
soap_done(struct soap *soap)

//销毁soap对象
#define soap_destroy(soap) soap_delete((soap), NULL)

另外,调试程序接口信息可以打开LOG Level, 如Cmake下

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -ggdb -DDEBUG")

使用宏DEBUG打开并输出调试信息到 recv.log, send.log, test.log .

设备发现

从官方文档上列举的这些方法,我们按照正常操作ONVIF设备客户端开始,那么第一步就必然是找到ONVIF在线的设备.

设备搜索步骤:

(1) 初始化客户端
初始化客户端, 包括uuid地址, 超时设置,头部信息等.

struct saop* onvif_init_soap(struct SOAP_ENV__Header *header,
                                    const char *wsa_To,
                                    const char *wsa_Action,
                                 int timeout,
                                 UserInfo_S *pUser){
    struct soap *soap = NULL;
    unsigned char macaddr[6] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06}; //设置MAC值
    char _HwId[1024];
    unsigned int Flagrand;
    soap = soap_new();

    if (soap == NULL) {
        //LOGE("soap is NULL\n");
        return NULL;
    }

    //设置命名空间
    soap_set_namespaces(soap, namespaces);
    if (timeout > 0){
        soap->recv_timeout = timeout;
        soap->send_timeout = timeout;
        soap->connect_timeout = timeout;
    }else{
        //设置超时默认值 10s
        soap->recv_timeout = 10;
        soap->send_timeout = 10;
        soap->connect_timeout = 10;
    }

    soap_default_SOAP_ENV__Header(soap, header);

    srand((int)time(0));
    Flagrand = rand() % 9000 + 1000; //取4位数

    sprintf(_HwId, "urn:uuid:%ud68a-1dd2-11b2-a1025-%02X%02X%02X%02X%02X%02X",
            Flagrand, macaddr[0], macaddr[1], macaddr[2], macaddr[3], macaddr[4], macaddr[5]);
    header->wsa__MessageID = (char *)soap_malloc(soap, 100);
    memset(header->wsa__MessageID, 0, 100);
    strncpy(header->wsa__MessageID, _HwId, strlen(_HwId));

    if (pUser != NULL){
        //TODO
    }

    if (wsa_Action != NULL){
        //was_Action = "http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe";
        header->wsa__Action = (char *)malloc(1024);
        memset(header->wsa__Action, '\0', 1024);
        strncpy(header->wsa__Action, wsa_Action, 1024);
    }

    if (wsa_To != NULL){
        //wsa_To = "urn:schemas-xmlsoap-org:ws:2005:04:discovery";
        header->wsa__To = (char *)malloc(1024);
        memset(header->wsa__To, '\0', 1024);
        strncpy(header->wsa__To, wsa_To, 1024);
    }

    soap->header = header;
    return soap;
}

(2) 设置Probe搜索参数

wsdd__ProbeType req;
struct __wsdd__ProbeMatches resp;
wsdd__ScopesType sScope;
struct SOAP_ENV__Header header;
struct soap *soap = NULL;

const char *wsa_To = "urn:schemas-xmlsoap-org:ws:2005:04:discovery";
const char *wsa_Action = "http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe";
const char *soap_endpoint = "soap.udp://239.255.255.250:3702/";

soap = onvif_init_soap(&header, wsa_To, wsa_Action, 5, NULL);

soap_default_SOAP_ENV__Header(soap, &header);
soap->header = &header;

soap_default_wsdd__ScopesType(soap, &sScope);
sScope.__item = "";
soap_default_wsdd__ProbeType(soap, &req);
req.Scopes = &sScope;
req.Types = "";

(3) 发送Probe Action

retval = soap_send___wsdd__Probe(soap, soap_endpoint, NULL, &req);

(4) 接收ProbeMatches


while(retval == SOAP_OK){
        retval = soap_recv___wsdd__ProbeMatches(soap, &resp);
        if (retval == SOAP_OK){
            if (soap->error){
                //LOGE("recv soap error:%s(%d)\n", *soap_faultstring(soap), *soap_faultcode(soap));
                retval = soap->error;
            }else{
                if (resp.wsdd__ProbeMatches != NULL &&
                    resp.wsdd__ProbeMatches->ProbeMatch != NULL &&
                    resp.wsdd__ProbeMatches->ProbeMatch->XAddrs != NULL){
                    HasDev ++;

                    if (on_device_found(resp)){// 非0表示退出
                        break;
                    }

                    sleep(1);
                }
            }//else
        }else if (soap->error){
            if (HasDev == 0){
                retval = soap->error;
            }else{
                retval = 0;
            }
            break;
        }//else if
    }//while

(5) 释放资源

soap_destroy(soap);
soap_end(soap);
soap_free(soap);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值