Example #1
0
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);

}
Example #2
0
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;
}
Example #3
0
/*
 *  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;
    }

}