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); }
sm_rcs_t sm_process_event (sm_table_t *tbl, sm_event_t *event) { static const char fname[] = "sm_process_event"; int state_id = event->state; int event_id = event->event; sm_rcs_t rc = SM_RC_ERROR; fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; cc_feature_t *feat_msg = NULL; line_t line_id; fsm_types_t fsm_type; callid_t call_id; sm_function_t hdlr; /* cached handler in order to compute its addr once */ /* * validate the state and event * and that there is a valid function for this state-event pair. */ if ((state_id > tbl->min_state) && (state_id < tbl->max_state) && (event_id > tbl->min_event) && (event_id < tbl->max_event)) { rc = SM_RC_DEF_CONT; /* * Save some paramters for debuging, the event handler may * free the fcb once returned. */ fsm_type = fcb->fsm_type; call_id = fcb->call_id; if ((hdlr = tbl->table[tbl->max_event * state_id + event_id]) != NULL) { FSM_DEBUG_SM(DEB_F_PREFIX"%s %-4d: 0x%08lx: sm entry: (%s:%s)\n", DEB_F_PREFIX_ARGS(FSM, fname), fsm_type_name(fsm_type), call_id, tbl->table[tbl->max_event * state_id + event_id], fsm_state_name(fsm_type, state_id), cc_msg_name((cc_msgs_t)(event_id))); rc = hdlr(event); } if (rc != SM_RC_DEF_CONT) { /* For event_id == CC_MSG_FEATURE then display the * feature associated with it. */ if (event_id == CC_MSG_FEATURE) { feat_msg = (cc_feature_t *) event->msg; } line_id = ((cc_feature_t *) event->msg)->line; DEF_DEBUG(DEB_L_C_F_PREFIX"%-5s :(%s:%s%s)\n", DEB_L_C_F_PREFIX_ARGS(GSM, line_id, call_id, fname), fsm_type_name(fsm_type), fsm_state_name(fsm_type, state_id), cc_msg_name((cc_msgs_t)(event_id)), feat_msg ? cc_feature_name(feat_msg->feature_id):" "); } } /* * Invalid state-event pair. */ else { GSM_ERR_MSG(GSM_F_PREFIX"illegal state-event pair: (%d <-- %d)\n", fname, state_id, event_id); rc = SM_RC_ERROR; } return rc; }
/* * Function: dp_update_keypress() * * Parameters: line - line number * call_id - call indentification * digit - collected digit * * Description: Dialplan interface function to pass the collected * digits. This routine will source collected digits * (including backspace) to dialplan and KPML. * Digits are passed during connected state and dialing * state. * * * Returns: none */ static void dp_update_keypress (line_t line, callid_t call_id, unsigned char digit) { const char fname[] = "dp_update_keypress"; lsm_states_t lsm_state; int skMask[MAX_SOFT_KEYS]; DEF_DEBUG(DEB_L_C_F_PREFIX"KEY .\n", DEB_L_C_F_PREFIX_ARGS(DP_API, line, call_id, fname) ); lsm_state = lsm_get_state(call_id); if (lsm_state == LSM_S_NONE) { DPINT_DEBUG(DEB_F_PREFIX"call not found\n", DEB_F_PREFIX_ARGS(DIALPLAN, fname)); return; } /* If the call is in connected state, digits are DTMF key presses * pass this to GSM and KPML module */ if (lsm_state == LSM_S_RINGOUT || lsm_state == LSM_S_CONNECTED || lsm_state == LSM_S_HOLDING) { DPINT_DEBUG(DEB_F_PREFIX"digit received in LSM state %s\n", DEB_F_PREFIX_ARGS(DIALPLAN, fname), lsm_state_name(lsm_state)); cc_digit_begin(CC_SRC_GSM, g_dp_int.call_id, g_dp_int.line, digit); if (!kpml_update_dialed_digits(line, call_id, digit)) { kpml_quarantine_digits(line, call_id, digit); } return; } if (g_dp_int.line != line) { DPINT_DEBUG(DEB_F_PREFIX"line %d does not match dialplan line %d\n", DEB_F_PREFIX_ARGS(DIALPLAN, fname), line, g_dp_int.line); return; } if (dp_check_plar_warmline(line, call_id)) { DPINT_DEBUG(DEB_F_PREFIX"warm line\n", DEB_F_PREFIX_ARGS(DIALPLAN, fname)); return; } if (digit == 0) { DPINT_DEBUG(DEB_F_PREFIX"digit is 0\n", DEB_F_PREFIX_ARGS(DIALPLAN, fname)); return; } ui_control_feature(line, call_id, skMask, 1, FALSE); /* if not in URL dialing mode pass it through kpml dialing * to quarantine digits */ if (g_dp_int.url_dialing == FALSE) { if (!kpml_update_dialed_digits(line, call_id, digit)) { /* * no valid subscription case: * if user pressed backspace, we can approve the delete without waiting * for any response. */ if (digit == BKSPACE_KEY) { dp_delete_last_digit(line, call_id); } kpml_quarantine_digits(line, call_id, digit); } } else { if (digit == BKSPACE_KEY) { /* no kpml for URL; go ahead and approve the delete */ dp_delete_last_digit(line, call_id); } } /* no further processing for back space key */ if (digit == BKSPACE_KEY) { return; } /* Make sure that call is in dialing state * if not then do not check the dial plan */ switch (lsm_state) { case LSM_S_OFFHOOK: dp_check_dialplan(line, call_id, digit); break; default: break; } }