Пример #1
0
/*
 *  Function: sipRelDevCoupledMessageStore
 *
 *  Parameters:
 *      pCoupledMessage - pointer to sipMessage_t for the message that
 *                        needed reliable delivery store.
 *      call_id         - pointer to const. char for the SIP call ID.
 *      cseq_number     - the uint32_t for CSeq of the message.
 *      sipMethod_t     - sipMethod_t the SIP method of the message.
 *      dest_ipaddr     - uint32_t IP address of the destination address.
 *      dest_port       - uint16_t destination port
 *      ignore_tag      - boolean to ignore tag.
 *
 *  Description:
 *      The function finds the corresponding entry in the gSIPRRList
 *  array that matches call_id, cseq number, method and possibly tag.
 *  If a match entry is found, the SIP message is composed and stored
 *  in the corresponding entry.
 *
 *  Returns:
 *      idx - When the entry is found and successfully stored the
 *              SIP message.
 *      RELDEV_NO_STORED_MSG - encounter errors or no message is
 *                             stored.
 */
int
sipRelDevCoupledMessageStore (sipMessage_t *pCoupledMessage,
                              const char *call_id,
                              uint32_t cseq_number,
                              sipMethod_t cseq_method,
                              boolean is_request,
                              int response_code,
                              cpr_ip_addr_t *dest_ipaddr,
                              uint16_t dest_port,
                              boolean ignore_tag)
{
    static const char *fname = "sipRelDevCoupledMessageStore";
    int i = 0;
    char to_tag[MAX_SIP_TAG_LENGTH];

    sipGetMessageToTag(pCoupledMessage, to_tag, MAX_SIP_TAG_LENGTH);
    CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Storing for reTx (cseq=%d, method=%s, "
                        "to_tag=<%s>)\n", DEB_F_PREFIX_ARGS(SIP_STORE, fname), cseq_number,
                        sipGetMethodString(cseq_method), to_tag);

    for (i = 0; i < SIP_RRLIST_LENGTH; i++) {
        if ((strcmp(call_id, gSIPRRList[i].call_id) == 0) &&
            (cseq_number == gSIPRRList[i].cseq_number) &&
            (cseq_method == gSIPRRList[i].cseq_method) &&
            ((ignore_tag) ? TRUE : (strcasecmp_ignorewhitespace(to_tag,
                                                     gSIPRRList[i].tag)
                                    == 0))) {
            hStatus_t sippmh_write_status = STATUS_FAILURE;
            uint32_t nbytes = SIP_UDP_MESSAGE_SIZE;

            /*
              When storing the ACK message check that you are storing it
              coupled with the correct response code and not transitional responses
            */
            if (is_request == FALSE ||
                (is_request == TRUE && gSIPRRList[i].response_code == response_code)) {
                gSIPRRList[i].coupled_message.message_buf[0] = '\0';
                sippmh_write_status =
                    sippmh_write(pCoupledMessage,
                                 gSIPRRList[i].coupled_message.message_buf,
                                 &nbytes);
                if (sippmh_write_status == STATUS_FAILURE) {
                    CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sippmh_write() failed.", fname);
                    return (RELDEV_NO_STORED_MSG);
                }
                if ((gSIPRRList[i].coupled_message.message_buf[0] == '\0') ||
                    (nbytes == 0)) {
                    CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sippmh_write() returned empty buffer string.",
                                      fname);
                    return (RELDEV_NO_STORED_MSG);
                }
                gSIPRRList[i].coupled_message.message_buf_len = nbytes;
                gSIPRRList[i].coupled_message.dest_ipaddr = *dest_ipaddr;
                gSIPRRList[i].coupled_message.dest_port = dest_port;
                gSIPRRList[i].valid_coupled_message = TRUE;
                /* Return the stored idx to the caller */
                return (i);
            }
        }
    }
    return (RELDEV_NO_STORED_MSG);
}
Пример #2
0
/**
 * This function will create the PUBLISH message and send it. it also starts the retry timer.
 *
 * @param[in] pcb_p -  pointer to PCB
 * @param[in] authen - boolean that indicates whether to add authorization header.
 *
 * @return TRUE if it successfully sent PUBLISH
 *         Otherwise, FALSE is returned
 *
 * @pre    (pcb_p != NULL)
 */
