上周弄了一周都没有弄出来,今天又去研究了下ONVIF Device Test Tool。终于有所发现了。
首先肯定是soap,关于鉴权的soap就不展开说了。
然后是获取能力。这里我是获取了所有能力。
接着是GetProfiles,为了得到在控制PTZ时的token。
代码已经调试通了某华和某康的IPC。
一开始我们用的是某华,在GetProfiles是的地址是PTZ的。但是在兼容某康时,变成了为实现可选项。通过上面说到的工具发现。用的token是Media的。但是控制的时候的地址是PTZ的。
下面上代码。实现的是相对位移的接口。
int onvif_OptPTZ(char* strIp, int port, char* user, char* password, ptz_common commond, float move_step)
{
int result = 0;
struct SOAP_ENV__Header Header;
struct soap *soap = NULL;
char *strOptPtz = NULL;
char *strGetToken = NULL;
//鉴权信息
USERINFO stUserInfo;
USERINFO *pAuth = NULL;
memset(&stUserInfo, 0x0, sizeof(stUserInfo));
if(user == NULL || password == NULL)
{
pAuth = NULL;
}
else
{
snprintf(stUserInfo.username, 64, "%s", user);
snprintf(stUserInfo.password, 32, "%s", password);
pAuth = &stUserInfo;
}
//创建一个带鉴权的soap
soap = ONVIF_Initsoap(&Header, NULL, NULL, 5, pAuth);
if(NULL == soap)
{
printf("FUNCTION:(%s) ---- Init soap error!\n", __FUNCTION__);
return -1;
}
char soap_endpoint[128];
snprintf(soap_endpoint, 128, "http://%s:%d/onvif/device_service", strIp, port);
_tds__GetCapabilities abi_req;
_tds__GetCapabilitiesResponse abi_resp;
memset(&abi_req, 0x0, sizeof(abi_req));
memset(&abi_resp, 0x0, sizeof(abi_resp));
abi_req.__sizeCategory = 1;
abi_req.Category = (enum tt__CapabilityCategory *)soap_malloc(soap, sizeof(int));
*(abi_req.Category) = tt__CapabilityCategory__All;
soap->header = &Header;
result = soap_call___tds__GetCapabilities(soap, soap_endpoint, NULL, &abi_req, &abi_resp);
if(result != SOAP_OK || abi_resp.Capabilities == NULL)
{
printf("soap error: %d--%d, %s, %s\n", __LINE__, soap->error, *soap_faultcode(soap), *soap_faultstring(soap));
goto onvif_OptPTZ_end;
}
if(abi_resp.Capabilities->Media)
{
// printf("Media: XAddr: (%s)\n", abi_resp.Capabilities->Media->XAddr);
strGetToken = abi_resp.Capabilities->Media->XAddr;
strOptPtz = abi_resp.Capabilities->PTZ->XAddr;
}
_trt__GetProfiles request_pro;
_trt__GetProfilesResponse reponse_pro;
memset(&request_pro,0,sizeof(request_pro));
memset(&reponse_pro,0,sizeof(reponse_pro));
soap->header = &Header;
result = soap_call___trt__GetProfiles(soap, strGetToken, NULL, &request_pro, &reponse_pro);
if(SOAP_OK != result)
{
printf("soap error: %d--%d, %s, %s\n", __LINE__, soap->error, *soap_faultcode(soap), *soap_faultstring(soap));
goto onvif_OptPTZ_end;
}
_tptz__RelativeMove ptz_req;
_tptz__RelativeMoveResponse ptz_resp;
memset(&ptz_req, 0x0, sizeof(ptz_req));
memset(&ptz_resp, 0x0, sizeof(ptz_resp));
// printf("__sizeProfiles: %d\n", reponse_pro.__sizeProfiles);
// printf("token: %s\n", reponse_pro.Profiles->token);
ptz_req.ProfileToken = reponse_pro.Profiles->token;
ptz_req.Translation = (struct tt__PTZVector *)soap_malloc(soap, sizeof(tt__PTZVector));
memset(ptz_req.Translation, 0x0, sizeof(tt__PTZVector));
ptz_req.Translation->PanTilt = (struct tt__Vector2D *)soap_malloc(soap, sizeof(tt__Vector2D));
memset(ptz_req.Translation->PanTilt, 0x0, sizeof(tt__Vector2D));
ptz_req.Translation->Zoom = (struct tt__Vector1D *)soap_malloc(soap, sizeof(tt__Vector1D));
memset(ptz_req.Translation->Zoom, 0x0, sizeof(tt__Vector1D));
if(move_step >= 1)
{
move_step = 0.99999;
}
switch(commond)
{
case PTZ_LEFT:
ptz_req.Translation->PanTilt->x = move_step;
break;
case PTZ_RIGHT:
ptz_req.Translation->PanTilt->x = -move_step;
break;
case PTZ_UP:
ptz_req.Translation->PanTilt->y = -move_step;
break;
case PTZ_DOWN:
ptz_req.Translation->PanTilt->y = move_step;
break;
case PTZ_LEFTUP:
ptz_req.Translation->PanTilt->x = move_step;
ptz_req.Translation->PanTilt->y = -move_step;
break;
case PTZ_LEFTDOWN:
ptz_req.Translation->PanTilt->x = move_step;
ptz_req.Translation->PanTilt->y = move_step;
break;
case PTZ_RIGHTUP:
ptz_req.Translation->PanTilt->x = -move_step;
ptz_req.Translation->PanTilt->y = -move_step;
break;
case PTZ_RIGHTDOWN:
ptz_req.Translation->PanTilt->x = -move_step;
ptz_req.Translation->PanTilt->y = move_step;
break;
case PTZ_ZOOMIN:
ptz_req.Translation->Zoom->x = move_step;
break;
case PTZ_ZOOMOUT:
ptz_req.Translation->Zoom->x = -move_step;
break;
default:
goto onvif_OptPTZ_end;
break;
}
soap->header = &Header;
result = soap_call___tptz__RelativeMove(soap, strOptPtz, NULL, &ptz_req, &ptz_resp);
if(SOAP_OK == result)
{
printf("RelativeMove----OK\n");
}
else
{
printf("RelativeMove----faild\n");
printf("soap error: %d--%d, %s, %s\n", __LINE__, soap->error, *soap_faultcode(soap), *soap_faultstring(soap));
}
onvif_OptPTZ_end:
soap_destroy(soap);
soap_end(soap);
soap_free(soap);
return result;
}