Ejemplo n.º 1
0
/**
 * This function will append presence notification to the pending queue.
 *
 * @param[in] event_data_p - pointer to event data.
 *
 * @return none.
 *
 * @pre (event_data_p != NULL)
 */
static void append_notification_to_pending_queue (ccsip_event_data_t *event_data_p)
{
    static const char fname[] = "append_notification_to_pending_queue";
    pres_pending_notify_t *pending_notify_p;
    Presence_ext_t *event_body_p = &(event_data_p->u.presence_rpid);

    /*
     * create pending list if it is not created yet.
     */
    if (s_pending_notify_list == NULL) {
        s_pending_notify_list = sll_create(NULL);
        if (s_pending_notify_list == NULL) {
            CSFLogError("src-common", "MSC: 0/0: %s: out of memory", fname);
            free_event_data(event_data_p);
            return;
        }
    }

    pending_notify_p = (pres_pending_notify_t *)sll_next(s_pending_notify_list, NULL);
    while (pending_notify_p != NULL) {
        if (strncmp(pending_notify_p->presentity, event_body_p->presence_body.entity,
                    CC_MAX_DIALSTRING_LEN - 1) == 0) {
            /* replace the current state with new state */
            free_event_data(pending_notify_p->event_data_p);
            pending_notify_p->event_data_p = event_data_p;
            return;
        }
        pending_notify_p = (pres_pending_notify_t *)sll_next(s_pending_notify_list,
                                                             pending_notify_p);
    }

    /*
     * To protect from DoS attacks, do not allow more than
     * MAX_REG_LINES entries in the list.
     */
    if (sll_count(s_pending_notify_list) == MAX_REG_LINES) {
        CSFLogError("src-common", "MSC: 0/0: %s: ignoring the NOTIFY "
            "to protect from DoS attack", fname);
        free_event_data(event_data_p);
        return;
    }
    pending_notify_p = (pres_pending_notify_t *)
                       cpr_malloc(sizeof(pres_pending_notify_t));
    if (pending_notify_p == NULL) {
        CSFLogError("src-common", "MSC: 0/0: %s: out of memory", fname);
        free_event_data(event_data_p);
        return;
    }
    sstrncpy(pending_notify_p->presentity, event_body_p->presence_body.entity,
             CC_MAX_DIALSTRING_LEN);
    pending_notify_p->event_data_p = event_data_p;
    (void) sll_append(s_pending_notify_list, pending_notify_p);
    return;
}
Ejemplo n.º 2
0
/**
 * This function will process if there are any pending notifications.
 *
 * @param none.
 *
 * @return none.
 */
static void sub_handler_initialized (void)
{
    static const char fname[] = "sub_handler_initialized";
    pres_pending_notify_t *pending_notify_p;
    char  *presentity_url = NULL;
    char  presentity_user[CC_MAX_DIALSTRING_LEN];
    Presence_ext_t *event_body_p = NULL;

    BLF_DEBUG("MSC: 0/0: %s: invoked", fname);
    s_subs_hndlr_initialized = TRUE;

    if (s_pending_notify_list == NULL) {
        BLF_DEBUG("MSC: 0/0: %s: no pending notfications", fname);
        return;
    }

    /*
     * process the pending NOTIFYs.
     */
    pending_notify_p = (pres_pending_notify_t *)sll_next(s_pending_notify_list, NULL);
    while (pending_notify_p != NULL) {
        /* strip of the "sip:" */
        presentity_url = strchr(pending_notify_p->presentity, ':');
        if (presentity_url == NULL)
        {
            BLF_ERROR("MSC: %s: Error parsing presentity_url", fname);
            return;
        }

        presentity_url = presentity_url + 1;

        /*
         * look for long from (user@host) matches first. if none found, look
         * for short form (user) matches.
         */
        event_body_p = &(pending_notify_p->event_data_p->u.presence_rpid);
        if (apply_presence_state_to_matching_feature_keys(presentity_url, event_body_p)
            != TRUE) {
            ccsip_util_extract_user(pending_notify_p->presentity, presentity_user);
            if (apply_presence_state_to_matching_feature_keys(presentity_user,
                event_body_p) != TRUE) {
                BLF_DEBUG("MSC: 0/0: %s: no matching BLF feature keys found", fname);
            }
        }
        BLF_DEBUG("MSC: 0/0: %s: processed a pending notfication for %s",
                  fname, presentity_url);
        free_event_data(pending_notify_p->event_data_p);
        (void) sll_remove(s_pending_notify_list, (void *)pending_notify_p);
        cpr_free(pending_notify_p);

        pending_notify_p = (pres_pending_notify_t *)sll_next(s_pending_notify_list,
                                                             NULL);
    }
    (void)sll_destroy(s_pending_notify_list);
    s_pending_notify_list = NULL;
}
Ejemplo n.º 3
0
/**
 * This function will post an event - SIPSPI_EV_CC_PUBLISH_REQ - to SIP stack
 * which will be handled by PUBLISH Handler in sip stack.
 *
 * @param[in] pub_req_p - pointer to a pub_req_t struct.
 *
 * @return  CC_RC_SUCCESS if the event is successfully posted.
 *          Otherwise, CC_RC_ERROR is returned.
 *
 * @pre (pub_req_p != NULL)
 */
