Exemplo n.º 1
0
/**
 * Returns dot notation IP address phone used for registration purpose. If phone is not
 * registered, then "0.0.0.0" is returned.
 * @return  char IP address used to register phone.
 */
cc_string_t CCAPI_DeviceInfo_getSignalingIPAddress(cc_deviceinfo_ref_t handle) 
{
    static const char *fname="CCAPI_DeviceInfo_getSignalingIPAddress";
    cpr_ip_addr_t ip_addr = {0,{0}};

    sip_config_get_net_device_ipaddr(&ip_addr);
    ipaddr2dotted(g_deviceInfo.registration_ip_addr, &ip_addr);
    CCAPP_DEBUG(DEB_F_PREFIX"returned %s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), g_deviceInfo.registration_ip_addr);
    return g_deviceInfo.registration_ip_addr;
}
Exemplo n.º 2
0
int
sipRelDevCoupledMessageSend (int idx)
{
    static const char *fname = "sipRelDevCoupledMessageSend";
    char dest_ipaddr_str[MAX_IPADDR_STR_LEN];

    if ((idx < 0) || (idx >= SIP_RRLIST_LENGTH)) {
        CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Argument Check: idx (=%d) out of bounds.",
                          fname, idx);
        return SIP_ERROR;
    }

    if (gSIPRRList[idx].valid_coupled_message) {
        ipaddr2dotted(dest_ipaddr_str,
                      &gSIPRRList[idx].coupled_message.dest_ipaddr);

        CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Sending stored coupled message (idx=%d) to "
                            "<%s>:<%d>\n", DEB_F_PREFIX_ARGS(SIP_MSG_SEND, fname), idx, dest_ipaddr_str,
                            gSIPRRList[idx].coupled_message.dest_port);
        if (sipTransportChannelSend(NULL,
                       gSIPRRList[idx].coupled_message.message_buf,
                       gSIPRRList[idx].coupled_message.message_buf_len,
                       sipMethodInvalid,
                       &(gSIPRRList[idx].coupled_message.dest_ipaddr),
                       gSIPRRList[idx].coupled_message.dest_port,
                       0) < 0) {
            CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sipTransportChannelSend() failed."
                              " Stored message not sent.\n", fname);
            return SIP_ERROR;
        }
    } else {
        CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Duplicate message detected but failed to"
                          " find valid coupled message. Stored message not sent.\n",
                          fname);
        return SIP_ERROR;
    }
    return SIP_OK;
}
Exemplo n.º 3
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);
    
}
Exemplo n.º 4
0
/*
 * sip_tls_create_connection()
 * Description : This routine is called is response to a create connection
 * request from SIP_SPI to SIP_TLS.
 *
 * Input : spi_msg - Pointer to sipSPIMessage_t containing the create conn
 * parameters.
 *        blocking - connection mode; FALSE - nonblock; TRUE - block
 *
 * Output : Nothing
 */
