예제 #1
0
/*
 *  Function: terminate_req_all()
 *
 *  Parameters: none.
 *
 *  Description:  terminates all out standing subscriptions
 *
 *  Returns: void
 */
static void
terminate_req_all (void)
{
    static const char fname[] = "terminate_req_all";
    pres_subscription_req_t *sub_req_p;

    BLF_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(BLF, fname));
    if (s_pres_req_list == NULL) {
        BLF_DEBUG(DEB_F_PREFIX"Exiting : no outstanding requests", DEB_F_PREFIX_ARGS(BLF, fname));
        return;
    }

    while ((sub_req_p = (pres_subscription_req_t *)
                sll_next(s_pres_req_list, NULL)) != NULL) {
        /*
         * post SIPSPI_EV_CC_SUBSCRIPTION_TERMINATED so that SIP stack cleans up.
         */
        (void) sub_int_subscribe_term(sub_req_p->sub_id, TRUE,
                                      sub_req_p->request_id,
                                      CC_SUBSCRIPTIONS_PRESENCE);

        /*
         * and remove the node from the list of subscriptions.
         */
        free_sub_request(sub_req_p);
    }
    /*
     * this function call indicates the subscription handler is going
     * out of service, set s_subs_hndlr_initialized to FALSE.
     */
    s_subs_hndlr_initialized = FALSE;
    BLF_DEBUG(DEB_F_PREFIX"Exiting", DEB_F_PREFIX_ARGS(BLF, fname));
}
예제 #2
0
파일: gsm.c 프로젝트: AsherBond/ikran
/**
 * 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);
}
예제 #3
0
/*
 *  Function: terminate_req()
 *
 *  Parameters: request_id - unique id of the subscription which needs to be terminated.
 *
 *  Description:  is invoked by platform to terminate a subscription.
 *                First, it posts SIPSPI_EV_CC_SUBSCRIBE to SIP stack with duration = 0.
 *                and then, it posts SIPSPI_EV_CC_SUBSCRIPTION_TERMINATED to SIP stack.
 *
 *  Returns: void
 */
static void
terminate_req (int request_id)
{
    static const char fname[] = "terminate_req";
    pres_subscription_req_t *sub_req_p;

    BLF_DEBUG(DEB_F_PREFIX"Entering (request_id=%d)",
              DEB_F_PREFIX_ARGS(BLF, fname), request_id);

    /*
     * check if the request exists.
     */
    if ((sub_req_p = (pres_subscription_req_t *)
                sll_find(s_pres_req_list, &request_id)) == NULL) {
        BLF_ERROR(MISC_F_PREFIX"request does not exist in the list", fname);
        return;
    }

    /*
     * post SIPSPI_EV_CC_SUBSCRIBE to SIP stack with duration = 0
     */
    sub_req_p->duration = 0;
    /*
     * no point in checking return value of the subsmanager_handle_ev_app_subscribe()
     * because we are terminating the request anyway.
     */
    (void) send_subscribe_ev_to_sip_task(sub_req_p);

    /*
     * 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(sub_req_p->sub_id, FALSE,
                                  sub_req_p->request_id,
                                  CC_SUBSCRIPTIONS_PRESENCE);

    /*
     * and remove the node from the list of subscriptions.
     */
    free_sub_request(sub_req_p);

    BLF_DEBUG(DEB_F_PREFIX"Exiting : request terminated", DEB_F_PREFIX_ARGS(BLF, fname));
    return;
}
예제 #4
0
void
configapp_process_request (ccsip_sub_not_data_t *msg)
{
    static const char fname[] = "configapp_process_request";
    ConfigApp_req_data_t *configdata;

    configdata = &(msg->u.subs_ind_data.eventData->u.configapp_data);

    update_kpmlconfig(configdata->sip_profile.kpml_val);
    CONFIGAPP_DEBUG(DEB_F_PREFIX"Updated kpml config value to %d.",
                           DEB_F_PREFIX_ARGS(CONFIG_APP, fname),
                           configdata->sip_profile.kpml_val);

    (void)sub_int_subscribe_ack(CC_SRC_MISC_APP, CC_SRC_SIP, msg->sub_id,
                                (uint16_t)SIP_SUCCESS_SETUP, 0);

    (void)sub_int_subscribe_term(msg->sub_id, TRUE, 0, CC_SUBSCRIPTIONS_CONFIGAPP);
    configapp_free_event_data(msg->u.subs_ind_data.eventData);
    return;
}
예제 #5
0
/*
 *  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;
}
예제 #6
0
/*
 *  Function: subscribe_response_ind()
 *
 *  Parameters: msg_data - the response data provoded by SIP stack.
 *
 *  Description: is invoked by SIP stack when it receives a response message for
 *               the SUBSCRIBE it sent out. For most of non-2xx final responses,
 *               it posts SIPSPI_EV_CC_SUBSCRIPTION_TERMINATED to SIP stack and
 *               lets the platform know that the subscription is rejected.
 *               if the resp is 423 (interval too short), then resends the subscription
 *               with double the previous duaration.
 *
 *  Returns: void
 */
