欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

GB28181目录订阅记录

程序员文章站 2022-07-05 23:13:15
...

  SIP域可通过订阅方式订阅其他SIP域的全部或部分目录的离线、上线、增加、删除、更新等变更信息。被订阅域在目录变更后应将变更事件通知订阅域

1、订阅流程

GB28181目录订阅记录
   A发送初始订阅消息订阅B的目录时Expires头域携带订阅过期时间,默认是600s,该时间应可配置。A在订阅过期时间到来之前订阅域应该刷新订阅。B在过期时间到来时若未收到刷新订阅的消息,则移除A的订阅状态。
刷新订阅消息的初始订阅消息属于同一个会话,会话ID应该一致。

2、抓包消息

服务器A(192.168.0.33)订阅海康NVR(192.168.0.64)目录

《1》、A初始订阅

GB28181目录订阅记录

《2》、NVR回复200 ok然后回复NOTIFY消息

(这个消息截图与初始化截图的是两个不同时间内获得的,所以有会话不一致,实际上同一个流程notify的会话ID和初始订阅的是一样的)
GB28181目录订阅记录
GB28181目录订阅记录

   服务器回复200 OK(这个流程也是不同时间跑的,所以会话ID与初始化订阅抓包截图的不一样,实际上应该是一致的)
GB28181目录订阅记录

《3》、订阅刷新的抓包

GB28181目录订阅记录

回复200 OK
GB28181目录订阅记录

由初始化订阅和订阅刷新可知,会话ID是要保持一致的,若刷新注册使用不同的ID在exoisp中创建刷新信息会出现错误码-6(NOFOUND)。

3、demo

《1》、初始化订阅

char rsp_xml_body[4096];
osip_message_t *rsp_msg = NULL;
char sour_call[128] = {0};
char dest_call[128] = {0};


sprintf(sour_call, "sip:%aaa@qq.com%s:%d", deviceInfo.server_id, deviceInfo.server_ip,deviceInfo.server_port);
sprintf(dest_call, "sip:%aaa@qq.com%s:%d", deviceInfo.ipc_id, deviceInfo.ipc_ip, deviceInfo.ipc_port);


eXosip_subscription_build_initial_subscribe(g_context_eXosip, &rsp_msg, dest_call, sour_call, NULL, "Catalog", 600);
snprintf(rsp_xml_body, 4096, "<?xml version=\"1.0\"?>\r\n"
"<Query>\r\n"
"<CmdType>Catalog</CmdType>\r\n"
"<SN>%s</SN>\r\n"
"<DeviceID>%s</DeviceID>\r\n"
"</Query>\r\n",
"25",
deviceInfo.ipc_id
);


osip_message_set_body(rsp_msg, rsp_xml_body, strlen(rsp_xml_body));
osip_message_set_content_type(rsp_msg, "Application/MANSCDP+xml");


eXosip_lock(g_context_eXosip);
eXosip_subscription_send_initial_request(g_context_eXosip, rsp_msg);
eXosip_unlock(g_context_eXosip);

会话id保存

//发送成功之后NVR回复200 OK,在这个200 OK 的event处理流程中需要保存会话ID用于刷新注册
case EXOSIP_SUBSCRIPTION_ANSWERED:
{
     m_SubCatalogId = g_event->did;  //保存会话ID
}break;

《2》、刷新订阅

{
    //refresh
    osip_message_t * sub = NULL;
    char rsp_xml_body[1024];
    memset(rsp_xml_body,0,1024);
    
    eXosip_lock(this->g_context_eXosip);
    int ret = eXosip_subscription_build_refresh_request(this->g_context_eXosip, this->m_SubCatalogId, &sub); /* 使用保存下来的会话ID */
    if(ret != OSIP_SUCCESS)
    {
      LOG_DEBUG << "eXosip_subscription_build_refresh_request FAILE! Error code: " << ret;
      return;
    }

    snprintf(rsp_xml_body, 1024, "<?xml version=\"1.0\"?>\r\n"
        "<Query>\r\n"
        "<CmdType>Catalog</CmdType>\r\n"
        "<SN>%s</SN>\r\n"
        "<DeviceID>%s</DeviceID>\r\n"
        "</Query>\r\n",
        "25",
        deviceInfo.ipc_id
        );

        osip_message_set_body(sub, rsp_xml_body, strlen(rsp_xml_body));
        osip_message_set_content_type(sub, "Application/MANSCDP+xml");

    ret = eXosip_subscription_send_refresh_request(this->g_context_eXosip, this->m_SubCatalogId, sub);
    eXosip_unlock(this->g_context_eXosip);
    if(ret != OSIP_SUCCESS)
    {
      LOG_DEBUG << "eXosip_subscription_send_refresh_request FAILE! Error code: " << ret;
      return;
    }
    LOG_DEBUG << "eXosip_subscription_send_refresh_request Success !!! ";
}

4、参考

[1]、GBT 28181-2016公共安全视频监控联网系统信息传输、交换、控制技术要求.pdf
[2]、exosip开发手册