一、适用平台
近期的项目采用的arm架构,需要实现球机的实时画面展示、云台控制、语音对讲,官方的SDK不支持arm架构,尝试使用gb28181协议实现,现阶段设备注册已实现
windows、Linux、arm都已测试,注册没有问题,SIP协议采用的exosip2,windows上编译的时候挺费劲
二、注册流程
基本流程是根据GBT28181_2016文档来实现的
具体步骤:
具体的内容是通过开源的平台抓包
设备注册请求
平台回复401
设备确认后再次发送注册消息
平台鉴权后回复 200 ok
三、主要代码
//检测事件类型
switch (event->type)
{
case EXOSIP_MESSAGE_NEW:
{
osip_message_t* pRegisterMsg = NULL;
pRegisterMsg = event->request;
if (0 == strcmp(event->request->sip_method, "REGISTER"))
{
if (pWWWAuEcho == NULL)
{
// qDebug("摄像机第一次发来未鉴权注册信息,返回401 %d\r\n" , iRet); // 摄像机第一次发来未鉴权注册信息,返回401
register401_Unauthorized(ctx, event);
}
else
{
//注册鉴权
char result[32];
Authentication(pWWWAuEcho, result);
std::string response = pWWWAuEcho->response;
//去除信息中的“号
response.erase(std::remove(response.begin(), response.end(), '"'), response.end());
//数据转换进行 判断鉴权
std::string src = result;
src = src.substr(0, 32);
if (src == response)
{
send_message(ctx, event->tid, SIP_OK, true, 3600, pRegisterMsg->req_uri);
}
else
{
break;
}
}
}
else if (0 == strcmp(event->request->sip_method, "MESSAGE"))
{
qDebug("---MESSAGE----\n");
osip_message_t* pRegisterMsg = NULL;
pRegisterMsg = event->request;
osip_header_t* p_header = NULL;
int expires = -1;
//查找有效信息头
osip_message_get_expires(pRegisterMsg, 0, &p_header);
if (p_header != NULL)
{
if (p_header->hvalue != NULL)
{
expires = atoi(p_header->hvalue);
}
}
send_message(ctx, event->tid, SIP_OK, true, expires, pRegisterMsg->req_uri);
}
}
break;
}
/*
功能:回复带有鉴权信息
ctx:eXosip_t结构体
pSipEvt:eXosip_event_t 事件描述信息
*/
int GB28181::register401_Unauthorized(eXosip_t * ctx, eXosip_event_t * pSipEvt)
{
int iReturnCode = 0;
osip_message_t * pSRegister = NULL;
osip_www_authenticate_t * header = NULL;
osip_www_authenticate_init(&header);
//添加www_authenticate信息(根据GB28181交互流程)
osip_www_authenticate_set_auth_type(header, osip_strdup("Digest"));
osip_www_authenticate_set_realm(header, osip_enquote(pcRealm.c_str()));
osip_www_authenticate_set_nonce(header, osip_enquote(pcNonce.c_str()));
char *pDest = NULL;
osip_www_authenticate_to_str(header, &pDest);
iReturnCode = eXosip_message_build_answer(ctx, pSipEvt->tid, SIP_UNAUTHORIZED, &pSRegister);
if (iReturnCode == 0 && pSRegister != NULL)
{
osip_message_set_www_authenticate(pSRegister, pDest);
osip_message_set_content_type(pSRegister, "Application/MANSCDP+xml");
eXosip_lock(ctx);
eXosip_message_send_answer(ctx, pSipEvt->tid, SIP_UNAUTHORIZED, pSRegister);
eXosip_unlock(ctx);
}
osip_www_authenticate_free(header);
free(pDest);
pDest = NULL;
return 0;
}