static void
subscribe_response_ind (ccsip_sub_not_data_t *msg_data)
{
    static const char fname[] = "subscribe_response_ind";
    int status_code = msg_data->u.subs_result_data.status_code;
    int request_id = msg_data->request_id;
    sub_id_t sub_id = msg_data->sub_id;
    pres_subscription_req_t *sub_req_p;

    BLF_DEBUG(DEB_F_PREFIX"Entering (status_code=%d)",
              DEB_F_PREFIX_ARGS(BLF, fname), status_code);

    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.
         * post SIPSPI_EV_CC_SUBSCRIPTION_TERMINATED so that SIP stack cleans up.
         */
        (void) sub_int_subscribe_term(sub_id, TRUE, request_id,
                                      CC_SUBSCRIPTIONS_PRESENCE);
        BLF_DEBUG(DEB_F_PREFIX"Exiting : subscription does not exist", DEB_F_PREFIX_ARGS(BLF, fname));
        return;
    }

    /*
     * note sub_id so that sub_id will be used in the subsequent interaction with SIP stack
     */
    sub_req_p->sub_id = sub_id;

    /*
     * If the status_code is 1xx or 2xx, then do nothing.
     */
    if ((status_code >= 100) && (status_code < 300)) {
        /* do nothing */
        BLF_DEBUG(DEB_F_PREFIX"Exiting :100-299 response", DEB_F_PREFIX_ARGS(BLF, fname));
        return;
    }

    /*
     * If the status_code is 423 (interval too short), resend with the new duration.
     */
    if (status_code == SIP_CLI_ERR_INTERVAL_TOO_SMALL) {
        sub_req_p->duration = msg_data->u.subs_result_data.expires;
        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);
            BLF_ERROR(MISC_F_PREFIX"Exiting : Unable to send SUBSCRIBE", fname);
            return;
        }
        BLF_DEBUG(DEB_F_PREFIX"Exiting : subscribed again with double duration", DEB_F_PREFIX_ARGS(BLF, fname));
        return;
    }

    /*
     * if the status_code is 481 (sub does not exist) and the app_id is non-zero (sppeddial/blf),
     * terminate the existing one and send a new subscription.
     */
    if ((status_code == SIP_CLI_ERR_CALLEG) && (sub_req_p->app_id > 0)) {
        ui_BLF_notification(request_id, CC_SIP_BLF_UNKNOWN, sub_req_p->app_id); /* until we get the current status */
        sub_req_p->blf_state = CC_SIP_BLF_UNKNOWN;
        /*
         * post SIPSPI_EV_CC_SUBSCRIPTION_TERMINATED so that SIP stack cleans up.
         */
        (void) sub_int_subscribe_term(sub_req_p->sub_id, TRUE,
                                      sub_req_p->request_id,
                                      CC_SUBSCRIPTIONS_PRESENCE);
        /*
         * send a new subscription
         */
        sub_req_p->sub_id = CCSIP_SUBS_INVALID_SUB_ID;
        sub_req_p->highest_cseq = 0;
        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);
            BLF_ERROR(MISC_F_PREFIX"Exiting : Unable to send SUBSCRIBE", fname);
            return;
        }
        BLF_DEBUG(DEB_F_PREFIX"Exiting : subscribed again after receiving 481", DEB_F_PREFIX_ARGS(BLF, fname));
        return;
    }

    /*
     * If the status_code is 481 (sub does not exist) and app_id is zero, terminate the subscription
     * so that platform can make a new subscription.
     * if the status_code is 403/603(forbidden), 489(Bad event), 401(Unauthorized) or
     * any uninterested code, then update the presence/BLF state as REJECTED.
     */
    ui_BLF_notification(request_id, CC_SIP_BLF_REJECTED, sub_req_p->app_id);
    /*
     * post SIPSPI_EV_CC_SUBSCRIPTION_TERMINATED so that SIP stack cleans up.
     */
    (void) sub_int_subscribe_term(sub_req_p->sub_id, TRUE,
                                  sub_req_p->request_id,
                                  CC_SUBSCRIPTIONS_PRESENCE);

    /*
     * and remove the node from the list of subscriptions.
     */
    free_sub_request(sub_req_p);

    BLF_DEBUG(DEB_F_PREFIX"Exiting : request terminated", DEB_F_PREFIX_ARGS(BLF, fname));
    return;
}
예제 #7
0
/*
 *  Function: terminate_cb()
 *
 *  Parameters: msg_data - the response data provoded by SIP stack.
 *
 *  Description:  is invoked by SIP stack when it needs to terminate a subscription because of
 *                some reason (failover, shutdown, etc). if the reason is shutdown, rollover, etc,
 *                we will terminate the subscription. Platform will resubscribe later if it is a failover/fallback.
 *                if it is a protocol error such as wrong header/wrong body, then terminate the subscription
 *                and resubscribe immediately.
 *
 *  Returns: void
 */
