mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-02-05 02:34:18 +00:00
1386 lines
33 KiB
C
Executable File
1386 lines
33 KiB
C
Executable File
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "cpr_types.h"
|
|
#include "cpr_stdlib.h"
|
|
#include "cpr_stdio.h"
|
|
#include "fsm.h"
|
|
#include "fim.h"
|
|
#include "lsm.h"
|
|
#include "sm.h"
|
|
#include "gsm.h" /* for GSM_ERR_MSG */
|
|
#include "ccapi.h"
|
|
#include "phone_debug.h"
|
|
#include "debug.h"
|
|
#include "text_strings.h"
|
|
#include "sip_interface_regmgr.h"
|
|
#include "resource_manager.h"
|
|
#include "platform_api.h"
|
|
|
|
#define FSM_MAX_FCBS (LSM_MAX_CALLS * (FSM_TYPE_MAX - 1))
|
|
#define FSM_S_IDLE 0
|
|
|
|
extern sm_table_t *pfsmcnf_sm_table;
|
|
extern sm_table_t *pfsmb2bcnf_sm_table;
|
|
extern sm_table_t *pfsmxfr_sm_table;
|
|
extern sm_table_t *pfsmdef_sm_table;
|
|
|
|
static fsm_fcb_t *fsm_fcbs;
|
|
static fsmdef_dcb_t fsm_dcb;
|
|
extern uint16_t g_numofselected_calls;
|
|
extern void dcsm_update_gsm_state(fsm_fcb_t *fcb, callid_t call_id, int state);
|
|
|
|
|
|
static const char *fsm_type_names[] = {
|
|
"HEAD",
|
|
"CNF",
|
|
"B2BCNF",
|
|
"XFR",
|
|
"DEF"
|
|
};
|
|
|
|
static resource_manager_t *ci_map_p[MAX_REG_LINES + 1];
|
|
static resource_manager_t *shown_calls_ci_map_p[MAX_REG_LINES + 1];
|
|
|
|
const char *
|
|
fsm_type_name (fsm_types_t type)
|
|
{
|
|
if ((type <= FSM_TYPE_MIN) || (type >= FSM_TYPE_MAX)) {
|
|
return (get_debug_string(GSM_UNDEFINED));
|
|
}
|
|
|
|
return (fsm_type_names[type]);
|
|
}
|
|
|
|
|
|
const char *
|
|
fsm_state_name (fsm_types_t type, int id)
|
|
{
|
|
switch (type) {
|
|
case FSM_TYPE_DEF:
|
|
return (fsmdef_state_name(id));
|
|
|
|
case FSM_TYPE_XFR:
|
|
return (fsmxfr_state_name(id));
|
|
|
|
case FSM_TYPE_CNF:
|
|
return (fsmcnf_state_name(id));
|
|
|
|
case FSM_TYPE_B2BCNF:
|
|
return (fsmb2bcnf_state_name(id));
|
|
|
|
case FSM_TYPE_NONE:
|
|
return ("IDLE");
|
|
|
|
default:
|
|
return (get_debug_string(GSM_UNDEFINED));
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
fsm_sm_ftr (cc_features_t ftr_id, cc_srcs_t src_id)
|
|
{
|
|
FSM_DEBUG_SM(get_debug_string(FSM_DBG_SM_FTR_ENTRY),
|
|
cc_feature_name(ftr_id), cc_src_name(src_id));
|
|
}
|
|
|
|
|
|
void
|
|
fsm_sm_ignore_ftr (fsm_fcb_t *fcb, int fname, cc_features_t ftr_id)
|
|
{
|
|
FSM_DEBUG_SM(get_debug_string(FSM_DBG_IGNORE_FTR),
|
|
fsm_type_name(fcb->fsm_type), fcb->call_id, fname,
|
|
cc_feature_name(ftr_id));
|
|
}
|
|
|
|
|
|
void
|
|
fsm_sm_ignore_src (fsm_fcb_t *fcb, int fname, cc_srcs_t src_id)
|
|
{
|
|
FSM_DEBUG_SM(get_debug_string(FSM_DBG_IGNORE_SRC),
|
|
fsm_type_name(fcb->fsm_type), fcb->call_id, fname,
|
|
cc_src_name(src_id));
|
|
}
|
|
|
|
|
|
void
|
|
fsm_init_fcb (fsm_fcb_t *fcb, callid_t call_id, fsmdef_dcb_t *dcb,
|
|
fsm_types_t type)
|
|
{
|
|
fcb->call_id = call_id;
|
|
|
|
fcb->state = FSM_S_IDLE;
|
|
fcb->old_state = FSM_S_IDLE;
|
|
|
|
fcb->fsm_type = type;
|
|
|
|
fcb->dcb = dcb;
|
|
|
|
fcb->xcb = NULL;
|
|
|
|
fcb->ccb = NULL;
|
|
|
|
fcb->b2bccb = NULL;
|
|
}
|
|
|
|
|
|
/*
|
|
* ROUTINE: fsm_get_fcb_by_call_id_and_type
|
|
*
|
|
* DESCRIPTION: return the fcb referenced by the given call_id and type
|
|
*
|
|
* PARAMETERS: fsm_id
|
|
*
|
|
* RETURNS: fcb
|
|
* !NULL: fcb found
|
|
* NULL: fcb not found
|
|
*
|
|
* NOTES:
|
|
*/
|
|
fsm_fcb_t *
|
|
fsm_get_fcb_by_call_id_and_type (callid_t call_id, fsm_types_t type)
|
|
{
|
|
static const char fname[] = "fsm_get_fcb_by_call_id_and_type";
|
|
fsm_fcb_t *fcb;
|
|
fsm_fcb_t *fcb_found = NULL;
|
|
|
|
FSM_FOR_ALL_CBS(fcb, fsm_fcbs, FSM_MAX_FCBS) {
|
|
if ((fcb->call_id == call_id) && (fcb->fsm_type == type)) {
|
|
fcb_found = fcb;
|
|
break;
|
|
}
|
|
}
|
|
|
|
FSM_DEBUG_SM(get_debug_string(GSM_DBG_PTR), "FSM", call_id,
|
|
fname, "fcb", fcb_found);
|
|
|
|
return (fcb_found);
|
|
}
|
|
|
|
/*
|
|
* DESCRIPTION: return the fcb referenced by the given call_id and type
|
|
*
|
|
* PARAMETERS: fsm_id
|
|
*
|
|
* @return void
|
|
* !NULL: fcb found
|
|
* NULL: fcb not found
|
|
*
|
|
*/
|
|
void
|
|
fsm_get_fcb_by_selected_or_connected_call_fcb (callid_t call_id, fsm_fcb_t **con_fcb_found,
|
|
fsm_fcb_t **sel_fcb_found)
|
|
{
|
|
static const char fname[] = "fsm_get_fcb_by_selected_or_connected_call_fcb";
|
|
fsm_fcb_t *fcb;
|
|
|
|
*con_fcb_found = NULL;
|
|
*sel_fcb_found = NULL;
|
|
|
|
FSM_FOR_ALL_CBS(fcb, fsm_fcbs, FSM_MAX_FCBS) {
|
|
|
|
if (fcb->call_id == call_id) {
|
|
/* Do not count current call_id */
|
|
continue;
|
|
}
|
|
if (fcb->fsm_type == FSM_TYPE_DEF &&
|
|
(fcb->state == FSMDEF_S_CONNECTED ||
|
|
fcb->state == FSMDEF_S_CONNECTED_MEDIA_PEND ||
|
|
fcb->state == FSMDEF_S_OUTGOING_ALERTING)) {
|
|
*con_fcb_found = fcb;
|
|
} else if (fcb->fsm_type == FSM_TYPE_DEF && fcb->dcb->selected) {
|
|
*sel_fcb_found = fcb;
|
|
break;
|
|
}
|
|
}
|
|
|
|
FSM_DEBUG_SM(get_debug_string(GSM_DBG_PTR), "FSM", call_id,
|
|
fname, "fcb", con_fcb_found);
|
|
|
|
}
|
|
|
|
/*
|
|
* ROUTINE: fsm_get_fcb_by_call_id
|
|
*
|
|
* DESCRIPTION: return the fcb referenced by the given call_id
|
|
*
|
|
* PARAMETERS: fsm_id
|
|
*
|
|
* RETURNS: fcb
|
|
* !NULL: fcb found
|
|
* NULL: fcb not found
|
|
*
|
|
* NOTES:
|
|
*/
|
|
fsm_fcb_t *
|
|
fsm_get_fcb_by_call_id (callid_t call_id)
|
|
{
|
|
static const char fname[] = "fsm_get_fcb_by_call_id";
|
|
fsm_fcb_t *fcb;
|
|
fsm_fcb_t *fcb_found = NULL;
|
|
|
|
FSM_FOR_ALL_CBS(fcb, fsm_fcbs, FSM_MAX_FCBS) {
|
|
if (fcb->call_id == call_id) {
|
|
fcb_found = fcb;
|
|
break;
|
|
}
|
|
}
|
|
|
|
FSM_DEBUG_SM(get_debug_string(GSM_DBG_PTR), "FSM", call_id,
|
|
fname, "fcb", fcb_found);
|
|
|
|
return (fcb_found);
|
|
}
|
|
|
|
|
|
/*
|
|
* ROUTINE: fsm_get_new_fcb
|
|
*
|
|
* DESCRIPTION: return a new fcb initialized with the given data
|
|
*
|
|
* PARAMETERS:
|
|
* call_id: call_id
|
|
* type: feature type
|
|
*
|
|
* RETURNS:
|
|
* fcb: the new fcb
|
|
*/
|
|
fsm_fcb_t *
|
|
fsm_get_new_fcb (callid_t call_id, fsm_types_t fsm_type)
|
|
{
|
|
static const char fname[] = "fsm_get_new_fcb";
|
|
fsm_fcb_t *fcb;
|
|
|
|
/*
|
|
* Get free fcb by using CC_NO_CALL_ID as the call_id because a free fcb
|
|
* will have a call_id of CC_NO_CALL_ID.
|
|
*/
|
|
fcb = fsm_get_fcb_by_call_id(CC_NO_CALL_ID);
|
|
if (fcb != NULL) {
|
|
fsm_init_fcb(fcb, call_id, FSMDEF_NO_DCB, fsm_type);
|
|
}
|
|
|
|
FSM_DEBUG_SM(get_debug_string(GSM_DBG_PTR), "FSM", call_id,
|
|
fname, "fcb", fcb);
|
|
|
|
return (fcb);
|
|
}
|
|
|
|
|
|
fsmdef_dcb_t *
|
|
fsm_get_dcb (callid_t call_id)
|
|
{
|
|
fsmdef_dcb_t *dcb;
|
|
|
|
dcb = fsmdef_get_dcb_by_call_id(call_id);
|
|
|
|
/*
|
|
* Return the fsm default dcb if a dcb was not found.
|
|
*/
|
|
if (dcb == NULL) {
|
|
dcb = &fsm_dcb;
|
|
}
|
|
|
|
return (dcb);
|
|
}
|
|
|
|
|
|
void
|
|
fsm_get_fcb (fim_icb_t *icb, callid_t call_id)
|
|
{
|
|
icb->cb = fsm_get_new_fcb(call_id, icb->scb->type);
|
|
}
|
|
|
|
|
|
void
|
|
fsm_init_scb (fim_icb_t *icb, callid_t call_id)
|
|
{
|
|
icb->scb->get_cb = &fsm_get_fcb;
|
|
|
|
switch (icb->scb->type) {
|
|
|
|
case FSM_TYPE_B2BCNF:
|
|
icb->scb->sm = pfsmb2bcnf_sm_table;
|
|
icb->scb->free_cb = fsmb2bcnf_free_cb;
|
|
|
|
break;
|
|
|
|
case FSM_TYPE_CNF:
|
|
icb->scb->sm = pfsmcnf_sm_table;
|
|
icb->scb->free_cb = fsmcnf_free_cb;
|
|
|
|
break;
|
|
case FSM_TYPE_XFR:
|
|
icb->scb->sm = pfsmxfr_sm_table;
|
|
icb->scb->free_cb = fsmxfr_free_cb;
|
|
|
|
break;
|
|
|
|
case FSM_TYPE_DEF:
|
|
icb->scb->sm = pfsmdef_sm_table;
|
|
icb->scb->free_cb = fsmdef_free_cb;
|
|
|
|
break;
|
|
|
|
case FSM_TYPE_HEAD:
|
|
default:
|
|
icb->scb->get_cb = NULL;
|
|
icb->scb->free_cb = NULL;
|
|
icb->scb->sm = NULL;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void
|
|
fsm_change_state (fsm_fcb_t *fcb, int fname, int new_state)
|
|
{
|
|
|
|
DEF_DEBUG(DEB_L_C_F_PREFIX"%s: %s -> %s\n",
|
|
DEB_L_C_F_PREFIX_ARGS(FSM, ((fcb->dcb == NULL)? CC_NO_LINE: fcb->dcb->line),
|
|
fcb->call_id, "fsm_change_state"),
|
|
fsm_type_name(fcb->fsm_type),
|
|
fsm_state_name(fcb->fsm_type, fcb->state),
|
|
fsm_state_name(fcb->fsm_type, new_state));
|
|
|
|
fcb->old_state = fcb->state;
|
|
fcb->state = new_state;
|
|
NOTIFY_STATE_CHANGE(fcb, fcb->call_id, new_state);
|
|
|
|
}
|
|
|
|
|
|
void
|
|
fsm_release (fsm_fcb_t *fcb, int fname, cc_causes_t cause)
|
|
{
|
|
fsm_change_state(fcb, fname, FSM_S_IDLE);
|
|
|
|
/* Cleanup any pending cac request for that call */
|
|
fsm_cac_call_release_cleanup(fcb->call_id);
|
|
|
|
fsm_init_fcb(fcb, CC_NO_CALL_ID, FSMDEF_NO_DCB, FSM_TYPE_NONE);
|
|
}
|
|
|
|
|
|
cc_int32_t
|
|
fsm_show_cmd (cc_int32_t argc, const char *argv[])
|
|
{
|
|
fsm_fcb_t *fcb;
|
|
int i = 0;
|
|
void *cb = NULL;
|
|
|
|
PR_ASSERT(i == 0);
|
|
|
|
/*
|
|
* check if need help
|
|
*/
|
|
if ((argc == 2) && (argv[1][0] == '?')) {
|
|
debugif_printf("%s", "show fsm\n");
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Print the fcbs
|
|
*/
|
|
debugif_printf("%s", "\n----------------------------- FSM fcbs -------------------------------");
|
|
debugif_printf("%s", "\ni call_id fcb type state dcb cb ");
|
|
debugif_printf("%s", "\n----------------------------------------------------------------------\n");
|
|
|
|
FSM_FOR_ALL_CBS(fcb, fsm_fcbs, FSM_MAX_FCBS) {
|
|
switch (fcb->fsm_type) {
|
|
case FSM_TYPE_CNF:
|
|
cb = fcb->ccb;
|
|
break;
|
|
|
|
case FSM_TYPE_B2BCNF:
|
|
cb = fcb->ccb;
|
|
break;
|
|
|
|
case FSM_TYPE_XFR:
|
|
cb = fcb->xcb;
|
|
break;
|
|
|
|
case FSM_TYPE_DEF:
|
|
cb = fcb->dcb;
|
|
break;
|
|
|
|
default:
|
|
cb = NULL;
|
|
}
|
|
|
|
debugif_printf("%-3d %-7d 0x%8p %-9s %-9s 0x%8p 0x%8p\n",
|
|
i++, fcb->call_id, fcb, fsm_type_name(fcb->fsm_type),
|
|
fsm_state_name(fcb->fsm_type, fcb->state),
|
|
fcb->dcb, cb);
|
|
}
|
|
|
|
return (0);
|
|
}
|
|
|
|
|
|
void
|
|
fsm_init (void)
|
|
{
|
|
fsm_fcb_t *fcb;
|
|
|
|
fsmdef_init_dcb(&fsm_dcb, 0, FSMDEF_CALL_TYPE_NONE, NULL, LSM_NO_LINE,
|
|
NULL);
|
|
|
|
fsmdef_init();
|
|
fsmb2bcnf_init();
|
|
fsmcnf_init();
|
|
fsmxfr_init();
|
|
|
|
fsm_cac_init();
|
|
|
|
/*
|
|
* Initialize the fcbs.
|
|
*/
|
|
fsm_fcbs = (fsm_fcb_t *) cpr_calloc(FSM_MAX_FCBS, sizeof(fsm_fcb_t));
|
|
if (fsm_fcbs == NULL) {
|
|
GSM_ERR_MSG(GSM_F_PREFIX"Failed to allcoate FSM FCBs.\n", "fsm_init");
|
|
return;
|
|
}
|
|
|
|
FSM_FOR_ALL_CBS(fcb, fsm_fcbs, FSM_MAX_FCBS) {
|
|
fsm_init_fcb(fcb, CC_NO_CALL_ID, FSMDEF_NO_DCB, FSM_TYPE_NONE);
|
|
}
|
|
|
|
/*
|
|
* Init call instance id map.
|
|
*/
|
|
fsmutil_init_ci_map();
|
|
}
|
|
|
|
void
|
|
fsm_shutdown (void)
|
|
{
|
|
fsmdef_shutdown();
|
|
|
|
fsmb2bcnf_shutdown();
|
|
|
|
fsmcnf_shutdown();
|
|
fsmxfr_shutdown();
|
|
|
|
fsm_cac_shutdown();
|
|
|
|
cpr_free(fsm_fcbs);
|
|
fsm_fcbs = NULL;
|
|
|
|
/*
|
|
* Free call instance id map.
|
|
*/
|
|
fsmutil_free_ci_map();
|
|
}
|
|
|
|
/*
|
|
* ROUTINE: fsm_set_fcb_dcbs
|
|
*
|
|
* DESCRIPTION: Set the dcbs for the fsms. The fsm call chain is setup before
|
|
* the dcb is known, so this function is called after the dcb
|
|
* is known to set the dcb in the fcbs.
|
|
*
|
|
* PARAMETERS:
|
|
* dcb
|
|
*
|
|
* RETURNS: NONE
|
|
*
|
|
* NOTES:
|
|
*/
|
|
cc_causes_t
|
|
fsm_set_fcb_dcbs (fsmdef_dcb_t *dcb)
|
|
{
|
|
callid_t call_id = dcb->call_id;
|
|
fsm_fcb_t *fcb;
|
|
fsm_types_t i;
|
|
|
|
for (i = FSM_TYPE_CNF; i < FSM_TYPE_MAX; i++) {
|
|
fcb = fsm_get_fcb_by_call_id_and_type(call_id, i);
|
|
if (fcb == NULL) {
|
|
return CC_CAUSE_ERROR;
|
|
}
|
|
fcb->dcb = dcb;
|
|
}
|
|
|
|
return CC_CAUSE_OK;
|
|
}
|
|
|
|
|
|
/*
|
|
* ROUTINE: fsm_get_new_outgoing_call_context
|
|
*
|
|
* DESCRIPTION: get a new outgoing call context
|
|
*
|
|
* PARAMETERS:
|
|
* fcb
|
|
* call_id
|
|
* line
|
|
*
|
|
* RETURNS: rc
|
|
* FSM_SUCCESS: context successfully created
|
|
* FSM_SUCCESS: context unsuccessfully created
|
|
*
|
|
* NOTES:
|
|
*/
|
|
cc_causes_t
|
|
fsm_get_new_outgoing_call_context (callid_t call_id, line_t line,
|
|
fsm_fcb_t *fcb, boolean expline)
|
|
{
|
|
static const char fname[] = "fsm_get_new_outgoing_call_context";
|
|
fsmdef_dcb_t *dcb;
|
|
cc_causes_t cause = CC_CAUSE_OK;
|
|
cc_causes_t lsm_rc;
|
|
|
|
/*
|
|
* Get a dcb to handle the call.
|
|
*/
|
|
dcb = fsmdef_get_new_dcb(call_id);
|
|
if (dcb == NULL) {
|
|
return CC_CAUSE_NO_RESOURCE;
|
|
}
|
|
|
|
/*
|
|
* Get a free facility associated with this line.
|
|
*/
|
|
lsm_rc = lsm_get_facility_by_line(call_id, line, expline, dcb);
|
|
if (lsm_rc != CC_CAUSE_OK) {
|
|
FSM_DEBUG_SM(get_debug_string(FSM_DBG_FAC_ERR), call_id, fname,
|
|
"lsm_get_facility_by_line failed", cc_cause_name(lsm_rc));
|
|
}
|
|
|
|
/*
|
|
* If no line was returned, then init the dcb with an invalid line to
|
|
* indicate that no line was returned.
|
|
*/
|
|
if (lsm_rc != CC_CAUSE_OK) {
|
|
line = LSM_NO_LINE;
|
|
}
|
|
fsmdef_init_dcb(dcb, call_id, FSMDEF_CALL_TYPE_OUTGOING, NULL, line, fcb);
|
|
|
|
cause = fsm_set_fcb_dcbs(dcb);
|
|
if (cause == CC_CAUSE_OK) {
|
|
cause = lsm_rc;
|
|
}
|
|
|
|
FSM_DEBUG_SM(get_debug_string(FSM_DBG_FAC_FOUND), call_id, fname,
|
|
dcb->line);
|
|
|
|
return cause;
|
|
}
|
|
|
|
|
|
/*
|
|
* ROUTINE: fsm_get_new_incoming_call_context
|
|
*
|
|
* DESCRIPTION: get a new incoming call context
|
|
*
|
|
* PARAMETERS:
|
|
* fcb
|
|
* call_id
|
|
*
|
|
* RETURNS: rc
|
|
* FSM_SUCCESS: context successfully created
|
|
* FSM_SUCCESS: context unsuccessfully created
|
|
*
|
|
* NOTES:
|
|
*/
|
|
cc_causes_t
|
|
fsm_get_new_incoming_call_context (callid_t call_id, fsm_fcb_t *fcb,
|
|
const char *called_number, boolean expline)
|
|
{
|
|
static const char fname[] = "fsm_get_new_incoming_call_context";
|
|
fsmdef_dcb_t *dcb;
|
|
line_t free_line;
|
|
cc_causes_t cause;
|
|
cc_causes_t lsm_rc;
|
|
|
|
|
|
/*
|
|
* Get a dcb to handle the call.
|
|
*/
|
|
dcb = fsmdef_get_new_dcb(call_id);
|
|
if (dcb == NULL) {
|
|
return CC_CAUSE_NO_RESOURCE;
|
|
}
|
|
|
|
/*
|
|
* Get a free facility associated with this called_number.
|
|
*/
|
|
if ((lsm_rc = lsm_get_facility_by_called_number(call_id, called_number,
|
|
&free_line, expline, dcb))
|
|
!= CC_CAUSE_OK) {
|
|
/*
|
|
* Set a default free line (This should really be changed
|
|
* to a special invalid value and GSM modified to recognize it.)
|
|
* The dcb is needed in order for GSM to clean up the call correctly.
|
|
*/
|
|
free_line = 1;
|
|
FSM_DEBUG_SM(get_debug_string(FSM_DBG_FAC_ERR), call_id, fname,
|
|
"lsm_get_facility_by_called_number",
|
|
cc_cause_name(lsm_rc));
|
|
}
|
|
|
|
fsmdef_init_dcb(dcb, call_id, FSMDEF_CALL_TYPE_INCOMING, called_number,
|
|
free_line, fcb);
|
|
|
|
cause = fsm_set_fcb_dcbs(dcb);
|
|
if (cause == CC_CAUSE_OK) {
|
|
cause = lsm_rc;
|
|
}
|
|
|
|
FSM_DEBUG_SM(get_debug_string(FSM_DBG_FAC_FOUND), call_id, fname,
|
|
dcb->line);
|
|
|
|
return cause;
|
|
}
|
|
|
|
/*
|
|
* fsmutil_is_cnf_leg
|
|
*
|
|
* Description:
|
|
*
|
|
* Returns TRUE if conferencing is active for the call_id
|
|
*
|
|
*
|
|
* Parameters:
|
|
*
|
|
* call_id - ccapi call identifier associated with the call.
|
|
* fsmxcb_ccbs - pointer to all conf ccbs
|
|
* max_ccbs - Max number of ccbs to check
|
|
*
|
|
* Returns TRUE if the conferencing is active for the call_id
|
|
*/
|
|
int
|
|
fsmutil_is_cnf_leg (callid_t call_id, fsmcnf_ccb_t *fsmcnf_ccbs,
|
|
unsigned short max_ccbs)
|
|
{
|
|
fsmcnf_ccb_t *ccb;
|
|
|
|
FSM_FOR_ALL_CBS(ccb, fsmcnf_ccbs, max_ccbs) {
|
|
if ((ccb->cnf_call_id == call_id) || (ccb->cns_call_id == call_id)) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/*
|
|
* fsmutil_is_xfr_leg
|
|
*
|
|
* Description:
|
|
*
|
|
* Returns transfer mode if the specified leg identified by call_id is
|
|
* participating in a xfer
|
|
*
|
|
* Parameters:
|
|
*
|
|
* call_id - ccapi call identifier associated with the call.
|
|
* fsmxfr_xcbs - pointer to all xfr ccbs
|
|
* max_xcbs - Max number of ccbs to check
|
|
*
|
|
* Returns: fsmxfr_modes_t
|
|
*/
|
|
int
|
|
fsmutil_is_xfr_leg (callid_t call_id, fsmxfr_xcb_t *fsmxfr_xcbs,
|
|
unsigned short max_xcbs)
|
|
{
|
|
fsmxfr_xcb_t *xcb;
|
|
|
|
FSM_FOR_ALL_CBS(xcb, fsmxfr_xcbs, max_xcbs) {
|
|
if ((xcb->xfr_call_id == call_id) || (xcb->cns_call_id == call_id)) {
|
|
return xcb->mode;
|
|
}
|
|
}
|
|
return FSMXFR_MODE_MIN;
|
|
}
|
|
|
|
void
|
|
fsm_display_no_free_lines (void)
|
|
{
|
|
char tmp_str[STATUS_LINE_MAX_LEN];
|
|
|
|
if ((platGetPhraseText(STR_INDEX_NO_FREE_LINES,
|
|
(char *)tmp_str,
|
|
(STATUS_LINE_MAX_LEN - 1))) == CPR_SUCCESS) {
|
|
lsm_ui_display_notify(tmp_str, NO_FREE_LINES_TIMEOUT);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Function: fsm_display_use_line_or_join_to_complete
|
|
*
|
|
* Description:
|
|
* The function is used to put up the status line
|
|
* "Use Line or Join to Complete"
|
|
*
|
|
* @param None
|
|
*
|
|
* @return None
|
|
*/
|
|
void
|
|
fsm_display_use_line_or_join_to_complete (void)
|
|
{
|
|
char tmp_str[STATUS_LINE_MAX_LEN];
|
|
|
|
if ((platGetPhraseText(STR_INDEX_USE_LINE_OR_JOIN_TO_COMPLETE,
|
|
(char *)tmp_str,
|
|
(STATUS_LINE_MAX_LEN - 1))) == CPR_SUCCESS) {
|
|
lsm_ui_display_notify(tmp_str, NO_FREE_LINES_TIMEOUT);
|
|
}
|
|
}
|
|
|
|
void
|
|
fsm_display_feature_unavailable (void)
|
|
{
|
|
char tmp_str[STATUS_LINE_MAX_LEN];
|
|
|
|
if ((platGetPhraseText(STR_INDEX_FEAT_UNAVAIL,
|
|
(char *)tmp_str,
|
|
(STATUS_LINE_MAX_LEN - 1))) == CPR_SUCCESS) {
|
|
lsm_ui_display_notify(tmp_str, NO_FREE_LINES_TIMEOUT);
|
|
}
|
|
}
|
|
|
|
void
|
|
fsm_set_call_status_feature_unavailable (callid_t call_id, line_t line)
|
|
{
|
|
char tmp_str[STATUS_LINE_MAX_LEN];
|
|
|
|
if ((platGetPhraseText(STR_INDEX_FEAT_UNAVAIL,
|
|
(char *)tmp_str,
|
|
(STATUS_LINE_MAX_LEN - 1))) == CPR_SUCCESS) {
|
|
ui_set_call_status(tmp_str, line, lsm_get_ui_id(call_id));
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Get total number of selected calls.
|
|
*
|
|
* @param void
|
|
*
|
|
* @return uint16_t
|
|
*
|
|
* @pre (none)
|
|
*/
|
|
uint16_t fsmutil_get_num_selected_calls (void)
|
|
{
|
|
return(g_numofselected_calls);
|
|
}
|
|
|
|
/**
|
|
* This function will hide/unhide ringingin calls.
|
|
*
|
|
* @param[in] hide - indicates whether calls should be hidden or unhidden
|
|
*
|
|
* @return none
|
|
*/
|
|
void fsm_display_control_ringin_calls (boolean hide)
|
|
{
|
|
fsm_fcb_t *fcb;
|
|
|
|
FSM_FOR_ALL_CBS(fcb, fsm_fcbs, FSM_MAX_FCBS) {
|
|
if ((fcb->state == FSMDEF_S_INCOMING_ALERTING) &&
|
|
(lsm_is_it_priority_call(fcb->call_id) == FALSE)) { /* priority call should not be hidden */
|
|
lsm_display_control_ringin_call (fcb->call_id, fcb->dcb->line, hide);
|
|
if (hide == TRUE) {
|
|
fsmutil_clear_shown_calls_ci_element(fcb->dcb->caller_id.call_instance_id, fcb->dcb->line);
|
|
} else {
|
|
fsmutil_set_shown_calls_ci_element(fcb->dcb->caller_id.call_instance_id, fcb->dcb->line);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* fsmutil_init_groupid
|
|
*
|
|
* Description:
|
|
*
|
|
* Assign the group id to the default control block.
|
|
*
|
|
* Parameters:
|
|
* dcb - default control block
|
|
* call_id - ccapi call identifier associated with the call
|
|
* call_type - incoming or outgoing call
|
|
*
|
|
* Returns: None. groupid will be assigned in the dcb.
|
|
*/
|
|
void
|
|
fsmutil_init_groupid (fsmdef_dcb_t *dcb, callid_t call_id,
|
|
fsmdef_call_types_t call_type)
|
|
{
|
|
fsmcnf_ccb_t *ccb = NULL;
|
|
|
|
/* if this was a consult leg of a conference then there will be
|
|
* a ccb on the primary leg
|
|
*/
|
|
dcb->group_id = CC_NO_GROUP_ID;
|
|
if (call_type != FSMDEF_CALL_TYPE_NONE) {
|
|
ccb = fsmcnf_get_ccb_by_call_id(call_id);
|
|
if (ccb) {
|
|
/* consult leg of a conference */
|
|
fsmdef_dcb_t *other_dcb = NULL;
|
|
|
|
other_dcb =
|
|
fsmdef_get_dcb_by_call_id(fsmcnf_get_other_call_id(ccb, call_id));
|
|
if (other_dcb) {
|
|
dcb->group_id = other_dcb->group_id;
|
|
}
|
|
} else {
|
|
/* either a primary or some other leg; not part of any conference */
|
|
|
|
dcb->group_id = dcb->call_id;
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Find out if the call pointed by call_id is a consult call
|
|
* of a conference, transfer.
|
|
*
|
|
* @param line line related to that call
|
|
* @param call_id call_id
|
|
*
|
|
* @return call attributes
|
|
*
|
|
* @pre none
|
|
*/
|
|
int
|
|
fsmutil_get_call_attr (fsmdef_dcb_t *dcb,
|
|
line_t line, callid_t call_id)
|
|
{
|
|
int call_attr;
|
|
|
|
if (fsmutil_is_cnf_consult_call(call_id) == TRUE) {
|
|
call_attr = LOCAL_CONF_CONSULT;
|
|
} else if (fsmutil_is_b2bcnf_consult_call(call_id) == TRUE) {
|
|
call_attr = CONF_CONSULT;
|
|
} else if (fsmutil_is_xfr_consult_call(call_id) == TRUE) {
|
|
call_attr = XFR_CONSULT;
|
|
} else {
|
|
if (dcb == NULL) {
|
|
return(NORMAL_CALL);
|
|
}
|
|
|
|
switch (dcb->active_feature) {
|
|
case CC_FEATURE_CFWD_ALL:
|
|
call_attr = CC_ATTR_CFWD_ALL;
|
|
break;
|
|
default:
|
|
call_attr = NORMAL_CALL;
|
|
break;
|
|
}
|
|
}
|
|
return call_attr;
|
|
}
|
|
|
|
/*
|
|
* fsmutil_is_cnf_consult_leg
|
|
*
|
|
* Description:
|
|
* Returns TRUE if the specified call_id is for a call that is
|
|
* the consultative call of a conference.
|
|
*
|
|
* Parameters:
|
|
* call_id - ccapi call identifier associated with the call.
|
|
* fsmxcb_ccbs - pointer to all conf ccbs
|
|
* max_ccbs - Max number of ccbs to check
|
|
*
|
|
* Returns: TRUE if consultative call; otherwise, FALSE.
|
|
*/
|
|
int
|
|
fsmutil_is_cnf_consult_leg (callid_t call_id, fsmcnf_ccb_t *fsmcnf_ccbs,
|
|
uint16_t max_ccbs)
|
|
{
|
|
fsmcnf_ccb_t *ccb;
|
|
|
|
FSM_FOR_ALL_CBS(ccb, fsmcnf_ccbs, max_ccbs) {
|
|
if (ccb->cns_call_id == call_id) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/*
|
|
* fsmutil_is_xfr_consult_leg
|
|
*
|
|
* Description:
|
|
* Returns TRUE if the specified call_id is for a call that is
|
|
* the consultative call of a transfer only when that consult
|
|
* was an initiated transfer.
|
|
*
|
|
* Parameters:
|
|
* call_id - ccapi call identifier associated with the call.
|
|
* fsmxfr_xcbs - pointer to all xfr ccbs
|
|
* max_xcbs - Max number of ccbs to check
|
|
*
|
|
* Returns: TRUE if consultative call; otherwise, FALSE.
|
|
*/
|
|
int
|
|
fsmutil_is_xfr_consult_leg (callid_t call_id, fsmxfr_xcb_t *fsmxfr_xcbs,
|
|
uint16_t max_xcbs)
|
|
{
|
|
fsmxfr_xcb_t *xcb;
|
|
|
|
FSM_FOR_ALL_CBS(xcb, fsmxfr_xcbs, max_xcbs) {
|
|
if ((xcb->mode == FSMXFR_MODE_TRANSFEROR) &&
|
|
(xcb->cns_call_id == call_id)) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/*
|
|
* fsmutil_clear_feature_invocation_state
|
|
*
|
|
* Description:
|
|
* This function clears the feature invocation state of the feature id
|
|
* supplied. This function is used by the code that would receive the
|
|
* feature ack (from SIP stack).
|
|
*
|
|
* Note: Code responsible for invoking features and receiving feature acks
|
|
* must call this function to clear the feature invocation state.
|
|
*
|
|
* Parameters:
|
|
* fsmdef_dcb_t *dcb - dcb associated with the call
|
|
* cc_features_t feature_id - feature id in question
|
|
*
|
|
* Returns: None
|
|
*/
|
|
static void
|
|
fsmutil_clear_feature_invocation_state (fsmdef_dcb_t *dcb,
|
|
cc_features_t feature_id)
|
|
{
|
|
if ((feature_id < CC_FEATURE_NONE) || (feature_id >= CC_FEATURE_MAX)) {
|
|
/* Log Error */
|
|
GSM_ERR_MSG(GSM_L_C_F_PREFIX"Invalid feature id -> %d\n", dcb->line, dcb->call_id, "fsmutil_clear_feature_invocation_state", feature_id);
|
|
return;
|
|
}
|
|
|
|
rm_clear_element((resource_manager_t *) dcb->feature_invocation_state,
|
|
(int16_t) feature_id);
|
|
}
|
|
|
|
/*
|
|
* fsmutil_process_feature_ack
|
|
*
|
|
* Description:
|
|
* This function implements the generic feature ack processing.
|
|
* Feature invocation state is Cleared when feature ack is received.
|
|
*
|
|
* Parameters:
|
|
* fsmdef_dcb_t *dcb - dcb associated with the call
|
|
* cc_features_t feature_id - feature id in question
|
|
*
|
|
* Returns: None
|
|
*/
|
|
void
|
|
fsmutil_process_feature_ack (fsmdef_dcb_t *dcb, cc_features_t feature_id)
|
|
{
|
|
/* clear the feature invocation state (was set when invoked) */
|
|
fsmutil_clear_feature_invocation_state(dcb, feature_id);
|
|
}
|
|
|
|
/*
|
|
* fsmutil_clear_all_feature_invocation_state
|
|
*
|
|
* Description:
|
|
* This function clears the feature invocation state of ALL features.
|
|
*
|
|
* This function may be used by the code that would initialize/reset
|
|
* the state machine.
|
|
*
|
|
* Parameters:
|
|
* fsmdef_dcb_t *dcb - dcb associated with the call
|
|
*
|
|
* Returns: None
|
|
*/
|
|
void
|
|
fsmutil_clear_all_feature_invocation_state (fsmdef_dcb_t *dcb)
|
|
{
|
|
rm_clear_all_elements((resource_manager_t *) dcb->feature_invocation_state);
|
|
}
|
|
|
|
/*
|
|
* fsmutil_init_feature_invocation_state
|
|
*
|
|
* Description:
|
|
* Utility function to allocate and init a feature invocation state table.
|
|
*
|
|
* Parameters:
|
|
* dcb - dcb whose feature invocation state table is being created
|
|
*
|
|
* Returns:
|
|
* none
|
|
*/
|
|
void
|
|
fsmutil_init_feature_invocation_state (fsmdef_dcb_t *dcb)
|
|
{
|
|
static const char fname[] = "fsmutil_init_feature_invocation_state";
|
|
|
|
dcb->feature_invocation_state = rm_create(CC_FEATURE_MAX);
|
|
|
|
if (!dcb->feature_invocation_state) {
|
|
GSM_ERR_MSG(GSM_L_C_F_PREFIX"failed to allocate feature invocation state table\n", dcb->line, dcb->call_id,
|
|
fname);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* fsmutil_free_feature_invocation_state
|
|
*
|
|
* Description:
|
|
* Utility function to free the feature invocation state table of the
|
|
* specified dcb.
|
|
*
|
|
* Parameters:
|
|
* None
|
|
*
|
|
* Returns:
|
|
* None
|
|
*/
|
|
void
|
|
fsmutil_free_feature_invocation_state (fsmdef_dcb_t *dcb)
|
|
{
|
|
rm_destroy((resource_manager_t *) dcb->feature_invocation_state);
|
|
dcb->feature_invocation_state = NULL;
|
|
}
|
|
|
|
/*
|
|
* fsmutil_free_all_ci_id
|
|
*
|
|
* Description:
|
|
* This function clears the entire call instance map.
|
|
*
|
|
* Parameters:
|
|
* None
|
|
*
|
|
* Returns:
|
|
* None
|
|
*/
|
|
void
|
|
fsmutil_free_all_ci_id (void)
|
|
{
|
|
uint16_t line;
|
|
|
|
for (line = 1; line <= MAX_REG_LINES; line++) {
|
|
rm_clear_all_elements((resource_manager_t *) ci_map_p[line]);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* fsmutil_free_ci_id
|
|
*
|
|
* Description:
|
|
* This function clears a specified call instance id from
|
|
* the call instance map.
|
|
*
|
|
* Note that call instance ids are one based. The resource manager
|
|
* used to implement the call instance map is zero based so we have
|
|
* to adjust the call instance id when using the resource manager API.
|
|
*
|
|
* Parameters:
|
|
* id - the call instance id to be freed
|
|
* line - line from where to free the call instance id
|
|
*
|
|
* Returns:
|
|
* None
|
|
*/
|
|
void
|
|
fsmutil_free_ci_id (uint16_t id, line_t line)
|
|
{
|
|
static const char fname[] = "fsmutil_free_ci_id";
|
|
|
|
if (id < 1 || id > MAX_CALLS) {
|
|
GSM_ERR_MSG(GSM_F_PREFIX"specified id %d is invalid\n", fname, id);
|
|
return;
|
|
}
|
|
|
|
if (line < 1 || line > MAX_REG_LINES) {
|
|
GSM_ERR_MSG(GSM_F_PREFIX"specified line %d is invalid\n", fname, line);
|
|
return;
|
|
}
|
|
|
|
rm_clear_element((resource_manager_t *) ci_map_p[line], (int16_t) --id);
|
|
}
|
|
|
|
#ifdef LOCAL_UI_CALLINSTANCE_ID
|
|
/*This routine is not needed now as the local assignment
|
|
*of call instance id is no longer supported.
|
|
*/
|
|
/*
|
|
* fsmutil_get_ci_id
|
|
*
|
|
* Description:
|
|
* This function locates the next available call instance id in
|
|
* the call instance map. This function is utilized when operating in
|
|
* the peer to peer mode to assign call instance ids for inbound
|
|
* and outbound calls.
|
|
*
|
|
* Note that call instance ids are one based. The resource manager
|
|
* used to implement the call instance map is zero based so we have
|
|
* to adjust the call instance id when using the resource manager API.
|
|
*
|
|
* Parameters:
|
|
* line - line from where to retrieve the call instance id
|
|
*
|
|
* Returns:
|
|
* uint16_t - Non-zero call instance id. 0 if no call instance ids
|
|
* are available.
|
|
*/
|
|
uint16_t
|
|
fsmutil_get_ci_id (line_t line)
|
|
{
|
|
static const char fname[] = "fsmutil_get_ci_id";
|
|
int16_t id;
|
|
uint16_t return_id = 0;
|
|
|
|
if (line < 1 || line > MAX_REG_LINES) {
|
|
GSM_ERR_MSG("specified line %d is invalid\n", fname, line);
|
|
return 0;
|
|
}
|
|
|
|
id = rm_get_free_element(ci_map_p[line]);
|
|
if (id >= 0) {
|
|
return_id = ++id;
|
|
}
|
|
return (return_id);
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
* fsmutil_set_ci_id
|
|
*
|
|
* Description:
|
|
* This function marks a specified call instance id as being in
|
|
* use in the call instance map. This function is used when in
|
|
* CCM mode to store the call instance id specified by the CCM
|
|
* for inbound and outbound calls.
|
|
*
|
|
* Note that call instance ids are one based. The resource manager
|
|
* used to implement the call instance map is zero based so we have
|
|
* to adjust the call instance id when using the resource manager API.
|
|
* Parameters:
|
|
*
|
|
* Parameters:
|
|
* id - The call instance id to set.
|
|
* line - Line being used for the call.
|
|
*
|
|
* Returns:
|
|
* None
|
|
*/
|
|
void
|
|
fsmutil_set_ci_id (uint16_t id, line_t line)
|
|
{
|
|
static const char fname[] = "fsmutil_set_ci_id";
|
|
|
|
if (id < 1 || id > MAX_CALLS) {
|
|
GSM_ERR_MSG(GSM_F_PREFIX"specified id %d is invalid\n", fname, id);
|
|
return;
|
|
}
|
|
|
|
if (line < 1 || line > MAX_REG_LINES) {
|
|
GSM_ERR_MSG(GSM_F_PREFIX"specified line %d is invalid\n", fname, line);
|
|
return;
|
|
}
|
|
|
|
rm_set_element(ci_map_p[line], (int16_t) --id);
|
|
}
|
|
|
|
/*
|
|
* fsmutil_init_ci_map
|
|
*
|
|
* Description:
|
|
* Utility function to allocate and init the call instance id map.
|
|
*
|
|
* Parameters:
|
|
* None
|
|
*
|
|
* Returns:
|
|
* None
|
|
*/
|
|
void
|
|
fsmutil_init_ci_map (void)
|
|
{
|
|
static const char fname[] = "fsmutil_init_ci_map";
|
|
uint16_t line;
|
|
|
|
for (line = 1; line <= MAX_REG_LINES; line++) {
|
|
ci_map_p[line] = rm_create(MAX_CALLS);
|
|
|
|
if (!ci_map_p[line]) {
|
|
GSM_ERR_MSG(GSM_F_PREFIX"failed to allocate call instance id map for line %d",
|
|
fname, line);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This function will allocate and initialize the shown_calls_call_instnace map.
|
|
*
|
|
* @return none
|
|
*/
|
|
void fsmutil_init_shown_calls_ci_map (void)
|
|
{
|
|
static const char fname[] = "fsmutil_init_shown_calls_ci_map";
|
|
uint16_t line;
|
|
|
|
for (line = 1; line <= MAX_REG_LINES; line++) {
|
|
shown_calls_ci_map_p[line] = rm_create(MAX_CALLS);
|
|
|
|
if (!shown_calls_ci_map_p[line]) {
|
|
GSM_ERR_MSG(GSM_F_PREFIX"failed to allocate shown calls call instance id map for line %d",
|
|
fname, line);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This function will set the shown_calls_call_instnace map to zeros.
|
|
*
|
|
* @return none
|
|
*/
|
|
void fsmutil_free_all_shown_calls_ci_map (void)
|
|
{
|
|
uint16_t line;
|
|
|
|
for (line = 1; line <= MAX_REG_LINES; line++) {
|
|
rm_clear_all_elements((resource_manager_t *) shown_calls_ci_map_p[line]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This function marks a given call to be hidden.
|
|
*
|
|
* @param[in] id - call instance id of the call to be hidden.
|
|
* @param[in] line - the line being used for the call.
|
|
*
|
|
* @return none
|
|
*/
|
|
void fsmutil_clear_shown_calls_ci_element (uint16_t id, line_t line)
|
|
{
|
|
static const char fname[] = "fsmutil_clear_shown_calls_ci_element";
|
|
|
|
if (id < 1 || id > MAX_CALLS) {
|
|
GSM_ERR_MSG(GSM_F_PREFIX"specified id %d is invalid\n", fname, id);
|
|
return;
|
|
}
|
|
|
|
if (line < 1 || line > MAX_REG_LINES) {
|
|
GSM_ERR_MSG(GSM_F_PREFIX"specified line %d is invalid\n", fname, line);
|
|
return;
|
|
}
|
|
|
|
rm_clear_element((resource_manager_t *) shown_calls_ci_map_p[line], (int16_t)(id - 1));
|
|
}
|
|
|
|
/**
|
|
* This function marks a given call to be shown.
|
|
*
|
|
* @param[in] id - call instance id of the call to be shown.
|
|
* @param[in] line - the line being used for the call.
|
|
*
|
|
* @return none
|
|
*/
|
|
void fsmutil_set_shown_calls_ci_element (uint16_t id, line_t line)
|
|
{
|
|
static const char fname[] = "fsmutil_set_shown_calls_ci_element";
|
|
|
|
if (id < 1 || id > MAX_CALLS) {
|
|
GSM_ERR_MSG(GSM_F_PREFIX"specified id %d is invalid\n", fname, id);
|
|
return;
|
|
}
|
|
|
|
if (line < 1 || line > MAX_REG_LINES) {
|
|
GSM_ERR_MSG(GSM_F_PREFIX"specified line %d is invalid\n", fname, line);
|
|
return;
|
|
}
|
|
|
|
rm_set_element(shown_calls_ci_map_p[line], (int16_t)(id - 1));
|
|
}
|
|
|
|
/**
|
|
* This function checks if a given call is to be shown.
|
|
*
|
|
* @param[in] id - call instance id of the call.
|
|
* @param[in] line - the line being used for the call.
|
|
*
|
|
* @return none
|
|
*/
|
|
boolean fsmutil_is_shown_calls_ci_element_set (uint16_t id, line_t line)
|
|
{
|
|
static const char fname[] = "fsmutil_is_shown_calls_ci_element_set";
|
|
|
|
if (id < 1 || id > MAX_CALLS) {
|
|
GSM_ERR_MSG(GSM_F_PREFIX"specified id %d is invalid\n", fname, id);
|
|
return FALSE;
|
|
}
|
|
|
|
if (line < 1 || line > MAX_REG_LINES) {
|
|
GSM_ERR_MSG(GSM_F_PREFIX"specified line %d is invalid\n", fname, line);
|
|
return FALSE;
|
|
}
|
|
|
|
if (rm_is_element_set(shown_calls_ci_map_p[line], (int16_t)(id - 1))) {
|
|
return (TRUE);
|
|
}
|
|
|
|
return (FALSE);
|
|
}
|
|
|
|
/*
|
|
* fsmutil_free_ci_map
|
|
*
|
|
* Description:
|
|
* Utility function to free the call instance id map.
|
|
*
|
|
* Parameters:
|
|
* None
|
|
*
|
|
* Returns:
|
|
* None
|
|
*/
|
|
void
|
|
fsmutil_free_ci_map (void)
|
|
{
|
|
uint16_t line;
|
|
|
|
for (line = 1; line <= MAX_REG_LINES; line++) {
|
|
rm_destroy((resource_manager_t *) ci_map_p[line]);
|
|
ci_map_p[line] = NULL;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* fsmutil_show_ci_map
|
|
*
|
|
* Description:
|
|
* Utility function to display the current state of the call
|
|
* instance map.
|
|
*
|
|
* Parameters:
|
|
* None
|
|
*
|
|
* Returns:
|
|
* None
|
|
*/
|
|
void
|
|
fsmutil_show_ci_map (void)
|
|
{
|
|
uint16_t line;
|
|
|
|
for (line = 1; line <= MAX_REG_LINES; line++) {
|
|
rm_show(ci_map_p[line]);
|
|
}
|
|
}
|