781 lines
21 KiB
C++
781 lines
21 KiB
C++
/***************************************************************************************
|
||
*
|
||
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||
*
|
||
* By downloading, copying, installing or using the software you agree to this license.
|
||
* If you do not agree to this license, do not download, install,
|
||
* copy or use the software.
|
||
*
|
||
* Copyright (C) 2014-2022, Happytimesoft Corporation, all rights reserved.
|
||
*
|
||
* Redistribution and use in binary forms, with or without modification, are permitted.
|
||
*
|
||
* Unless required by applicable law or agreed to in writing, software distributed
|
||
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
|
||
* language governing permissions and limitations under the License.
|
||
*
|
||
****************************************************************************************/
|
||
|
||
#include "sys_inc.h"
|
||
#include "hsip.h"
|
||
#include "sua.h"
|
||
#include "gb28181_subscribe.h"
|
||
#include "gb28181_msg.h"
|
||
#include "sip_parse.h"
|
||
#include "sip_tx.h"
|
||
#include "gb28181_cfg.h"
|
||
|
||
|
||
/****************************************************************************/
|
||
|
||
GB28181_SUBSCRIBE g_alarm_subscribe;
|
||
GB28181_ALARM_REQ g_alarm_req;
|
||
|
||
GB28181_SUBSCRIBE g_catalog_subscribe;
|
||
GB28181_CATALOG_REQ g_catalog_req;
|
||
|
||
GB28181_SUBSCRIBE g_mobile_position_subscribe;
|
||
GB28181_MOBILE_POSITION_REQ g_mobile_position_req;
|
||
|
||
extern HSIP_CLASS hsip;
|
||
extern HSIP_USER g_user;
|
||
|
||
|
||
/****************************************************************************/
|
||
|
||
HSIP_MSG * gb28181_notify_build(HSIP_USER * p_user, char * p_xml, int len, GB28181_SUBSCRIBE * p_subscribe)
|
||
{
|
||
HSIP_MSG * tx_msg = sip_get_msg_large_buf(1024 + len);
|
||
if (NULL == tx_msg)
|
||
{
|
||
log_print(HT_LOG_ERR, "%s, get message buffer failed\r\n", __FUNCTION__);
|
||
return NULL;
|
||
}
|
||
|
||
tx_msg->msg_type = 0;
|
||
tx_msg->msg_sub_type = SIP_MT_NTF;
|
||
tx_msg->msg_crpty_mode = p_user->user_crpty_mode;
|
||
tx_msg->local_port = p_user->sip_port;
|
||
|
||
sip_add_tx_msg_fline(tx_msg, "NOTIFY", "%s SIP/2.0", p_subscribe->subscriber_uri);
|
||
|
||
if (p_user->usrf_tcp_sip == 1)
|
||
{
|
||
sip_add_tx_msg_via(tx_msg, "SIP/2.0/TCP %s:%u;branch=z9hG4bK%x",
|
||
p_user->user_ip, p_user->user_port, (uint32)time(NULL));
|
||
}
|
||
else
|
||
{
|
||
sip_add_tx_msg_via(tx_msg, "SIP/2.0/UDP %s:%u;branch=z9hG4bK%x",
|
||
p_user->user_ip, p_user->user_port, (uint32)time(NULL));
|
||
}
|
||
|
||
sip_add_tx_msg_line(tx_msg, "From", "<%s>", p_user->user_sip_addr);
|
||
|
||
if (p_subscribe->subscriber_tag[0] != '\0')
|
||
{
|
||
sip_add_tx_msg_line(tx_msg, "To", "<%s>;%s", p_subscribe->subscriber_uri, p_subscribe->subscriber_tag);
|
||
}
|
||
else
|
||
{
|
||
sip_add_tx_msg_line(tx_msg, "To", "<%s>", p_subscribe->subscriber_uri);
|
||
}
|
||
|
||
sip_add_tx_msg_line(tx_msg, "Call-ID", "%s", p_subscribe->subscribe_callid);
|
||
|
||
if (p_user->notify_cseq++ == 0)
|
||
{
|
||
p_user->notify_cseq = 1;
|
||
}
|
||
|
||
sip_add_tx_msg_line(tx_msg, "CSeq", "%u NOTIFY", p_user->notify_cseq);
|
||
sip_add_tx_msg_line(tx_msg, "Subscription-State", "active");
|
||
sip_add_tx_msg_line(tx_msg, "Event", "%s", p_subscribe->subscribe_event);
|
||
sip_add_tx_msg_line(tx_msg, "Contact", "<sip:%s@%s:%u>", p_user->user_name, p_user->user_ip, p_user->user_port);
|
||
sip_add_tx_msg_line(tx_msg, "Max-Forwards", "70");
|
||
sip_add_tx_msg_line(tx_msg, "User-Agent", "%s", hsip.ver);
|
||
sip_add_tx_msg_line(tx_msg, "Content-Type", "Application/MANSCDP+xml");
|
||
sip_add_tx_msg_line(tx_msg, "Content-Length", "%d", len + 2);
|
||
sip_add_tx_msg_sdp_line(tx_msg, "", "%s", p_xml);
|
||
|
||
tx_msg->remote_ip = inet_addr(p_user->server_ipstr);
|
||
tx_msg->remote_port = htons(p_user->server_port);
|
||
|
||
return tx_msg;
|
||
}
|
||
|
||
BOOL gb28181_alarm_notify_send(GB28181_ALARM * p_req)
|
||
{
|
||
char xml[1024];
|
||
int offset = 0;
|
||
int tlen = sizeof(xml);
|
||
|
||
HSIP_USER * p_user = &g_user;
|
||
|
||
offset = gb28181_alarm_notify_xml_build(xml, tlen, p_req);
|
||
|
||
HSIP_MSG * tx_msg = gb28181_notify_build(p_user, xml, offset, &g_alarm_subscribe);
|
||
if (NULL == tx_msg)
|
||
{
|
||
log_print(HT_LOG_ERR, "%s, gb28181_notify_build failed\r\n", __FUNCTION__);
|
||
return FALSE;
|
||
}
|
||
|
||
user_tx_free_msg(p_user, tx_msg);
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
BOOL gb28181_media_notify_send(GB28181_MEDIA_NOTIFY * p_req)
|
||
{
|
||
char xml[1024];
|
||
int offset = 0;
|
||
int tlen = sizeof(xml);
|
||
|
||
HSIP_USER * p_user = &g_user;
|
||
|
||
offset = gb28181_media_notify_xml_build(xml, tlen, p_req);
|
||
|
||
HSIP_MSG * tx_msg = gb28181_notify_build(p_user, xml, offset, &g_alarm_subscribe);
|
||
if (NULL == tx_msg)
|
||
{
|
||
log_print(HT_LOG_ERR, "%s, gb28181_notify_build failed\r\n", __FUNCTION__);
|
||
return FALSE;
|
||
}
|
||
|
||
user_tx_free_msg(p_user, tx_msg);
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
BOOL gb28181_catalog_notify_send(GB28181_CATALOG * p_req)
|
||
{
|
||
char xml[SIP_MAX_BUFF];
|
||
int offset = 0;
|
||
int tlen = sizeof(xml);
|
||
|
||
HSIP_USER * p_user = &g_user;
|
||
|
||
offset = gb28181_catalog_notify_xml_build(xml, tlen, p_req);
|
||
|
||
HSIP_MSG * tx_msg = gb28181_notify_build(p_user, xml, offset, &g_catalog_subscribe);
|
||
if (NULL == tx_msg)
|
||
{
|
||
log_print(HT_LOG_ERR, "%s, gb28181_notify_build failed\r\n", __FUNCTION__);
|
||
return FALSE;
|
||
}
|
||
|
||
user_tx_free_msg(p_user, tx_msg);
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
BOOL gb28181_mobile_position_notify_send(GB28181_MOBILE_POSITION * p_req)
|
||
{
|
||
char xml[1024];
|
||
int offset = 0;
|
||
int tlen = sizeof(xml);
|
||
|
||
HSIP_USER * p_user = &g_user;
|
||
|
||
offset = gb28181_mobile_position_notify_xml_build(xml, tlen, p_req);
|
||
|
||
HSIP_MSG * tx_msg = gb28181_notify_build(p_user, xml, offset, &g_mobile_position_subscribe);
|
||
if (NULL == tx_msg)
|
||
{
|
||
log_print(HT_LOG_ERR, "%s, gb28181_notify_build failed\r\n", __FUNCTION__);
|
||
return FALSE;
|
||
}
|
||
|
||
user_tx_free_msg(p_user, tx_msg);
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
/***
|
||
* 调用此接口下发事件通知给事件订阅者
|
||
**/
|
||
BOOL gb28181_event_notify(GB28181_ALARM * p_req)
|
||
{
|
||
if (g_alarm_subscribe.subscriber[0] == '\0')
|
||
{
|
||
log_print(HT_LOG_ERR, "%s, subscriber is empty!!!\r\n", __FUNCTION__);
|
||
return FALSE;
|
||
}
|
||
|
||
// todo : 使用g_alarm_req跟p_req比较,是否满足事件下发条件
|
||
|
||
return gb28181_alarm_notify_send(p_req);
|
||
}
|
||
|
||
/***
|
||
* 调用此接口下发媒体状态通知给事件订阅者
|
||
**/
|
||
BOOL gb28181_media_notify(GB28181_MEDIA_NOTIFY * p_req)
|
||
{
|
||
if (g_alarm_subscribe.subscriber[0] == '\0')
|
||
{
|
||
log_print(HT_LOG_ERR, "%s, subscriber is empty!!!\r\n", __FUNCTION__);
|
||
return FALSE;
|
||
}
|
||
|
||
return gb28181_media_notify_send(p_req);
|
||
}
|
||
|
||
BOOL gb28181_catalog_notify(GB28181_CATALOG * p_req)
|
||
{
|
||
if (g_catalog_subscribe.subscriber[0] == '\0')
|
||
{
|
||
log_print(HT_LOG_ERR, "%s, subscriber is empty!!!\r\n", __FUNCTION__);
|
||
return FALSE;
|
||
}
|
||
|
||
return gb28181_catalog_notify_send(p_req);
|
||
}
|
||
|
||
BOOL gb28181_mobile_position_notify(GB28181_MOBILE_POSITION * p_req)
|
||
{
|
||
if (g_mobile_position_subscribe.subscriber[0] == '\0')
|
||
{
|
||
log_print(HT_LOG_ERR, "%s, subscriber is empty!!!\r\n", __FUNCTION__);
|
||
return FALSE;
|
||
}
|
||
|
||
return gb28181_mobile_position_notify_send(p_req);
|
||
}
|
||
|
||
/****************************************************************************/
|
||
|
||
HSIP_MSG * gb28181_subscribe_res_build(HSIP_MSG * rx_msg, GB28181_REQ_HDR * p_req)
|
||
{
|
||
char xml[1024];
|
||
int offset = 0;
|
||
int tlen = sizeof(xml);
|
||
|
||
offset += snprintf(xml+offset, tlen-offset,
|
||
"<?xml version=\"1.0\"?>\r\n"
|
||
"<Response>\r\n"
|
||
"<CmdType>%s</CmdType>\r\n"
|
||
"<SN>%u</SN>\r\n"
|
||
"<DeviceID>%s</DeviceID>\r\n"
|
||
"<Result>OK</Result>\r\n"
|
||
"<Response>\r\n",
|
||
rx_msg->cmdt,
|
||
p_req->SN,
|
||
p_req->DeviceID);
|
||
|
||
HSIP_MSG * tx_msg = sip_get_msg_buf();
|
||
if (NULL == tx_msg)
|
||
{
|
||
log_print(HT_LOG_ERR, "%s, get message buffer failed\r\n", __FUNCTION__);
|
||
return NULL;
|
||
}
|
||
|
||
tx_msg->msg_type = 1;
|
||
tx_msg->msg_sub_type = 200;
|
||
tx_msg->local_port = rx_msg->local_port;
|
||
tx_msg->local_ip = rx_msg->local_ip;
|
||
|
||
sip_add_tx_msg_fline(tx_msg, "SIP/2.0", "200 OK");
|
||
|
||
sip_copy_msg_via(rx_msg, tx_msg);
|
||
sip_copy_msg_line(rx_msg, tx_msg, "From");
|
||
sip_copy_msg_line(rx_msg, tx_msg, "To");
|
||
sip_copy_msg_line(rx_msg, tx_msg, "Call-ID");
|
||
sip_copy_msg_line(rx_msg, tx_msg, "CSeq");
|
||
|
||
sip_add_tx_msg_line(tx_msg, "User-Agent", "%s", hsip.ver);
|
||
sip_add_tx_msg_line(tx_msg, "Content-Type", "Application/MANSCDP+xml");
|
||
sip_add_tx_msg_line(tx_msg, "Content-Length", "%d", offset+2);
|
||
|
||
sip_add_tx_msg_sdp_line(tx_msg, "", "%s", xml);
|
||
|
||
tx_msg->remote_ip = rx_msg->remote_ip;
|
||
tx_msg->remote_port = rx_msg->remote_port;
|
||
|
||
return tx_msg;
|
||
}
|
||
|
||
BOOL gb28181_subscribe_alarm_handler(HSIP_MSG * rx_msg, XMLN * p_root)
|
||
{
|
||
int expires = 600;
|
||
BOOL ret = FALSE;
|
||
char fname[64];
|
||
|
||
HSIP_USER * p_user = &g_user;
|
||
|
||
GB28181_SUBSCRIBE subscribe;
|
||
memset(&subscribe, 0, sizeof(subscribe));
|
||
|
||
GB28181_ALARM_REQ req;
|
||
memset(&req, 0, sizeof(req));
|
||
|
||
// 获取请求参数
|
||
if (!gb28181_alarm_req_parse(p_root, &req))
|
||
{
|
||
log_print(HT_LOG_ERR, "%s, param error\r\n", __FUNCTION__);
|
||
return FALSE;
|
||
}
|
||
|
||
HDRV * event_hdrv = sip_find_headline(rx_msg, "Event");
|
||
HDRV * expires_hdrv = sip_find_headline(rx_msg, "Expires");
|
||
|
||
if (event_hdrv == NULL || event_hdrv->value_string == NULL)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
if (sip_get_user_name(rx_msg, "From", fname, sizeof(fname)) == FALSE)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
if (expires_hdrv && expires_hdrv->value_string)
|
||
{
|
||
expires = atoi(expires_hdrv->value_string);
|
||
if (expires < 0)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
if (expires == 0) // 取消订阅
|
||
{
|
||
HSIP_MSG * tx_msg = gb28181_subscribe_res_build(rx_msg, &req.hdr);
|
||
if (tx_msg)
|
||
{
|
||
sip_add_tx_msg_line(tx_msg, "Expires", "0");
|
||
sip_add_tx_msg_line(tx_msg, "Event", "%s", event_hdrv->value_string);
|
||
user_tx_free_msg(p_user, tx_msg);
|
||
}
|
||
|
||
g_alarm_subscribe.subscriber[0] = '\0';
|
||
g_alarm_subscribe.subscribe_event[0] = '\0';
|
||
g_alarm_subscribe.subscribe_sn = 0;
|
||
g_alarm_subscribe.subscribe_st = 0;
|
||
g_alarm_subscribe.subscribe_expires = 0;
|
||
|
||
return TRUE;
|
||
}
|
||
}
|
||
|
||
// 记录订阅信息
|
||
strncpy(subscribe.subscribe_event, event_hdrv->value_string, sizeof(subscribe.subscribe_event));
|
||
strncpy(subscribe.subscriber, fname, sizeof(subscribe.subscriber));
|
||
subscribe.subscribe_sn = req.hdr.SN;
|
||
subscribe.subscribe_st = sys_os_get_uptime();
|
||
subscribe.subscribe_expires = expires;
|
||
|
||
if (sip_get_msg_call_id(rx_msg, subscribe.subscribe_callid, sizeof(subscribe.subscribe_callid)) == FALSE)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
if (sip_get_sip_address(rx_msg, "From", subscribe.subscriber_uri, sizeof(subscribe.subscriber_uri)) == FALSE)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
if (sip_get_sip_address(rx_msg, "To", subscribe.subscriber_dst, sizeof(subscribe.subscriber_dst)) == FALSE)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
sip_get_user_tag(rx_msg, "From", subscribe.subscriber_tag, sizeof(subscribe.subscriber_tag));
|
||
|
||
HSIP_MSG * tx_msg = gb28181_subscribe_res_build(rx_msg, &req.hdr);
|
||
if (tx_msg)
|
||
{
|
||
sip_add_tx_msg_line(tx_msg, "Expires", "%d", subscribe.subscribe_expires);
|
||
sip_add_tx_msg_line(tx_msg, "Event", "%s", event_hdrv->value_string);
|
||
sip_add_tx_msg_line(tx_msg, "Contact", "<sip:%s@%s:%u>", p_user->user_name, p_user->user_ip, p_user->user_port);
|
||
}
|
||
user_tx_free_msg(p_user, tx_msg);
|
||
|
||
// 保存订阅参数
|
||
memcpy(&g_alarm_subscribe, &subscribe, sizeof(GB28181_SUBSCRIBE));
|
||
memcpy(&g_alarm_req, &req, sizeof(GB28181_ALARM_REQ));
|
||
|
||
// todo : 下面的代码作为测试用
|
||
{
|
||
sleep(3);
|
||
|
||
GB28181_ALARM alarm;
|
||
memset(&alarm, 0, sizeof(alarm));
|
||
|
||
strcpy(alarm.DeviceID, g_gb28181_cfg.channels[0].cid);
|
||
alarm.AlarmPriority = 2;
|
||
strcpy(alarm.AlarmMethod, "2");
|
||
alarm.AlarmTime = time(NULL);
|
||
alarm.AlarmDescriptionFlag = 1;
|
||
strcpy(alarm.AlarmDescription, "test");
|
||
|
||
gb28181_event_notify(&alarm);
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
BOOL gb28181_subscribe_catalog_handler(HSIP_MSG * rx_msg, XMLN * p_root)
|
||
{
|
||
int expires = 600;
|
||
BOOL ret = FALSE;
|
||
char fname[64];
|
||
|
||
HSIP_USER * p_user = &g_user;
|
||
|
||
GB28181_SUBSCRIBE subscribe;
|
||
memset(&subscribe, 0, sizeof(subscribe));
|
||
|
||
GB28181_CATALOG_REQ req;
|
||
memset(&req, 0, sizeof(req));
|
||
|
||
// 获取请求参数
|
||
if (!gb28181_catalog_req_parse(p_root, &req))
|
||
{
|
||
log_print(HT_LOG_ERR, "%s, param error\r\n", __FUNCTION__);
|
||
return FALSE;
|
||
}
|
||
|
||
HDRV * event_hdrv = sip_find_headline(rx_msg, "Event");
|
||
HDRV * expires_hdrv = sip_find_headline(rx_msg, "Expires");
|
||
|
||
if (event_hdrv == NULL || event_hdrv->value_string == NULL)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
if (sip_get_user_name(rx_msg, "From", fname, sizeof(fname)) == FALSE)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
if (expires_hdrv && expires_hdrv->value_string)
|
||
{
|
||
expires = atoi(expires_hdrv->value_string);
|
||
if (expires < 0)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
if (expires == 0) // 取消订阅
|
||
{
|
||
HSIP_MSG * tx_msg = gb28181_subscribe_res_build(rx_msg, &req.hdr);
|
||
if (tx_msg)
|
||
{
|
||
sip_add_tx_msg_line(tx_msg, "Expires", "0");
|
||
sip_add_tx_msg_line(tx_msg, "Event", "%s", event_hdrv->value_string);
|
||
user_tx_free_msg(p_user, tx_msg);
|
||
}
|
||
|
||
g_catalog_subscribe.subscriber[0] = '\0';
|
||
g_catalog_subscribe.subscribe_event[0] = '\0';
|
||
g_catalog_subscribe.subscribe_sn = 0;
|
||
g_catalog_subscribe.subscribe_st = 0;
|
||
g_catalog_subscribe.subscribe_expires = 0;
|
||
|
||
return TRUE;
|
||
}
|
||
}
|
||
|
||
// 记录订阅信息
|
||
strncpy(subscribe.subscribe_event, event_hdrv->value_string, sizeof(subscribe.subscribe_event));
|
||
strncpy(subscribe.subscriber, fname, sizeof(subscribe.subscriber));
|
||
subscribe.subscribe_sn = req.hdr.SN;
|
||
subscribe.subscribe_st = sys_os_get_uptime();
|
||
subscribe.subscribe_expires = expires;
|
||
|
||
if (sip_get_msg_call_id(rx_msg, subscribe.subscribe_callid, sizeof(subscribe.subscribe_callid)) == FALSE)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
if (sip_get_sip_address(rx_msg, "From", subscribe.subscriber_uri, sizeof(subscribe.subscriber_uri)) == FALSE)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
if (sip_get_sip_address(rx_msg, "To", subscribe.subscriber_dst, sizeof(subscribe.subscriber_dst)) == FALSE)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
sip_get_user_tag(rx_msg, "From", subscribe.subscriber_tag, sizeof(subscribe.subscriber_tag));
|
||
|
||
HSIP_MSG * tx_msg = gb28181_subscribe_res_build(rx_msg, &req.hdr);
|
||
if (tx_msg)
|
||
{
|
||
sip_add_tx_msg_line(tx_msg, "Expires", "%d", subscribe.subscribe_expires);
|
||
sip_add_tx_msg_line(tx_msg, "Event", "%s", event_hdrv->value_string);
|
||
sip_add_tx_msg_line(tx_msg, "Contact", "<sip:%s@%s:%u>", p_user->user_name, p_user->user_ip, p_user->user_port);
|
||
}
|
||
user_tx_free_msg(p_user, tx_msg);
|
||
|
||
// 保存订阅参数
|
||
memcpy(&g_catalog_subscribe, &subscribe, sizeof(GB28181_SUBSCRIBE));
|
||
memcpy(&g_catalog_req, &req, sizeof(GB28181_CATALOG_REQ));
|
||
|
||
// todo : 下面的代码作为测试用
|
||
{
|
||
sleep(3);
|
||
|
||
int i;
|
||
|
||
GB28181_CATALOG catalog;
|
||
memset(&catalog, 0, sizeof(catalog));
|
||
|
||
// 模拟目录上报事件
|
||
catalog.SumNum = g_gb28181_cfg.channel_nums;
|
||
catalog.Num = g_gb28181_cfg.channel_nums;
|
||
|
||
catalog.DeviceList = (GB28181_DEVICE *)malloc(sizeof(GB28181_DEVICE) * catalog.Num);
|
||
if (catalog.DeviceList)
|
||
{
|
||
memset(catalog.DeviceList, 0, sizeof(GB28181_DEVICE) * catalog.Num);
|
||
|
||
for (i = 0; i < catalog.Num; i++)
|
||
{
|
||
strcpy(catalog.DeviceList[i].DeviceID, g_gb28181_cfg.channels[i].cid);
|
||
strcpy(catalog.DeviceList[i].Name, g_gb28181_cfg.channels[i].cname);
|
||
strcpy(catalog.DeviceList[i].Manufacturer, "Happytimesoft");
|
||
strcpy(catalog.DeviceList[i].Model, "IPC");
|
||
catalog.DeviceList[i].RegisterWay = 1;
|
||
strcpy(catalog.DeviceList[i].ParentID, g_gb28181_cfg.device_id);
|
||
strcpy(catalog.DeviceList[i].Owner, "Owner");
|
||
strcpy(catalog.DeviceList[i].CivilCode, "CivilCode");
|
||
strcpy(catalog.DeviceList[i].Address, "Address");
|
||
}
|
||
|
||
gb28181_catalog_notify(&catalog);
|
||
|
||
sleep(5);
|
||
|
||
// 模拟通道名称改变事件
|
||
if (catalog.Num > 0)
|
||
{
|
||
strcpy(catalog.DeviceList[catalog.Num-1].Name, "TEST");
|
||
}
|
||
|
||
gb28181_catalog_notify(&catalog);
|
||
|
||
free(catalog.DeviceList);
|
||
}
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
BOOL gb28181_subscribe_mobile_position_handler(HSIP_MSG * rx_msg, XMLN * p_root)
|
||
{
|
||
int expires = 600;
|
||
BOOL ret = FALSE;
|
||
char fname[64];
|
||
|
||
HSIP_USER * p_user = &g_user;
|
||
|
||
GB28181_SUBSCRIBE subscribe;
|
||
memset(&subscribe, 0, sizeof(subscribe));
|
||
|
||
GB28181_MOBILE_POSITION_REQ req;
|
||
memset(&req, 0, sizeof(req));
|
||
|
||
// 获取请求参数
|
||
if (!gb28181_mobile_position_req_parse(p_root, &req))
|
||
{
|
||
log_print(HT_LOG_ERR, "%s, param error\r\n", __FUNCTION__);
|
||
return FALSE;
|
||
}
|
||
|
||
HDRV * event_hdrv = sip_find_headline(rx_msg, "Event");
|
||
HDRV * expires_hdrv = sip_find_headline(rx_msg, "Expires");
|
||
|
||
if (event_hdrv == NULL || event_hdrv->value_string == NULL)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
if (sip_get_user_name(rx_msg, "From", fname, sizeof(fname)) == FALSE)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
if (expires_hdrv && expires_hdrv->value_string)
|
||
{
|
||
expires = atoi(expires_hdrv->value_string);
|
||
if (expires < 0)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
if (expires == 0) // 取消订阅
|
||
{
|
||
HSIP_MSG * tx_msg = gb28181_subscribe_res_build(rx_msg, &req.hdr);
|
||
if (tx_msg)
|
||
{
|
||
sip_add_tx_msg_line(tx_msg, "Expires", "0");
|
||
sip_add_tx_msg_line(tx_msg, "Event", "%s", event_hdrv->value_string);
|
||
user_tx_free_msg(p_user, tx_msg);
|
||
}
|
||
|
||
g_mobile_position_subscribe.subscriber[0] = '\0';
|
||
g_mobile_position_subscribe.subscribe_event[0] = '\0';
|
||
g_mobile_position_subscribe.subscribe_sn = 0;
|
||
g_mobile_position_subscribe.subscribe_st = 0;
|
||
g_mobile_position_subscribe.subscribe_expires = 0;
|
||
|
||
return TRUE;
|
||
}
|
||
}
|
||
|
||
// 记录订阅信息
|
||
strncpy(subscribe.subscribe_event, event_hdrv->value_string, sizeof(subscribe.subscribe_event));
|
||
strncpy(subscribe.subscriber, fname, sizeof(subscribe.subscriber));
|
||
subscribe.subscribe_sn = req.hdr.SN;
|
||
subscribe.subscribe_st = sys_os_get_uptime();
|
||
subscribe.subscribe_expires = expires;
|
||
|
||
if (sip_get_msg_call_id(rx_msg, subscribe.subscribe_callid, sizeof(subscribe.subscribe_callid)) == FALSE)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
if (sip_get_sip_address(rx_msg, "From", subscribe.subscriber_uri, sizeof(subscribe.subscriber_uri)) == FALSE)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
if (sip_get_sip_address(rx_msg, "To", subscribe.subscriber_dst, sizeof(subscribe.subscriber_dst)) == FALSE)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
sip_get_user_tag(rx_msg, "From", subscribe.subscriber_tag, sizeof(subscribe.subscriber_tag));
|
||
|
||
HSIP_MSG * tx_msg = gb28181_subscribe_res_build(rx_msg, &req.hdr);
|
||
if (tx_msg)
|
||
{
|
||
sip_add_tx_msg_line(tx_msg, "Expires", "%d", subscribe.subscribe_expires);
|
||
sip_add_tx_msg_line(tx_msg, "Event", "%s", event_hdrv->value_string);
|
||
sip_add_tx_msg_line(tx_msg, "Contact", "<sip:%s@%s:%u>", p_user->user_name, p_user->user_ip, p_user->user_port);
|
||
}
|
||
user_tx_free_msg(p_user, tx_msg);
|
||
|
||
// 保存订阅参数
|
||
memcpy(&g_mobile_position_subscribe, &subscribe, sizeof(GB28181_SUBSCRIBE));
|
||
memcpy(&g_mobile_position_req, &req, sizeof(GB28181_MOBILE_POSITION_REQ));
|
||
|
||
return ret;
|
||
}
|
||
|
||
BOOL gb28181_subscribe_handler(HSIP_MSG * rx_msg, XMLN * p_root)
|
||
{
|
||
BOOL ret = FALSE;
|
||
|
||
if (strcasecmp(rx_msg->cmdt, "Alarm") == 0) // 告警订阅
|
||
{
|
||
ret = gb28181_subscribe_alarm_handler(rx_msg, p_root);
|
||
}
|
||
else if (strcasecmp(rx_msg->cmdt, "Catalog") == 0) // 目录订阅
|
||
{
|
||
ret = gb28181_subscribe_catalog_handler(rx_msg, p_root);
|
||
}
|
||
else if (strcasecmp(rx_msg->cmdt, "MobilePosition") == 0) // 移动设备位置订阅
|
||
{
|
||
ret = gb28181_subscribe_mobile_position_handler(rx_msg, p_root);
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
BOOL gb28181_subscribe_rx(HSIP_MSG * rx_msg)
|
||
{
|
||
BOOL ret = FALSE;
|
||
|
||
XMLN * p_root = gb28181_msg_parse(rx_msg);
|
||
if (NULL == p_root)
|
||
{
|
||
log_print(HT_LOG_ERR, "%s, gb28181_msg_parse failed\r\n", __FUNCTION__);
|
||
return FALSE;
|
||
}
|
||
|
||
switch (rx_msg->manscdp)
|
||
{
|
||
case MANSCDP_Query:
|
||
ret = gb28181_subscribe_handler(rx_msg, p_root);
|
||
break;
|
||
}
|
||
|
||
xml_node_del(p_root);
|
||
|
||
return ret;
|
||
}
|
||
|
||
void gb28181_subscribe_timer()
|
||
{
|
||
uint32 cur_time = sys_os_get_uptime();
|
||
|
||
if (g_catalog_subscribe.subscriber[0] != '\0')
|
||
{
|
||
if (cur_time - g_catalog_subscribe.subscribe_st >= g_catalog_subscribe.subscribe_expires)
|
||
{
|
||
// 订阅超时
|
||
g_catalog_subscribe.subscriber[0] = '\0';
|
||
g_catalog_subscribe.subscribe_event[0] = '\0';
|
||
g_catalog_subscribe.subscribe_sn = 0;
|
||
g_catalog_subscribe.subscribe_st = 0;
|
||
g_catalog_subscribe.subscribe_expires = 0;
|
||
}
|
||
}
|
||
|
||
if (g_alarm_subscribe.subscriber[0] != '\0')
|
||
{
|
||
if (cur_time - g_alarm_subscribe.subscribe_st >= g_alarm_subscribe.subscribe_expires)
|
||
{
|
||
// 订阅超时
|
||
g_alarm_subscribe.subscriber[0] = '\0';
|
||
g_alarm_subscribe.subscribe_event[0] = '\0';
|
||
g_alarm_subscribe.subscribe_sn = 0;
|
||
g_alarm_subscribe.subscribe_st = 0;
|
||
g_alarm_subscribe.subscribe_expires = 0;
|
||
}
|
||
}
|
||
|
||
if (g_mobile_position_subscribe.subscriber[0] != '\0')
|
||
{
|
||
uint32 interval = 5;
|
||
|
||
if (g_mobile_position_req.IntervalFlag)
|
||
{
|
||
interval = g_mobile_position_req.Interval;
|
||
}
|
||
|
||
if (cur_time - g_mobile_position_subscribe.subscribe_st >= g_mobile_position_subscribe.subscribe_expires)
|
||
{
|
||
// 订阅超时
|
||
g_mobile_position_subscribe.subscriber[0] = '\0';
|
||
g_mobile_position_subscribe.subscribe_event[0] = '\0';
|
||
g_mobile_position_subscribe.subscribe_sn = 0;
|
||
g_mobile_position_subscribe.subscribe_st = 0;
|
||
g_mobile_position_subscribe.subscribe_expires = 0;
|
||
}
|
||
else if (cur_time - g_mobile_position_subscribe.prev_send_time >= interval)
|
||
{
|
||
// todo : 此处获取真实的GPS位置
|
||
|
||
GB28181_MOBILE_POSITION mobpos;
|
||
memset(&mobpos, 0, sizeof(mobpos));
|
||
|
||
mobpos.Time = time(NULL);
|
||
strcpy(mobpos.TargetID, g_gb28181_cfg.device_id);
|
||
|
||
gb28181_mobile_position_notify(&mobpos);
|
||
|
||
g_mobile_position_subscribe.prev_send_time = sys_os_get_uptime();
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|