/** * This function will find the matching feature keys. * * @param[in] presentity - pointer to presentity * @param[in] event_body_p - pointer to presense body * * @return TRUE/FALSE * * @pre (presentity != NULL) */ static boolean apply_presence_state_to_matching_feature_keys (char *presentity, Presence_ext_t *event_body_p) { pres_subscription_req_t *sub_req_p; int blf_state; boolean match_found = FALSE; sub_req_p = (pres_subscription_req_t *)sll_next(s_pres_req_list, NULL); while (sub_req_p != NULL) { /* apply the state to all the entries whose presentity matches */ if ((sub_req_p->app_id > 0) && (strncmp(sub_req_p->presentity, presentity, CC_MAX_DIALSTRING_LEN - 1) == 0)) { match_found = TRUE; /* derive the BLF state from event data */ blf_state = extract_blf_state(event_body_p, sub_req_p->feature_mask); ui_BLF_notification(sub_req_p->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); } } sub_req_p = (pres_subscription_req_t *)sll_next(s_pres_req_list, sub_req_p); } return match_found; }
/** * This function will post an event - CC_FEATURE_BLF_ALERT_TONE - to GSM task if * there is an entry in BLF_ALERTING state. * * @param[in] none * * @return none */ void pres_play_blf_audible_alert (void) { pres_subscription_req_t *sub_req_p; sub_req_p = (pres_subscription_req_t *)sll_next(s_pres_req_list, NULL); while (sub_req_p != NULL) { if ((sub_req_p->app_id > 0) && (sub_req_p->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); break; } sub_req_p = (pres_subscription_req_t *)sll_next(s_pres_req_list, sub_req_p); } }
/** * This function will process b2bcnf 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_b2bcnf_msg (uint32_t cmd, void *msg) { static const char fname[] = "sub_process_b2bcnf_msg"; cc_feature_data_t data; callid_t call_id, other_call_id = CC_NO_CALL_ID; fsmb2bcnf_get_sub_call_id_from_ccb((fsmcnf_ccb_t *)((ccsip_sub_not_data_t *)msg)->request_id, &call_id, &other_call_id); switch (cmd) { case SUB_MSG_B2BCNF_SUBSCRIBE_RESP: GSM_DEBUG(DEB_F_PREFIX"B2BCNF subs response\n", DEB_F_PREFIX_ARGS(GSM,fname)); sub_process_b2bcnf_sub_resp((ccsip_sub_not_data_t *)msg); break; case SUB_MSG_B2BCNF_NOTIFY: GSM_DEBUG(DEB_F_PREFIX"B2BCNF subs notify\n", DEB_F_PREFIX_ARGS(GSM,fname)); sub_process_feature_notify((ccsip_sub_not_data_t *)msg, call_id, other_call_id); break; case SUB_MSG_B2BCNF_TERMINATE: /* * This is posted by SIP stack if it is shutting down or rolling over. * if so, notify b2bcnf to cleanup state machine. */ GSM_DEBUG(DEB_F_PREFIX"B2BCNF subs terminate\n", DEB_F_PREFIX_ARGS(GSM,fname)); data.notify.subscription = CC_SUBSCRIPTIONS_REMOTECC; data.notify.method = CC_RCC_METHOD_REFER; data.notify.data.rcc.feature = CC_FEATURE_B2BCONF; data.notify.cause = CC_CAUSE_ERROR; cc_feature(CC_SRC_GSM, call_id, 0, CC_FEATURE_NOTIFY, &data); break; default: GSM_DEBUG(DEB_F_PREFIX"B2BCNF subs unknown event\n", DEB_F_PREFIX_ARGS(GSM,fname)); break; } }
/* * 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 sip_cc_feature (callid_t call_id, line_t line, cc_features_t feature, void *data) { cc_feature(CC_SRC_SIP, call_id, line, feature, (cc_feature_data_t *)data); }