首页 > 其他分享 >onvif的应用

onvif的应用

时间:2024-08-29 15:50:50浏览次数:10  
标签:__ uuid soap 应用 cpp SOAP onvif

一、前言

  • CMU(Center Manager Unit),即中心管理单位
  • PU(Prefocus Unit),即监控前端单元,负责在CMU的控制下使用摄像机采集视频流、使用麦克风采集音频流、使用控制口采集报警信息、对摄像机云台镜头进行控制
  • CU(Client Unit),监控系统的监控客户端单元,负责将PU采集到的视频流、音频流、报警信息提交给监控用户,并根据用户要求操作PU设备,如云台、镜头等

二、传统视频监控系统的一个局域网应用场景

  1. PU设备上线后,向CMU注册,建立连接
  2. CMU与PU进行信令交互,请求能力集,获取配置
  3. CU上线,向CMU注册,建立连接
  4. CMU与CU进行信令交互,传输设备列表
  5. CU向PU请求码流

三、应用onvif规范后对应场景

  1. PU设备上线后,向CMU发送HELLO消息
  2. CMU需要搜寻设备时,向PU发送PROBE消息
  3. CMU与PU进行信令交互,请求能力集,获取配置
  4. CU上线,向CMU注册,建立连接
  5.  CMU与CU进行信令交互,传输设备列表
  6. 在CMU的协调下,CU同PU建立连接传输码流

有了onvif之后

  1. PU与CMU的交互方式发生了改变,CMU不再与PU保持长连接
  2. 遵循ONVIF规范,信令以及消息内容有了统一的标准

四、设备发现main函数说明

#include <iostream>

#include "wsdd.nsmap"

#include "soapH.h"

using namespace std;

int main()

{

   /*****声明变量***********/

     structsoap *soap;              //soap环境变量

     structwsdd__ProbeType req;      //客户端发送的Probe

     struct__wsdd__ProbeMatches resp; //服务端回的Probematchs

     structwsdd__ScopesType sScope;   //Probe里面的范围

     structSOAP_ENV__Header header;   //SOAP的头

     intresult = 0;                    //返回值        

     int count = 0;                   //获得的设信息备个数

    

     /**获取uuid(windows下叫guid,linux下叫uuid),格式为urn:uuid:8-4-4-4-12,由系统随机产生**/

     staticchar buf[64] = {0};   //用来保存uuid号

   

     UUID uuid;     /*声明guid为GUID结构体变量,包含4个变量,分别是

                 unsigned longData1;

                 unsigned short Data2;

                 unsigned short Data3;

                 unsigned char  Data4[ 8 ];

                        */

if (S_OK== CoCreateuuid(&guid))    //如果uuid生成成功,则将其转为字符串,保存在buf中

{

       _snprintf(buf,sizeof(buf)

      ,"urn:uuid:%08X-%04X-%04x-%02X%02X-%02X%02X%02X%02X%02X%02X"

      , uuid.Data1

      , uuid.Data2

      , uuid.Data3

      , uuid.Data4[0], uuid.Data4[1]

      , uuid.Data4[2], uuid.Data4[3], uuid.Data4[4],uuid.Data4[5]

      , uuid.Data4[6], uuid.Data4[7]

      );

     }

soap = soap_new(); //初始化soap

    if(soap==NULL)

     {

        return -1;

     }   

     soap_set_namespaces(soap,namespaces);    //设置命名空间    

soap->recv_timeout = 5;      //设置接收Probematchs时间,超过5秒钟没有数据就退出

soap_default_SOAP_ENV__Header(soap,&header);   //将header设置为soap消息的头属性

/*****给头赋值******/

     header.wsa__MessageID =buf;                     

     header.wsa__To="urn:schemas-xmlsoap-org:ws:2005:04:discovery";

     header.wsa__Action="http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe";

     soap->header = &header;

     /*设置所需寻找设备的类型和范围,二者至少设定一个,否则可能收到非ONVIF设备,出现异常*/

     soap_default_wsdd__ScopesType(soap,&sScope);

     sScope.__item ="onvif://www.onvif.org";     //设置所需设备的sScope

     soap_default_wsdd__ProbeType(soap,&req);     

     req.Scopes = &sScope;

     req.Types ="tdn:NetworkVideoTransmitter";

     /*设置所需设备的类型,tdn为命名空间前缀,为wsdd.nsmap文件中{"tdn","http://www.onvif.org/ver10/network/wsdl"}的tdn,如果不是tdn,而是其它,如ns1这里也要随之改为ns1*/

 

     //通过组播发送Probe探针,发送成功返回0,否则-1

result = soap_send___wsdd__Probe(soap,"soap.udp://239.255.255.250:3702", NULL, &req);

     if(result==-1)

     {

   cout<<"soap error:"<<soap->error<<soap_faultcode(soap)

<<"---"<<soap_faultstring(soap)<<endl; 

     }else                  

     {

         do{    

             result = soap_recv___wsdd__ProbeMatches(soap,&resp);

//接收ProbeMatches,成功返回0,否则-1 

              if (result==-1)   

               {

               cout<<"共发现"<<count<<"个设备"<<endl;

cout<<"soap error:"<<soap->error<<soap_faultcode(soap)

<<"---"<<soap_faultstring(soap)<<endl;

                break;

                }else  

               {

                    count++;

                    cout<<"========================================="<<endl;              

                    cout<<"UUID:"<<""<<resp.wsdd__ProbeMatches->ProbeMatch->

wsa__EndpointReference.Address<<endl;             

cout<<"Type:"<<""<<resp.wsdd__ProbeMatches->ProbeMatch->Types<<endl;

                    cout<<"Scopes:"<<""<< resp.wsdd__ProbeMatches->

ProbeMatch->Scopes->__item<<endl;                       

                    cout<<"DeviceService Address:"<<""<<resp.wsdd__ProbeMatches->

ProbeMatch->XAddrs<<endl;                      

                    cout<<"MetadataVersion:"<<""<<resp.wsdd__ProbeMatches->

ProbeMatch->MetadataVersion<<endl;

                }

          }while(1);

     }                       

/********清除变量************/

     soap_destroy(soap); // removedeserialized class instances (C++ only)

     soap_end(soap);     //clean up and remove deserialized data

     soap_done(soap);

     return result;

}

