/**
 * 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);
    }
}
示例#3
0
文件: gsm.c 项目: AsherBond/ikran
/**
 * 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;
}
示例#5
0
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);
}