static void
terminate_cb (ccsip_sub_not_data_t *msg_data)
{
    static const char fname[] = "terminate_cb";
    ccsip_reason_code_e reason_code = msg_data->reason_code;
    int status_code = msg_data->u.subs_term_data.status_code;
    int request_id = msg_data->request_id;
    sub_id_t sub_id = msg_data->sub_id;
    pres_subscription_req_t *sub_req_p = NULL;
    int orig_duration = 0;

    BLF_DEBUG(DEB_F_PREFIX"Entering (reason_code=%d, status_code=%d)",
              DEB_F_PREFIX_ARGS(BLF, fname), reason_code, status_code);

    if (s_pres_req_list != NULL) {
        sub_req_p = (pres_subscription_req_t *)
            sll_find(s_pres_req_list, &request_id);
    }
    if (sub_req_p == NULL) {
        /*
         * we are not aware of any such subcription. So
         * post SIPSPI_EV_CC_SUBSCRIPTION_TERMINATED so that SIP stack cleans up.
         */
        (void) sub_int_subscribe_term(sub_id, TRUE, request_id,
                                      CC_SUBSCRIPTIONS_PRESENCE);
        BLF_DEBUG(DEB_F_PREFIX"Exiting : subscription does not exist", DEB_F_PREFIX_ARGS(BLF, fname));
        return;
    }

    orig_duration = sub_req_p->duration;
    if (reason_code == SM_REASON_CODE_ERROR) { // protocol error
        /*
         * Send a terminating SUBSCRIBE (expires=0) to make sure other end terminates the subscription
         */
        sub_req_p->duration = 0;
        /*
         * no point in checking return value of the subsmanager_handle_ev_app_subscribe()
         * because we are terminating the subscription anyway.
         */
        (void) send_subscribe_ev_to_sip_task(sub_req_p);
    }
    /*
     * post SIPSPI_EV_CC_SUBSCRIPTION_TERMINATED so that SIP stack cleans up.
     * In case of SM_REASON_CODE_RESET_REG, SM_REASON_CODE_ROLLOVER & SM_REASON_CODE_SHUTDOWN,
     * SIP stack already cleaned up SCB.
     */
    if ((reason_code != SM_REASON_CODE_RESET_REG) &&
        (reason_code != SM_REASON_CODE_ROLLOVER) &&
        (reason_code != SM_REASON_CODE_SHUTDOWN)) {
        (void) sub_int_subscribe_term(sub_id, TRUE, request_id,
                                  CC_SUBSCRIPTIONS_PRESENCE);
    }

    /* let platform know that the current state is UNKNOWN */
    ui_BLF_notification(request_id, CC_SIP_BLF_UNKNOWN, sub_req_p->app_id);

    if ((reason_code == SM_REASON_CODE_ERROR) ||
        (reason_code == SM_REASON_CODE_RESET_REG)) {
        /*
         * send a new subscription
         */
        sub_req_p->sub_id = CCSIP_SUBS_INVALID_SUB_ID;
        sub_req_p->highest_cseq = 0;
        sub_req_p->duration = orig_duration;
        (void) send_subscribe_ev_to_sip_task(sub_req_p);
    } else {
        /*
         * remove the node from the list of subscriptions because we may be shutting down/rolling over.
         */
        free_sub_request(sub_req_p);
    }

    BLF_DEBUG(DEB_F_PREFIX"Exiting : terminated subscription", DEB_F_PREFIX_ARGS(BLF, fname));
    return;
}