/** * 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; }
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; }
/** * 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); }
/* * 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); }
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); } }
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); } }