280 lines
7.4 KiB
C++
280 lines
7.4 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 "sip_parse.h"
|
|
#include "sip_trans.h"
|
|
|
|
/***************************************************************************************/
|
|
|
|
extern HSIP_CLASS hsip;
|
|
|
|
/***************************************************************************************/
|
|
|
|
STRANSN * sip_trans_get_idle(STRANS * thiz, BOOL b_sig)
|
|
{
|
|
STRANSN * p_trans =(STRANSN *)pps_fl_pop(thiz->trans_fl);
|
|
if (p_trans)
|
|
{
|
|
memset(p_trans, 0, sizeof(STRANSN));
|
|
|
|
// Set the global ID of this call
|
|
sprintf(p_trans->callid, "%u%u@%s", (uint32)rand(), sys_os_get_uptime(), hsip.local_ipstr);
|
|
|
|
if (b_sig == TRUE)
|
|
{
|
|
p_trans->p_wait_sig = sys_os_create_sig();
|
|
}
|
|
|
|
// Set default retransmission parameters
|
|
p_trans->state_retx_count = 0;
|
|
p_trans->state_timer_interval = 1;
|
|
p_trans->state_retx_max_times = 5;
|
|
|
|
pps_ctx_ul_add(thiz->trans_ul, p_trans); // Add to UsedList for easy management
|
|
}
|
|
else
|
|
{
|
|
// pps_ctx_show(thiz->trans_fl);
|
|
}
|
|
|
|
return p_trans;
|
|
}
|
|
|
|
BOOL sip_trans_set_msg(STRANSN * p_trans, void * p_msg)
|
|
{
|
|
if (p_trans == NULL || p_msg == NULL)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
HSIP_MSG * tx_msg = (HSIP_MSG *)p_msg;
|
|
|
|
char cseq[16];
|
|
|
|
if (sip_get_user_name(tx_msg, "From", p_trans->from, sizeof(p_trans->from)) == FALSE)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if (sip_get_user_name(tx_msg, "To", p_trans->to, sizeof(p_trans->to)) == FALSE)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if (sip_get_msg_call_id(tx_msg, p_trans->callid, sizeof(p_trans->callid)) == FALSE)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if (sip_get_msg_cseq(tx_msg, cseq, sizeof(cseq)) == FALSE)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
p_trans->seq = (uint32)atoi(cseq);
|
|
p_trans->tx_msg = tx_msg;
|
|
p_trans->state = 1;
|
|
|
|
log_print(HT_LOG_INFO, "%s, from[%s] to[%s] callid[%s] seq[%u]\r\n",
|
|
__FUNCTION__, p_trans->from, p_trans->to, p_trans->callid, p_trans->seq);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void sip_trans_set_idle(STRANS * thiz, STRANSN * p_trans)
|
|
{
|
|
sip_trans_hash_del(thiz, p_trans);
|
|
|
|
sys_os_destroy_sig_mutex(p_trans->p_wait_sig);
|
|
|
|
memset(p_trans, 0, sizeof(STRANSN));
|
|
|
|
pps_fl_push_tail(thiz->trans_fl, p_trans);
|
|
}
|
|
|
|
void sip_trans_free_used(STRANS * thiz, STRANSN * p_trans)
|
|
{
|
|
pps_ctx_ul_del(thiz->trans_ul, p_trans);
|
|
sip_trans_set_idle(thiz, p_trans);
|
|
}
|
|
|
|
STRANSN * sip_trans_lookup_start(STRANS * thiz)
|
|
{
|
|
return (STRANSN *)pps_lookup_start(thiz->trans_ul);
|
|
}
|
|
|
|
STRANSN * sip_trans_lookup_next(STRANS * thiz, STRANSN * p_trans)
|
|
{
|
|
return (STRANSN *)pps_lookup_next(thiz->trans_ul, p_trans);
|
|
}
|
|
|
|
void sip_trans_lookup_stop(STRANS * thiz)
|
|
{
|
|
pps_lookup_end(thiz->trans_ul);
|
|
}
|
|
|
|
/*******************************************************\
|
|
Get the index value of the corresponding PTRANS transaction entry
|
|
\*******************************************************/
|
|
uint32 sip_trans_get_index(STRANS * thiz, STRANSN * p_trans)
|
|
{
|
|
return pps_get_index(thiz->trans_fl, p_trans);
|
|
}
|
|
|
|
STRANSN * sip_trans_get_by_index(STRANS * thiz, uint32 index)
|
|
{
|
|
return (STRANSN *)pps_get_node_by_index(thiz->trans_fl, index);
|
|
}
|
|
|
|
/*******************************************************\
|
|
PTRANS transaction table entry HASH operation
|
|
\*******************************************************/
|
|
void sip_trans_hash_add(STRANS * thiz, STRANSN * p_trans)
|
|
{
|
|
snprintf(p_trans->hash_key, sizeof(p_trans->hash_key)-1, "%s%s%s%u", p_trans->callid, p_trans->from, p_trans->to, p_trans->seq);
|
|
ihash_add(thiz->trans_hash, p_trans->hash_key, sip_trans_get_index(thiz, p_trans), 0);
|
|
}
|
|
|
|
void sip_trans_hash_del(STRANS * thiz, STRANSN * p_trans)
|
|
{
|
|
ihash_del(thiz->trans_hash, p_trans->hash_key, sip_trans_get_index(thiz, p_trans));
|
|
}
|
|
|
|
STRANSN * sip_trans_hash_find(STRANS * thiz, const char * hash_key)
|
|
{
|
|
uint32 trans_index = (uint32) ihash_find_index_from_keystr(thiz->trans_hash, hash_key);
|
|
if (trans_index == 0xFFFFFFFF || trans_index >= thiz->trans_num)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
return sip_trans_get_by_index(thiz, trans_index);
|
|
}
|
|
|
|
/*******************************************************\
|
|
Transaction timer, check retransmission requirements
|
|
\*******************************************************/
|
|
void sip_trans_timer(STRANS * thiz, uint32 cur_t)
|
|
{
|
|
uint32 i;
|
|
STRANSN * p_trans;
|
|
|
|
for (i = 0; i < thiz->trans_num; i++)
|
|
{
|
|
p_trans = sip_trans_get_by_index(thiz, i);
|
|
if (p_trans == NULL || p_trans->last_tx_time == 0 || p_trans->state != 1)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if ((cur_t - p_trans->last_tx_time) > p_trans->state_timer_interval)
|
|
{
|
|
if (p_trans->state_retx_count > p_trans->state_retx_max_times)
|
|
{
|
|
p_trans->state = 4;
|
|
|
|
if (p_trans->p_wait_sig)
|
|
{
|
|
sys_os_sig_sign(p_trans->p_wait_sig); // Notify the caller, the caller checks the state unit to determine whether it is successful or not
|
|
}
|
|
|
|
continue;
|
|
}
|
|
|
|
// sip_user_send_msg(&g_user, p_trans->tx_msg);
|
|
|
|
p_trans->last_tx_time = sys_os_get_uptime();
|
|
p_trans->state_retx_count++;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*******************************************************\
|
|
Response packet receiving processing
|
|
\*******************************************************/
|
|
STRANSN * sip_trans_rly_find(STRANS * thiz, const char * callid, const char * from, const char * to, uint32 seq)
|
|
{
|
|
char hash_key[128];
|
|
snprintf(hash_key, sizeof(hash_key)-1, "%s%s%s%u", callid, from, to, seq);
|
|
|
|
STRANSN * p_trans = sip_trans_hash_find(thiz, hash_key);
|
|
if (p_trans == NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
if ((strcasecmp(p_trans->from, from) != 0) || (strcasecmp(p_trans->to, to) != 0) || p_trans->seq != seq)
|
|
{
|
|
log_print(HT_LOG_ERR, "%s, hash err!!!\r\n", __FUNCTION__);
|
|
return NULL;
|
|
}
|
|
|
|
p_trans->state = 2;
|
|
|
|
return p_trans;
|
|
}
|
|
|
|
/*******************************************************\
|
|
Transaction request response waiting
|
|
\*******************************************************/
|
|
int sip_trans_wait(STRANSN * p_trans, int ms)
|
|
{
|
|
return sys_os_sig_wait_timeout(p_trans->p_wait_sig, ms);
|
|
}
|
|
|
|
/*******************************************************\
|
|
Transaction initialization function
|
|
\*******************************************************/
|
|
void sip_trans_init(STRANS * thiz, int num)
|
|
{
|
|
memset(thiz, 0, sizeof(STRANS));
|
|
|
|
thiz->trans_num = num;
|
|
thiz->trans_fl = pps_ctx_fl_init(num, sizeof(STRANSN), TRUE);
|
|
thiz->trans_ul = pps_ctx_ul_init(thiz->trans_fl, TRUE);
|
|
|
|
thiz->trans_hash = ihash_init(num, num);
|
|
}
|
|
|
|
void sip_trans_uninit(STRANS * thiz)
|
|
{
|
|
if (thiz->trans_hash)
|
|
{
|
|
ihash_uninit(thiz->trans_hash);
|
|
thiz->trans_hash = NULL;
|
|
}
|
|
|
|
if (thiz->trans_ul)
|
|
{
|
|
pps_ul_free(thiz->trans_ul);
|
|
thiz->trans_ul = NULL;
|
|
}
|
|
|
|
if (thiz->trans_fl)
|
|
{
|
|
pps_fl_free(thiz->trans_fl);
|
|
thiz->trans_fl = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
|