pjsip_hdr* parse_hdr_p_charging_function_addresses(pjsip_parse_ctx* ctx) { // The P-Charging-Function-Addresses header has the following ABNF: // // P-Charging-Addr = "P-Charging-Function-Addresses" HCOLON // charge-addr-params // *(SEMI charge-addr-params) // charge-addr-params = ccf / ecf / generic-param // ccf = "ccf" EQUAL gen-value // ecf = "ecf" EQUAL gen-value // // Where the ccf and ecf elements may be repeated to specify backup CDFs // for redundancy. pj_pool_t* pool = ctx->pool; pj_scanner* scanner = ctx->scanner; pjsip_p_c_f_a_hdr* hdr = pjsip_p_c_f_a_hdr_create(pool); pj_str_t name; pj_str_t value; pjsip_param *param; for (;;) { pjsip_parse_param_imp(scanner, pool, &name, &value, PJSIP_PARSE_REMOVE_QUOTE); param = PJ_POOL_ALLOC_T(pool, pjsip_param); param->name = name; param->value = value; if (!pj_stricmp2(&name, "ccf")) { pj_list_insert_before(&hdr->ccf, param); } else if (!pj_stricmp2(&name, "ecf")) { pj_list_insert_before(&hdr->ecf, param); } else { pj_list_insert_before(&hdr->other_param, param); } // We might need to swallow the ';'. if (!pj_scan_is_eof(scanner) && *scanner->curptr == ';') { pj_scan_get_char(scanner); } // If we're EOF or looking at a newline, we're done. pj_scan_skip_whitespace(scanner); if (pj_scan_is_eof(scanner) || (*scanner->curptr == '\r') || (*scanner->curptr == '\n')) { break; } } // We're done parsing this header. pjsip_parse_end_hdr_imp(scanner); return (pjsip_hdr*)hdr; }
void *pjsip_p_c_f_a_hdr_shallow_clone(pj_pool_t* pool, const void* o) { pjsip_p_c_f_a_hdr* hdr = pjsip_p_c_f_a_hdr_create(pool); pjsip_p_c_f_a_hdr* other = (pjsip_p_c_f_a_hdr*)o; pjsip_param_shallow_clone(pool, &hdr->ccf, &other->ccf); pjsip_param_shallow_clone(pool, &hdr->ecf, &other->ecf); pjsip_param_shallow_clone(pool, &hdr->other_param, &other->other_param); return hdr; }
/// Add P-Charging headers on incoming out-of-dialog/dialog initiating requests static void proxy_add_p_charging_header(pjsip_tx_data *tdata) { LOG_DEBUG("Add P-Charging headers"); std::string cdf_domain = PJUtils::pj_str_to_string(&stack_data.cdf_domain); if (cdf_domain != "") { // Add the P-Charging-Function-Addresses. The value of the CDF is passed in // as a parameter in bono - if this isn't present then don't set these // headers. pjsip_p_c_f_a_hdr* p_c_f_a = pjsip_p_c_f_a_hdr_create(tdata->pool); pjsip_param* new_param = (pjsip_param*) pj_pool_alloc(tdata->pool, sizeof(pjsip_param)); new_param->name = STR_CCF; new_param->value = stack_data.cdf_domain; pj_list_insert_before(&p_c_f_a->ccf, new_param); pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)p_c_f_a); // Add the P-Charging-Vector Id. The icid-value is the Call-ID, and the // icid-generated-at is the bono hostname - it must be unique to the node that // generates it. pjsip_cid_hdr* call_id = (pjsip_cid_hdr*)pjsip_msg_find_hdr_by_name(tdata->msg, &STR_CALL_ID, NULL); std::string c_id = PJUtils::pj_str_to_string(&call_id->id); c_id.erase(std::remove(c_id.begin(), c_id.end(), '@'), c_id.end()); c_id.erase(std::remove(c_id.begin(), c_id.end(), '"'), c_id.end()); pjsip_p_c_v_hdr* p_c_v = pjsip_p_c_v_hdr_create(tdata->pool); pj_strdup2(tdata->pool, &p_c_v->icid, c_id.c_str()); p_c_v->icid_gen_addr = stack_data.public_host; pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)p_c_v); } }