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); }
/** * 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); }
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; }
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(); } } }
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); } }