static boolean sipSPISendPublish (ccsip_publish_cb_t *pcb_p, boolean authen) 
{
    static const char fname[] = "sipSPISendPublish";
    static uint32_t   cseq = 0;
    char              dest_sip_addr_str[MAX_IPADDR_STR_LEN];
    char             *domainloc;
    char              src_addr_str[MAX_IPADDR_STR_LEN];
    char              sip_temp_str[MAX_SIP_URL_LENGTH];
    char              sip_temp_tag[MAX_SIP_URL_LENGTH];
    uint8_t           mac_address[MAC_ADDRESS_LENGTH];
    char              via[SIP_MAX_VIA_LENGTH];
    int               max_forwards_value = 70;
    static uint16_t   count = 1;
    sipMessage_t     *request = NULL;
    int               timeout = 0;
   
    request = GET_SIP_MESSAGE();
    if (!request) {
        return FALSE;
    }

    /*
     * Populate full RURI if it is not yet. Sometimes, applications may only provide user part.
     */
    if (pcb_p->full_ruri[0] == 0) {
        sstrncpy(pcb_p->full_ruri, "sip:", MAX_SIP_URL_LENGTH);
        sstrncat(pcb_p->full_ruri, pcb_p->ruri, MAX_SIP_URL_LENGTH - sizeof("sip:"));
        /* check if it has host part */
        domainloc = strchr(pcb_p->full_ruri, '@');
        if (domainloc == NULL) {
            domainloc = pcb_p->full_ruri + strlen(pcb_p->full_ruri);
            if ((domainloc - pcb_p->full_ruri) < (MAX_SIP_URL_LENGTH - 1)) {
                /* Do not include @ when there is no user part */
                if (pcb_p->ruri[0] != '\0') {
                    *domainloc++ = '@';
                }
                ipaddr2dotted(dest_sip_addr_str, &pcb_p->hb.dest_sip_addr);
                sstrncpy(domainloc, dest_sip_addr_str,
                         MAX_SIP_URL_LENGTH - (domainloc - (pcb_p->full_ruri)));
            }
        }
    }

    ipaddr2dotted(src_addr_str, &pcb_p->hb.src_addr);

    // Add request line
    if (HSTATUS_SUCCESS != sippmh_add_request_line(request,
                                                   sipGetMethodString(sipMethodPublish),
                                                   pcb_p->full_ruri, SIP_VERSION)) {
        CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Request line\n", fname);
        free_sip_message(request);
        return (FALSE);
    }

    // Add local Via 
    snprintf(via, sizeof(via), "SIP/2.0/%s %s:%d;%s=%s%.8x",
             sipTransportGetTransportType(1, TRUE, NULL),
             src_addr_str, pcb_p->hb.local_port, VIA_BRANCH,
             VIA_BRANCH_START, (unsigned int) cpr_rand());
    if (HSTATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_VIA, via)) {
        CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding VIA header\n", fname);
        free_sip_message(request);
        return (FALSE);
    }

    // Add To Header
    snprintf(sip_temp_str, MAX_SIP_URL_LENGTH, "<%s>", pcb_p->full_ruri);
    if (HSTATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_TO, sip_temp_str)) {
        CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding TO header\n", fname);
        free_sip_message(request);
        return (FALSE);
    }

    // Add From Header.
    sstrncat(sip_temp_str, ";tag=", MAX_SIP_URL_LENGTH - strlen(sip_temp_str));
    sip_util_make_tag(sip_temp_tag);
    sstrncat(sip_temp_str, sip_temp_tag, MAX_SIP_URL_LENGTH - strlen(sip_temp_str));
    if (HSTATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_FROM, sip_temp_str)) {
        CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding FROM header\n", fname);
        free_sip_message(request);
        return (FALSE);
    }

    // Add Call-ID Header. 
    platform_get_wired_mac_address(mac_address);
    count++;
    snprintf(pcb_p->hb.sipCallID, MAX_SIP_CALL_ID, "%.4x%.4x-%.4x%.4x-%.8x-%.8x@%s", // was MAX_SIP_URL_LENGTH
                 mac_address[0] * 256 + mac_address[1],
                 mac_address[2] * 256 + mac_address[3],
                 mac_address[4] * 256 + mac_address[5], count,
                 (unsigned int) cpr_rand(),
                 (unsigned int) cpr_rand(),
                 src_addr_str);
    if (HSTATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_CALLID, pcb_p->hb.sipCallID)) {
        CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding CALLID header\n", fname);
        free_sip_message(request);
        return (FALSE);
    }

    // Add Contact header. Contact header is not needed as per RFC. BUT CCM needs it.
    snprintf(sip_temp_str, MAX_SIP_URL_LENGTH, "<sip:%.4x%.4x%.4x@%s:%d>",
             mac_address[0] * 256 + mac_address[1],
             mac_address[2] * 256 + mac_address[3],
             mac_address[4] * 256 + mac_address[5],
             src_addr_str, pcb_p->hb.local_port);
    if (HSTATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_CONTACT, sip_temp_str)) {
        CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Contact header\n", fname);
        free_sip_message(request);
        return (FALSE);
    }

    // Add Cseq. 
    cseq++;
    if (cseq == 0) {
        cseq = 1;
    }
    if (HSTATUS_SUCCESS != sippmh_add_cseq(request, sipGetMethodString(sipMethodPublish), cseq)) {
        CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding CSEQ header\n", fname);
        free_sip_message(request);
        return (FALSE);
    }

    // Add UserAgent header
    (void) sippmh_add_text_header(request, SIP_HEADER_USER_AGENT,
                                  sipHeaderUserAgent);


    // Add SIP-If-Match header.
    if (pcb_p->entity_tag != NULL) {
        if (HSTATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_SIPIFMATCH,
                                                      pcb_p->entity_tag)) {
            CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Event header\n", fname);
            free_sip_message(request);
            return (FALSE);
        }
    }

    // Add Expires Header
    if (HSTATUS_SUCCESS != sippmh_add_int_header(request, SIP_HEADER_EXPIRES,
                pcb_p->hb.orig_expiration)) {
        CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Expires header\n", fname);
        free_sip_message(request);
        return (FALSE);
    }

    // Add max-forwards header
    config_get_value(CFGID_SIP_MAX_FORWARDS, &max_forwards_value,
                     sizeof(max_forwards_value));
    if (HSTATUS_SUCCESS !=
        sippmh_add_int_header(request, SIP_HEADER_MAX_FORWARDS,
            max_forwards_value)) {
        CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Max-Forwards header\n", fname);
        free_sip_message(request);
        return (FALSE);
    }

    // add Authorization header
    if (authen) {
        if (HSTATUS_SUCCESS != sippmh_add_text_header(request, AUTHOR_HDR(pcb_p->hb.authen.status_code),
                                                      pcb_p->hb.authen.authorization)) {
            CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Authorization header\n", fname);
            free_sip_message(request);
            return (FALSE);
        }
    }

    // Add content, if any
    if (pcb_p->hb.event_data_p) {
        if (add_content(pcb_p->hb.event_data_p, request, fname) == FALSE) {
            CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Content\n", fname);
            free_sip_message(request);
            return (FALSE);
        }
    } else {
        if (HSTATUS_SUCCESS != sippmh_add_int_header(request, SIP_HEADER_CONTENT_LENGTH, 0)) {
            CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Content-Len\n", fname);
            free_sip_message(request);
            return (FALSE);
        }
    }

    ccsip_common_util_set_retry_settings(&pcb_p->hb, &timeout);
    if (sipTransportCreateSendMessage(NULL, request, sipMethodPublish,
                                      &(pcb_p->hb.dest_sip_addr),
                                      (int16_t) pcb_p->hb.dest_sip_port,
                                      FALSE, TRUE, timeout, pcb_p,
                                      RELDEV_NO_STORED_MSG) < 0) {
        CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to send PUBLISH message\n", fname);
        return (FALSE);
    }

    return (TRUE);
    
}