Example #1
0
/*
 * Report OSP usage from OSP cookie
 * param msg SIP message
 * param cookie OSP cookie (buffer owned by ospReportUsage, can be modified)
 * param callid Call ID
 * param release Who releases the call first. 0 orig, 1 term
 * param type Usage type
 * return
 */
static int ospReportUsageFromCookie(
    struct sip_msg* msg,
    char* cookie,
    OSPT_CALL_ID* callid,
    OSPE_RELEASE release,
    OSPE_ROLE type)
{
    char* tmp;
    char* token;
    char tag;
    char* value;
    unsigned long long transid = 0;
    time_t authtime = 0;
    unsigned destcount = 0;
    time_t duration = 0;
    time_t endtime = time(NULL);
    int cookieflags = 0;
    unsigned releasecode;
    char firstvia[OSP_STRBUF_SIZE];
    char from[OSP_STRBUF_SIZE];
    char rpid[OSP_STRBUF_SIZE];
    char pai[OSP_STRBUF_SIZE];
    char divuser[OSP_STRBUF_SIZE];
    char divhost[OSP_STRBUF_SIZE];
    char pci[OSP_STRBUF_SIZE];
    char to[OSP_STRBUF_SIZE];
    char nexthop[OSP_STRBUF_SIZE];
    char* snid = NULL;
    char* dnid = NULL;
    char* calling;
    char* called;
    char* originator = NULL;
    char* terminator;
    char source[OSP_STRBUF_SIZE];
    char dest[OSP_STRBUF_SIZE];
    char srcdev[OSP_STRBUF_SIZE];
    OSPTTRANHANDLE transaction = -1;
    int errorcode;

    LM_DBG("cookie '%s' type '%d'\n", cookie == NULL ? "NULL" : cookie, type);

    if (cookie != NULL) {
        for (token = strtok_r(cookie, "_", &tmp);
            token;
            token = strtok_r(NULL, "_", &tmp))
        {
            tag = *token;
            value= token + 1;

            switch (tag) {
                case OSP_COOKIE_TRANSID:
                case OSP_COOKIE_TRANSIDUP:
                    transid = atoll(value);
                    cookieflags |= OSP_COOKIEHAS_TRANSID;
                    break;
                case OSP_COOKIE_AUTHTIME:
                case OSP_COOKIE_AUTHTIMEUP:
                    authtime = atoi(value);
                    duration = endtime - authtime;
                    cookieflags |= OSP_COOKIEHAS_AUTHTIME;
                    break;
                case OSP_COOKIE_SRCIP:
                case OSP_COOKIE_SRCIPUP:
                    originator = value;
                    cookieflags |= OSP_COOKIEHAS_SRCIP;
                    break;
                case OSP_COOKIE_DCOUNT:
                case OSP_COOKIE_DCOUNTUP:
                    destcount = (unsigned)atoi(value);
                    cookieflags |= OSP_COOKIEHAS_DSTCOUNT;
                    break;
                case OSP_COOKIE_SNID:
                case OSP_COOKIE_SNIDUP:
                    snid = value;
                    break;
                case OSP_COOKIE_DNID:
                case OSP_COOKIE_DNIDUP:
                    dnid = value;
                    break;
                default:
                    LM_ERR("unexpected tag '%c' / value '%s'\n", tag, value);
                    break;
            }
        }
    }

    switch (type) {
        case OSPC_ROLE_DESTINATION:
            if (cookieflags == OSP_COOKIEHAS_TERMALL) {
                releasecode = 10016;
            } else {
                releasecode = 9016;
            }
            break;
        case OSPC_ROLE_SOURCE:
        case OSPC_ROLE_OTHER:
        case OSPC_ROLE_UNDEFINED:
        default:
            if (cookieflags == OSP_COOKIEHAS_ORIGALL) {
                releasecode = 10016;
            } else {
                releasecode = 9016;
            }
            break;
    }

    if (releasecode == 9016) {
        transid = 0;
        originator = NULL;
        authtime = 0;
        duration = 0;
        destcount = 0;
    }

    ospGetViaAddress(msg, firstvia, sizeof(firstvia));
    ospGetFromUserpart(msg, from, sizeof(from));
    ospGetRpidUserpart(msg, rpid, sizeof(rpid));
    ospGetPaiUserpart(msg, pai, sizeof(pai));
    ospGetDiversion(msg, divuser, sizeof(divuser), divhost, sizeof(divhost));
    ospGetPChargeInfoUserpart(msg, pci, sizeof(pci));
    ospGetToUserpart(msg, to, sizeof(to));
    ospGetNextHop(msg, nexthop, sizeof(nexthop));

    LM_DBG("first via '%s' from '%s' to '%s' next hop '%s'\n",
        firstvia,
        from,
        to,
        nexthop);

    if (release == OSPC_RELEASE_DESTINATION) {
        LM_DBG("term '%s' released the call, call_id '%.*s' transaction_id '%llu'\n",
            firstvia,
            callid->Length,
            callid->Value,
            transid);
        if (originator == NULL) {
            originator = nexthop;
        }
        calling = to;
        called = from;
        terminator = firstvia;
    } else {
        if (release == OSPC_RELEASE_SOURCE) {
            LM_DBG("orig '%s' released the call, call_id '%.*s' transaction_id '%llu'\n",
                firstvia,
                callid->Length,
                callid->Value,
                transid);
        } else {
            LM_DBG("unknown '%s' released the call, call_id '%.*s' transaction_id '%llu'\n",
                firstvia,
                callid->Length,
                callid->Value,
                transid);
        }
        if (originator == NULL) {
            originator = firstvia;
        }
        calling = from;
        called = to;
        terminator = nexthop;
    }

    errorcode = OSPPTransactionNew(_osp_provider, &transaction);

    LM_DBG("created transaction handle '%d' (%d)\n", transaction, errorcode);

    switch (type) {
        case OSPC_ROLE_DESTINATION:
            srcdev[0] = '\0';
            ospConvertToOutAddress(originator, source, sizeof(source));
            strncpy(dest, _osp_out_device, sizeof(dest));
            dest[sizeof(dest) - 1] = '\0';
            break;
        case OSPC_ROLE_SOURCE:
        case OSPC_ROLE_OTHER:
        case OSPC_ROLE_UNDEFINED:
        default:
            ospConvertToOutAddress(originator, srcdev, sizeof(srcdev));
            strncpy(source, _osp_out_device, sizeof(source));
            source[sizeof(source) - 1] = '\0';
            ospConvertToOutAddress(terminator, dest, sizeof(dest));
            break;
    }

    /* RoleInfo must be set before BuildUsageFromScratch */
    OSPPTransactionSetRoleInfo(transaction, OSPC_RSTATE_STOP, OSPC_RFORMAT_OSP, OSPC_RVENDOR_OPENSIPS);

    errorcode = OSPPTransactionBuildUsageFromScratch(
        transaction,
        transid,
        type,
        source,
        dest,
        srcdev,
        "",
        calling,
        OSPC_NFORMAT_E164,
        called,
        OSPC_NFORMAT_E164,
        callid->Length,
        callid->Value,
        0,
        NULL,
        NULL);

    LM_DBG("built usage handle '%d' (%d)\n", transaction, errorcode);

    if ((errorcode == OSPC_ERR_NO_ERROR) && (destcount > 0)) {
        errorcode = OSPPTransactionSetDestinationCount(
            transaction,
            destcount);
    }

    if (errorcode == OSPC_ERR_NO_ERROR) {
        OSPPTransactionSetProtocol(transaction, OSPC_PROTTYPE_SOURCE, OSPC_PROTNAME_SIP);
        OSPPTransactionSetProtocol(transaction, OSPC_PROTTYPE_DESTINATION, OSPC_PROTNAME_SIP);

        OSPPTransactionSetSrcNetworkId(transaction, snid);
        OSPPTransactionSetDestNetworkId(transaction, dnid);

        OSPPTransactionSetRemotePartyId(transaction, OSPC_NFORMAT_E164, rpid);
        OSPPTransactionSetAssertedId(transaction, OSPC_NFORMAT_E164, pai);
        OSPPTransactionSetDiversion(transaction, divuser, divhost);
        OSPPTransactionSetChargeInfo(transaction, OSPC_NFORMAT_E164, pci);

        ospReportUsageWrapper(
            transaction,
            releasecode,
            duration,
            authtime,
            endtime,
            0,
            0,
            0,
            0,
            release);
    }

    return errorcode;
}
Example #2
0
/*
 * Report OSP usage from OSP cookie
 *     SER checks ftag by itself, without release parameter
 * param msg SIP message
 * param cookie OSP cookie
 * param callid Call ID
 * param type Usage type
 * return
 */
