/// Returns a canonical IMS public user identity from a URI as per TS 23.003 /// 13.4. std::string PJUtils::public_id_from_uri(const pjsip_uri* uri) { if (PJSIP_URI_SCHEME_IS_SIP(uri)) { pjsip_sip_uri public_id; memcpy((char*)&public_id, (char*)uri, sizeof(pjsip_sip_uri)); public_id.passwd.slen = 0; public_id.port = 0; public_id.user_param.slen = 0; public_id.method_param.slen = 0; public_id.transport_param.slen = 0; public_id.ttl_param = -1; public_id.lr_param = 0; public_id.maddr_param.slen = 0; public_id.other_param.next = NULL; public_id.header_param.next = NULL; return uri_to_string(PJSIP_URI_IN_FROMTO_HDR, (pjsip_uri*)&public_id); } else if (PJSIP_URI_SCHEME_IS_TEL(uri)) { pjsip_tel_uri public_id; memcpy((char*)&public_id, (char*)uri, sizeof(pjsip_tel_uri)); public_id.context.slen = 0; public_id.ext_param.slen = 0; public_id.isub_param.slen = 0; public_id.other_param.next = NULL; return uri_to_string(PJSIP_URI_IN_FROMTO_HDR, (pjsip_uri*)&public_id); } else { return std::string(); } }
/// Returns a canonical SIP address of record from a URI, as per the rules /// in RFC3261 s10.3 step 5. In particular, strip all parameters and the /// password before rendering the URI to a string. std::string PJUtils::aor_from_uri(const pjsip_sip_uri* uri) { std::string input_uri = uri_to_string(PJSIP_URI_IN_FROMTO_HDR, (pjsip_uri*)uri); std::string returned_aor; pjsip_sip_uri aor; memcpy((char*)&aor, (char*)uri, sizeof(pjsip_sip_uri)); aor.passwd.slen = 0; aor.port = 0; aor.user_param.slen = 0; aor.method_param.slen = 0; aor.transport_param.slen = 0; aor.ttl_param = -1; aor.lr_param = 0; aor.maddr_param.slen = 0; aor.other_param.next = NULL; aor.header_param.next = NULL; returned_aor = uri_to_string(PJSIP_URI_IN_FROMTO_HDR, (pjsip_uri*)&aor); LOG_DEBUG("aor_from_uri converted %s to %s", input_uri.c_str(), returned_aor.c_str()); return returned_aor; }
/// Returns a canonical SIP address of record from a URI, as per the rules /// in RFC3261 s10.3 step 5. In particular, strip all parameters and the /// password before rendering the URI to a string. std::string PJUtils::aor_from_uri(const pjsip_sip_uri* uri) { pjsip_sip_uri aor; memcpy((char*)&aor, (char*)uri, sizeof(pjsip_sip_uri)); aor.passwd.slen = 0; aor.port = 0; aor.user_param.slen = 0; aor.method_param.slen = 0; aor.transport_param.slen = 0; aor.ttl_param = -1; aor.lr_param = 0; aor.maddr_param.slen = 0; aor.other_param.next = NULL; aor.header_param.next = NULL; return uri_to_string(PJSIP_URI_IN_FROMTO_HDR, (pjsip_uri*)&aor); }
/// Adds a Record-Route header to the message with the specified user name, /// port and transport. If the user parameter is NULL the user field is left /// blank. void PJUtils::add_record_route(pjsip_tx_data* tdata, const char* transport, int port, const char* user) { pjsip_rr_hdr* rr = pjsip_rr_hdr_create(tdata->pool); pjsip_sip_uri* uri = pjsip_sip_uri_create(tdata->pool, PJ_FALSE); uri->host = stack_data.name[0]; uri->port = port; pj_strdup2(tdata->pool, &uri->transport_param, transport); uri->lr_param = PJ_TRUE; if (user != NULL) { pj_strdup2(tdata->pool, &uri->user, user); } rr->name_addr.uri = (pjsip_uri*)uri; pjsip_msg_insert_first_hdr(tdata->msg, (pjsip_hdr*)rr); LOG_DEBUG("Added Record-Route header, URI = %s", uri_to_string(PJSIP_URI_IN_ROUTING_HDR, rr->name_addr.uri).c_str()); }
/// Checks whether the next Route header in the message refers to this node, /// and optionally returns the header. If there are no Route headers it /// returns false. pj_bool_t PJUtils::is_next_route_local(const pjsip_msg* msg, pjsip_route_hdr* start, pjsip_route_hdr** hdr) { bool rc = false; pjsip_route_hdr* route_hdr = (pjsip_route_hdr*)pjsip_msg_find_hdr(msg, PJSIP_H_ROUTE, (start != NULL) ? start->next : NULL); if (route_hdr != NULL) { // Found the next Route header, so check whether the URI corresponds to // this node or one of its aliases. pjsip_uri* uri = route_hdr->name_addr.uri; LOG_DEBUG("Found Route header, URI = %s", uri_to_string(PJSIP_URI_IN_ROUTING_HDR, uri).c_str()); if ((is_home_domain(uri)) || (is_uri_local(uri))) { rc = true; if (hdr != NULL) { *hdr = route_hdr; } } } return rc; }
void MementoAppServerTsx::on_initial_request(pjsip_msg* req) { TRC_DEBUG("Memento processing an initial request of type %s", (req->line.req.method.id == PJSIP_INVITE_METHOD) ? "INVITE" : "BYE"); // Get the current time time_t rawtime; time(&rawtime); tm* start_time = localtime(&rawtime); _start_time_xml = create_formatted_timestamp(start_time, XML_PATTERN); _start_time_cassandra = create_formatted_timestamp(start_time, TIMESTAMP_PATTERN); // Is the call originating or terminating? std::string served_user; pjsip_routing_hdr* psu_hdr = (pjsip_routing_hdr*) pjsip_msg_find_hdr_by_name(req, &P_SERVED_USER, NULL); if (psu_hdr != NULL) { pjsip_uri* uri = (pjsip_uri*)pjsip_uri_get_uri(&psu_hdr->name_addr); served_user = uri_to_string(PJSIP_URI_IN_ROUTING_HDR, uri); pjsip_param* sescase = pjsip_param_find(&psu_hdr->other_param, &SESCASE); if ((sescase != NULL) && (pj_stricmp(&sescase->value, &ORIG) == 0)) { TRC_DEBUG("Request is originating"); _outgoing = true; } } // Get the caller, callee and impu values if (_outgoing) { // Get the callee's URI amd name from the To header. _callee_uri = uri_to_string(PJSIP_URI_IN_FROMTO_HDR, (pjsip_uri*)pjsip_uri_get_uri(PJSIP_MSG_TO_HDR(req)->uri)); _callee_name = pj_str_to_string(&((pjsip_name_addr*) (PJSIP_MSG_TO_HDR(req)->uri))->display); // Get the caller's URI and name from the P-Asserted Identity header. If // this is missing, use the From header. pjsip_routing_hdr* asserted_id = (pjsip_routing_hdr*) pjsip_msg_find_hdr_by_name(req, &P_ASSERTED_IDENTITY, NULL); if (asserted_id != NULL) { _caller_uri = uri_to_string(PJSIP_URI_IN_FROMTO_HDR, (pjsip_uri*)pjsip_uri_get_uri(&asserted_id->name_addr)); _caller_name = pj_str_to_string(&asserted_id->name_addr.display); } else { TRC_WARNING("INVITE missing P-Asserted-Identity"); send_request(req); return; } // Set the IMPU equal to the caller's URI _impu = _caller_uri; } else { // Get the callee's URI from the request URI. There can be no name value. _callee_uri = uri_to_string(PJSIP_URI_IN_FROMTO_HDR, req->line.req.uri); // Get the caller's URI and name from the From header. _caller_uri = uri_to_string(PJSIP_URI_IN_FROMTO_HDR, (pjsip_uri*)pjsip_uri_get_uri(PJSIP_MSG_FROM_HDR(req)->uri)); _caller_name = pj_str_to_string(&((pjsip_name_addr*) (PJSIP_MSG_FROM_HDR(req)->uri))->display); // Set the IMPU equal to the callee's URI _impu = _callee_uri; } // Add a unique ID containing the IMPU to the record route header. // This has the format: // <YYYYMMDDHHMMSS>_<unique_id>_<base64 encoded impu>.memento.<home domain> _unique_id = std::to_string(Utils::generate_unique_integer(0,0)); std::string encoded_impu = base64_encode(reinterpret_cast<const unsigned char*>(_impu.c_str()), _impu.length()); std::string dialog_id = std::string(_start_time_cassandra). append("_"). append(_unique_id). append("_"). append(encoded_impu); add_to_dialog(dialog_id); send_request(req); }