/** * This function will process SUBSCRIBED feature NOTIFY messages. * * @param[in] cmd - command * @param[in] msg - pointer to ccsip_sub_not_data_t * * @return none * * @pre (msg != NULL) */ static void sub_process_feature_msg (uint32_t cmd, void *msg) { callid_t call_id; cc_feature_ack_t temp_msg; switch (cmd) { case SUB_MSG_FEATURE_SUBSCRIBE_RESP: /* * if the response in non-2xx final, we should reset the active feature. */ call_id = (callid_t)(((ccsip_sub_not_data_t *)msg)->request_id); if (((ccsip_sub_not_data_t *)msg)->u.subs_result_data.status_code > 299) { 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); } break; case SUB_MSG_FEATURE_NOTIFY: call_id = (callid_t)(((ccsip_sub_not_data_t *)msg)->request_id); sub_process_feature_notify((ccsip_sub_not_data_t *)msg, call_id, CC_NO_CALL_ID); break; case SUB_MSG_FEATURE_TERMINATE: /* * This is posted by SIP stack if it is shutting down or rolling over. * if so, sip stack already cleaned up the subscription. so do nothing. */ break; } }
boolean gsm_process_msg (uint32_t cmd, void *msg) { static const char fname[] = "gsm_process_msg"; boolean release_msg = TRUE; cc_msgs_t msg_id = ((cc_setup_t *)msg)->msg_id; int event_id = msg_id; GSM_DEBUG(DEB_F_PREFIX"cmd= 0x%x\n", DEB_F_PREFIX_ARGS(GSM, fname), cmd); switch (cmd) { case GSM_GSM: case GSM_SIP: if (gsm_initialized) { if (event_id == CC_MSG_FEATURE && (((cc_feature_t *) msg)->feature_id == CC_FEATURE_CAC_RESP_PASS)) { fsm_cac_process_bw_avail_resp (); /* Release all memory for CC_FEATURE_CAC_..message */ release_msg = TRUE; GSM_DEBUG(DEB_F_PREFIX"CAC Message Processed: 0x%x\n", DEB_F_PREFIX_ARGS(GSM, fname), cmd); } else if (event_id == CC_MSG_FEATURE && (((cc_feature_t *) msg)->feature_id == CC_FEATURE_CAC_RESP_FAIL)) { fsm_cac_process_bw_failed_resp (); /* Release all memory for CC_FEATURE_CAC_..message */ release_msg = TRUE; GSM_DEBUG(DEB_F_PREFIX"CAC Message Processed: 0x%x\n", DEB_F_PREFIX_ARGS(GSM, fname), cmd); } else { release_msg = fim_process_event(msg, FALSE); GSM_DEBUG(DEB_F_PREFIX"Message Processed: 0x%x\n", DEB_F_PREFIX_ARGS(GSM, fname), cmd); } } if (release_msg == TRUE) { fim_free_event(msg); } break; default: GSM_DEBUG(DEB_F_PREFIX"Unknown Cmd received: 0x%x\n", DEB_F_PREFIX_ARGS(GSM, fname), cmd); break; } return(release_msg); }
/** * 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); }
cc_causes_t fsm_cac_process_bw_avail_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 CAC 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 %d.", DEB_F_PREFIX_ARGS("CAC", fname), cac_data->call_id); /* Let GSM process completed request */ fim_process_event(cac_data->msg_ptr, TRUE); 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. */ DEF_DEBUG(DEB_F_PREFIX"Requesting next allocation %d.", DEB_F_PREFIX_ARGS("CAC", fname), next_cac_data->call_id); 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); }