五、CMakeList说明

  • soap目录编译成了libonvif_soap,依赖openssl,还需要定义两个宏WITH_OPENSSL和 WITH_DOM
  • onvif目录编译成了libonvif,依赖libonvif_soap.
cmake_minimum_required(VERSION 3.0)
project(OnvifDemo)
 
set(CMAKE_CXX_STANDARD 11)
 
set(CMAKE_CXX_FLAGS "-g -O0")
 
set(LIB_SOAP_SRC
    soap/struct_timeval.cpp
    soap/duration.cpp
    soap/wsaapi.cpp
    soap/dom.cpp
    soap/wsseapi.cpp
    soap/smdevp.cpp
    soap/mecevp.cpp
    soap/threads.cpp
    soap/stdsoap2.cpp)
 
add_library(onvif_soap STATIC ${LIB_SOAP_SRC})
target_link_libraries(onvif_soap PUBLIC ssl crypto)
target_compile_definitions(onvif_soap PUBLIC WITH_OPENSSL WITH_DOM)
target_include_directories(onvif_soap PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/onvif)
 
add_library(onvif STATIC onvif/soapC.cpp onvif/soapClient.cpp)
target_include_directories(onvif PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(onvif PUBLIC onvif_soap)
 
add_executable(dev_scan tests/scan_device.cpp)
target_link_libraries(dev_scan PRIVATE onvif)

六、调试过程注意事项

1)出现如下语法错误

error C2143:语法错误 : 缺少“{”(在“:”的前面)

error C2059:语法错误 : “:”

error C2143:语法错误 : 缺少“{”(在“:”的前面)

需要将工程中的.c文件改成.cpp文件即可

2)无法解析的外部命令错误soap_check_faultsubcode

在stdsoap2.h中,声明的soap_check_faultsubcode(structsoap *soap)函数在soapC.cpp中未实现, 可在soapC.cpp中添加如下实现

SOAP_FMAC3 const char * SOAP_FMAC4soap_check_faultsubcode(struct soap *soap)

{

    soap_fault(soap);

    if(soap->version == 2)

    {  

if(soap->fault->SOAP_ENV__Code &&soap->fault->SOAP_ENV__Code->SOAP_ENV__Subcode &&soap->fault->SOAP_ENV__Code->SOAP_ENV__Subcode)

returnsoap->fault->SOAP_ENV__Code->SOAP_ENV__Subcode->SOAP_ENV__Value;

        return NULL;

    }

    returnsoap->fault->faultcode;

}

3) 无法解析的外部命令错误soap_check_faultdetail

在stdsoap2.h中,声明的soap_check_faultdetail(struct soap *soap)函数在soapC.cpp中未实现,,可在soapC.cpp中添加如下实现

SOAP_FMAC3 const char * SOAP_FMAC4soap_check_faultdetail(struct soap *soap)

{

    soap_fault(soap);

    if(soap->version == 2 && soap->fault->SOAP_ENV__Detail)

        returnsoap->fault->SOAP_ENV__Detail->__any;

    if(soap->fault->detail)

        return soap->fault->detail->__any;

    returnNULL;

}

4) 出现无法解析的外部符号_soap_in_xsd__duration

无法解析的外部符号_soap_in_xsd__duration,该符号在函数_soap_getelement中被引用soapC.obj : error LNK2019: 无法解析的外部符号_soap_out_xsd__duration,该符号在函数_soap_putelement中被引用

soapC.obj: error LNK2019: 无法解析的外部符号_soap_default_xsd__duration,该符号在函数_soap_default__tse__FindMetadata中被引用

需要将custom文件夹下面的duration.h和duration.c导入工程中

5)如果是调用soap_call_XXXX_Probe()来实现设备发现时,不能发现所有onvif设备

该函数实现过程中只有一次接收过程,所以无法发现所有的设备的问题。如果使用该函数,还需要对函数的实现做以下更改:

