Linux c++ onvif客户端开发(7):struct soap包装类

server/2024/11/12 23:44:24/

 本文是Linux c++ onvif客户端开发系列文章之一:

  • Linux c++ onvif客户端开发(1): 根据wsdl生成cpp源文件
  • Linux c++ onvif客户端开发(2): 获取摄像头H264/H265 RTSP地址
  • Linux c++ onvif客户端开发(3): 扫描设备
  • Linux c++ onvif客户端开发(4): 扫描某个设备是否支持onvif
  • Linux c++ onvif客户端开发(5):gsoap内存管理
  • Linux c++ onvif客户端开发(6):获取设备信息

 可以先先看一下gsoap内存管理这篇文章。

 先定义一个fault结构

struct OnvifFault {std::string code;std::string subcode;std::string str; // stringstd::string detail;
};

再对struct soap进行包装

class OnvifSoap {
public:OnvifSoap(int timeout);~OnvifSoap();void InitHeader();void InitProbeType(struct wsdd__ProbeType *probe);int Error() { return soap_->error; }// 返回的xml中soap:Faultstd::string FaultString();std::string FaultCode();std::string FaultSubcode();std::string FaultDetail();struct soap *Soap() const;void Destroy();// 填写Fault信息void FillFault(OnvifFault *fault = nullptr);private:struct soap *soap_;
};

 实现


#define SOAP_PROBE_TO "urn:schemas-xmlsoap-org:ws:2005:04:discovery"
#define SOAP_PROBE_ACTION                                                      \"http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe"#define SOAP_MCAST_ADDR "soap.udp://239.255.255.250:3702" // onvif规定的组播地址#define SOAP_ITEM ""                            // 寻找的设备范围
#define SOAP_TYPES "dn:NetworkVideoTransmitter" // 寻找的设备类型#define SOAP_SOCK_TIMEOUT (2) // socket超时时间(单秒秒)OnvifSoap::OnvifSoap(int timeout) {// There is no need to call soap_init to initialize the context// allocated with soap_new, since soap_new initializes the allocated// context.// https://www.genivia.com/doc/guide/html/group__group__context.html#ga87c20488b2dc680aaa7689b1d024989csoap_ = soap_new();if (!soap_)throw std::runtime_error("soap_new() fail");soap_set_namespaces(soap_, namespaces); // 设置soap的namespaces// 不正常数据设置成5sif (timeout <= 0)timeout = SOAP_SOCK_TIMEOUT;soap_->recv_timeout = timeout; // 设置超时(超过指定时间没有数据就退出)soap_->send_timeout = timeout;soap_->connect_timeout = timeout;#if defined(__linux__) ||                                                      \defined(__linux) // 参考https://www.genivia.com/dev.html#client-c的修改:soap_->socket_flags = MSG_NOSIGNAL; // To prevent connection reset errors
#endifsoap_set_mode(soap_,SOAP_C_UTFSTRING); // 设置为UTF-8编码,否则叠加中文OSD会乱码
}OnvifSoap::~OnvifSoap() {soap_destroy(soap_); // delete managed C++ objectssoap_end(soap_);     // delete managed memory。soap_mallocsoap_done(soap_);    // stackedsoap_free(soap_);    /* we're done with the context */
}/*** @brief 填充Header, 用于Probe操作*
<SOAP-ENV:Header><wsa:MessageID>urn:uuid:dc8f9f8a-05b2-45c2-a63e-f5b47636af83</wsa:MessageID><wsa:To
SOAP-ENV:mustUnderstand="true">urn:schemas-xmlsoap-org:ws:2005:04:discovery</wsa:To><wsa:Action
SOAP-ENV:mustUnderstand="true">http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe</wsa:Action>
</SOAP-ENV:Header>*/
void OnvifSoap::InitHeader() {// T * soap_new_T(struct soap*) allocates and initializes data of type T// in context-managed heap memory, managed data is deleted with// soap_destroy (deletes C++ objects) and soap_end (deletes all other// data), and you can also use soap_malloc to allocate uninitialized// context-managed memory.struct SOAP_ENV__Header *header = soap_new_SOAP_ENV__Header(soap_);header->wsa__MessageID = (char *)soap_wsa_rand_uuid(soap_);header->wsa__To = soap_strdup(soap_, SOAP_PROBE_TO);header->wsa__Action = soap_strdup(soap_, SOAP_PROBE_ACTION);soap_->header = header;
}/*** @brief 填充body Probe数据, 用于Probe操作*     <SOAP-ENV:Body><wsdd:Probe><wsdd:Types>dn:NetworkVideoTransmitter</wsdd:Types><wsdd:Scopes/></wsdd:Probe></SOAP-ENV:Body>* @param probe*/
void OnvifSoap::InitProbeType(struct wsdd__ProbeType *probe) {// 用于描述查找哪类的Web服务struct wsdd__ScopesType *scope = soap_new_wsdd__ScopesType(soap_);// soap_default_wsdd__ScopesType(soap_, scope); // 设置寻找设备的范围scope->__item = soap_strdup(soap_, "");probe->Scopes = scope;probe->Types = soap_strdup(soap_, SOAP_TYPES); // 设置寻找设备的类型
}std::string OnvifSoap::FaultString() {const char *fault_string = soap_fault_string(soap_);if (!fault_string)return std::string();elsereturn std::string(fault_string);
}std::string OnvifSoap::FaultCode() {const char **code = soap_faultcode(soap_);if (code && *code)return std::string(*code);elsereturn std::string();
}std::string OnvifSoap::FaultSubcode() {const char *subcode = soap_fault_subcode(soap_);if (!subcode)return std::string();elsereturn std::string(subcode);
}std::string OnvifSoap::FaultDetail() {const char *detail = soap_fault_detail(soap_);if (!detail)return std::string();elsereturn std::string(detail);
}struct soap *OnvifSoap::Soap() const {return soap_;
}void OnvifSoap::Destroy() { soap_->destroy(); }void OnvifSoap::FillFault(OnvifFault *fault) {if (!fault)return;// strconst char *fault_string = soap_fault_string(soap_);if (fault_string)fault->str.assign(fault_string);// codeconst char **code = soap_faultcode(soap_);if (code && *code)fault->code.assign(*code);// subcodeconst char *subcode = soap_fault_subcode(soap_);if (subcode)fault->subcode.assign(subcode);// detailconst char *detail = soap_fault_detail(soap_);if (detail)fault->detail.assign(detail);
}


