/*************************************************************************************** * * 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", "", 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, "\r\n" "\r\n" "%s\r\n" "%u\r\n" "%s\r\n" "OK\r\n" "\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", "", 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", "", 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", "", 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(); } } }