static cc_rcs_t pub_int_req (pub_req_t *pub_req_p)
{
    cc_rcs_t ret_code;

    ret_code = app_send_message(pub_req_p, sizeof(pub_req_t), CC_SRC_SIP,  SIPSPI_EV_CC_PUBLISH_REQ);

    if (ret_code != CC_RC_SUCCESS) {
        free_event_data(pub_req_p->event_data_p);
    }
    return ret_code;
}
Ejemplo n.º 4
0
/**
 * This function will free up the PCB resources and removes it from the PCB list.
 *
 * @param[in] pcb_p -  pointer to a PCB.
 *
 * @return  none
 *
 *  @pre    (pcb_p != NULL)
 */
static void free_pcb (ccsip_publish_cb_t *pcb_p)
{
   if (pcb_p->hb.authen.authorization != NULL) {
       cpr_free(pcb_p->hb.authen.authorization);
   }
   if (pcb_p->hb.authen.sip_authen != NULL) {
       sippmh_free_authen(pcb_p->hb.authen.sip_authen);
   }

    cpr_free(pcb_p->entity_tag);
    free_pending_reqs(pcb_p->pending_reqs);
    (void)cprDestroyTimer(pcb_p->retry_timer.timer);
    free_event_data(pcb_p->hb.event_data_p);
    (void)sll_remove(s_PCB_list, (void *)pcb_p);
    cpr_free(pcb_p);
}
Ejemplo n.º 5
0
/**
 * 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);
}
Ejemplo n.º 6
0
/**
 * This function will free up entire list of pending requests
 *
 * @param[in] list -  pending requests list handle
 *
 * @return none 
 *
 */
static void free_pending_reqs (sll_handle_t list)
{
    pub_req_t *msg_p;

    if (list == NULL)  {
        return;
    }

    msg_p = (pub_req_t *)sll_next(list, NULL);
    while (msg_p != NULL) {
        free_event_data(msg_p->event_data_p);
        (void)sll_remove(list, (void *)msg_p);
        cpr_free(msg_p);
        msg_p = (pub_req_t *)sll_next(list, NULL);
    }
    sll_destroy(list);
}
Ejemplo n.º 7
0
/**
 * This function will process incoming unsolicited NOTIFY for presence event.
 * This can only be inovked by misc app.
 *
 * @param[in] msg_data - pointer to ccsip_sub_not_data_t
 *
 * @return none
 *
 * @pre (msg_data != NULL)
 */
static void
unsolicited_notify_ind_cb (ccsip_sub_not_data_t *msg_data)
{
    Presence_ext_t *event_body_p = NULL;
    char  *presentity_url = NULL;
    char  presentity_user[CC_MAX_DIALSTRING_LEN];
    static const char fname[] = "unsolicited_notify_ind_cb";

    BLF_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(BLF, fname));
    /*
     * 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 (event_body_p == NULL) {
        BLF_DEBUG("Exiting pres_sub_not_handler.c:%s(): no presence body", fname);
        return;
    }

    if (s_subs_hndlr_initialized == FALSE) {
        /*
         * append this Notification to pending queue
         * until subscription handler is initialized.
         */
        append_notification_to_pending_queue(msg_data->u.notify_ind_data.eventData);
        BLF_DEBUG("MSC: 0/0: %s: appended presence notification to the pending queue",
                  fname);
        return;

    }

    if (s_pres_req_list == NULL) {
        free_event_data(msg_data->u.notify_ind_data.eventData);
        BLF_DEBUG(DEB_F_PREFIX"Exiting : no pres requests", DEB_F_PREFIX_ARGS(BLF, fname));
        return;
    }
    /* strip of the "sip:" */
    presentity_url = strchr(event_body_p->presence_body.entity, ':');
    if (presentity_url == NULL)
    {
        BLF_ERROR("MSC: %s: Error parsing presentity_url", fname);
        return;
    }

    presentity_url = presentity_url + 1;

    /*
     * look for long from (user@host) matches first. if none found, look
     * for short form (user) matches.
     */
    if (apply_presence_state_to_matching_feature_keys(presentity_url, event_body_p) != TRUE) {
        ccsip_util_extract_user(event_body_p->presence_body.entity, presentity_user);
        if (apply_presence_state_to_matching_feature_keys(presentity_user, event_body_p) != TRUE) {
            BLF_DEBUG("pres_sub_not_handler.c:%s(): no matching BLF feature keys found", fname);
        }
    }

    free_event_data(msg_data->u.notify_ind_data.eventData);
    BLF_DEBUG("Exiting pres_sub_not_handler.c:%s(): pres state processed successfully", fname);
    return;
}
Ejemplo n.º 8
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;
}
Ejemplo n.º 9
0
/**
 * This function will process SIPSPI_EV_CC_PUBLISH posted by applications.
 * If there is an outstanding transaction, it will hold the request in the pending list.
 *
 * @param[in] buf -  inter-process message buffer.
 *
 * @return SIP_OK if it successfully processes the request.
 *         SIP_ERROR if it fails to process the request.
 *         SIP_DEFER if it defers the processing.
 *
 * @note  This will not free buf.
 *
 * @pre    (buf != NULL)
 */
