/* * Report terminate call setup usage */ void ospReportTermSetupUsage(void) { osp_inbound* inbound = ospGetInboundInfo(); osp_dest* dest = ospGetTermDestination(); OSPTTRANHANDLE trans = -1; OSPE_ROLE_STATE rstate; int errorcode; if (inbound == NULL) { if (dest == NULL) { if (dest->reported == 0) { dest->reported = 1; LM_INFO("report term setup for call_id '%.*s' transaction_id '%llu'\n", dest->callidsize, dest->callid, dest->transid); errorcode = OSPPTransactionNew(_osp_provider, &trans); if (errorcode == OSPC_ERR_NO_ERROR) { if (dest->lastcode == 200) { rstate = OSPC_RSTATE_START; } else if (dest->lastcode == 300) { rstate = OSPC_RSTATE_REDIRECT; } else { rstate = OSPC_RSTATE_STOP; } /* RoleInfo must be set before BuildUsageFromScratch */ OSPPTransactionSetRoleInfo(trans, rstate, OSPC_RFORMAT_OSP, OSPC_RVENDOR_OPENSIPS); ospBuildUsageFromDestination(trans, inbound, dest, 0); OSPPTransactionSetProtocol(trans, OSPC_PROTTYPE_DESTINATION, OSPC_PROTNAME_SIP); ospReportUsageFromDestination(trans, inbound, dest); } } else { LM_DBG("term setup already reported\n"); } } else { LM_ERR("without term setup to report\n"); } } else { LM_ERR("internal error\n"); } }
/* * 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; }
/* * Report originate call setup usage */ void ospReportOrigSetupUsage(void) { osp_inbound* inbound = ospGetInboundInfo(); struct usr_avp* destavp = NULL; int_str destval; osp_dest* dest = NULL; osp_dest* lastused = NULL; OSPTTRANHANDLE trans = -1; int lastcode = 0; OSPE_ROLE_STATE rstate; int errcode; errcode = OSPPTransactionNew(_osp_provider, &trans); if (errcode != OSPC_ERR_NO_ERROR) { return; } if (inbound == NULL) { return; } 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 destination is wrapped in a string */ dest = (osp_dest*)destval.s.s; if (dest->used == 1) { LM_DBG("iterating through used destination\n"); if (dest->reported == 1) { LM_DBG("orig setup already reported\n"); break; } else { dest->reported = 1; ospDumpDestination(dest); lastused = dest; if (dest->lastcode == 200) { rstate = OSPC_RSTATE_START; } else if (dest->lastcode == 300) { rstate = OSPC_RSTATE_REDIRECT; } else { rstate = OSPC_RSTATE_STOP; } /* RoleInfo must be set before BuildUsageFromScratch */ OSPPTransactionSetRoleInfo(trans, rstate, OSPC_RFORMAT_OSP, OSPC_RVENDOR_OPENSIPS); ospBuildUsageFromDestination(trans, inbound, dest, lastcode); OSPPTransactionSetProtocol(trans, OSPC_PROTTYPE_SOURCE, OSPC_PROTNAME_SIP); OSPPTransactionSetProtocol(trans, OSPC_PROTTYPE_DESTINATION, dest->protocol); lastcode = dest->lastcode; } } else { LM_DBG("destination has not been used, breaking out\n"); break; } } if (lastused) { LM_INFO("report orig setup for call_id '%.*s' transaction_id '%llu'\n", lastused->callidsize, lastused->callid, lastused->transid); ospReportUsageFromDestination(trans, inbound, lastused); } else { /* If a Toolkit transaction handle was created, but we did not find * any destinations to report, we need to release the handle. Otherwise, * the ospReportUsageFromDestination will release it. */ OSPPTransactionDelete(trans); } }