onvif gsoap 设备端接口方法部署示例及gsoap代码调用分析

一、获取并编译gsoap

  1. 下载gsoap
  2. 环境准备
 sudo apt-get install flex bison libssl-dev unzip zlib1g-dev ffmpeg
  1. 编译安装
unzip gsoap_2.8.*.zip
cd gsoap-2.8
./configure --prefix=PREFIX 
make
sudo make install

二、编译生成onvif core lib 相关库

  1. 新建soap目录,从gsoap-2.8/gsoap拷贝相关文件到soap目录
stdsoap2.cpp - from "gsoap" folder
duration.c - from "gsoap/custom" folder
stlvector.h- from "gsoap" folder
stdsoap2.h- from "gsoap" folder
duration.h- from "gsoap/custom" folder
将duartion.c 改为 duartion.cpp c++编译需要
duration.cpp 改 #invlude<soapH.h> 为 #include "onvifH.h",如果你用了"soapcpp2 -p onvif"那头文件将是onvifH.h命名
  1. onvif core lib profile包含三个库 OnvifDeviceLib(设备信息) OnvifDiscoveryLib(设备发现) OnvifEventLib(事件)
  2. OnvifDeviceLib库生成
//生成web service 远程调用接口头文件
wsdl2h -t gsoap-2.8/gsoap/typemap.dat -o rcx.h http://www.onvif.org/onvif/ver10/device/wsdl/devicemgmt.wsdl
//生成需要部署实现的c++代码接口
soapcpp2 -p onvifdevice -n -j -L -I gsoap-2.8/gsoap/import -x rcx.h
//生成文件如下
duration.cpp  onvifdeviceC.cpp                   onvifdeviceDeviceBindingProxy.h      onvifdeviceDeviceBindingService.h  onvifdevice.nsmap  stdsoap2.cpp  stlvector.h
duration.h    onvifdeviceDeviceBindingProxy.cpp  onvifdeviceDeviceBindingService.cpp  onvifdeviceH.h                     onvifdeviceStub.h  stdsoap2.h

目录结构如下:

OnvifDeviceLib/
├── onvif
│   └── deviceserviceimplement.cpp
├── soap
│   ├── duration.cpp
│   ├── duration.h
│   ├── onvifdeviceC.cpp
│   ├── onvifdeviceDeviceBindingProxy.cpp
│   ├── onvifdeviceDeviceBindingProxy.h
│   ├── onvifdeviceDeviceBindingService.cpp
│   ├── onvifdeviceDeviceBindingService.h
│   ├── onvifdeviceH.h
│   ├── onvifdevice.nsmap
│   ├── onvifdeviceStub.h
│   ├── stdsoap2.cpp
│   ├── stdsoap2.h
│   └── stlvector.h

我们需要实现deviceserviceimplement.cpp,代码示例如下:

#include "soap/onvifdeviceDeviceBindingService.h" //这个是我们需要实现函数接口定义的头文件
/// Web service operation 'GetServices' (returns error code or SOAP_OK) 获取服务端信息接口
int DeviceBindingService::GetServices(_devicews__GetServices *devicews__GetServices, _devicews__GetServicesResponse &devicews__GetServicesResponse)  {
    //service Device 设备信息服务
    devicews__Service * serviceDevice = new devicews__Service();
//    service1->Capabilities = new _devicews__Service_Capabilities;  //这个注释是因为这个是可选项
//    service1->Capabilities->__any = "adsadadad";
    serviceDevice->Namespace = "http://www.onvif.org/ver10/device/wsdl";
    serviceDevice->Version = new tt__OnvifVersion();
    serviceDevice->Version->Major = 2;
    serviceDevice->Version->Minor = 42;
    serviceDevice->XAddr = "192.168.1.10";
    devicews__GetServicesResponse.Service.push_back(serviceDevice);

    //service Media 媒体服务
    devicews__Service * serviceMedia = new devicews__Service();
//    service1->Capabilities = new _devicews__Service_Capabilities;
//    service1->Capabilities->__any = "adsadadad";
    serviceMedia->Namespace = "http://www.onvif.org/ver10/media/wsdl";
    serviceMedia->Version = new tt__OnvifVersion();
    serviceMedia->Version->Major = 2;
    serviceMedia->Version->Minor = 42;
    serviceMedia->XAddr = "192.168.1.10";
    devicews__GetServicesResponse.Service.push_back(serviceMedia);

    //service Event 事件服务
    devicews__Service * serviceEvent = new devicews__Service();
//    service1->Capabilities = new _devicews__Service_Capabilities;
//    service1->Capabilities->__any = "adsadadad";
    serviceEvent->Namespace = "http://www.onvif.org/ver10/events/wsdl";
    serviceEvent->Version = new tt__OnvifVersion();
    serviceEvent->Version->Major = 2;
    serviceEvent->Version->Minor = 42;
    serviceEvent->XAddr = "192.168.1.10";
    devicews__GetServicesResponse.Service.push_back(serviceEvent);


    //service PTZ ptz服务
    devicews__Service * servicePTZ = new devicews__Service();
//    service1->Capabilities = new _devicews__Service_Capabilities;
//    service1->Capabilities->__any = "adsadadad";
    servicePTZ->Namespace = "http://www.onvif.org/ver20/ptz/wsdl";
    servicePTZ->Version = new tt__OnvifVersion();
    servicePTZ->Version->Major = 2;
    servicePTZ->Version->Minor = 42;
    servicePTZ->XAddr = "192.168.1.10";
    devicews__GetServicesResponse.Service.push_back(servicePTZ);


    //service Imaging 图片服务
    devicews__Service * serviceImaging = new devicews__Service();
//    service1->Capabilities = new _devicews__Service_Capabilities;
//    service1->Capabilities->__any = "adsadadad";
    serviceImaging->Namespace = "http://www.onvif.org/ver20/imaging/wsdl";
    serviceImaging->Version = new tt__OnvifVersion();
    serviceImaging->Version->Major = 2;
    serviceImaging->Version->Minor = 42;
    serviceImaging->XAddr = "192.168.1.10";
    devicews__GetServicesResponse.Service.push_back(serviceImaging);

    return SOAP_OK;
}
/// Web service operation 'GetDeviceInformation' (returns error code or SOAP_OK) 获取设备信息接口
int DeviceBindingService::GetDeviceInformation(_devicews__GetDeviceInformation *devicews__GetDeviceInformation, _devicews__GetDeviceInformationResponse &devicews__GetDeviceInformationResponse)  {
        devicews__GetDeviceInformationResponse.FirmwareVersion = "0.1";
        devicews__GetDeviceInformationResponse.HardwareId = "1";
        devicews__GetDeviceInformationResponse.Manufacturer = "This is sample onvif server";
        devicews__GetDeviceInformationResponse.Model = "2";
        devicews__GetDeviceInformationResponse.SerialNumber = "100000";
        return SOAP_OK;
}

测试的工具为ONVIF Device Test Tool 17.06
测试该项功能集成后的示例为:
在这里插入图片描述

三、接收协议请求后的应答过程

过程为:创建gsoap 实例,等待请求,匹配请求,做出应答
代码示例:
设备发现过程将在下一篇介绍,设备发现会将服务器ip和端口告知客户端。
故如下例子将监听改端口,后获取请求并匹配协议请求接口。

#include "soap/wsddapi.h"
int main()
{
	//创建soap
	struct soap *soap = soap_new();
	//绑定监听端口和soap
	soap_bind(soap, NULL, tcpPort, 100);
	//创建设备信息服务
	DeviceBindingService *sw;
	sw = new DeviceBindingService(soap);
	//监听并接收请求
	while(true){
		soap_accept(soap); //slect 等待请求
	    if (soap_begin_serve(soap)) //server未创建
           //... error
           soap_stream_fault(soap, std::cerr);
        if(sw->dispatch() == SOAP_NO_METHOD)
        {
        	//匹配不成功
            printf("Method fault \n");
            fflush(stdout);
            soap_stream_fault(soap, std::cerr);
            soap_closesock(soap);
		}
			printf("loop end \n");
			fflush(stdout);
			soap_destroy(soap); //断开连接,http为短连接,接着进行监听。
	}
	delete sw;
	soap_end(soap);
	soap_free(soap);
}

调用过程如下:

soap_accept(soap); //slect 等待请求 接收请求
	sw->dispatch() //匹配请求
		DeviceBindingService::dispatch(struct soap* soap)
				if (!soap_match_tag(soap, soap->tag, "devicews:GetServices"))
					return serve___devicews__GetServices(soap, this);
				if (!soap_match_tag(soap, soap->tag, "devicews:GetDeviceInformation"))
					return serve___devicews__GetDeviceInformation(soap, this);		
						service->GetDeviceInformation()
							DeviceBindingService::GetDeviceInformation()//最终调用到这里,这个是由我们实现的函数。

有什么疑问可以提出,然后有想了解更多的请给我留言,后续可以更新大家较为关心的内容。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值