/* * Build SIP message for destination * param msg SIP message * param isfirst Is first destination * param type Main or branch route block * param format URI format * param redirect Is for redirect * return MODULE_RETURNCODE_TRUE success MODULE_RETURNCODE_FALSE failure */ static int ospPrepareDestination( struct sip_msg* msg, int isfirst, int type, int format, int redirect) { char buffer[OSP_HEADERBUF_SIZE]; str newuri = { buffer, sizeof(buffer) }; osp_dest* dest = ospGetNextOrigDestination(); int result = MODULE_RETURNCODE_FALSE; if (dest != NULL) { ospRebuildDestionationUri(&newuri, dest, format); LM_INFO("prepare route to URI '%.*s' for call_id '%.*s' transaction_id '%llu'\n", newuri.len, newuri.s, dest->callidsize, dest->callid, dest->transid); if (type == OSP_MAIN_ROUTE) { if (redirect) { dest->lastcode = 300; } if (isfirst == OSP_FIRST_ROUTE) { set_ruri(msg, &newuri); } else { append_branch(msg, &newuri, NULL, NULL, Q_UNSPECIFIED, 0, NULL); } /* Do not add route specific OSP information */ result = MODULE_RETURNCODE_TRUE; } else if (type == OSP_BRANCH_ROUTE) { /* For branch route, add route specific OSP information */ /* Update the Request-Line */ set_ruri(msg, &newuri); /* Add OSP token header */ ospAddOspHeader(msg, dest->token, dest->tokensize); /* Add branch-specific OSP Cookie */ ospRecordOrigTransaction(msg, dest->transid, dest->srcdev, dest->calling, dest->called, dest->authtime, dest->destcount); /* Handle calling number translation */ ospSetCalling(msg, dest); result = MODULE_RETURNCODE_TRUE; } else { LM_ERR("unsupported route block type\n"); } } else { LM_DBG("there is no more routes\n"); ospReportOrigSetupUsage(); } return result; }
/* * Build SIP message for destination * param msg SIP message * param isfirst Is first destination * param type Main or branch route block * param format URI format * return MODULE_RETURNCODE_TRUE success MODULE_RETURNCODE_FALSE failure */ static int ospPrepareDestination( struct sip_msg* msg, int isfirst, int type, int format) { str newuri = {NULL, 0}; int result = MODULE_RETURNCODE_FALSE; LOG(L_DBG, "osp: ospPrepareDestination\n"); osp_dest *dest = ospGetNextOrigDestination(); if (dest != NULL) { ospRebuildDestionationUri(&newuri, dest->called, dest->host, "", format); LOG(L_INFO, "osp: prepare route to URI '%.*s' for call_id '%.*s' transaction_id '%llu'\n", newuri.len, newuri.s, dest->callidsize, dest->callid, dest->transid); if (type == OSP_MAIN_ROUTE) { if (isfirst == OSP_FIRST_ROUTE) { rewrite_uri(msg, &newuri); } else { append_branch(msg, &newuri, NULL, NULL, Q_UNSPECIFIED, 0, NULL); } result = MODULE_RETURNCODE_TRUE; } else { LOG(L_ERR, "osp: ERROR: unsupported route block type\n"); } } else { LOG(L_DBG, "osp: there is no more routes\n"); ospReportOrigSetupUsage(); } if (newuri.len > 0) { pkg_free(newuri.s); } return result; }
/* * Check if there is an unused and supported originate destination from an AVP * avpid - osp_origdest_avpid * value - osp_dest wrapped in a string * search unused (used==0) & supported (support==1) * return 0 success, -1 failure */ int ospCheckOrigDestination(void) { struct usr_avp* destavp = NULL; int_str destval; osp_dest* dest = NULL; int result = -1; for (destavp = search_first_avp(AVP_VAL_STR, _osp_origdest_avpid, NULL, 0); destavp != NULL; destavp = search_next_avp(destavp, NULL)) { get_avp_val(destavp, &destval); /* OSP destintaion is wrapped in a string */ dest = (osp_dest*)destval.s.s; if (dest->used == 0) { if (dest->supported == 1) { LM_DBG("orig dest exist\n"); result = 0; break; } else { /* Make it looks like used */ dest->used = 1; /* 111 means wrong protocol */ dest->lastcode = 111; LM_DBG("destination does not been supported\n"); } } else { LM_DBG("destination has already been used\n"); } } if (result == -1) { LM_DBG("there is not unused destination\n"); ospReportOrigSetupUsage(); } return result; }
/* * Report call setup usage for both client and server side * param clientcode Client status * param servercode Server status */ void ospRecordEvent( int clientcode, int servercode) { osp_dest* dest; LM_DBG("client status '%d'\n", clientcode); if ((clientcode != 0) && (dest = ospGetLastOrigDestination())) { ospRecordCode(clientcode, dest); if (ospIsToReportUsage(servercode) == 1) { ospReportOrigSetupUsage(); } } LM_DBG("server status '%d'\n", servercode); if ((servercode != 0) && (dest = ospGetTermDestination())) { ospRecordCode(servercode, dest); if (ospIsToReportUsage(servercode) == 1) { ospReportTermSetupUsage(); } } }
/* * Build SIP message for destination * param msg SIP message * param isfirst Is first destination * param route Main or branch route block * param response Is for response * param rsptype SIP response type * return MODULE_RETURNCODE_TRUE success MODULE_RETURNCODE_FALSE failure */ static int ospPrepareDestination( struct sip_msg* msg, int isfirst, int route, int response, int* rsptype) { str cnam; char buffer[OSP_HEADERBUF_SIZE]; str newuri = { buffer, sizeof(buffer) }; osp_inbound* inbound = ospGetInboundInfo(); osp_dest* dest = ospGetNextOrigDestination(); int result = MODULE_RETURNCODE_TRUE; if (inbound != NULL) { if (dest != NULL) { if (response) { /* SIP 300 or 380 response */ if (route == OSP_MAIN_ROUTE) { if (dest->srvtype == OSPC_SERVICE_CNAMQUERY) { LM_INFO("prepare CNAM for call_id '%.*s' transaction_id '%llu'\n", dest->callidsize, dest->callid, dest->transid); if (dest->cnam[0] != '\0') { cnam.s = dest->cnam; cnam.len = strlen(dest->cnam); add_avp(_osp_cnam_avptype | AVP_VAL_STR, _osp_cnam_avpid, (int_str)cnam); } dest->lastcode = 380; *rsptype = 380; } else { /* For default service, voice service or ported number query service */ ospRebuildDestUri(&newuri, dest); LM_INFO("prepare route to URI '%.*s' for call_id '%.*s' transaction_id '%llu'\n", newuri.len, newuri.s, dest->callidsize, dest->callid, dest->transid); if (isfirst == OSP_FIRST_ROUTE) { set_ruri(msg, &newuri); } else { append_branch(msg, &newuri, NULL, NULL, Q_UNSPECIFIED, 0, NULL); } /* Do not add route specific OSP information */ dest->lastcode = 300; *rsptype = 300; } } else { LM_ERR("unsupported route block type\n"); result = MODULE_RETURNCODE_FALSE; } } else { /* Single destination or all destinations */ ospRebuildDestUri(&newuri, dest); LM_INFO("prepare route to URI '%.*s' for call_id '%.*s' transaction_id '%llu'\n", newuri.len, newuri.s, dest->callidsize, dest->callid, dest->transid); if (route == OSP_MAIN_ROUTE) { if (isfirst == OSP_FIRST_ROUTE) { set_ruri(msg, &newuri); } else { append_branch(msg, &newuri, NULL, NULL, Q_UNSPECIFIED, 0, NULL); } /* Do not add route specific OSP information */ } else if (route == OSP_BRANCH_ROUTE) { /* For branch route, add route specific OSP information */ /* Update the Request-Line */ set_ruri(msg, &newuri); /* Add OSP token header */ ospAddOspToken(msg, dest->token, dest->tokensize); /* Add branch-specific OSP Cookie */ ospRecordOrigTransaction(msg, inbound, dest); /* Handle calling number translation */ ospSetCalling(msg, inbound, dest); /* Set call attempt start time */ dest->starttime = time(NULL); } else { LM_ERR("unsupported route block type\n"); result = MODULE_RETURNCODE_FALSE; } } } else { LM_DBG("there is no more routes\n"); if (!response) { ospReportOrigSetupUsage(); } result = MODULE_RETURNCODE_FALSE; } } else { LM_ERR("internal error\n"); result = MODULE_RETURNCODE_FALSE; } return result; }