由于海康HikVision (Hik)平台摄像机的SDK不支持Arm Linux平台,为了跨平台的兼容性,只能使用ISAPI作为控制或接收相机数据的方式,ISAPI是Hik的一套HTTP通信协议,这里不过多介绍,详细可以查看[1-2]

签名机制

签名在ISAPI中是一个核心问题,几乎每一次API调用都需要签名,签名机制在Intelligent Security API (General Application)[1] 中3.1章Authentication有充分介绍,这里不赘述,核心代码如下(相对于原代码作了一些简化):

#include <iostream>
#include <string>
#include "md5.h"

struct http_auth
{
	char* httpBuf;//temp buffer 4096
	char* user;   //user name
	char* pass;   //password
	char* realm;  //in WWW-Authenticate header
	char* nonce;  //in WWW-Authenticate header
	char* method; //request method -> strdup("GET")
} ;

std::string generate_auth(http_auth ct,char *uri)
{
	char ha1Buf[33];
	char ha2Buf[33];
	unsigned char tmp[16];
	//cnonce 用于生成的字串为8位,可重复4次扩展为32位
	int cnonce = rand();
	
	memset(ct->httpBuf,'\0',4096);
	sprintf((char*)ct->httpBuf, "%s:%s:%s",ct->user,ct->realm,ct->pass);
	md5_hash(ct->httpBuf, strlen(ct->httpBuf), tmp);
	hex_from_raw(tmp, 16, ha1Buf);
	
	snprintf((char*)ct->httpBuf, 4096, "%s:%s",ct->method,uri);
	md5_hash(ct->httpBuf, strlen(ct->httpBuf), tmp);
	hex_from_raw(tmp, 16, ha2Buf);
	
	memset(ct->httpBuf,'\0',4096);
	sprintf((char*)ct->httpBuf, "%s:%s:00000001:%08x:auth:%s",\
					ha1Buf, ct->nonce, cnonce, ha2Buf);
	md5_hash(ct->httpBuf, strlen(ct->httpBuf), tmp);
	hex_from_raw(tmp, 16, ha1Buf);
	
	snprintf(ct->httpBuf, 4096, "Digest username=\"%s\", realm=\"%s\", "
					"nonce=\"%s\", uri=\"%s\", response=\"%s\", qop=auth, "
					"nc=00000001, cnonce=\"%08x\"",
					ct->user, ct->realm, ct->nonce, uri, ha1Buf, cnonce);
	return std::string(ct->httpBuf);
}

使用任意一个API获取 realm 和 nonce ,这里需要自己解析 WWW-Authenticate,且每次过期都需要请求(一般每次API调用都重新生成签名),在有签名的 API 请求Header中应包含验证信息 Authorization

~$ curl -X GET -i 'http://192.168.0.100:80/ISAPI/Security/users'

HTTP/1.1 401 Unauthorized
Date: Fri, 22 Apr 2022 10:39:44 GMT
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Content-Length: 178
Content-Type: text/html
Connection: close
WWW-Authenticate: Digest qop="auth", realm="IP Camera(F9868)", nonce="323533623a35306462333232633a418b56a32f5c61f15b209459378c035d", stale="FALSE"

<!DOCTYPE html>
<html><head><title>Document Error: Unauthorized</title></head>
<body><h2>Access Error: 401 -- Unauthorized</h2>
<p>Authentication Error</p>
</body>
</html>
双向语音

双向语音(Two-Way Audio),请求过程如下(一般ID都是1) :

1. Optional: Get parameters, including channel No., encoding mode, and so on, of all two-way audio channels by 
the request URL: GET /ISAPI/System/TwoWayAudio/channels .
2. Specify a channel of device to start the two-way audio by 
the request URL: PUT /ISAPI/System/TwoWayAudio/channels/<ID>/open
3. Perform the following operations to transmit the audio data between platform and device.
Send Audio Data to Device Request URL: PUT /ISAPI/System/TwoWayAudio/channels/<ID>/audioData
Receive Audio Data from Request URL: GET /ISAPI/System/TwoWayAudio/channels/Device<ID>/audioData
4. Stop two-way audio of the specific channel by 
the request URL: PUT /ISAPI/System/TwoWayAudio/channels/<ID>/close .

需要注意的是,发送或接收数据时连接为HTTP长连接即 keep-alive,发送数据时单次只能发送8000个bytes ,不同采样率及位深的音频每秒发送次数不同,公式如下:

每秒字节数 = 采样率 x 位深 x 音频通道数 x 1() ÷ 8 

如:采样率为16Khz,位深为16bit的音频,通道为单声道,每秒字节数 = 16000 x 16 x 1 ÷ 8 = 32000B = 32KB,所以在Hik相机上需要每秒传4次8000B的数据,即每250ms传一次8000B的数据

参考:

1 . Hikvision Isapi Core Protocol - Intelligent Security API (General Application)
2 . Intelligent Security API (Display and Control)
3 . hpwang666/httpclient

Logo

更多推荐