static int ospReportUsageFromCookie(
    struct sip_msg* msg,
    char* cookie, 
    OSPTCALLID* callid, 
    OSPE_MSG_ROLETYPES type)
{
    int release;
    char* tmp;
    char* token;
    char tag;
    char* value;
    unsigned long long transid = 0;
    time_t authtime = 0;
    unsigned destinationCount = 0;
    time_t endtime = time(NULL);
    char firstvia[OSP_STRBUF_SIZE];
    char from[OSP_STRBUF_SIZE];
    char to[OSP_STRBUF_SIZE];
    char nexthop[OSP_STRBUF_SIZE];
    char* calling;
    char* called;
    char* originator = NULL;
    char* terminator;
    char* source;
    char srcbuf[OSP_STRBUF_SIZE];
    char* destination;
    char dstbuf[OSP_STRBUF_SIZE];
    char* srcdev;
    char devbuf[OSP_STRBUF_SIZE];
    OSPTTRANHANDLE transaction = -1;
    int errorcode;

    LOG(L_DBG, "osp: ospReportUsageFromCookie\n");

    LOG(L_DBG, "osp: '%s' type '%d'\n", cookie, type);
    if (cookie != NULL) {
        for (token = strtok_r(cookie, "_", &tmp);
            token;
            token = strtok_r(NULL, "_", &tmp))
        {
            tag = *token;
            value= token + 1;

            switch (tag) {
                case OSP_COOKIE_TRANSID:
                case OSP_COOKIE_TRANSIDUP:
                    transid = atoll(value);
                    break;
                case OSP_COOKIE_AUTHTIME:
                case OSP_COOKIE_AUTHTIMEUP:
                    authtime = atoi(value);
                    break;
                case OSP_COOKIE_SRCIP:
                case OSP_COOKIE_SRCIPUP:
                    originator = value;
                    break;
                case OSP_COOKIE_DSTCOUNT:
                case OSP_COOKIE_DSTCOUNTUP:
                    destinationCount = (unsigned)atoi(value);
                    break;
                default:
                    LOG(L_ERR, "osp: ERROR: unexpected tag '%c' / value '%s'\n", tag, value);
                    break;
            }
        }
    }

    ospGetSourceAddress(msg, firstvia, sizeof(firstvia));
    ospGetFromUserpart(msg, from, sizeof(from));
    ospGetToUserpart(msg, to, sizeof(to));
    ospGetNextHop(msg, nexthop, sizeof(nexthop));

    LOG(L_DBG, "osp: first via '%s' from '%s' to '%s' next hop '%s'\n",
        firstvia,
        from,
        to,
        nexthop);

    /* SER checks ftag by itself */
    errorcode = ospGetDirection(msg);
    switch (errorcode) {
        case 0:
            release = OSP_RELEASE_ORIG;
            break;
        case 1:
            release = OSP_RELEASE_TERM;
            break;
        default:
            /* This approach has a problem of flipping called/calling number */
            if (strcmp(firstvia, originator) == 0) {
                release = OSP_RELEASE_ORIG;
            } else {
                release = OSP_RELEASE_TERM;
            }
    }

    if (release == OSP_RELEASE_ORIG) {
        LOG(L_DBG,
            "osp: orig '%s' released the call, call_id '%.*s' transaction_id '%llu'\n",
            firstvia,
            callid->ospmCallIdLen,
            callid->ospmCallIdVal,
            transid);
        if (originator == NULL) {
            originator = firstvia;
        }
        calling = from;
        called = to;
        terminator = nexthop;
    } else {
        release = OSP_RELEASE_TERM;
        LOG(L_DBG,
            "osp: term '%s' released the call, call_id '%.*s' transaction_id '%llu'\n",
            firstvia,
            callid->ospmCallIdLen,
            callid->ospmCallIdVal,
            transid);
        if (originator == NULL) {
            originator = nexthop;
        }
        calling = to;
        called = from;
        terminator = firstvia;
    }

    errorcode = OSPPTransactionNew(_osp_provider, &transaction);

    LOG(L_DBG, "osp: created transaction handle '%d' (%d)\n", transaction, errorcode);

    switch (type) {
        case OSPC_DESTINATION:
            ospConvertAddress(originator, srcbuf, sizeof(srcbuf));
            source = srcbuf;
            destination = _osp_device_ip;
            srcdev = "";
            break;
        case OSPC_SOURCE:
        case OSPC_OTHER:
        case OSPC_UNDEFINED_ROLE:
        default:
            source = _osp_device_ip;
            ospConvertAddress(terminator, dstbuf, sizeof(dstbuf));
            destination = dstbuf;
            ospConvertAddress(originator, devbuf, sizeof(devbuf));
            srcdev = devbuf;
            break;
    }

    errorcode = OSPPTransactionBuildUsageFromScratch(
        transaction,
        transid,
        type,
        source,
        destination,
        srcdev,
        "",
        calling,
        OSPC_E164,
        called,
        OSPC_E164,
        callid->ospmCallIdLen,
        callid->ospmCallIdVal,
        (enum OSPEFAILREASON)0,
        NULL,
        NULL);

    LOG(L_DBG, "osp: built usage handle '%d' (%d)\n", transaction, errorcode);

    if ((errorcode == OSPC_ERR_NO_ERROR) && (destinationCount > 0)) {
        errorcode = OSPPTransactionSetDestinationCount(
            transaction,
            destinationCount);
    }

    ospReportUsageWrapper(
        transaction,
        cookie == NULL ? 9016 : 10016,
        cookie == NULL ? 0 : endtime - authtime,
        authtime,
        endtime,
        0,0,
        0,0,
        release);

    return errorcode;
}
Example #3
0
/*
 * Report OSP usage from OSP cookie
 * param msg SIP message
 * param cookie OSP cookie (buffer owned by ospReportUsage, can be modified)
 * param callid Call ID
 * param release Who releases the call first. 0 orig, 1 term
 * param type Usage type
 * return
 */
