/** * Bring up the Sipcc stack in service * @return */ cc_return_t CCAPI_Service_start() { if (isServiceStartRequestPending == TRUE) { DEF_DEBUG("CCAPI_Service_start request is already pending. Ignoring this.\n"); return CC_SUCCESS; } DEF_DEBUG("CCAPI_Service_start - \n"); isServiceStartRequestPending = TRUE; registration_processEvent(EV_CC_START); return (CC_SUCCESS); }
/* * Function: ccUnload * * Description: * - deinit portable runtime. * - Cleanup call control modules, GSM and SIp Stack * * Parameters: none * * Returns: none * */ void ccUnload (void) { static const char fname[] = "ccUnload"; DEF_DEBUG(DEB_F_PREFIX"ccUnload called..\n", DEB_F_PREFIX_ARGS(SIP_CC_INIT, fname)); if (platform_initialized == FALSE) { TNP_DEBUG(DEB_F_PREFIX"system is not loaded, ignore unload\n", DEB_F_PREFIX_ARGS(SIP_CC_INIT, fname)); return; } /* * We are going to send an unload msg to each of the thread, which on * receiving the msg, will kill itself. */ send_task_unload_msg(CC_SRC_SIP); send_task_unload_msg(CC_SRC_GSM); if (FALSE == gHardCodeSDPMode) { send_task_unload_msg(CC_SRC_MISC_APP); } send_task_unload_msg(CC_SRC_CCAPP); cprSleep(200); gStopTickTask = TRUE; }
static void fsm_cac_notify_failure (cac_data_t *cac_data) { const char fname[] = "fsm_cac_notify_failure"; cc_setup_t *msg = (cc_setup_t *) cac_data->msg_ptr; cc_msgs_t msg_id = msg->msg_id; callid_t call_id = msg->call_id; line_t line = msg->line; int event_id = msg_id; cc_srcs_t src_id = msg->src_id; /* Notify UI about the failure */ lsm_ui_display_notify_str_index(STR_INDEX_NO_BAND_WIDTH); /* Send response from network side regarding the failure */ if (event_id == CC_MSG_SETUP && src_id == CC_SRC_SIP) { DEF_DEBUG(DEB_F_PREFIX"Send CAC failure to SIP %d.", DEB_F_PREFIX_ARGS("CAC", fname), cac_data->call_id); cc_int_release(CC_SRC_GSM, CC_SRC_SIP, call_id, line, CC_CAUSE_CONGESTION, NULL, NULL); } else { /* If the cac failed, GSM is not spinning yet, so just send the * information to UI in this case. Other case, where GSM receives event * will send the information from GSM. * If the UI is not cleaned up, session infomation is not cleared. */ ui_call_state(evOnHook, line, call_id, CC_CAUSE_CONGESTION); } }
/** * * Check if there are pending CAC requests * * @param call_id request a cac for this call_id * sessions number of sessions in the request * msg ccapi msg, that is held to process * till cac response is received. * * @return CC_CAUSE_BW_OK if the bandwidth is received. * CC_CAUSE_Ok Call returned successfully, not sure about BW yet * CC_CAUSE_ERROR: Call returned with failure. * * @pre (NULL) */ cc_causes_t fsm_cac_call_bandwidth_req (callid_t call_id, uint32_t sessions, void *msg) { const char fname[] = "fsm_cac_call_bandwidth_req"; cac_data_t *cac_data, *cac_pend_data; /* If wlan not connected return OK */ cac_data = fsm_get_new_cac_data(); if (cac_data == NULL) { return(CC_CAUSE_CONGESTION); } cac_data->msg_ptr = msg; cac_data->call_id = call_id; cac_data->cac_state = FSM_CAC_IDLE; cac_data->sessions = sessions; fsm_init_cac_failure_timer(cac_data, CAC_FAILURE_TIMEOUT); /* Make sure there is no pending requests before submitting * another one */ if ((cac_pend_data = fsm_cac_check_if_pending_req()) == NULL) { /* * Make sure sufficient bandwidth available to make a outgoing call. This * should be done before allocating other resources. */ DEF_DEBUG(DEB_F_PREFIX"CAC request for %d sessions %d.", DEB_F_PREFIX_ARGS("CAC", fname), call_id, sessions); if (fsm_cac_process_bw_allocation(cac_data) == CC_CAUSE_CONGESTION) { return(CC_CAUSE_CONGESTION); } cac_data->cac_state = FSM_CAC_REQ_PENDING; } else if (cac_pend_data->cac_state == FSM_CAC_IDLE) { if (fsm_cac_process_bw_allocation(cac_pend_data) == CC_CAUSE_CONGESTION) { /* Clear all remaining data */ fsm_cac_clear_list(); return(CC_CAUSE_CONGESTION); } } (void) sll_append(s_cac_list, cac_data); return(CC_CAUSE_OK); }
/** * * Indicate to the platform that current failover activity * is complete i.e. either success or encountered an error * and that the platform should put the User interaction back * in service. * * @param none * * @return none */ void platform_reg_failover_cfm (void) { static const char fname[] = "platform_reg_failover_cfm"; DEF_DEBUG(DEB_F_PREFIX"***********Failover completed.***********\n", DEB_F_PREFIX_ARGS(PLAT_API, fname)); }
/* * Function: destroy_gsm_thread * Description: shutdown gsm and kill gsm thread * Parameters: none * Returns: none */ void destroy_gsm_thread() { static const char fname[] = "destroy_gsm_thread"; DEF_DEBUG(DEB_F_PREFIX"Unloading GSM and destroying GSM thread\n", DEB_F_PREFIX_ARGS(SIP_CC_INIT, fname)); gsm_shutdown(); dp_shutdown(); (void) cprDestroyThread(gsm_thread); }
/** * API to mute/unmute audio * @param [in] val - TRUE=> mute FALSE => unmute * @return SUCCESS or FAILURE * NOTE: The mute state is persisted within the stack and shall be remembered across hold/resume. * This API doesn't perform the mute operation but simply caches the mute state of the session. */ cc_return_t CCAPI_Call_setAudioMute (cc_call_handle_t handle, cc_boolean val) { unsigned int session_id = ccpro_get_sessionId_by_callid(GET_CALL_ID(handle)); session_data_t * sess_data_p = (session_data_t *)findhash(session_id); DEF_DEBUG(DEB_F_PREFIX": val=%d, handle=%d datap=%p", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI_Call_setAudioMute"), val, handle, sess_data_p); if ( sess_data_p != NULL ) { sess_data_p->audio_mute = val; } return CC_SUCCESS; }
/** * Free the snapshot * @param cc_callinfo_ref_t - refrence to the block to be freed * @return void */ void CCAPI_Call_releaseCallInfo(cc_callinfo_ref_t ref) { if (ref != NULL ) { DEF_DEBUG(DEB_F_PREFIX"ref=%p: count=%d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI_Call_releaseCallInfo"), ref, ref->ref_count); ref->ref_count--; if ( ref->ref_count == 0 ) { cleanSessionData(ref); cpr_free(ref); } } }
/** * * Process time-out event. This cause cac data to send failure notifications. * * @param void *tmr_data - timer data * * @return none * * * @pre (NULL) */ void fsm_cac_process_bw_fail_timer (void *tmr_data) { const char fname[] = "fsm_cac_process_bw_fail_timer"; DEF_DEBUG(DEB_F_PREFIX"CAC request timedout %d.", DEB_F_PREFIX_ARGS("CAC", fname), (callid_t)(long)tmr_data); /* Time-out causes same set of processing as bw failure */ fsm_cac_process_bw_failed_resp(); }
/** * end Consult leg * @param [in] handle - call handle * @return SUCCESS or FAILURE */ cc_return_t CCAPI_Call_endConsultativeCall(cc_call_handle_t handle){ cc_callinfo_ref_t info_handle = CCAPI_Call_getCallInfo(handle); cc_call_attr_t attr = CCAPI_CallInfo_getCallAttr(info_handle); if (attr != CC_ATTR_CONF_CONSULT && attr != CC_ATTR_XFR_CONSULT && attr != CC_ATTR_LOCAL_CONF_CONSULT && attr != CC_ATTR_LOCAL_XFER_CONSULT) { DEF_DEBUG(DEB_F_PREFIX"This method only calls on a consultative call, handle %u", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI_Call_endConsultativeCall"), handle); return CC_FAILURE; } return CC_CallFeature_endConsultativeCall(handle); }
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); }
/** * Indicate to the platform that reg manager intends to fallback to * primary CCM. Currently the fallback_to is always to CC_TYPE_CCM. * * @param fallback_to - type of call control, * e.g. cip_sipcc_CcMgmtConst_CC_TYPE_CCM * * @return none */ void platform_reg_fallback_ind (int fallback_to) { static const char fname[] = "platform_reg_fallback_ind"; feature_update_t msg; DEF_DEBUG(DEB_F_PREFIX"***********Fallback to %d CUCM.***********\n", DEB_F_PREFIX_ARGS(PLAT_API, fname), fallback_to); msg.sessionType = SESSIONTYPE_CALLCONTROL; msg.featureID = CCAPP_FALLBACK_IND; msg.update.ccFeatUpd.data.line_info.info = fallback_to; if ( ccappTaskPostMsg(CCAPP_FALLBACK_IND, &msg, sizeof(feature_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { CCAPP_ERROR(PLT_F_PREFIX"failed to send platform_reg_fallback_ind(%d) msg \n", fname, fallback_to); } }
/** * Send a reset or restart request to the adapter * * @param action - reset or restart * @return none * */ void platform_reset_req (DeviceResetType action) { static const char fname[] = "platform_reset_req"; feature_update_t msg; DEF_DEBUG(DEB_F_PREFIX"***********%s, requested***********\n", DEB_F_PREFIX_ARGS(PLAT_API, fname), (action==1)? "RESET":"RESTART"); msg.sessionType = SESSIONTYPE_CALLCONTROL; msg.featureID = DEVICE_SERVICE_CONTROL_REQ; msg.update.ccFeatUpd.data.reset_type = action; if ( ccappTaskPostMsg(CCAPP_FEATURE_UPDATE, &msg, sizeof(feature_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { CCAPP_DEBUG(DEB_F_PREFIX"failed to send platform_reset_req(%d) msg \n", DEB_F_PREFIX_ARGS(PLAT_API, fname), action); } }
/** * * clears all the entries in the cac list * * @param void * * @return void * * @pre (NULL) */ void fsm_cac_clear_list (void) { const char fname[] = "fsm_cac_clear_list"; cac_data_t *cac_data; cac_data_t *prev_cac_data; DEF_DEBUG(DEB_F_PREFIX"Clear all pending CAC dat.", DEB_F_PREFIX_ARGS("CAC", fname)); cac_data = (cac_data_t *) sll_next(s_cac_list, NULL); while (cac_data != NULL) { prev_cac_data = cac_data; cac_data = (cac_data_t *) sll_next(s_cac_list, cac_data); fsm_cac_notify_failure(prev_cac_data); fsm_clear_cac_data(prev_cac_data); } }
/** * * Check if there are pending CAC requests * * @param none * * @return cac_data returns first pending request. * * @pre (NULL) */ static cc_causes_t fsm_cac_process_bw_allocation (cac_data_t *cac_data) { const char fname[] = "fsm_cac_process_bw_allocation"; if (lsm_allocate_call_bandwidth(cac_data->call_id, cac_data->sessions) == CC_CAUSE_CONGESTION) { DEF_DEBUG(DEB_F_PREFIX"CAC Allocation failed.", DEB_F_PREFIX_ARGS("CAC", fname)); fsm_cac_notify_failure(cac_data); fsm_clear_cac_data(cac_data); return(CC_CAUSE_CONGESTION); } cac_data->cac_state = FSM_CAC_REQ_PENDING; return(CC_CAUSE_OK); }
/** * * Called when the bandwidth response with failed bw is received. This * also process held ccapi messages through fim event chain * * @param none * * @return CC_CAUSE_NO_RESOURCE No bandwidth * CC_CAUSE_OK if ok * * * @pre (NULL) */ cc_causes_t fsm_cac_process_bw_failed_resp (void) { const char fname[] = "fsm_cac_process_bw_avail_resp"; cac_data_t *cac_data = NULL; cac_data_t *next_cac_data = NULL; cac_data = (cac_data_t *) sll_next(s_cac_list, NULL); if (cac_data != NULL) { switch (cac_data->cac_state) { default: case FSM_CAC_IDLE: DEF_DEBUG(DEB_F_PREFIX"No Pending request.", DEB_F_PREFIX_ARGS("CAC", fname)); /* * Make sure sufficient bandwidth available to make a outgoing call. This * should be done before allocating other resources. */ if (fsm_cac_process_bw_allocation(cac_data) == CC_CAUSE_CONGESTION) { sll_remove(s_cac_list, cac_data); return(CC_CAUSE_NO_RESOURCE); } break; case FSM_CAC_REQ_PENDING: next_cac_data = (cac_data_t *) sll_next(s_cac_list, cac_data); sll_remove(s_cac_list, cac_data); /* Request for the next bandwidth */ DEF_DEBUG(DEB_F_PREFIX"Process pending responses even after failure.", DEB_F_PREFIX_ARGS("CAC", fname)); /* Let GSM process completed request */ fsm_cac_notify_failure(cac_data); fsm_clear_cac_data(cac_data); if (next_cac_data != NULL) { /* * Make sure sufficient bandwidth available to make a outgoing call. This * should be done before allocating other resources. */ if (fsm_cac_process_bw_allocation(next_cac_data) == CC_CAUSE_CONGESTION) { /* If the next data was in idle state and the request fialed * then clean up the remaining list */ if (next_cac_data->cac_state == FSM_CAC_IDLE) { /* Clear all remaining data */ fsm_cac_clear_list(); } else { sll_remove(s_cac_list, next_cac_data); } return(CC_CAUSE_NO_RESOURCE); } } break; } } return(CC_CAUSE_NO_RESOURCE); }
/* * Function: notify_ind_cb() * * Parameters: msg_data - the response data provoded by SIP stack. * * Description: is invoked by SIP stack when it receives a NOTIFY message. it takes * action based on subscription_state and blf state derived from event body. * * Returns: void */ static void notify_ind_cb (ccsip_sub_not_data_t * msg_data) { static const char fname[] = "notify_ind_cb"; int sub_state = msg_data->u.notify_ind_data.subscription_state; sip_subs_state_reason_e reason = msg_data->u.notify_ind_data.subscription_state_reason; uint32_t retry_after = msg_data->u.notify_ind_data.retry_after; int request_id = msg_data->request_id; sub_id_t sub_id = msg_data->sub_id; pres_subscription_req_t *sub_req_p; Presence_ext_t *event_body_p = NULL; uint32_t cseq = msg_data->u.notify_ind_data.cseq; int blf_state; BLF_DEBUG(DEB_F_PREFIX"Entering (subscription_state=%d)", DEB_F_PREFIX_ARGS(BLF, fname), sub_state); /* * memory for event bodies is allocated by sip stack and it is the * responsibility of the user (this module) to free it when it is done with it. */ if ((msg_data->u.notify_ind_data.eventData != NULL) && (msg_data->u.notify_ind_data.eventData->type != EVENT_DATA_PRESENCE)) { BLF_ERROR(MISC_F_PREFIX"NOTIFY does not contain presence body", fname); free_event_data(msg_data->u.notify_ind_data.eventData); msg_data->u.notify_ind_data.eventData = NULL; } event_body_p = (msg_data->u.notify_ind_data.eventData == NULL) ? NULL : &(msg_data->u.notify_ind_data.eventData->u.presence_rpid); if ((s_pres_req_list == NULL) || ((sub_req_p = (pres_subscription_req_t *) sll_find(s_pres_req_list, &request_id)) == NULL)) { /* * since we do not have subscription for this, help SIP stack clean up. * first, post SIPSPI_EV_CC_NOTIFY_RESPONSE so that SIP stack sends 481, then * post SIPSPI_EV_CC_SUBSCRIPTION_TERMINATED so that SIP stack cleans up. */ (void) sub_int_notify_ack(sub_id, SIP_CLI_ERR_CALLEG, cseq); (void) sub_int_subscribe_term(sub_id, TRUE, request_id, CC_SUBSCRIPTIONS_PRESENCE); free_event_data(msg_data->u.notify_ind_data.eventData); BLF_DEBUG(DEB_F_PREFIX"Exiting : subscription does not exist", DEB_F_PREFIX_ARGS(BLF, fname)); return; } /* * post SIPSPI_EV_CC_NOTIFY_RESPONSE. */ (void) sub_int_notify_ack(sub_id, SIP_STATUS_SUCCESS, cseq); /* * check if it is out of sequence NOTIFY, if so, do not use the presence state carried in it. */ if (cseq < sub_req_p->highest_cseq) { free_event_data(msg_data->u.notify_ind_data.eventData); BLF_ERROR(MISC_F_PREFIX"Exiting : out of sequence NOTIFY received", fname); return; } else { sub_req_p->highest_cseq = cseq; } /* * If the Subscription_state is terminated, then ... */ if (sub_state == SUBSCRIPTION_STATE_TERMINATED) { /* * post SIPSPI_EV_CC_SUBSCRIPTION_TERMINATED to SIP stack. */ (void) sub_int_subscribe_term(sub_id, TRUE, sub_req_p->request_id, CC_SUBSCRIPTIONS_PRESENCE); if (reason == SUBSCRIPTION_STATE_REASON_DEACTIVATED) { /* if the reason is "decativated", re-subscribe. */ sub_req_p->sub_id = CCSIP_SUBS_INVALID_SUB_ID; sub_req_p->highest_cseq = 0; /* * post SIPSPI_EV_CC_SUBSCRIBE to SIP stack */ if (send_subscribe_ev_to_sip_task(sub_req_p) != CC_RC_SUCCESS) { /* let platform know that we can not continue */ ui_BLF_notification(request_id, CC_SIP_BLF_REJECTED, sub_req_p->app_id); /* * remove the node from the list of subscriptions. */ free_sub_request(sub_req_p); } } else if ((reason == SUBSCRIPTION_STATE_REASON_TIMEOUT) || (reason == SUBSCRIPTION_STATE_REASON_PROBATION) || (reason == SUBSCRIPTION_STATE_REASON_GIVEUP)) { /* let the app know that susbcription expired so that it can resusbcribe later */ ui_BLF_notification(request_id, CC_SIP_BLF_EXPIRED, sub_req_p->app_id); sub_req_p->blf_state = CC_SIP_BLF_EXPIRED; if (sub_req_p->app_id > 0) { /* * Since it is speeddial/blf, we must send a new subscription. */ sub_req_p->sub_id = CCSIP_SUBS_INVALID_SUB_ID; sub_req_p->highest_cseq = 0; if ((reason == SUBSCRIPTION_STATE_REASON_PROBATION) || (reason == SUBSCRIPTION_STATE_REASON_GIVEUP)) { /* * Start a timer based on retry-after value. If retry-after value is 0, * use a default value of 5 sec */ if (retry_after == 0) { retry_after = DEFAULT_RETRY_AFTER_MILLISECS; } else { retry_after = (retry_after * 1000); // converting into millisecs } if ((cprCancelTimer(s_retry_after_timers[sub_req_p->app_id - 1]) == CPR_SUCCESS) && (cprStartTimer(s_retry_after_timers[sub_req_p->app_id - 1], retry_after, (void *) sub_req_p) == CPR_SUCCESS)) { /* * Timer successfully started. free up event data and return. */ free_event_data(msg_data->u.notify_ind_data.eventData); BLF_DEBUG(DEB_F_PREFIX"Exiting : retry_after Timer started", DEB_F_PREFIX_ARGS(BLF, fname)); return; } } if (send_subscribe_ev_to_sip_task(sub_req_p) != CC_RC_SUCCESS) { /* * remove the node from the list of subscriptions. */ free_sub_request(sub_req_p); BLF_ERROR(MISC_F_PREFIX"Unable to send SUBSCRIBE", fname); } BLF_DEBUG(DEB_F_PREFIX"subscribed again after expiration", DEB_F_PREFIX_ARGS(BLF, fname)); } else { /* * and remove the node from the list of subscriptions. */ free_sub_request(sub_req_p); } } else { ui_BLF_notification(request_id, CC_SIP_BLF_REJECTED, sub_req_p->app_id); /* * and remove the node from the list of subscriptions. */ free_sub_request(sub_req_p); } } else { /* derive the BLF state from event data */ blf_state = extract_blf_state(event_body_p, sub_req_p->feature_mask); ui_BLF_notification(request_id, blf_state, sub_req_p->app_id); sub_req_p->blf_state = blf_state; /* * if blf state is ALERTING, * play blf alerting audible tone. */ if (blf_state == CC_SIP_BLF_ALERTING) { /* * Post an event to GSM to play alerting tone. */ cc_feature(CC_SRC_MISC_APP, CC_NO_CALL_ID, 0, CC_FEATURE_BLF_ALERT_TONE, NULL); } DEF_DEBUG(DEB_F_PREFIX"SUB %d: BLF %d", DEB_F_PREFIX_ARGS(BLF_INFO, fname), sub_state, blf_state); } free_event_data(msg_data->u.notify_ind_data.eventData); BLF_DEBUG(DEB_F_PREFIX"Exiting : acted based on subscription state", DEB_F_PREFIX_ARGS(BLF, fname)); return; }
void ccsip_dump_send_msg_info (char *msg, sipMessage_t *pSIPMessage, cpr_ip_addr_t *cc_remote_ipaddr, uint16_t cc_remote_port) { char *disp_buf; const char *req_uri; const char *cseq; const char *callid; char ipaddr_str[MAX_IPADDR_STR_LEN]; static const char fname[] = "ccsip_dump_send_msg_info"; ipaddr2dotted(ipaddr_str, cc_remote_ipaddr); req_uri = sippmh_get_header_val(pSIPMessage, SIP_HEADER_TO, NULL); if (req_uri == NULL) { /* No REQ URI, fill with blank */ req_uri = ""; } cseq = sippmh_get_header_val(pSIPMessage, SIP_HEADER_CSEQ, NULL); if (cseq == NULL) { /* No REQ CSEQ, fill with blank */ cseq = ""; } callid = sippmh_get_header_val(pSIPMessage, SIP_HEADER_CALLID, NULL); if (callid == NULL) { /* No REQ CSEQ, fill with blank */ callid = ""; } /* For messages starting with SIP add 8 byte. default * debugs do not show all the SIP message information * rather show initial msg. */ if (msg != NULL) { if (msg[0] == 'S' && msg[1] == 'I' && msg[2] == 'P') { disp_buf = &msg[8]; } else { disp_buf = msg; } if ((strncmp(disp_buf, SIP_METHOD_REGISTER, sizeof(SIP_METHOD_REGISTER)-1) == 0) && (!dump_reg_msg)) { return; } } else { /* No msg. buffer */ disp_buf = NULL; } if (disp_buf != NULL) { DEF_DEBUG(DEB_F_PREFIX"<%s:%-4d>:%c%c%c%c%c%c%c: %-10s :%-6s::%s\n", DEB_F_PREFIX_ARGS(SIP_MSG_SEND, fname), ipaddr_str, cc_remote_port, disp_buf[0], disp_buf[1], disp_buf[2], disp_buf[3], disp_buf[4], disp_buf[5], disp_buf[6], req_uri, cseq, callid); } else { /* No msg to send */ DEF_DEBUG(DEB_F_PREFIX"<%s:%-4d>: empty message\n", DEB_F_PREFIX_ARGS(SIP_MSG_SEND, fname), ipaddr_str, cc_remote_port); } }
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; }
/** * map the VCM RTP enums to MS format payload enums * @param [in] ptype: payload type * @param [in] dynamic_ptype_value : dynamic payload * @param [in] mode for some codecs * @return Corresponding MS payload type */ vcm_media_payload_type_t vcmRtpToMediaPayload (int32_t ptype, int32_t dynamic_ptype_value, uint16_t mode) { vcm_media_payload_type_t type = VCM_Media_Payload_G711Ulaw64k; const char fname[] = "vcm_rtp_to_media_payload"; DEF_DEBUG(DEB_F_PREFIX"%d: %d: %d\n", DEB_F_PREFIX_ARGS(MED_API, fname), ptype, dynamic_ptype_value, mode); switch (ptype) { case RTP_PCMU: type = VCM_Media_Payload_G711Ulaw64k; break; case RTP_PCMA: type = VCM_Media_Payload_G711Alaw64k; break; case RTP_G729: type = VCM_Media_Payload_G729; break; case RTP_L16: type = CREATE_MT_MAP(dynamic_ptype_value, VCM_Media_Payload_Wide_Band_256k); break; case RTP_G722: type = VCM_Media_Payload_G722_64k; break; case RTP_ILBC: if (mode == SIPSDP_ILBC_MODE20) { type = CREATE_MT_MAP(dynamic_ptype_value, VCM_Media_Payload_ILBC20); } else { type = CREATE_MT_MAP(dynamic_ptype_value, VCM_Media_Payload_ILBC30); } break; case RTP_ISAC: type = CREATE_MT_MAP(dynamic_ptype_value, VCM_Media_Payload_ISAC); break; case RTP_H263: type = CREATE_MT_MAP(dynamic_ptype_value, VCM_Media_Payload_H263); break; case RTP_H264_P0: case RTP_H264_P1: type = CREATE_MT_MAP(dynamic_ptype_value, VCM_Media_Payload_H264); break; case RTP_VP8: type = CREATE_MT_MAP(dynamic_ptype_value, VCM_Media_Payload_VP8); break; case RTP_OPUS: type = CREATE_MT_MAP(dynamic_ptype_value, VCM_Media_Payload_OPUS); break; default: type = VCM_Media_Payload_NonStandard; err_msg(DEB_F_PREFIX "Can not map payload type=%d\n", DEB_F_PREFIX_ARGS(MED_API, fname), ptype); } return type; }
/* * 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; } }
/* * Function: send_task_unload_msg * * Description: * - send shutdown and thread destroy msg to sip, gsm, ccapp, misc * threads * Parameters: destination thread * * Returns: none * */ void send_task_unload_msg(cc_srcs_t dest_id) { const char *fname = "send_task_unload_msg"; uint16_t len = 4; cprBuffer_t msg = gsm_get_buffer(len); int sdpmode = 0; config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); if (msg == NULL) { err_msg("%s: failed to allocate msg cprBuffer_t\n", fname); return; } DEF_DEBUG(DEB_F_PREFIX"send Unload message to %s task ..\n", DEB_F_PREFIX_ARGS(SIP_CC_INIT, fname), dest_id == CC_SRC_SIP ? "SIP" : dest_id == CC_SRC_GSM ? "GSM" : dest_id == CC_SRC_MISC_APP ? "Misc App" : dest_id == CC_SRC_CCAPP ? "CCApp" : "Unknown"); switch(dest_id) { case CC_SRC_SIP: { /* send this msg so phone can send unRegister msg */ SIPTaskPostShutdown(SIP_EXTERNAL, CC_CAUSE_SHUTDOWN, ""); /* allow unRegister msg to sent out and shutdown to complete */ if (!sdpmode) { cprSleep(2000); } /* send a unload message to the SIP Task to kill sip thread*/ msg = SIPTaskGetBuffer(len); if (msg == NULL) { err_msg("%s:%d: failed to allocate sip msg buffer\n", fname); return; } if (SIPTaskSendMsg(THREAD_UNLOAD, (cprBuffer_t)msg, len, NULL) == CPR_FAILURE) { cpr_free(msg); err_msg("%s: Unable to send THREAD_UNLOAD msg to sip thread", fname); } } break; case CC_SRC_GSM: { msg = gsm_get_buffer(len); if (msg == NULL) { err_msg("%s: failed to allocate gsm msg cprBuffer_t\n", fname); return; } if (CPR_FAILURE == gsm_send_msg(THREAD_UNLOAD, msg, len)) { err_msg("%s: Unable to send THREAD_UNLOAD msg to gsm thread", fname); } } break; case CC_SRC_MISC_APP: { msg = cpr_malloc(len); if (msg == NULL) { err_msg("%s: failed to allocate misc msg cprBuffer_t\n", fname); return; } if (CPR_FAILURE == MiscAppTaskSendMsg(THREAD_UNLOAD, msg, len)) { err_msg("%s: Unable to send THREAD_UNLOAD msg to Misc App thread", fname); } } break; case CC_SRC_CCAPP: { msg = cpr_malloc(len); if (msg == NULL) { err_msg("%s: failed to allocate ccapp msg cprBuffer_t\n", fname); return; } if (ccappTaskPostMsg(CCAPP_THREAD_UNLOAD, msg, len, CCAPP_CCPROVIER) == CPR_FAILURE ) { err_msg("%s: Unable to send THREAD_UNLOAD msg to CCapp thread", fname); } err_msg("%s: send UNLOAD msg to CCapp thread good", fname); } break; default: err_msg("%s: Unknown destination task passed=%d.", fname, dest_id); break; } }
/* * Function: get_state() * * Parameters: request_id - unique id assigned by the platform to this subscription. Platform * uses this to track the status updates and to make subsequent termination * request. * duration - how long the subscription is requested to be valid. * watcher - entity that is requesting the presence state. * presentity - entity whose presence state is requested. * app_id - application that is making the subscription. * 0: indicates call list blf application. * 1..n: indicates the speeddial/blf associated with (1..n)th line button. * feature_mask - indicates the additional features enabled. * * Description: is invoked by platform side whenever it needs to susbcribe * for presence state of a presentity. This stores the susbcription * data in a linked list and posts SIPSPI_EV_CC_SUBSCRIBE * to SIP stack. We need to store the subscription data so that * SUBSCRIBE response and NOTIFYs can be mapped to subscriptions. * * Returns: void */ static void get_state (int request_id, int duration, const char *watcher, const char *presentity, int app_id, int feature_mask) { static const char fname[] = "get_state"; pres_subscription_req_t *sub_req_p; DEF_DEBUG(DEB_F_PREFIX"REQ %d: TM %d: WTR %s: PRT %s: FMSK %d: APP %d", DEB_F_PREFIX_ARGS(BLF_INFO, fname), request_id, duration, watcher, presentity, feature_mask, app_id); /* * if there is no subscription list yet, create one. */ if (s_pres_req_list == NULL) { s_pres_req_list = sll_create(find_matching_node); if (s_pres_req_list == NULL) { /* let platform know that we can not continue */ ui_BLF_notification(request_id, CC_SIP_BLF_REJECTED, app_id); BLF_ERROR(MISC_F_PREFIX"Exiting : request list creation failed", fname); return; } } /* * check if a request is already created by walking through the list. if not, create one. */ if ((sub_req_p = (pres_subscription_req_t *) sll_find(s_pres_req_list, &request_id)) == NULL) { /* * populate subscription request and append it to the list. */ sub_req_p = (pres_subscription_req_t *) cpr_malloc(sizeof(pres_subscription_req_t)); if (sub_req_p == NULL) { BLF_ERROR(MISC_F_PREFIX"Exiting : malloc failed", fname); return; } sub_req_p->request_id = request_id; sub_req_p->sub_id = CCSIP_SUBS_INVALID_SUB_ID; sub_req_p->highest_cseq = 0; sub_req_p->duration = duration; sstrncpy(sub_req_p->presentity, presentity, CC_MAX_DIALSTRING_LEN); sstrncpy(sub_req_p->watcher, watcher, CC_MAX_DIALSTRING_LEN); sub_req_p->app_id = app_id; sub_req_p->feature_mask = feature_mask; sub_req_p->blf_state = CC_SIP_BLF_UNKNOWN; (void) sll_append(s_pres_req_list, sub_req_p); } else { /* already exists. just update the duration */ sub_req_p->duration = duration; } /* * post SIPSPI_EV_CC_SUBSCRIBE to SIP stack */ if (send_subscribe_ev_to_sip_task(sub_req_p) != CC_RC_SUCCESS) { /* * remove the node from the list of subscriptions. */ free_sub_request(sub_req_p); /* let platform know that we can not continue */ ui_BLF_notification(request_id, CC_SIP_BLF_REJECTED, app_id); BLF_ERROR(MISC_F_PREFIX"Exiting : Unable to send SUBSCRIBE", fname); return; } BLF_DEBUG(DEB_F_PREFIX"Exiting : request made successfully", DEB_F_PREFIX_ARGS(BLF, fname)); return; }
void ccsip_dump_recv_msg_info (sipMessage_t *pSIPMessage, cpr_ip_addr_t *cc_remote_ipaddr, uint16_t cc_remote_port) { char *disp_buf; const char *req_uri; const char *cseq; const char *callid; char ipaddr_str[MAX_IPADDR_STR_LEN]; cpr_ip_addr_t cc_ipaddr; static const char fname[] = "ccsip_dump_recv_msg_info"; util_ntohl(&cc_ipaddr, cc_remote_ipaddr); ipaddr2dotted(ipaddr_str, &cc_ipaddr); req_uri = sippmh_get_cached_header_val(pSIPMessage, FROM); if (req_uri == NULL) { /* No REQ URI, fill with blank */ req_uri = ""; } cseq = sippmh_get_cached_header_val(pSIPMessage, CSEQ); if (cseq == NULL) { /* No REQ CSEQ, fill with blank */ cseq = ""; } callid = sippmh_get_cached_header_val(pSIPMessage, CALLID); if (callid == NULL) { /* No REQ CSEQ, fill with blank */ callid = ""; } if (!dump_reg_msg) { if (strstr(cseq, SIP_METHOD_REGISTER) != NULL) { return; } } /* For messages starting with SIP add 8 byte. default * debugs do not show all the SIP message information * rather show initial msg. */ if (pSIPMessage->mesg_line != NULL) { if (pSIPMessage->mesg_line[0] == 'S' && pSIPMessage->mesg_line[1] == 'I' && pSIPMessage->mesg_line[2] == 'P') { disp_buf = &(pSIPMessage->mesg_line[8]); } else { disp_buf = pSIPMessage->mesg_line; } } else { /* * It is possible that this function is called with * invalid message or partially received. */ disp_buf = NULL; } if (disp_buf != NULL) { DEF_DEBUG(DEB_F_PREFIX"<%s:%-4d>:%c%c%c%c%c%c%c: %-10s :%-6s::%s\n", DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname), ipaddr_str, cc_remote_port, disp_buf[0], disp_buf[1], disp_buf[2], disp_buf[3], disp_buf[4], disp_buf[5], disp_buf[6], req_uri, cseq, callid); } else { /* No line received */ DEF_DEBUG(DEB_F_PREFIX"<%s:%-4d>: empty message\n", DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname), ipaddr_str, cc_remote_port); } }