1 背景说明
要和摄像头直接通信,第一步必须获取webserver地址,通过该地址才能进一步获得设备的能力、提供的媒体频信息等内容。webserver地址就是在probe应答包中, 具体是XAddrs:http://192.168.15.240/onvif/device_service,接下来的获取设备能力函数将使用此地址进行通信。
2 GetCapabilities命令说明
GetCapabilities函数在不同的版本中实际名称并不一样,我的版本中是:
SOAP_FMAC5 int SOAP_FMAC6 soap_call___ns2__GetCapabilities(struct soap *soap, const char *soap_endpoint, const char *soap_action, struct _ns2__GetCapabilities *ns2__GetCapabilities, struct _ns2__GetCapabilitiesResponse *ns2__GetCapabilitiesResponse)
该函数需要提供请求指针、应答指针。可以指定请求设备的全部能力还是某一部分能力:
enum ns3__CapabilityCategory { ns3__CapabilityCategory__All = 0, ns3__CapabilityCategory__Analytics = 1, ns3__CapabilityCategory__Device = 2, ns3__CapabilityCategory__Events = 3, ns3__CapabilityCategory__Imaging = 4, ns3__CapabilityCategory__Media = 5, ns3__CapabilityCategory__PTZ = 6 };
以下实例中指定查询ns3__CapabilityCategory__Media能力。一般的可以选择查询ALL能力。
最后从报文中提取出媒体信息URI :http://192.168.15.240/onvif/Media,将用于查询具体的视频源、编码器配置参数。
如果设备具备用户名、密码,那么查询设备能力可能需要鉴权过程,本文没有研究ONVIF的鉴权机制,默认摄像头无需输入用户名密码。如果出现鉴权应答,那么应答 getCapResponse.Capabilities就是NULL指针。soap_call___ns2__GetCapabilities函数返回值是501。
具体的应用实例如下:
/******************************************************************************
* Name: MyGetCapabilities
*
* Desc: 获取指定设备节点的能力
* Param:
struct soap *soap,
int index, 设备序号
* Return: BOOL, TRUE: success, FALSE: fail
* Global:
* Note:
* Author: Tom-hongtao.gao
* -------------------------------------
* Log: 2013/07/24, Create this function by Tom-hongtao.gao
******************************************************************************/
BOOL MyGetCapabilities(struct soap *soap, int index)
{
BOOL bret=FALSE;
int result = 0;
DEVICENODE * deviceode = DLFindbyIndex(index);
if(!deviceode)
{
printf("--Error: DLFindbyIndex(%d) return NULL! \n", index);
return FALSE;
}
if(deviceode->webserver==NULL || strlen(deviceode->webserver)==0)
{
printf("--Error: deviceode->webserver is NULL! \n");
return FALSE;
}
struct _ns2__GetCapabilities getCapReq={0};
struct _ns2__GetCapabilitiesResponse getCapResponse={0};
enum ns3__CapabilityCategory temp_category = ns3__CapabilityCategory__Media;
getCapReq.__sizeCategory=1;
getCapReq.Category=&temp_category;
result = soap_call___ns2__GetCapabilities(soap, deviceode->webserver, NULL, &getCapReq, &getCapResponse);
if(result==-1)
{
printf("soap error: %d, %s, %s\n", soap->error, *soap_faultcode(soap), *soap_faultstring(soap));
result = soap->error;
bret = FALSE;
}
else
{
if(getCapResponse.Capabilities==NULL)
{
printf(" GetCapabilities failed! result=%d \n",result);
bret = FALSE;
}
else
{
printf(" GetCapabilities OK! result=%d \n",result);
//printf(" Media->XAddr=%s \n", getCapResponse.Capabilities->Media->XAddr);
DLSetMediaUri(index, getCapResponse.Capabilities->Media->XAddr);
//PrintfNodebyIndex(index);
bret = TRUE;
}
}
soap_end(soap);
return bret;
}
实际的数据报文如下:
略