http://www.ppmy.cn/server/5400.html

相关文章

flutter书架形式格口的动态创建(行、列数,是否全选的配置)

根据传入的行列数创建不同格口数量的书架 左图&#xff1a;5行3列、右图&#xff1a;3行3列 代码 import package:jade/bean/experienceStation/ExpCellSpecsBean.dart; import package:jade/configs/PathConfig.dart; import package:jade/utils/DialogUtils.dart; import p…

安全开发实战(1)--Cdn

目录 安全开发专栏 CDN介绍 1.信息收集阶段 1.1判断CDN是否存在 1.1.1, One 1.1.2,Two(改进) 1.1.3,进行整合 增加输入功能 1.1.4 批量读取监测存储(进行测试) 问题1: 问题2: 解决方案: 1.1.4 基本编写完成 命令框中: cdn存在.txt 总结 这里我是根据整个渗透测…

HttpServletResponse HttpServletRequest

HttpServletResponse 和 HttpServletRequest 是 Java Servlet API 中的两个核心接口&#xff0c;它们分别代表了 HTTP 响应和 HTTP 请求。在基于 Java 的 Web 应用中&#xff0c;特别是使用 Servlet 技术时&#xff0c;这两个接口被广泛应用。 HttpServletRequest HttpServle…

机器学习系统的设计

1.混淆矩阵 混淆矩阵作用就是看一看在测试集样本集中&#xff1a; 真实值是 正例 的样本中&#xff0c;被分类为 正例 的样本数量有多少&#xff0c;这部分样本叫做真正例&#xff08;TP&#xff0c;True Positive&#xff09;&#xff0c;预测为真&#xff0c;实际为真真实值…

webpack or vite? vuex or pinia?

2022.2.18, 新建一个vue3的项目&#xff0c;过程如下&#xff1a; 目录结构如下&#xff1a; 当还在犹豫选择webpack还是vite&#xff0c;vuex或者pinia的时候&#xff0c;尤大大已经给出了默认选择&#xff0c;vite && pinia。

Git基本使用

找一个文件夹 git init 代码仓库&#xff0c;里面的内容千万不要动 新建一个文件&#xff0c;如test.txt git add test.txt //git add . //all 暂存区 git commit -m "新增了一个点赞" 最常用的流程&#xff1a; 修改一个文件 git add git commit git log //查…

论文笔记:LayoutNUWA: Revealing the Hidden Layout Expertise of Large Language Models

iclr 2024 reviewer 评分 568 图形布局生成大模型 1 intro 现有方法主要将布局生成视为一个数值优化任务&#xff0c;专注于量化方面&#xff0c;同时忽略了布局的语义信息&#xff0c;如各布局元素之间的关系。论文提出了LayoutNUWA&#xff0c;这是第一个将布局生成视为代…

Navicat 干货 | 了解 PostgreSQL 规则

PostgreSQL 是一个强大的开源关系型数据库管理系统&#xff0c;为增强数据管理和操作提供了丰富的功能。这些功能中包含了规则&#xff0c;这是一种用于控制数据库内部查询和命令处理方式的机制。本文将探讨 PostgreSQL 规则的工作原理&#xff0c;以及它们与触发器的区别&…