예제 #1
0
void ccsip_dump_send_msg_info (char *msg, sipMessage_t *pSIPMessage,
                               cpr_ip_addr_t *cc_remote_ipaddr,
                               uint16_t cc_remote_port)
{
    char *disp_buf;
    const char *req_uri;
    const char *cseq;
    const char *callid;
    char ipaddr_str[MAX_IPADDR_STR_LEN];
    static const char fname[] = "ccsip_dump_send_msg_info";

    ipaddr2dotted(ipaddr_str, cc_remote_ipaddr);

    req_uri = sippmh_get_header_val(pSIPMessage, SIP_HEADER_TO, NULL);
    if (req_uri == NULL) {
        /* No REQ URI, fill with blank */
        req_uri = "";
    }
    cseq = sippmh_get_header_val(pSIPMessage, SIP_HEADER_CSEQ, NULL);
    if (cseq == NULL) {
        /* No REQ CSEQ, fill with blank */
        cseq = "";
    }
    callid = sippmh_get_header_val(pSIPMessage, SIP_HEADER_CALLID, NULL);
    if (callid == NULL) {
        /* No REQ CSEQ, fill with blank */
        callid = "";
    }

    /* For messages starting with SIP add 8 byte. default
     * debugs do not show all the SIP message information
     * rather show initial msg.
     */
    if (msg != NULL) {
        if (msg[0] == 'S' &&
            msg[1] == 'I' &&
            msg[2] == 'P') {
            disp_buf = &msg[8];
        } else {
            disp_buf = msg;
        }
        if ((strncmp(disp_buf, SIP_METHOD_REGISTER, sizeof(SIP_METHOD_REGISTER)-1) == 0) &&
            (!dump_reg_msg)) {
            return;
        }
    } else {
        /* No msg. buffer */
        disp_buf = NULL;
    }


    if (disp_buf != NULL) {
        DEF_DEBUG(DEB_F_PREFIX"<%s:%-4d>:%c%c%c%c%c%c%c: %-10s :%-6s::%s\n",
                    DEB_F_PREFIX_ARGS(SIP_MSG_SEND, fname),
                    ipaddr_str, cc_remote_port,
                    disp_buf[0],
                    disp_buf[1],
                    disp_buf[2],
                    disp_buf[3],
                    disp_buf[4],
                    disp_buf[5],
                    disp_buf[6],
                    req_uri,
                    cseq, callid);
    } else {
        /* No msg to send */
        DEF_DEBUG(DEB_F_PREFIX"<%s:%-4d>: empty message\n",
                  DEB_F_PREFIX_ARGS(SIP_MSG_SEND, fname),
                  ipaddr_str, cc_remote_port);
    }
}
예제 #2
0
/**
 * This function will process the response to PUBLISH request sent by us.
 *
 * @param[in] pSipMessage -  pointer to received SIP response msg
 *
 * @return SIP_OK if it successfully processes the response.
 *         SIP_ERROR if it fails to process the response.
 *
 * @pre    (pSipMessage != NULL)
 */
