/*************************************************************************************** * * 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 "hqueue.h" #include "linked_list.h" #include "rfc_md5.h" #include "word_analyse.h" #include "digcalc.h" #include "ppstack.h" #include "hsip.h" #include "sua.h" #include "sip_parse.h" #include "sip_tx.h" #include "sip_reg.h" #include "sip_timer.h" #include "sip_pstate.h" #include "gb28181_msg.h" #include "gb28181_cfg.h" #include "gb28181_subscribe.h" /*************************************************************************************** 全局数据 ***************************************************************************************/ extern HSIP_CLASS hsip; extern HSIP_USER g_user; uint32 sua_reg_interval = 30; uint32 sua_reg_cnt = 0; /*************************************************************************************** Timer消息处理 ***************************************************************************************/ void sip_timer() { uint32 i; uint32 cur_time = sys_os_get_uptime(); SUA * p_sua = NULL; HSIP_USER * p_user = &g_user; // SIP呼叫表项处理 for (i = 0; i < MAX_NUM_SUA; i++) { p_sua = (SUA *)sua_get_by_index(i); if (p_sua == NULL) { continue; } // SUA呼叫表项处理 if (p_sua->uaf_state_timer == 1 && p_sua->call_state != SUA_CS_IDLE) { if (p_sua->state_retx_count < p_sua->state_retx_max_times) { if (p_sua->state_timer_interval <= (cur_time - p_sua->last_tx_time)) { sip_resend_sua_msg(p_sua); // 消息重传处理 } } else { // 重传次数超过最大值,进入失败状态 sua_call_state(p_sua, CSE_TIMEOUT, NULL); } } // 此处仅测试用,实际开发中应已读取录像来判断 else if ((p_sua->uaf_playback || p_sua->uaf_download) && p_sua->play_st > 0 && p_sua->st > 0 && p_sua->et > 0) { if ((cur_time - p_sua->play_st) > (p_sua->et - p_sua->st)) { // 录像回放结束 GB28181_MEDIA_NOTIFY req; strcpy(req.DeviceID, p_sua->req_name); strcpy(req.NotifyType, "121"); gb28181_media_status_tx(p_user, &req); } } } // 外部SIP注册表项处理 if (sua_reg_cnt++ >= sua_reg_interval) { if (p_user->user_state != HSIP_AUTH_200) { if (p_user->usrf_tcp_sip == 0) { HSIP_MSG * tx_msg = sip_build_register_normal_msg(p_user, inet_addr(p_user->server_ipstr), htons(p_user->server_port)); if (tx_msg) { user_tx_free_msg(p_user, tx_msg); } } } else { if ((cur_time - p_user->last_reg_time) >= (p_user->expires_time >> 1)) { HSIP_MSG * tx_msg = sip_build_register_normal_msg(p_user, inet_addr(p_user->server_ipstr), htons(p_user->server_port)); if (tx_msg) { user_tx_free_msg(p_user, tx_msg); } } } sua_reg_cnt = 0; } if (p_user->usrf_auth == 1) { if (cur_time - p_user->last_hb_time >= g_gb28181_cfg.heartbeat_interval) { gb28181_heartbeat_tx(p_user); p_user->last_hb_time = sys_os_get_uptime(); } } gb28181_subscribe_timer(); sip_trans_timer(&(hsip.sip_trans), cur_time); } /*************************************************************************************** 系统定时器初始化 ***************************************************************************************/ #if __WINDOWS_OS__ #ifdef _WIN64 void CALLBACK sip_win_timer(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2) #else void CALLBACK sip_win_timer(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2) #endif { if (hsip.sys_init_flag == 2) { SIPTM stm; memset(&stm, 0, sizeof(SIPTM)); stm.msg_src = SIP_TIMER_SRC; hqBufPut(hsip.msg_queue, (char *)&stm); } } void sip_timer_init() { hsip.timer_id = timeSetEvent(1000, 0, sip_win_timer, 0, TIME_PERIODIC); } void sip_timer_deinit() { timeKillEvent(hsip.timer_id); } #else void * sip_timer_task(void * argv) { struct timeval tv; while (hsip.sys_timer_run == 1) { tv.tv_sec = 1; tv.tv_usec = 0; select(1, NULL, NULL, NULL, &tv); if (hsip.sys_init_flag > 1) { SIPTM stm; memset(&stm, 0, sizeof(SIPTM)); stm.msg_src = SIP_TIMER_SRC; hqBufPut(hsip.msg_queue, (char *)&stm); } } hsip.timer_id = 0; log_print(HT_LOG_DBG, "sip timer task exit\r\n"); return NULL; } void sip_timer_init() { hsip.sys_timer_run = 1; pthread_t thrd = sys_os_create_thread((void *)sip_timer_task, NULL); if (thrd == 0) { log_print(HT_LOG_ERR, "%s, sip_timer_task failed\r\n", __FUNCTION__); return;; } hsip.timer_id = thrd; log_print(HT_LOG_DBG, "%s, create sip timer thread sucessful\r\n", __FUNCTION__); } void sip_timer_deinit() { hsip.sys_timer_run = 0; while (hsip.timer_id != 0) { usleep(10*1000); } } #endif