主要是鉴权没弄过,折腾onvif的人肯定会碰到,所以特别记录一下.
开始本来是在X64的WIN32或ubuntu工控机平台弄海康摄像头控制的,因为有SDK的直接支持.
结果无人车主控选的是NVIDIA XAIVER arm下控制云台,这就想起了用ONVIF了.
ONVIF无非就是用gsoap+rtsp来折腾的 就把gsoap库先下载和onvif官方下载对应的文件wsdl接口.如果是搞过webservice的活应该有所了解, gsoap 我不多说 百度一下应该好多讲的只管下载.
版本没有太大的要求, 下面文件有些我可能删除了. 我保留主要文件 .
![](https://i-blog.csdnimg.cn/blog_migrate/31f6e2f92c3acfb2acd94d4a5d017cb3.png)
onvif标准接口也是下载 一堆wsdl文件 PTZ在下面
![](https://i-blog.csdnimg.cn/blog_migrate/733626814142c9c37bd416e2bf795681.png)
主要作用类的封装:
class OnvifSDK
{
public:
std::string MediaAddr;
std::string PTZAddr;
public:
static struct soap* NewSoap(const char* ip);
OnvifSDK(struct soap* soap_, const char* username, const char* password);
virtual ~OnvifSDK();
bool GetDeviceInfo(char* url);
bool GetCapabilities(char* url);
bool GetProfiles();
std::string GetUri(enum tt__TransportProtocol transtype);
bool GetStstus(float* pvalue, float* tvalue, float* zvalue);
//连续控制
void ControlPTZ(int control, bool control_type, int speed);
//绝对控制
void SetPTZ(float pvalue, float tvalue, float zvalue);
//相对控制
void SetMoveStep(ptz_common commond, float move_step);
protected:
#ifdef WITH_OPENSSL
#else
void calc_nonce(struct soap* soap, char nonce[SOAP_WSSE_NONCELEN]);
struct _wsse__Security* soap_wsse_add_Security(struct soap* soap);
int soap_wsse_add_UsernameTokenText(struct soap* soap, const char* id, const char* username, const char* password);
int soap_wsse_add_UsernameTokenDigest(struct soap* soap, const char* id, const char* username, const char* password);
void calc_digest(struct soap* soap, const char* created,const char* nonce, int noncelen, const char* password, char hash[SOAP_SMD_SHA1_SIZE]);
void TokenTimestmap(struct soap* pSoap, time_t lifetime = TOKEN_TIMESTAMP);
int soap_wsse_add_Timestamp(struct soap* soap, const char* id, time_t lifetime);
#endif
private:
std::string UserName;
std::string PassWord;
std::string Band;
enum xsd__boolean TrueFlag;
struct tt__PTZSpeed PTZSpeed;
struct tt__Vector2D PTZVectorPT;
struct tt__Vector1D PTZVectorZ;
struct tt__PTZVector VectorABSPTZ;
struct soap* soap;
struct _tds__GetCapabilities capa_req;
struct _tds__GetCapabilitiesResponse capa_resp;
struct _trt__GetProfiles trt__GetProfiles;
struct _trt__GetProfilesResponse trt__GetProfilesResponse;
struct _trt__GetStreamUri trt__GetStreamUri;
struct _trt__GetStreamUriResponse trt__GetStreamUriResponse;
struct _tptz__GetStatus tptz__GetStatus;
struct _tptz__GetStatusResponse tptz__GetStatusResponse;
struct _tptz__ContinuousMove tptz__ContinuousMove;
struct _tptz__ContinuousMoveResponse tptz__ContinuousMoveResponse;
struct _tptz__Stop tptz__Stop;
struct _tptz__StopResponse tptz__StopResponse;
struct _tds__GetDeviceInformation tds__GetDeviceInformation;
struct _tds__GetDeviceInformationResponse tds__GetDeviceInformationResponse;
struct _tptz__AbsoluteMove tptz__AbsoluteMove;
struct _tptz__AbsoluteMoveResponse tptz__AbsoluteMoveResponse;
struct _tptz__RelativeMove tptz__RelativeMove;
struct _tptz__RelativeMoveResponse tptz__RelativeMoveResponse;
};
实现部分(ptz控制方法):
bool OnvifSDK::GetDeviceInfo(char* url)
{
soap_wsse_add_UsernameTokenDigest(soap, "", UserName.c_str(), PassWord.c_str());
int ret = soap_call___tds__GetDeviceInformation(soap, url, NULL, &tds__GetDeviceInformation, &tds__GetDeviceInformationResponse);
if (ret != SOAP_OK)
return false;
if (soap->error)
return false;
else
{
Band = std::string(tds__GetDeviceInformationResponse.Manufacturer);
return true;
}
}
bool OnvifSDK::GetCapabilities(char* url)
{
capa_req.__sizeCategory = 1;
capa_req.Category = (enum tt__CapabilityCategory*)malloc(sizeof(enum tt__CapabilityCategory));
enum tt__CapabilityCategory temp_category = tt__CapabilityCategory__All;
capa_req.Category = &temp_category;
capa_resp.Capabilities = (struct tt__Capabilities*)malloc(sizeof(struct tt__Capabilities)) ;
soap_wsse_add_UsernameTokenDigest(soap, "", UserName.