cpr_socket_t
sip_tls_create_connection (sipSPIMessage_t *spi_msg, boolean blocking,
        sec_level_t sec)
{
    const char fname[] = "sip_tls_create_connection";
    int idx;
    sipSPICreateConnection_t *create_msg;
    char ipaddr_str[MAX_IPADDR_STR_LEN];
    plat_soc_status_e ret;
    cpr_socket_t sock = INVALID_SOCKET;
    uint16_t sec_port = 0;
    plat_soc_connect_status_e conn_status;
    int tos_dscp_val = 0; // set to default if there is no config. for dscp
#ifdef IPV6_STACK_ENABLED
    int ip_mode = CPR_IP_MODE_IPV4;
#endif
    uint16_t af_listen = AF_INET6;
    cpr_sockaddr_storage sock_addr;
    uint16_t       addr_len;
    int ip_mode = 0; // currently hardcoded to ipv4
    plat_soc_connect_mode_e conn_mode;

#ifdef IPV6_STACK_ENABLED

    config_get_value(CFGID_IP_ADDR_MODE, &ip_mode, sizeof(ip_mode));

    /*
     * Create a socket
     */
    if (ip_mode == CPR_IP_MODE_IPV6 ||
        ip_mode == CPR_IP_MODE_DUAL) {
        af_listen = AF_INET6;
    } else {
#endif
        af_listen = AF_INET;
#ifdef IPV6_STACK_ENABLED
    }
#endif

    sip_tcp_init_conn_table();
    create_msg = &(spi_msg->createConnMsg);
    ipaddr2dotted(ipaddr_str, &create_msg->addr);
    ret = platSecIsServerSecure();
    if (ret != PLAT_SOCK_SECURE) {
        CCSIP_DEBUG_ERROR(SIP_F_PREFIX
                          "Secure connection is not created because"
                          " there is no secure servers\n", fname);
        return INVALID_SOCKET;
    }
    CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX
                        "Creating secure connection\n", DEB_F_PREFIX_ARGS(SIP_TLS, fname));
    /* connect securely via TLS */
    config_get_value(CFGID_DSCP_FOR_CALL_CONTROL, (int *)&tos_dscp_val,
                     sizeof(tos_dscp_val));

    if (sec == AUTHENTICATED) {
        conn_mode = PLAT_SOCK_AUTHENTICATED;
    } else if (sec == ENCRYPTED) {
        conn_mode = PLAT_SOCK_ENCRYPTED;
    } else {
        CCSIP_DEBUG_ERROR(SIP_F_PREFIX
                          "Secure connection is not created. Security mode was"
                          " not encrypyted or authenticated.\n", fname);
        conn_mode = PLAT_SOCK_NON_SECURE;
    }
    sock = platSecSocConnect(ipaddr_str,          /* host  */
                            create_msg->port,    /* port */
                            ip_mode,             /* ip mode, ipv4 = 0, ipv6 = 1, dual = 2 */
                            blocking,            /* 1 - block  */
                            tos_dscp_val, /* TOS value  */
                            conn_mode,   /* The mode (Auth/Encry/None) */
                            &sec_port);          /* local port */

    if (sock < 0) {

        CCSIP_DEBUG_ERROR(SIP_F_PREFIX
                          "Secure connect failed!!\n",fname);
        return INVALID_SOCKET;
    }
    CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX "Secure connect ok", DEB_F_PREFIX_ARGS(SIP_TLS, fname));
    if (!blocking) {
        /* should not call this api in blocking mode */
        conn_status = platSecSockIsConnected(sock);
        if (conn_status == PLAT_SOCK_CONN_FAILED) {
            (void)sipSocketClose(sock, TRUE);
            CCSIP_DEBUG_ERROR(SIP_F_PREFIX
                              "Establish non-blocking mode secure"
                              " connection failed!!\n", fname);
            return INVALID_SOCKET;
        }
    } else {
        conn_status = PLAT_SOCK_CONN_OK;
    }
    if (sip_tcp_set_sock_options(sock) != TRUE) {
        CCSIP_DEBUG_ERROR(SIP_F_PREFIX "Socket set option failure",
                          fname);
    }

    idx = sip_tcp_get_free_conn_entry();
    if (idx == -1) {
        /* Send create connection failed message to SIP_SPI */
        (void)sipSocketClose(sock, TRUE);
        CCSIP_DEBUG_ERROR(SIP_F_PREFIX
                          "Get free TCP connection entry failed\n",
                           fname);
        return INVALID_SOCKET;
    }

    memset(&sock_addr, 0, sizeof(sock_addr));
    (void) sip_set_sockaddr(&sock_addr, af_listen, create_msg->addr,
                            (uint16_t)(create_msg->port), &addr_len);

    sip_tcp_conn_tab[idx].fd = sock;
    sip_tcp_conn_tab[idx].ipaddr = create_msg->addr;
    sip_tcp_conn_tab[idx].port = create_msg->port;
    sip_tcp_conn_tab[idx].context = spi_msg->context;
    sip_tcp_conn_tab[idx].dirtyFlag = FALSE;
    sip_tcp_conn_tab[idx].addr = sock_addr;
    sip_tcp_conn_tab[idx].soc_type = SIP_SOC_TLS;

    if (conn_status == PLAT_SOCK_CONN_OK) {
        sip_tcp_conn_tab[idx].state = SOCK_CONNECTED;
    } else {
        sip_tcp_conn_tab[idx].state = SOCK_CONNECT_PENDING;
    }
    create_msg->local_listener_port = (uint16) sec_port;
    CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX
                        "Local listening port=%d\n", DEB_F_PREFIX_ARGS(SIP_TLS, fname),
                        create_msg->local_listener_port);
    (void)sip_tcp_attach_socket(sock);
    return (sock);
}
Exemplo n.º 5
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);
    }
}
Exemplo n.º 6
0
void ccsip_dump_recv_msg_info (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];
    cpr_ip_addr_t cc_ipaddr;
    static const char fname[] = "ccsip_dump_recv_msg_info";

    util_ntohl(&cc_ipaddr, cc_remote_ipaddr);
    ipaddr2dotted(ipaddr_str, &cc_ipaddr);

    req_uri = sippmh_get_cached_header_val(pSIPMessage, FROM);
    if (req_uri == NULL) {
        /* No REQ URI, fill with blank */
        req_uri = "";
    }
    cseq = sippmh_get_cached_header_val(pSIPMessage, CSEQ);
    if (cseq == NULL) {
        /* No REQ CSEQ, fill with blank */
        cseq = "";
    }
    callid = sippmh_get_cached_header_val(pSIPMessage, CALLID);
    if (callid == NULL) {
        /* No REQ CSEQ, fill with blank */
        callid = "";
    }

    if (!dump_reg_msg) {
       if (strstr(cseq, SIP_METHOD_REGISTER) != NULL) {
          return;
       }
    }

    /* For messages starting with SIP add 8 byte. default
     * debugs do not show all the SIP message information
     * rather show initial msg.
     */
    if (pSIPMessage->mesg_line != NULL) {
        if (pSIPMessage->mesg_line[0] == 'S' &&
            pSIPMessage->mesg_line[1] == 'I' &&
            pSIPMessage->mesg_line[2] == 'P') {
            disp_buf = &(pSIPMessage->mesg_line[8]);
        } else {
            disp_buf = pSIPMessage->mesg_line;
        }
    } else {
        /*
         * It is possible that this function is called with
         * invalid message or partially received.
         */
        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_RECV, 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 line received */
        DEF_DEBUG(DEB_F_PREFIX"<%s:%-4d>: empty message\n",
                  DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname),
                  ipaddr_str, cc_remote_port);
    }
}