int publish_handle_ev_app_publish (cprBuffer_t buf)
{
    static const char fname[] = "publish_handle_ev_app_publish";
    pub_req_t *msg_p = (pub_req_t *)buf;
    ccsip_publish_cb_t *pcb_p;


    /*
     * If this is initial PUBLISH, allocate a PCB.
     * Otherwise, look up for PCB based on pub_handle.
     */ 
    if (msg_p->pub_handle != NULL_PUBLISH_HANDLE) {
        pcb_p = find_pcb(msg_p->pub_handle);
        
        if (pcb_p == NULL) {
            send_resp_to_app(PUBLISH_FAILED_NOCONTEXT, msg_p->pub_handle, msg_p->app_handle,
                             msg_p->callback_task, msg_p->resp_msg_id);
            free_event_data(msg_p->event_data_p);
            CCSIP_DEBUG_ERROR(SIP_F_PREFIX
                              "Modification PUBLISH cannot be sent as the PCB is missing\n",
                              fname);
            return SIP_ERROR;
        }

        /*
         * Check if there is an outstanding transaction.
         * if so, put the request in pending request queue.
         */
        if (pcb_p->outstanding_trxn == TRUE) {
            if (append_pending_reqs(pcb_p, msg_p) == TRUE) {
                CCSIP_DEBUG_TASK(DEB_F_PREFIX"deffering as there is an outstanding transaction\n",
                                 DEB_F_PREFIX_ARGS(SIP_PUB, fname));
                return SIP_DEFER;
            }
            /* free up PCB and respond with error */
            free_pcb (pcb_p);
            send_resp_to_app(PUBLISH_FAILED_NORESOURCE, msg_p->pub_handle, msg_p->app_handle,
                             msg_p->callback_task, msg_p->resp_msg_id);
            free_event_data(msg_p->event_data_p);
            CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Queueing outgoing PUBLISH request failed\n", fname);
            return SIP_ERROR;
        }
        /*
         * if event_data_p is NULL, this is terminating PUBLISH.
         * otherwise, it is a modifying PUBLISH.
         */
        free_event_data(pcb_p->hb.event_data_p);
        pcb_p->hb.event_data_p = msg_p->event_data_p;
        if ((msg_p->event_data_p == NULL) && (msg_p->expires == 0)) { // removing PUBLISH
            pcb_p->hb.orig_expiration = 0;
        }
    } else {
        pcb_p = get_new_pcb();
        if (pcb_p == NULL) {
            send_resp_to_app(PUBLISH_FAILED_NORESOURCE, msg_p->pub_handle, msg_p->app_handle,
                             msg_p->callback_task, msg_p->resp_msg_id);
            free_event_data(msg_p->event_data_p);
            CCSIP_DEBUG_ERROR(SIP_F_PREFIX"PCB allocation failed\n", fname);
            return SIP_ERROR;
        }
        pcb_p->app_handle = msg_p->app_handle;
        sstrncpy(pcb_p->ruri, msg_p->ruri, MAX_URI_LENGTH);
        sstrncpy(pcb_p->esc, msg_p->esc, MAX_URI_LENGTH);
        pcb_p->hb.orig_expiration = msg_p->expires;
        pcb_p->hb.event_type = msg_p->event_type;
        pcb_p->hb.event_data_p = msg_p->event_data_p;
        pcb_p->callback_task = msg_p->callback_task;
        pcb_p->resp_msg_id = msg_p->resp_msg_id;
    }

    pcb_p->hb.authen.cred_type = 0;

    if (sipSPISendPublish(pcb_p, FALSE) == TRUE) {
        pcb_p->outstanding_trxn = TRUE;
        outgoingPublishes++;
        CCSIP_DEBUG_TASK(DEB_F_PREFIX"PUBLISH request sent successfully\n", DEB_F_PREFIX_ARGS(SIP_PUB, fname));
        return SIP_OK;
    }

    /* free up PCB and respond with error */
    free_pcb (pcb_p);
    send_resp_to_app(PUBLISH_FAILED_SEND, msg_p->pub_handle, msg_p->app_handle,
                     msg_p->callback_task, msg_p->resp_msg_id);
    CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Failed to send PUBLISH request\n", fname);
    return SIP_ERROR;
    
}