int publish_handle_ev_sip_response (sipMessage_t *pSipMessage)
{
    static const char fname[] = "publish_handle_ev_sip_response";
    const char     *callID_p = NULL;
    int             response_code = 0;
    const char     *expires = NULL;
    const char     *sip_etag = NULL;
    long            expiry_time;
    pub_req_t      *msg_p;
    ccsip_publish_cb_t *pcb_p;
    int entity_tag_size;

    callID_p = sippmh_get_cached_header_val(pSipMessage, CALLID);
    if (!callID_p) {
        CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Cannot obtain SIP Call ID.\n", fname);
        return SIP_ERROR;
    }

    /*
     * Find PCB by Call-ID. The Call-IDs generated by the phone ae unique.
     */
    pcb_p = find_pcb_by_sip_callid(callID_p);
    if (pcb_p == NULL) {
        CCSIP_DEBUG_ERROR(SIP_F_PREFIX"No matching PCB found\n", fname);
        return SIP_ERROR;
    }

    /*
     * Cancel the retry_timer and set the retx_flag to FALSE.
     */
    sip_platform_msg_timer_subnot_stop(&(pcb_p->retry_timer));
    pcb_p->hb.retx_flag = FALSE;
    
    // Parse the return code
    (void) sipGetResponseCode(pSipMessage, &response_code);

    if (response_code >= 200) {
        pcb_p->outstanding_trxn = FALSE;
    }


    if ((response_code == SIP_CLI_ERR_UNAUTH) ||
        (response_code == SIP_CLI_ERR_PROXY_REQD)) {
        CCSIP_DEBUG_TASK(DEB_F_PREFIX"Authentication Required\n", DEB_F_PREFIX_ARGS(SIP_PUB, fname));
        if (ccsip_common_util_generate_auth(pSipMessage, &pcb_p->hb, SIP_METHOD_PUBLISH,
                                            response_code, pcb_p->full_ruri) == TRUE) {
            if (sipSPISendPublish(pcb_p, TRUE) == TRUE) {
                pcb_p->outstanding_trxn = TRUE;
                CCSIP_DEBUG_TASK(DEB_F_PREFIX"sent request with Auth header\n", DEB_F_PREFIX_ARGS(SIP_PUB, fname));
                return SIP_OK;
             }
        }
        /*
         * Since we failed to resend the PUBLISH request, free up the PCB and let the app know.
         */
        send_resp_to_app(PUBLISH_FAILED_SEND, pcb_p->pub_handle, pcb_p->app_handle,
                         pcb_p->callback_task, pcb_p->resp_msg_id);
        free_pcb (pcb_p);
        CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to respond to auth challenge\n", fname);
        return SIP_ERROR;
    }

    /*
     * if response code is 423, grab Min-Expires and send new PUBLISH with new expires value
     */
    if (response_code == SIP_CLI_ERR_INTERVAL_TOO_SMALL) {
        expires = sippmh_get_header_val(pSipMessage,
                                        (const char *)SIP_HEADER_MIN_EXPIRES,
                                        NULL);
        if (expires) {
            expiry_time = strtoul(expires, NULL, 10);
            //ensure new Min-Expires is > what we set before in Expires
            if ((long) expiry_time > pcb_p->hb.expires) {
                pcb_p->hb.expires = expiry_time;
                pcb_p->hb.orig_expiration = expiry_time;
            }
            if (sipSPISendPublish(pcb_p, FALSE) == TRUE) {
                pcb_p->outstanding_trxn = TRUE;
                CCSIP_DEBUG_TASK(DEB_F_PREFIX"sent request with increased expires\n", DEB_F_PREFIX_ARGS(SIP_PUB, fname));
                return SIP_OK;
             }
        }
        /*
         * Since we failed to resend the PUBLISH request, free up the PCB and let the app know.
         */
        send_resp_to_app(PUBLISH_FAILED_SEND, pcb_p->pub_handle, pcb_p->app_handle,
                         pcb_p->callback_task, pcb_p->resp_msg_id);
        free_pcb (pcb_p);
        CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to respond to 423\n", fname);
        return SIP_ERROR;
    }
    
    /*
     * if the response_code is > 299, free up the PCB and let the app know.
     */
    if (response_code > 299) {
        send_resp_to_app(response_code, pcb_p->pub_handle, pcb_p->app_handle,
                         pcb_p->callback_task, pcb_p->resp_msg_id);
        free_pcb (pcb_p);
        CCSIP_DEBUG_TASK(DEB_F_PREFIX"received %d response\n", DEB_F_PREFIX_ARGS(SIP_PUB, fname), response_code);
        return SIP_OK;
    }

    /*
     * if the response is < 200, do nothing.
     */
    if (response_code < 200) {
        CCSIP_DEBUG_TASK(DEB_F_PREFIX"received %d response\n", DEB_F_PREFIX_ARGS(SIP_PUB, fname), response_code);
        return SIP_OK;
    }
    
    /*
     * If it is PUBLISH remove operation, free up PCB
     */
    if (pcb_p->hb.orig_expiration == 0) {
        send_resp_to_app(response_code, pcb_p->pub_handle, pcb_p->app_handle,
                         pcb_p->callback_task, pcb_p->resp_msg_id);
        free_pcb (pcb_p);
        CCSIP_DEBUG_TASK(DEB_F_PREFIX"removed PCB as this was a terminating PUBLISH\n", DEB_F_PREFIX_ARGS(SIP_PUB, fname));
        return SIP_OK;
    }

    /*
     * extract Expires and SIP-ETag headers and save them.
     */
    expires = sippmh_get_header_val(pSipMessage, SIP_HEADER_EXPIRES, NULL);
    if (expires) {
        expiry_time = strtoul(expires, NULL, 10);
        pcb_p->hb.expires = expiry_time;
    }
    sip_etag = sippmh_get_header_val(pSipMessage, SIP_HEADER_SIPETAG, NULL);
    if (sip_etag != NULL) {
        cpr_free(pcb_p->entity_tag);
        entity_tag_size = strlen(sip_etag) + 1;
        pcb_p->entity_tag = cpr_malloc(entity_tag_size);
        if (pcb_p->entity_tag != NULL) {
            sstrncpy(pcb_p->entity_tag, sip_etag, entity_tag_size);
        } else {
            free_pcb (pcb_p);
            send_resp_to_app(PUBLISH_FAILED_NORESOURCE, pcb_p->pub_handle, pcb_p->app_handle,
                             pcb_p->callback_task, pcb_p->resp_msg_id);
            CCSIP_DEBUG_ERROR(SIP_F_PREFIX"memory allocation failed\n", fname);
            return SIP_ERROR;
            
        }
    }

    /*
     * If there are no pending requests, provide the response to the application.
     */
    msg_p = (pub_req_t *)sll_next(pcb_p->pending_reqs, NULL);
    if (msg_p != NULL) {
        (void)sll_remove(pcb_p->pending_reqs, msg_p);
        (void)publish_handle_ev_app_publish(msg_p);
        cpr_free(msg_p);
        return SIP_OK;
    }
    send_resp_to_app(response_code, pcb_p->pub_handle, pcb_p->app_handle,
                     pcb_p->callback_task, pcb_p->resp_msg_id);
    CCSIP_DEBUG_TASK(DEB_F_PREFIX"sent response %d to app\n", DEB_F_PREFIX_ARGS(SIP_PUB, fname), response_code);
    return SIP_OK;
}
예제 #3
0
/*
 *  Function: ccsip_handle_info_package
 *
 *  Parameters:
 *      ccb         - the SIP CCB
 *      pSipMessage - the SIP message
 *
 *  Description:
 *      Handles an incoming unsolicited Info Package message.
 *      XXX Currently this function only handles the first part in a
 *          multi-part Info Package message.
 *
 *  Return:
 *      SIP_OK - if request processed.
 *      SIP_ERROR - if there is error
 */
