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