函数的接收部分,将原来的XXXX:Response更改为YYYY:ProbeMatches

其中,

6)在VS中出现fatal error C1128: 节数超过对象文件格式限制:请使用/bigobj 进行编译的错误

这是由于源代码文件太大,需添加选项/bigobj,在项目属性-> C/C++ ->命令行的附加选项中添加/bigobj

七、总结

1)了解gsoap工具的使用方法、编程方法以及文件结构,参考Genivia - gSOAP 用户指南,可根据需要查找相关内容

2)学会利用抓包工具,用于分析客户端所发出的消息,以及服务端回复的消息

标签:__,uuid,soap,应用,cpp,SOAP,onvif
From: https://blog.csdn.net/janet110617/article/details/141677910

相关文章

  • gstreamer教程(8)——构建应用之Pad和Pad的能力集
    Pad和能力集:正如我们在 Elements 中看到的那样,pad是Element与外部世界的接口。数据从一个Element的sourcepad流向另一个Element的sinkpad。元素可以处理的媒体类型都是通过pad的能力集公布的。我们将在本章后面详细讨论功能(参见 pad的功能)。Pad:pad类......
  • 最新零代码,套娃一样开发IoT应用!
    V3.0全新升级:社区版|文档(18万字)|AI问答|入门示例50+|设计极简前端技术日新月异,UIOTOS是一款最新开源的前端零代码工具(无需用户懂前端开发,不同于低代码)。三年磨一剑,独创的页面嵌套技术,给WEB前端、UI原型、组态HMI、工控上位机,以及工作流、规则链等图形可视化编辑,带来了全......
  • 深入浅出LLamaSharp:打造智能.NET应用,不需GPU也能玩转LLaMA模型
            在如今的.NET社区中,机器学习和人工智能的应用越来越普遍。今天我要给大家推荐一个名叫LLamaSharp的开源项目。这是llama.cpp的C#/.NET绑定,提供了高级的API,使得我们能在本地设备上使用C#/.NET推理LLaMA模型,并且部署它。        LLamaSharp支持在Windo......
  • QUIC在京东直播的应用与实践
    一.前言与背景国内的互联网直播技术从2005年前后兴起,彼时最具代表性的直播产品是由PPLive创始人姚欣在华中科技大学就读期间发起的校园直播项目PPLive。当时的直播技术用的还是基于windows系统自带的mediaplayer内置的COM组件开发的播放器,采用的是RTSP协议。受当时的互联网传......
  • 在Vue3应用中使用TypeScript的最佳实践
    随着Vue3的推出,TypeScript逐渐成为了前端开发中的一种必备技能。Vue3的设计更好地支持TypeScript,这使得开发者可以在开发过程中充分利用TypeScript的强类型系统,从而提高代码的可维护性和可读性。在这篇博客中,我们将深入探讨在Vue3应用中使用TypeScript的最佳实践,并通过示例......
  • 不改一行代码轻松玩转 Go 应用微服务治理
    作者:赵源筱Go应用微服务治理简介Go语言具有简洁、高效、并发性强等特性,已经被广泛认为是构建微服务的理想选择之一。Go语言作为构建Kubernetes、Docker的主要编程语言,目前不仅在云原生基础组件领域中被广泛使用,也逐渐被越来越多的开发者应用于各类业务场景中,基于微服务架构......
  • 干货 | NXP NCF3321 卡保护应用阈值修改讲解
    1.前言    NCF3321是世平集团代理的NXP所研发的新一代车规级NFC前端IC,相比上代NFC前端IC性能提升巨大、支持多类型多协议卡检测、支持手机模拟NFC识别、支持手机与卡共同检测、宽范围工作温度工作更加稳定。    NCF3321是一款高度集成的高性能......
  • 使用 nuxi analyze 命令分析 Nuxt 应用的生产包
    title:使用nuxianalyze命令分析Nuxt应用的生产包date:2024/8/29updated:2024/8/29author:cmdragonexcerpt:使用nuxianalyze命令可以帮助你深入了解生产包的结构和大小,从而做出针对性的优化。通过定期分析生产包,你可以识别并解决性能瓶颈,提高应用的加载速度和......
  • 鸿蒙开发实战:声明静态订阅应用规范
    静态订阅者在未接收订阅的目标事件时,处于未拉起状态,当系统或应用发布了指定的公共事件后,静态订阅者将被拉起,并执行onReceiveEvent回调。开发者可通过在onReceiveEvent回调中执行业务逻辑,实现当应用接收到特定公共事件时执行业务逻辑的目的。例如,某应用希望在设备开机的时......
  • 关于安科瑞蓄电池在线监测系统的设计与应用-安科瑞 蒋静
    蓄电池在线监测系统是一种用于实时监测蓄电池状态并分析其性能的重要设备。该系统通过监测蓄电池的关键参数,如电压、电流、温度、内阻等,对电池的性能和健康状况进行评估,从而及时发现潜在问题并采取相应的维护措施。以下是对蓄电池在线监测系统的详细介绍:一、系统概述蓄电池在......