static int ospReportUsageFromCookie(
    struct sip_msg* msg,
    char* cookie, 
    OSPTCALLID* callid, 
    int release,
    OSPE_MSG_ROLETYPES type)
{
    char* tmp;
    char* token;
    char tag;
    char* value;
    unsigned long long transid = 0;
    time_t authtime = 0;
    unsigned destinationCount = 0;
    time_t duration = 0;
    time_t endtime = time(NULL);
    int cookieflags = 0;
    unsigned releasecode;
    char firstvia[OSP_STRBUF_SIZE];
    char from[OSP_STRBUF_SIZE];
    char to[OSP_STRBUF_SIZE];
    char nexthop[OSP_STRBUF_SIZE];
    char* calling;
    char* called;
    char* originator = NULL;
    char* terminator;
    char* source;
    char srcbuf[OSP_STRBUF_SIZE];
    char* destination;
    char dstbuf[OSP_STRBUF_SIZE];
    char* srcdev;
    char devbuf[OSP_STRBUF_SIZE];
    OSPTTRANHANDLE transaction = -1;
    int errorcode;

    LM_DBG("'%s' type '%d'\n", cookie, type);
    if (cookie != NULL) {
        for (token = strtok_r(cookie, "_", &tmp);
            token;
            token = strtok_r(NULL, "_", &tmp))
        {
            tag = *token;
            value= token + 1;

            switch (tag) {
                case OSP_COOKIE_TRANSID:
                case OSP_COOKIE_TRANSIDUP:
                    transid = atoll(value);
                    cookieflags |= OSP_COOKIEHAS_TRANSID;
                    break;
                case OSP_COOKIE_AUTHTIME:
                case OSP_COOKIE_AUTHTIMEUP:
                    authtime = atoi(value);
                    duration = endtime - authtime;
                    cookieflags |= OSP_COOKIEHAS_AUTHTIME;
                    break;
                case OSP_COOKIE_SRCIP:
                case OSP_COOKIE_SRCIPUP:
                    originator = value;
                    cookieflags |= OSP_COOKIEHAS_SRCIP;
                    break;
                case OSP_COOKIE_DSTCOUNT:
                case OSP_COOKIE_DSTCOUNTUP:
                    destinationCount = (unsigned)atoi(value);
                    cookieflags |= OSP_COOKIEHAS_DSTCOUNT;
                    break;
                default:
                    LM_ERR("unexpected tag '%c' / value '%s'\n", tag, value);
                    break;
            }
        }
    }

    switch (type) {
        case OSPC_DESTINATION:
            if (cookieflags == OSP_COOKIEHAS_TERMALL) {
                releasecode = 10016;
            } else {
                releasecode = 9016;
            }
            break;
        case OSPC_SOURCE:
        case OSPC_OTHER:
        case OSPC_UNDEFINED_ROLE:
        default:
            if (cookieflags == OSP_COOKIEHAS_ORIGALL) {
                releasecode = 10016;
            } else {
                releasecode = 9016;
            }
            break;
    }

    if (releasecode == 9016) {
        transid = 0;
        originator = NULL;
        authtime = 0;
        duration = 0;
        destinationCount = 0;
    }

    ospGetSourceAddress(msg, firstvia, sizeof(firstvia));
    ospGetFromUserpart(msg, from, sizeof(from));
    ospGetToUserpart(msg, to, sizeof(to));
    ospGetNextHop(msg, nexthop, sizeof(nexthop));

    LM_DBG("first via '%s' from '%s' to '%s' next hop '%s'\n",
        firstvia,
        from,
        to,
        nexthop);

    if (release == OSP_RELEASE_ORIG) {
        LM_DBG("orig '%s' released the call, call_id '%.*s' transaction_id '%llu'\n",
            firstvia,
            callid->ospmCallIdLen,
            callid->ospmCallIdVal,
            transid);
        if (originator == NULL) {
            originator = firstvia;
        }
        calling = from;
        called = to;
        terminator = nexthop;
    } else {
        release = OSP_RELEASE_TERM;
        LM_DBG("term '%s' released the call, call_id '%.*s' transaction_id '%llu'\n",
            firstvia,
            callid->ospmCallIdLen,
            callid->ospmCallIdVal,
            transid);
        if (originator == NULL) {
            originator = nexthop;
        }
        calling = to;
        called = from;
        terminator = firstvia;
    }

    errorcode = OSPPTransactionNew(_osp_provider, &transaction);

    LM_DBG("created transaction handle '%d' (%d)\n", transaction, errorcode);

    switch (type) {
        case OSPC_DESTINATION:
            ospConvertAddress(originator, srcbuf, sizeof(srcbuf));
            source = srcbuf;
            destination = _osp_device_ip;
            srcdev = "";
            break;
        case OSPC_SOURCE:
        case OSPC_OTHER:
        case OSPC_UNDEFINED_ROLE:
        default:
            source = _osp_device_ip;
            ospConvertAddress(terminator, dstbuf, sizeof(dstbuf));
            destination = dstbuf;
            ospConvertAddress(originator, devbuf, sizeof(devbuf));
            srcdev = devbuf;
            break;
    }

    errorcode = OSPPTransactionBuildUsageFromScratch(
        transaction,
        transid,
        type,
        source,
        destination,
        srcdev,
        "",
        calling,
        OSPC_E164,
        called,
        OSPC_E164,
        callid->ospmCallIdLen,
        callid->ospmCallIdVal,
        (enum OSPEFAILREASON)0,
        NULL,
        NULL);

    LM_DBG("built usage handle '%d' (%d)\n", transaction, errorcode);

    if ((errorcode == OSPC_ERR_NO_ERROR) && (destinationCount > 0)) {
        errorcode = OSPPTransactionSetDestinationCount(
            transaction,
            destinationCount);
    }

    ospReportUsageWrapper(
        transaction,
        releasecode,
        duration,
        authtime,
        endtime,
        0,
        0,
        0,
        0,
        release);

    return errorcode;
}