Пример #1
0
/*
 * 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");
    }
}
Пример #2
0
/*
 * 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;
}
Пример #3
0
/*
 * 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);
    }
}