Esempio n. 1
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);
    }
Esempio n. 2
0
/**
 * This function will process SUBSCRIBED feature NOTIFY messages.
 *
 * @param[in] msg - pointer to ccsip_sub_not_data_t
 *
 * @return none
 *
 * @pre (msg != NULL)
 */
static void sub_process_feature_notify (ccsip_sub_not_data_t *msg, callid_t call_id,
                                        callid_t other_call_id)
{
    static const char fname[] = "sub_process_feature_notify";
    ccsip_event_data_t      *ev_data;
    cc_feature_ack_t temp_msg;


    /*
     * send response to NOTIFY.
     */
    (void)sub_int_notify_ack(msg->sub_id, SIP_STATUS_SUCCESS, msg->u.notify_ind_data.cseq);

    /*
     * if the subscription state is terminated, clean up the subscription.
     */
    if (msg->u.notify_ind_data.subscription_state == SUBSCRIPTION_STATE_TERMINATED) {
        /*
         * post SIPSPI_EV_CC_SUBSCRIPTION_TERMINATED.
         * do not force SUB/NOT mgr to cleanup SCB immediately, because we may have to handle digest
         * challenges to terminating SUBSCRIBE sent.
         */
       (void)sub_int_subscribe_term(msg->sub_id, FALSE, msg->request_id, CC_SUBSCRIPTIONS_REMOTECC);
        
    }
    ev_data     = msg->u.notify_ind_data.eventData;
    msg->u.notify_ind_data.eventData = NULL;
    if (ev_data == NULL) {
        GSM_ERR_MSG(DEB_F_PREFIX"No body in the NOTIFY message\n", 
                    DEB_F_PREFIX_ARGS(GSM, fname));
        /*
         * if (no content & subscription state is TERMINATED
         * then reset active_feature to NONE.
         */
        if (msg->u.notify_ind_data.subscription_state == SUBSCRIPTION_STATE_TERMINATED) {
            memset(&temp_msg, 0, sizeof(temp_msg));
            temp_msg.msg_id     = CC_MSG_FEATURE_ACK;
            temp_msg.src_id     = CC_SRC_GSM;
            temp_msg.call_id    = call_id;
            fim_process_event((void *)&temp_msg, FALSE);
        }
        return;
    }

    // other types of event data is not supported as of now.
    free_event_data(ev_data);
}
Esempio n. 3
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;
}
Esempio n. 4
0
void
GSMTask (void *arg)
{
    static const char fname[] = "GSMTask";
    void           *msg;
    phn_syshdr_t   *syshdr;
    boolean        release_msg = TRUE;

    /*
     * Get the GSM message queue handle
     * A hack until the tasks in irx are
     * CPRized.
     */
    gsm_msg_queue = (cprMsgQueue_t) arg;
    if (!gsm_msg_queue) {
        GSM_ERR_MSG(GSM_F_PREFIX"invalid input, exiting\n", fname);
        return;
    }

    if (platThreadInit("GSMTask") != 0) {
        return;
    }

    /*
     * Adjust relative priority of GSM thread.
     */
    (void) cprAdjustRelativeThreadPriority(GSM_THREAD_RELATIVE_PRIORITY);

    /*
     * Initialize all the GSM modules
     */
    lsm_init();
    fsm_init();
    fim_init();
    gsm_init();
    dcsm_init();

    cc_init();

    fsmutil_init_shown_calls_ci_map();
    /*
     * On Win32 platform, the random seed is stored per thread; therefore,
     * each thread needs to seed the random number.  It is recommended by
     * MS to do the following to ensure randomness across application
     * restarts.
     */
    cpr_srand((unsigned int)time(NULL));

    /*
     * Cache random numbers for SRTP keys
     */
    gsmsdp_cache_crypto_keys();

    while (1) {

        release_msg = TRUE;

        msg = cprGetMessage(gsm_msg_queue, TRUE, (void **) &syshdr);
        if (msg) {
            switch (syshdr->Cmd) {
            case TIMER_EXPIRATION:
                gsm_process_timer_expiration(msg);
                break;

            case GSM_SIP:
            case GSM_GSM:
                release_msg = gsm_process_msg(syshdr->Cmd, msg);
                break;

            case DP_MSG_INIT_DIALING:
            case DP_MSG_DIGIT_STR:
            case DP_MSG_STORE_DIGIT:
            case DP_MSG_DIGIT:
            case DP_MSG_DIAL_IMMEDIATE:
            case DP_MSG_REDIAL:
            case DP_MSG_ONHOOK:
            case DP_MSG_OFFHOOK:
            case DP_MSG_UPDATE:
            case DP_MSG_DIGIT_TIMER:
            case DP_MSG_CANCEL_OFFHOOK_TIMER:
                dp_process_msg(syshdr->Cmd, msg);
                break;

            case SUB_MSG_B2BCNF_SUBSCRIBE_RESP:
            case SUB_MSG_B2BCNF_NOTIFY:
            case SUB_MSG_B2BCNF_TERMINATE:
                sub_process_b2bcnf_msg(syshdr->Cmd, msg);
                break;

            case SUB_MSG_FEATURE_SUBSCRIBE_RESP:
            case SUB_MSG_FEATURE_NOTIFY:
            case SUB_MSG_FEATURE_TERMINATE:
                sub_process_feature_msg(syshdr->Cmd, msg);
                break;

            case SUB_MSG_KPML_SUBSCRIBE:
            case SUB_MSG_KPML_TERMINATE:
            case SUB_MSG_KPML_NOTIFY_ACK:
            case SUB_MSG_KPML_SUBSCRIBE_TIMER:
            case SUB_MSG_KPML_DIGIT_TIMER:
                kpml_process_msg(syshdr->Cmd, msg);
                break;

            case REG_MGR_STATE_CHANGE:
                gsm_reset();
                break;
            case THREAD_UNLOAD:
                destroy_gsm_thread();
                break;

            default:
                GSM_ERR_MSG(GSM_F_PREFIX"Unknown message\n", fname);
                break;
            }

            cprReleaseSysHeader(syshdr);
            if (release_msg == TRUE) {
                cprReleaseBuffer(msg);
            }
            
            /* Check if there are pending messages for dcsm 
             * if it in the right state perform its operation 
             */
            dcsm_process_jobs();
        }
    }
}
Esempio n. 5
0
void
gsm_process_timer_expiration (void *msg)
{
    static const char fname[] = "gsm_process_timer_expiration";
    cprCallBackTimerMsg_t *timerMsg;
    void *timeout_msg = NULL;

    timerMsg = (cprCallBackTimerMsg_t *) msg;
    TMR_DEBUG(DEB_F_PREFIX"Timer %s expired\n", DEB_F_PREFIX_ARGS(GSM, fname), timerMsg->expiredTimerName);

    switch (timerMsg->expiredTimerId) {

    case GSM_MULTIPART_TONES_TIMER:
    case GSM_CONTINUOUS_TONES_TIMER:
        lsm_tmr_tones_callback(timerMsg->usrData);
        break;

    case GSM_ERROR_ONHOOK_TIMER:
        fsmdef_error_onhook_timeout(timerMsg->usrData);
        break;

    case GSM_AUTOANSWER_TIMER:
        fsmdef_auto_answer_timeout(timerMsg->usrData);
        break;

    case GSM_REVERSION_TIMER:
        fsmdef_reversion_timeout((callid_t)(long)timerMsg->usrData);
        break;

    case GSM_CAC_FAILURE_TIMER:
        fsm_cac_process_bw_fail_timer(timerMsg->usrData);
        break;

    case GSM_DIAL_TIMEOUT_TIMER:
        dp_dial_timeout(timerMsg->usrData);
        break;

    case GSM_KPML_INTER_DIGIT_TIMER:
        kpml_inter_digit_timer_callback(timerMsg->usrData);
        break;
    case GSM_KPML_CRITICAL_DIGIT_TIMER:
    case GSM_KPML_EXTRA_DIGIT_TIMER:
        break;

    case GSM_KPML_SUBSCRIPTION_TIMER:
        kpml_subscription_timer_callback(timerMsg->usrData);
        break;

    case GSM_REQ_PENDING_TIMER:
        timeout_msg = fsmdef_feature_timer_timeout(
                          CC_FEATURE_REQ_PEND_TIMER_EXP,
                          timerMsg->usrData);
        break;

    case GSM_RINGBACK_DELAY_TIMER:
        timeout_msg = fsmdef_feature_timer_timeout(
                          CC_FEATURE_RINGBACK_DELAY_TIMER_EXP,
                          timerMsg->usrData);
        break;
    case GSM_FLASH_ONCE_TIMER:
        if (media_timer_callback != NULL) {
            (* ((media_timer_callback_fp)(media_timer_callback)))();
        }
        break;
	case GSM_TONE_DURATION_TIMER:
		lsm_tone_duration_tmr_callback(timerMsg->usrData);
		break;
    default:
        GSM_ERR_MSG(GSM_F_PREFIX"unknown timer %d\n", fname,
                    timerMsg->expiredTimerName);
        break;
    }

    /* 
     * If there is a timer message to be processed by state machine,
     * hands it to GSM state machine here.
     */
    if (timeout_msg != NULL) {
        /* Let state machine handle glare timer expiration */
        gsm_process_msg(GSM_GSM, timeout_msg);
        cprReleaseBuffer(timeout_msg);
    }
}