int
ccsip_handle_info_package(ccsipCCB_t *ccb, sipMessage_t *pSipMessage)
{
    static const char *fname = "ccsip_handle_info_package";
    const char  *info_package;
    const char  *content_type;
    info_index_t info_index;
    type_index_t type_index;
    handler_record_t *record;
    uint16_t     status_code;
    const char  *reason_phrase;
    int          return_code = SIP_ERROR;

    /* FIXME Media Control currently does not follow the IETF draft
             draft-ietf-sip-info-events-01, so short-circuit here and
             bypass all the Info Package related stuff below. */
    // leading white spaces are trimmed, but not trailing ones
    content_type = sippmh_get_cached_header_val(pSipMessage,
                                                CONTENT_TYPE);
    if (content_type &&
        httpish_strncasecmp(content_type,
                            SIP_CONTENT_TYPE_MEDIA_CONTROL,
                            strlen(SIP_CONTENT_TYPE_MEDIA_CONTROL)) == 0) {

        media_control_info_package_handler(ccb->dn_line, ccb->gsm_id,
                                           "",  // legacy mode, no Info Package
                                           SIP_CONTENT_TYPE_MEDIA_CONTROL,
                                           pSipMessage->mesg_body[0].msgBody);

        if (sipSPISendErrorResponse(pSipMessage, 200, SIP_SUCCESS_SETUP_PHRASE,
                                    0, NULL, NULL) != TRUE) {
            CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR),
                              fname, SIP_SUCCESS_SETUP_PHRASE);
            return SIP_ERROR;
        }

        return SIP_OK;
    }

    /*
     * Parse the Info-Package header
     */
    // leading white spaces are trimmed, but not trailing ones
    info_package = sippmh_get_header_val(pSipMessage,
                                         SIP_HEADER_INFO_PACKAGE,
                                         NULL);

    if (info_package == NULL) {
        /* No Info-Package header */
        CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Missing Info-Package header",
                            DEB_F_PREFIX_ARGS(SIP_INFO_PACKAGE, fname));

        if (pSipMessage->num_body_parts == 0) {
            /* No Info-Package header, and no body poarts */
            CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Missing message body",
                                DEB_F_PREFIX_ARGS(SIP_INFO_PACKAGE, fname));
            /* Send 200 OK for legacy UA support */
            status_code = 200;
            reason_phrase = SIP_SUCCESS_SETUP_PHRASE;
            return_code = SIP_OK;
        } else {
            /* No Info-Package header, but with body part(s) */
            if (pSipMessage->num_body_parts > 1) {
                CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Multipart Info Package",
                                    DEB_F_PREFIX_ARGS(SIP_INFO_PACKAGE, fname));
            }

            type_index = find_type_index(pSipMessage->mesg_body[0].msgContentType);
            if (type_index == INDEX_NOT_FOUND) {
                /* No Info-Package header, and Content-Type is not supported */
                CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Unsupported Content Type",
                                    DEB_F_PREFIX_ARGS(SIP_INFO_PACKAGE, fname));
                /* Send 415 Unsupported Media Type */
                status_code = SIP_CLI_ERR_MEDIA;
                reason_phrase = SIP_CLI_ERR_MEDIA_PHRASE;
            } else {
                /* No Info-Package header, but Conent-Type is supported */
                /* Send 200 OK for legacy UA support */
                status_code = 200;
                reason_phrase = SIP_SUCCESS_SETUP_PHRASE;
                return_code = SIP_OK;
            }
        }
    } else {
        /* With Info-Package header */
        if (pSipMessage->num_body_parts == 0) {
            /* With Info-Package header, but no body parts */
            CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Missing message body",
                                DEB_F_PREFIX_ARGS(SIP_INFO_PACKAGE, fname));

            /* ? */
            /* Send 489 Bad Event */
            status_code = SIP_CLI_ERR_BAD_EVENT;
            reason_phrase = SIP_CLI_ERR_BAD_EVENT_PHRASE;

        } else {
            /* With Info-Package header and body part(s) */
            if (pSipMessage->num_body_parts > 1) {
                CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Multipart Info Package "
                                    "(only the first part is processed)\n",
                                    DEB_F_PREFIX_ARGS(SIP_INFO_PACKAGE, fname));
            }

            info_index = find_info_index(info_package);
            if (info_index == INDEX_NOT_FOUND) {
                /* Info-Package is not supported */
                CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Unsupported Info Package",
                                    DEB_F_PREFIX_ARGS(SIP_INFO_PACKAGE, fname));

                /* Send 489 Bad Event */
                status_code = SIP_CLI_ERR_BAD_EVENT;
                reason_phrase = SIP_CLI_ERR_BAD_EVENT_PHRASE;

            } else {
                /* Info-Package is supported */
                type_index = find_type_index(pSipMessage->mesg_body[0].msgContentType);
                record = find_handler_record(info_index, type_index);
                if (record == NULL) {
                    /* Info-Package header is supported, but Content-Type is not */
                    CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Unsupported Content Type",
                                        DEB_F_PREFIX_ARGS(SIP_INFO_PACKAGE, fname));
                    /* Send 415 Unsupported Media Type */
                    status_code = SIP_CLI_ERR_MEDIA;
                    reason_phrase = SIP_CLI_ERR_MEDIA_PHRASE;
                } else {
                    /* a handler is registered */
                    (*record->handler)(ccb->dn_line, ccb->gsm_id,
                                       g_registered_info[record->info_index],
                                       s_registered_type[record->type_index],
                                       pSipMessage->mesg_body[0].msgBody);
                    /* Send 200 OK */
                    status_code = 200;
                    reason_phrase = SIP_SUCCESS_SETUP_PHRASE;
                    return_code = SIP_OK;
                }
            }
        }
    }

    if (sipSPISendErrorResponse(pSipMessage, status_code, reason_phrase,
                                0, NULL, NULL) != TRUE) {
        CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR),
                          fname, reason_phrase);
        return SIP_ERROR;
    }

    return return_code;
}