724 lines
18 KiB
C
Executable File
724 lines
18 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 "cpr_string.h"
|
|
#include "cpr_errno.h"
|
|
#include "phone.h"
|
|
#include "phntask.h"
|
|
#include "lsm.h"
|
|
#include "ccapi.h"
|
|
#include "phone_debug.h"
|
|
#include "fim.h"
|
|
#include "sdp.h"
|
|
#include "debug.h"
|
|
#include "gsm_sdp.h"
|
|
#include "uiapi.h"
|
|
#include "gsm.h"
|
|
#include "prot_configmgr.h"
|
|
#include "singly_link_list.h"
|
|
|
|
typedef enum dcsm_state {
|
|
DCSM_S_MIN = -1,
|
|
DCSM_S_READY,
|
|
DCSM_S_WAITING,
|
|
DCSM_S_MAX
|
|
} dcsm_state_e;
|
|
|
|
#define DCSM_MAX_CALL_IDS (LSM_MAX_CALLS)
|
|
|
|
static struct dcsm_icb_t {
|
|
callid_t call_ids[DCSM_MAX_CALL_IDS];
|
|
line_t line;
|
|
int gsm_state;
|
|
sll_handle_t s_msg_list;
|
|
|
|
dcsm_state_e state;
|
|
} dcsm_cb;
|
|
|
|
static const char *dcsm_state_names[] = {
|
|
"DCSM_READY",
|
|
"DCSM_WAITING"
|
|
};
|
|
|
|
extern cc_int32_t g_dcsmDebug;
|
|
|
|
static sm_rcs_t dcsm_wait_ev_feature_handling(void *event, int event_id);
|
|
static sm_rcs_t dcsm_wait_ev_offhook_handling(void *event, int event_id);
|
|
static sm_rcs_t dcsm_wait_ev_dialstring_handling(void *event, int event_id);
|
|
|
|
typedef sm_rcs_t (*pdcsm_sm_evt_handler)(void *event, int event_id);
|
|
|
|
typedef struct _dcsm_table_t {
|
|
int min_state;
|
|
int max_state;
|
|
int min_event;
|
|
int max_event;
|
|
pdcsm_sm_evt_handler *table;
|
|
} dcsm_table_t;
|
|
|
|
|
|
static pdcsm_sm_evt_handler dcsm_function_table[DCSM_S_MAX][CC_MSG_MAX] =
|
|
{
|
|
/* DCSM_S_READY ------------------------------------------------------------ */
|
|
{
|
|
/* DCSM_E_SETUP */ NULL,
|
|
/* DCSM_E_SETUP_ACK */ NULL,
|
|
/* DCSM_E_PROCEEDING */ NULL,
|
|
/* DCSM_E_ALERTING */ NULL,
|
|
/* DCSM_E_CONNECTED */ NULL,
|
|
/* DCSM_E_CONNECTED_ACK */ NULL,
|
|
/* DCSM_E_RELEASE */ NULL,
|
|
/* DCSM_E_RELEASE_COMPLETE */ NULL,
|
|
/* DCSM_E_FEATURE */ NULL,
|
|
/* DCSM_E_FEATURE_ACK */ NULL,
|
|
/* DCSM_E_OFFHOOK */ NULL,
|
|
/* DCSM_E_ONHOOK */ NULL,
|
|
/* DCSM_E_LINE */ NULL,
|
|
/* DCSM_E_DIGIT_BEGIN */ NULL,
|
|
/* DCSM_E_DIGIT_END */ NULL,
|
|
/* DCSM_E_DIALSTRING */ NULL,
|
|
/* DCSM_E_MWI */ NULL,
|
|
/* DCSM_E_SESSION_AUDIT */ NULL
|
|
},
|
|
|
|
/* DCSM_S_WAITING----------------------------------------------------- */
|
|
{
|
|
/* DCSM_E_SETUP */ NULL,
|
|
/* DCSM_E_SETUP_ACK */ NULL,
|
|
/* DCSM_E_PROCEEDING */ NULL,
|
|
/* DCSM_E_ALERTING */ NULL,
|
|
/* DCSM_E_CONNECTED */ NULL,
|
|
/* DCSM_E_CONNECTED_ACK */ NULL,
|
|
/* DCSM_E_RELEASE */ NULL,
|
|
/* DCSM_E_RELEASE_COMPLETE */ NULL,
|
|
/* DCSM_E_FEATURE */ dcsm_wait_ev_feature_handling,
|
|
/* DCSM_E_FEATURE_ACK */ NULL,
|
|
/* DCSM_E_OFFHOOK */ dcsm_wait_ev_offhook_handling,
|
|
/* DCSM_E_ONHOOK */ NULL,
|
|
/* DCSM_E_LINE */ NULL,
|
|
/* DCSM_E_DIGIT_BEGIN */ NULL,
|
|
/* DCSM_E_DIGIT_END */ NULL,
|
|
/* DCSM_E_DIALSTRING */ dcsm_wait_ev_dialstring_handling,
|
|
/* DCSM_E_MWI */ NULL,
|
|
/* DCSM_E_SESSION_AUDIT */ NULL
|
|
},
|
|
};
|
|
|
|
static dcsm_table_t dcsm_sm_table;
|
|
static dcsm_table_t *pdcsm_sm_table = &dcsm_sm_table;
|
|
|
|
/*
|
|
* Adds event to the dcsm queue.
|
|
*
|
|
* @param event - Call control event to add
|
|
*
|
|
* @return TRUE if the event is added.
|
|
|
|
*
|
|
*/
|
|
static boolean
|
|
dcsm_add_event_to_queue (void *event)
|
|
{
|
|
(void) sll_append(dcsm_cb.s_msg_list, event);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/*
|
|
* Get a event from the queue.
|
|
*
|
|
* @param none
|
|
*
|
|
* @return pointer to the event.
|
|
|
|
*
|
|
*/
|
|
static void *
|
|
dcsm_get_first_event_from_queue (void)
|
|
{
|
|
void *msg_ptr = NULL;
|
|
|
|
msg_ptr = sll_next(dcsm_cb.s_msg_list, NULL);
|
|
|
|
sll_remove(dcsm_cb.s_msg_list, msg_ptr);
|
|
|
|
return(msg_ptr);
|
|
}
|
|
|
|
/*
|
|
* Get dcsm state name.
|
|
*
|
|
* @param int - state id
|
|
*
|
|
* @return ponter to the state name either
|
|
* DCSM_READY or DCSM_WAITING.
|
|
*
|
|
*/
|
|
const char *dcsm_get_state_name (int state)
|
|
{
|
|
if ((state <= DCSM_S_MIN) ||
|
|
(state >= DCSM_S_MAX)) {
|
|
return (get_debug_string(GSM_UNDEFINED));
|
|
}
|
|
|
|
return dcsm_state_names[state];
|
|
}
|
|
|
|
/**
|
|
* Feed the event to FIM state machine a direct function call
|
|
* to process message retrieved from the queue.
|
|
*
|
|
* @param void * - pointer to the message to be processed
|
|
*
|
|
* @return none.
|
|
*/
|
|
static void dcsm_process_event_to_gsm (void *msg_ptr)
|
|
{
|
|
if (fim_process_event(msg_ptr, FALSE) == TRUE) {
|
|
|
|
fim_free_event(msg_ptr);
|
|
|
|
/* Release buffer too */
|
|
cpr_free(msg_ptr);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Process ready state events.
|
|
*
|
|
* @param none
|
|
*
|
|
* @return none.
|
|
*/
|
|
|
|
static void dcsm_do_ready_state_job (void)
|
|
{
|
|
static const char fname[] = "dcsm_do_ready_state_job";
|
|
void *msg_ptr;
|
|
int event_id;
|
|
cc_feature_t *feat_msg = NULL;
|
|
callid_t call_id = CC_NO_CALL_ID;
|
|
|
|
if (dcsm_cb.state != DCSM_S_READY) {
|
|
DEF_DEBUG(DEB_F_PREFIX": not in ready state.\n",
|
|
DEB_F_PREFIX_ARGS("DCSM", fname));
|
|
return;
|
|
}
|
|
|
|
msg_ptr = dcsm_get_first_event_from_queue();
|
|
|
|
/* Check if there is any msg available */
|
|
if (msg_ptr != NULL) {
|
|
event_id = (int)(((cc_setup_t *)msg_ptr)->msg_id);
|
|
if (event_id == CC_MSG_FEATURE) {
|
|
feat_msg = (cc_feature_t *) msg_ptr;
|
|
if (feat_msg != NULL) {
|
|
call_id = feat_msg->call_id;
|
|
}
|
|
}
|
|
|
|
DEF_DEBUG(DEB_F_PREFIX"%d: event (%s%s)\n",
|
|
DEB_F_PREFIX_ARGS("DCSM", fname), call_id,
|
|
cc_msg_name((cc_msgs_t)(event_id)),
|
|
feat_msg ? cc_feature_name(feat_msg->feature_id):" ");
|
|
dcsm_process_event_to_gsm(msg_ptr);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Function process events based on the state of DCSM.
|
|
*
|
|
* @param none
|
|
*
|
|
* @return none.
|
|
*/
|
|
void dcsm_process_jobs (void)
|
|
{
|
|
dcsm_do_ready_state_job();
|
|
}
|
|
|
|
/**
|
|
* Adds call_id to the list of call_id's which made DCSM to move
|
|
* to waiting state.
|
|
*
|
|
* @param callid_t - call id that has to be added to the list
|
|
*
|
|
* @return none.
|
|
*/
|
|
static void dcsm_add_call_id_to_list (callid_t call_id)
|
|
{
|
|
static const char fname[] = "dcsm_add_call_id_to_list";
|
|
int i, loc = -1;
|
|
|
|
for (i=0; i< DCSM_MAX_CALL_IDS; i++) {
|
|
if (dcsm_cb.call_ids[i] == CC_NO_CALL_ID) {
|
|
loc = i;
|
|
} else if (dcsm_cb.call_ids[i] == call_id) {
|
|
//Call_id already present so do not try to add again
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (loc == -1) {
|
|
|
|
/* Should never happen as there is a space to store call_id
|
|
* for each calls
|
|
*/
|
|
DCSM_ERROR(DCSM_F_PREFIX"DCSM No space to store call_id.\n",
|
|
DEB_F_PREFIX_ARGS("DCSM", fname));
|
|
return;
|
|
}
|
|
|
|
dcsm_cb.call_ids[loc] = call_id;
|
|
}
|
|
|
|
/**
|
|
* Remove call_id from the list and see if the call_ids list is null.
|
|
*
|
|
* @param callid_t - call id that to be removed from the list.
|
|
*
|
|
* @return TRUE - if the call_ids list is empty.
|
|
* FALSE - call_ids list is not empty.
|
|
*/
|
|
static boolean dcsm_remove_check_for_empty_list (callid_t call_id)
|
|
{
|
|
int i;
|
|
boolean call_id_present = FALSE;
|
|
|
|
for (i=0; i< DCSM_MAX_CALL_IDS; i++) {
|
|
if (dcsm_cb.call_ids[i] == call_id) {
|
|
dcsm_cb.call_ids[i] = CC_NO_CALL_ID;
|
|
|
|
/* Found out that other call_id exist by setting
|
|
* call_id_preset, so return true, don't have to
|
|
* continue
|
|
*/
|
|
if (call_id_present == TRUE) {
|
|
return FALSE;
|
|
}
|
|
|
|
} else if (dcsm_cb.call_ids[i] != CC_NO_CALL_ID) {
|
|
call_id_present = TRUE;
|
|
}
|
|
}
|
|
|
|
if (call_id_present == TRUE) {
|
|
return(FALSE);
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
/*
|
|
* The function responsible for setting gsm state machine.
|
|
*
|
|
* @param callid_t - call id of the call
|
|
* state - current GSM state
|
|
*
|
|
* @return void
|
|
*
|
|
*/
|
|
void
|
|
dcsm_update_gsm_state (fsm_fcb_t *fcb, callid_t call_id, int state)
|
|
{
|
|
int last_state;
|
|
static const char fname[] = "dcsm_update_gsm_state";
|
|
fsmdef_dcb_t *dcb;
|
|
|
|
if (fcb->fsm_type != FSM_TYPE_DEF) {
|
|
DEF_DEBUG(DEB_F_PREFIX"%d: Not handling for %s\n",
|
|
DEB_F_PREFIX_ARGS("DCSM", fname), call_id,
|
|
fsm_type_name(fcb->fsm_type));
|
|
return;
|
|
}
|
|
|
|
last_state = dcsm_cb.state;
|
|
|
|
switch (state) {
|
|
case FSMDEF_S_RELEASING:
|
|
dcb = fsmdef_get_dcb_by_call_id(call_id);
|
|
if (dcb && dcb->send_release == FALSE) {
|
|
/* This call is already released from SIP persepctive. so no need to wait */
|
|
break;
|
|
}
|
|
case FSMDEF_S_CONNECTING:
|
|
case FSMDEF_S_HOLD_PENDING:
|
|
case FSMDEF_S_RESUME_PENDING:
|
|
dcsm_add_call_id_to_list(call_id);
|
|
|
|
dcsm_cb.state = DCSM_S_WAITING;
|
|
break;
|
|
case FSMDEF_S_MIN:
|
|
case FSMDEF_S_IDLE:
|
|
case FSMDEF_S_COLLECT_INFO:
|
|
case FSMDEF_S_CALL_SENT:
|
|
case FSMDEF_S_OUTGOING_PROCEEDING:
|
|
case FSMDEF_S_KPML_COLLECT_INFO:
|
|
case FSMDEF_S_OUTGOING_ALERTING:
|
|
case FSMDEF_S_INCOMING_ALERTING:
|
|
case FSMDEF_S_JOINING:
|
|
case FSMDEF_S_CONNECTED:
|
|
case FSMDEF_S_CONNECTED_MEDIA_PEND:
|
|
case FSMDEF_S_HOLDING:
|
|
case FSMDEF_S_PRESERVED:
|
|
case FSMDEF_S_MAX:
|
|
/* If there are no other call_id then move it to
|
|
* ready state else, it will remain in waiting
|
|
* state
|
|
*/
|
|
if (dcsm_remove_check_for_empty_list(call_id) == TRUE) {
|
|
dcsm_cb.state = DCSM_S_READY;
|
|
/* Check if there are any pending events in the queue
|
|
* if so send a DCSM_EV_READY to the GSM so dcsm will
|
|
* get a chance to execute.
|
|
*/
|
|
if (sll_count(dcsm_cb.s_msg_list) > 0 ) {
|
|
if (gsm_send_msg(DCSM_EV_READY, NULL, 0) == CPR_FAILURE) {
|
|
DCSM_ERROR(DCSM_F_PREFIX"send DCSM_EV_READY ERROR.\n",
|
|
DEB_F_PREFIX_ARGS(DCSM, fname));
|
|
}
|
|
}
|
|
}
|
|
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
DEF_DEBUG(DEB_F_PREFIX"%d : %s --> %s\n",
|
|
DEB_F_PREFIX_ARGS("DCSM", fname), call_id,
|
|
dcsm_get_state_name(last_state),
|
|
dcsm_get_state_name(dcsm_cb.state));
|
|
return;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Feature passed through when state machine is in waiting state
|
|
*
|
|
* @param sm_event_t
|
|
*
|
|
* @return sm_rcs_t
|
|
*
|
|
* @pre (none)
|
|
*/
|
|
static sm_rcs_t
|
|
dcsm_wait_ev_offhook_handling (void *event, int event_id)
|
|
{
|
|
static const char fname[] = "dcsm_wait_ev_offhook_handling";
|
|
|
|
DEF_DEBUG(DEB_F_PREFIX": offhook\n",
|
|
DEB_F_PREFIX_ARGS("DCSM", fname));
|
|
|
|
dcsm_add_event_to_queue(event);
|
|
return (SM_RC_END);
|
|
}
|
|
/**
|
|
*
|
|
* Feature passed through when state machine is in waiting state
|
|
*
|
|
* @param sm_event_t
|
|
*
|
|
* @return sm_rcs_t
|
|
*
|
|
* @pre (none)
|
|
*/
|
|
static sm_rcs_t
|
|
dcsm_wait_ev_feature_handling (void *event, int event_id)
|
|
{
|
|
static const char fname[] = "dcsm_wait_ev_feature_handling";
|
|
cc_feature_t *feat_msg = (cc_feature_t *) event;
|
|
sm_rcs_t rc = SM_RC_END;
|
|
cc_features_t ftr_id = CC_FEATURE_UNDEFINED;
|
|
callid_t call_id = CC_NO_CALL_ID;
|
|
|
|
if (feat_msg != NULL) {
|
|
ftr_id = feat_msg->feature_id;
|
|
call_id = feat_msg->call_id;
|
|
}
|
|
|
|
DEF_DEBUG(DEB_F_PREFIX"%d: id= %s%s\n",
|
|
DEB_F_PREFIX_ARGS("DCSM", fname), call_id,
|
|
cc_msg_name((cc_msgs_t)(event_id)),
|
|
feat_msg ? cc_feature_name(feat_msg->feature_id):" ");
|
|
|
|
switch (ftr_id) {
|
|
case CC_FEATURE_ANSWER:
|
|
case CC_FEATURE_NEW_CALL:
|
|
case CC_FEATURE_REDIAL:
|
|
case CC_FEATURE_RESUME:
|
|
case CC_FEATURE_JOIN:
|
|
dcsm_add_event_to_queue(event);
|
|
DEF_DEBUG(DEB_F_PREFIX"%d: Event queued\n",
|
|
DEB_F_PREFIX_ARGS("DCSM", fname), call_id);
|
|
rc = SM_RC_END;
|
|
break;
|
|
default:
|
|
DEF_DEBUG(DEB_F_PREFIX"%d: Feature msg not handled\n",
|
|
DEB_F_PREFIX_ARGS("DCSM", fname), call_id);
|
|
|
|
rc = SM_RC_CONT;
|
|
break;
|
|
}
|
|
|
|
|
|
return (rc);
|
|
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Feature passed through when state machine is in waiting state
|
|
*
|
|
* @param sm_event_t
|
|
*
|
|
* @return sm_rcs_t
|
|
*
|
|
* @pre (none)
|
|
*/
|
|
static sm_rcs_t
|
|
dcsm_wait_ev_dialstring_handling (void *event, int event_id)
|
|
{
|
|
static const char fname[] = "dcsm_wait_ev_dialstring_handling";
|
|
|
|
DEF_DEBUG(DEB_F_PREFIX": dialstring\n",
|
|
DEB_F_PREFIX_ARGS("DCSM", fname));
|
|
|
|
dcsm_add_event_to_queue(event);
|
|
return (SM_RC_END);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Feature passed through when state machine is in waiting state
|
|
*
|
|
* @param sm_event_t
|
|
*
|
|
* @return sm_rcs_t
|
|
*
|
|
* @pre (none)
|
|
*/
|
|
sm_rcs_t
|
|
dcsm_process_event (void *event, int event_id)
|
|
{
|
|
static const char fname[] = "dcsm_process_event";
|
|
callid_t call_id;
|
|
int state_id;
|
|
sm_rcs_t rc = SM_RC_CONT;
|
|
fsm_fcb_t *fcb = (fsm_fcb_t *) event;
|
|
cc_feature_t *feat_msg = NULL;
|
|
pdcsm_sm_evt_handler hdlr; /* cached handler in order to compute its addr once */
|
|
|
|
call_id = fcb->call_id;
|
|
|
|
if (event_id == CC_MSG_FEATURE) {
|
|
feat_msg = (cc_feature_t *) event;
|
|
|
|
if (feat_msg != NULL){
|
|
call_id = feat_msg->call_id;
|
|
}
|
|
}
|
|
|
|
DEF_DEBUG(DEB_F_PREFIX"DCSM %-4d:(%s:%s%s)\n",
|
|
DEB_F_PREFIX_ARGS("DCSM", fname), call_id,
|
|
dcsm_get_state_name(dcsm_cb.state),
|
|
cc_msg_name((cc_msgs_t)(event_id)),
|
|
feat_msg ? cc_feature_name(feat_msg->feature_id):" ");
|
|
|
|
state_id = dcsm_cb.state; // Get current state;
|
|
|
|
/*
|
|
* validate the state and event
|
|
* and that there is a valid function for this state-event pair.
|
|
*/
|
|
if ((state_id > pdcsm_sm_table->min_state) &&
|
|
(state_id < pdcsm_sm_table->max_state) &&
|
|
(event_id > pdcsm_sm_table->min_event) &&
|
|
(event_id < pdcsm_sm_table->max_event)) {
|
|
|
|
if ((hdlr = pdcsm_sm_table->table[pdcsm_sm_table->max_event * state_id +
|
|
event_id]) != NULL) {
|
|
DEF_DEBUG(DEB_F_PREFIX"%-4d: dcsm entry: (%s)\n",
|
|
DEB_F_PREFIX_ARGS("DCSM", fname), call_id,
|
|
cc_msg_name((cc_msgs_t)(event_id)));
|
|
|
|
rc = hdlr(event, event_id);
|
|
}
|
|
|
|
}
|
|
|
|
return (rc);
|
|
|
|
}
|
|
|
|
/*
|
|
* Function responsible for searching the list.
|
|
*
|
|
* @param cac_data_t *key_p - pointer to the key.
|
|
* @param cac_data_t *cac_data - cac data.
|
|
*
|
|
* @return void
|
|
*
|
|
*/
|
|
static sll_match_e
|
|
dcsm_match_event (void *key_p, void *msg_data)
|
|
{
|
|
return SLL_MATCH_FOUND;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Show function for DCSM
|
|
*
|
|
* @param argc - number of parameter passed
|
|
* argv - argument passed
|
|
*
|
|
* @return 0 - if function successful
|
|
*/
|
|
cc_int32_t
|
|
dcsm_show_cmd (cc_int32_t argc, const char *argv[])
|
|
{
|
|
void *msg_ptr;
|
|
int i;
|
|
cc_setup_t *msg;
|
|
cc_msgs_t msg_id;
|
|
line_t line;
|
|
callid_t call_id;
|
|
cc_feature_t *feat_msg = NULL;
|
|
|
|
|
|
/*
|
|
* check if need help
|
|
*/
|
|
if ((argc == 2) && (argv[1][0] == '?')) {
|
|
debugif_printf("%s", "show dcsm\n");
|
|
return (0);
|
|
}
|
|
|
|
|
|
if (dcsm_cb.s_msg_list == NULL) {
|
|
return(0);
|
|
}
|
|
|
|
debugif_printf("%s", "\n-------------------------- DCSM Data --------------------------");
|
|
debugif_printf("\nDCSM State = %s",dcsm_get_state_name(dcsm_cb.state));
|
|
debugif_printf("%s", "\nDCSM waiting calls \n");
|
|
|
|
for (i=0; i< DCSM_MAX_CALL_IDS; i++) {
|
|
if (dcsm_cb.call_ids[i] != CC_NO_CALL_ID) {
|
|
debugif_printf("%d ", dcsm_cb.call_ids[i]);
|
|
}
|
|
}
|
|
debugif_printf("%s", "\n");
|
|
|
|
debugif_printf("%s", "\nDCSM waiting events \n");
|
|
i = 0;
|
|
msg_ptr = sll_next(dcsm_cb.s_msg_list, NULL);
|
|
while (msg_ptr) {
|
|
msg_ptr = sll_next(dcsm_cb.s_msg_list, msg_ptr);
|
|
|
|
if (msg_ptr) {
|
|
msg = (cc_setup_t *) msg_ptr;
|
|
msg_id = msg->msg_id;
|
|
call_id = msg->call_id;
|
|
line = msg->line;
|
|
if ((int)msg_id == CC_MSG_FEATURE) {
|
|
feat_msg = (cc_feature_t *) msg_ptr;
|
|
}
|
|
|
|
debugif_printf("Event %d (%d/%d): (%s%s)\n",
|
|
i++, line, call_id, cc_msg_name(msg_id),
|
|
feat_msg ? cc_feature_name(feat_msg->feature_id):" ");
|
|
}
|
|
}
|
|
debugif_printf("%s", "\n-------------------------- DCSM Data Done-----------------------");
|
|
|
|
return (0);
|
|
}
|
|
|
|
|
|
/**
|
|
*
|
|
* Initialize dcsm state machine.
|
|
*
|
|
* @param none
|
|
*
|
|
* @return none
|
|
*
|
|
* @pre none
|
|
*/
|
|
void
|
|
dcsm_init (void)
|
|
{
|
|
static const char fname[] = "dcsm_init";
|
|
int i;
|
|
|
|
/*
|
|
* Initialize the state/event table.
|
|
*/
|
|
dcsm_sm_table.min_state = DCSM_S_MIN;
|
|
dcsm_sm_table.max_state = DCSM_S_MAX;
|
|
dcsm_sm_table.min_event = CC_MSG_MIN;
|
|
dcsm_sm_table.max_event = CC_MSG_MAX;
|
|
dcsm_sm_table.table = (&(dcsm_function_table[0][0]));
|
|
|
|
dcsm_cb.state = DCSM_S_READY;
|
|
|
|
for (i=0; i< DCSM_MAX_CALL_IDS; i++) {
|
|
dcsm_cb.call_ids[i] = CC_NO_CALL_ID;
|
|
}
|
|
|
|
/* allocate and initialize cac list */
|
|
dcsm_cb.s_msg_list = sll_create((sll_match_e(*)(void *, void *))
|
|
dcsm_match_event);
|
|
|
|
if (dcsm_cb.s_msg_list == NULL) {
|
|
DCSM_ERROR(DCSM_F_PREFIX"DCSM CB creation failed.\n",
|
|
DEB_F_PREFIX_ARGS("DCSM", fname));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Shut down routine for dcsm state machine.
|
|
*
|
|
* @param none
|
|
*
|
|
* @return none
|
|
*
|
|
* @pre none
|
|
*/
|
|
void
|
|
dcsm_shutdown (void)
|
|
{
|
|
void *msg_ptr;
|
|
|
|
if (dcsm_cb.s_msg_list == NULL) {
|
|
return;
|
|
}
|
|
|
|
msg_ptr = sll_next(dcsm_cb.s_msg_list, NULL);
|
|
while (msg_ptr) {
|
|
msg_ptr = sll_next(dcsm_cb.s_msg_list, msg_ptr);
|
|
|
|
if (msg_ptr) {
|
|
fim_free_event(msg_ptr);
|
|
|
|
/* Release buffer too */
|
|
cpr_free(msg_ptr);
|
|
}
|
|
}
|
|
|
|
sll_destroy(dcsm_cb.s_msg_list);
|
|
dcsm_cb.s_msg_list = NULL;
|
|
}
|
|
|