コード例 #1
0
ファイル: usage.c プロジェクト: BackupTheBerlios/ser
/*
 * Report originate call setup usage
 */
void ospReportOrigSetupUsage(void)
{
    osp_dest* dest = NULL;
    osp_dest* lastused = NULL;
    struct usr_avp* destavp = NULL;
    int_str destval;
    struct search_state state;
    OSPTTRANHANDLE transaction = -1;
    int lastcode = 0;
    int errorcode;

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

    errorcode = OSPPTransactionNew(_osp_provider, &transaction);

    for (destavp = search_first_avp(AVP_NAME_STR | AVP_VAL_STR, (int_str)OSP_ORIGDEST_NAME, &destval, &state);
        destavp != NULL;
        destavp = search_next_avp(&state, &destval)) 
    {
        /* OSP destination is wrapped in a string */
        dest = (osp_dest*)destval.s.s;

        if (dest->used == 1) {
            if (dest->reported == 1) {
                LOG(L_DBG, "osp: orig setup already reported\n");
                break;
            } else {
                dest->reported = 1;
            }

            LOG(L_DBG, "osp: iterating through used destination\n");

            ospDumpDestination(dest);

            lastused = dest;

            errorcode = ospBuildUsageFromDestination(transaction, dest, lastcode);

            lastcode = dest->lastcode;
        } else {
            LOG(L_DBG, "osp: destination has not been used, breaking out\n");
            break;
        }
    }

    if (lastused) {
        LOG(L_INFO,
            "osp: report orig setup for call_id '%.*s' transaction_id '%llu'\n",
            lastused->callidsize,
            lastused->callid,
            lastused->transid);
        errorcode = ospReportUsageFromDestination(transaction, 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(transaction);
    }
}
コード例 #2
0
ファイル: res_osp.c プロジェクト: wildzero-cw/callweaver
int cw_osp_terminate(int handle, int cause, time_t start, time_t duration)
{
	unsigned int dummy = 0;
	int res = -1;
	enum OSPEFAILREASON reason;

	time_t endTime = 0;
	time_t alertTime = 0;
	time_t connectTime = 0;
	unsigned isPddInfoPresent = 0;
	unsigned pdd = 0;
	unsigned releaseSource = 0;
	unsigned char *confId = "";
	
	reason = cause2reason(cause);
	if (OSPPTransactionRecordFailure(handle, reason))
		cw_log(LOG_WARNING, "Failed to record call termination for handle %d\n", handle);
	else if (OSPPTransactionReportUsage(handle, duration, start,
			       endTime,alertTime,connectTime,isPddInfoPresent,pdd,releaseSource,confId,
		       	       0, 0, 0, 0, &dummy, NULL))
		cw_log(LOG_WARNING, "Failed to report duration for handle %d\n", handle);
	else {
		cw_log(LOG_DEBUG, "Completed recording handle %d\n", handle);
		OSPPTransactionDelete(handle);
		res = 0;
	}
	return res;
}
コード例 #3
0
ファイル: osptoolkit.c プロジェクト: Distrotech/opensips
/*
 * Report OSP usage thread function
 * param usagearg OSP usage information
 * return
 */
static OSPTTHREADRETURN ospReportUsageWork(
    void* usagearg)
{
    int i;
    const int MAX_RETRIES = 5;
    osp_usage* usage;
    int errorcode;

    usage = (osp_usage*)usagearg;

    OSPPTransactionRecordFailure(
        usage->transaction,
        usage->cause);

#if 0
    OSPPTransactionSetTermCause(
        usage->transaction,
        OSPC_TCAUSE_SIP,
        usage->cause,
        NULL);
#endif

    for (i = 1; i <= MAX_RETRIES; i++) {
        errorcode = OSPPTransactionReportUsage(
            usage->transaction,
            usage->duration,
            usage->start,
            usage->end,
            usage->alert,
            usage->connect,
            usage->haspdd,
            usage->pdd * 1000,
            usage->release,
            NULL, -1, -1, -1, -1, NULL, NULL);

        if (errorcode == OSPC_ERR_NO_ERROR) {
            LM_DBG("reporte usage for '%llu'\n",
                ospGetTransactionId(usage->transaction));
            break;
        } else {
            LM_ERR("failed to report usage for '%llu' (%d) attempt '%d' of '%d'\n",
                ospGetTransactionId(usage->transaction),
                errorcode,
                i,
                MAX_RETRIES);
        }
    }

    OSPPTransactionDelete(usage->transaction);

    free(usage);

    OSPTTHREADRETURN_NULL();
}
コード例 #4
0
ファイル: usage.c プロジェクト: KISSMonX/opensips
/*
 * Report originate call setup usage
 */
void ospReportOrigSetupUsage(void)
{
    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;
    }

    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, 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, 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);
    }
}
コード例 #5
0
/*
 * Request OSP authorization and routeing
 * param msg SIP message
 * param ignore1
 * param ignore2
 * return MODULE_RETURNCODE_TRUE success, MODULE_RETURNCODE_FALSE failure, others error
 */
int ospRequestRouting(
    struct sip_msg* msg,
    char* ignore1,
    char* ignore2)
{
    int i, errcode;
    char rn[OSP_STRBUF_SIZE];
    char cic[OSP_STRBUF_SIZE];
    int npdi;
    OSPE_OPERATOR_NAME type;
    char opname[OSPC_OPNAME_NUMBER][OSP_STRBUF_SIZE];
    osp_inbound inbound;
    char sourcebuf[OSP_STRBUF_SIZE];
    char srcdevbuf[OSP_STRBUF_SIZE];
    char divhostbuf[OSP_STRBUF_SIZE];
    char useragent[OSP_STRBUF_SIZE];
    struct usr_avp* avp = NULL;
    int_str avpval;
    unsigned int cinfonum = 0;
    char cinfo[OSP_DEF_CINFONUM][OSP_STRBUF_SIZE];
    char cinfostr[OSP_STRBUF_SIZE];
    unsigned int callidnumber = 1;
    OSPT_CALL_ID* callids[callidnumber];
    unsigned int logsize = 0;
    char* detaillog = NULL;
    char tohost[OSP_STRBUF_SIZE];
    char tohostbuf[OSP_STRBUF_SIZE];
    const char* preferred[2] = { NULL };
    unsigned int destcount;
    struct timeval ts, te, td;
    char datebuf[OSP_STRBUF_SIZE];
    unsigned int sdpfpnum = 0;
    char sdpfp[OSP_DEF_SDPFPNUM][OSP_STRBUF_SIZE];
    char* sdpfpstr[OSP_DEF_SDPFPNUM];
    OSPTTRANHANDLE trans = -1;
    int result = MODULE_RETURNCODE_FALSE;

    ospInitInboundInfo(&inbound);

    if ((errcode = OSPPTransactionNew(_osp_provider, &trans)) != OSPC_ERR_NO_ERROR) {
        LM_ERR("failed to create new OSP transaction (%d)\n", errcode);
    } else if (ospGetCallId(msg, &(callids[0])) != 0) {
        LM_ERR("failed to extract call id\n");
    } else if (ospGetFromUser(msg, inbound.calling, sizeof(inbound.calling)) != 0) {
        LM_ERR("failed to extract calling number\n");
    } else if ((ospGetUriUser(msg, inbound.called, sizeof(inbound.called)) != 0) && (ospGetToUser(msg, inbound.called, sizeof(inbound.called)) != 0)) {
        LM_ERR("failed to extract called number\n");
    } else if (ospGetSource(msg, inbound.source, sizeof(inbound.source)) != 0) {
        LM_ERR("failed to extract source address\n");
    } else if (ospGetSrcDev(msg, inbound.srcdev, sizeof(inbound.srcdev)) != 0) {
        LM_ERR("failed to extract source deivce address\n");
    } else {
        inbound.authtime = time(NULL);

        if(msg->rcv.bind_address && msg->rcv.bind_address->address_str.s) {
            ospCopyStrToBuffer(&msg->rcv.bind_address->address_str, inbound.ingressaddr, sizeof(inbound.ingressaddr));
        }

        ospConvertToOutAddress(inbound.source, sourcebuf, sizeof(sourcebuf));
        ospConvertToOutAddress(inbound.srcdev, srcdevbuf, sizeof(srcdevbuf));

        switch (_osp_service_type) {
        case 1:
        case 2:
            OSPPTransactionSetServiceType(trans, (_osp_service_type == 1) ? OSPC_SERVICE_NPQUERY : OSPC_SERVICE_CNAMQUERY);

            ospGetToHost(msg, tohost, sizeof(tohost));
            ospConvertToOutAddress(tohost, tohostbuf, sizeof(tohostbuf));
            preferred[0] = tohostbuf;

            destcount = 1;
            break;
        case 0:
        default:
            OSPPTransactionSetServiceType(trans, OSPC_SERVICE_VOICE);

            destcount = _osp_max_dests;
            break;
        }

        if (ospGetNpParam(msg, rn, sizeof(rn), cic, sizeof(cic), &npdi) == 0) {
            OSPPTransactionSetNumberPortability(trans, rn, cic, npdi);
        }

        for (type = OSPC_OPNAME_START; type < OSPC_OPNAME_NUMBER; type++) {
            if (ospGetOperatorName(msg, type, opname[type], sizeof(opname[type])) == 0) {
                OSPPTransactionSetOperatorName(trans, type, opname[type]);
            }
        }

        if (ospGetFromDisplay(msg, inbound.fromdisplay, sizeof(inbound.fromdisplay)) == 0) {
            OSPPTransactionSetFrom(trans, OSPC_NFORMAT_DISPLAYNAME, inbound.fromdisplay);
        }

        if (ospGetFromUri(msg, inbound.fromuri, sizeof(inbound.fromuri)) == 0) {
            OSPPTransactionSetFrom(trans, OSPC_NFORMAT_URL, inbound.fromuri);
        }

        if (ospGetToUri(msg, inbound.touri, sizeof(inbound.touri)) == 0) {
            OSPPTransactionSetTo(trans, OSPC_NFORMAT_URL, inbound.touri);
        }

        if (ospGetPaiUser(msg, inbound.paiuser, sizeof(inbound.paiuser)) == 0) {
            OSPPTransactionSetAssertedId(trans, OSPC_NFORMAT_E164, inbound.paiuser);
        }

        if (ospGetRpidUser(msg, inbound.rpiduser, sizeof(inbound.rpiduser)) == 0) {
            OSPPTransactionSetRemotePartyId(trans, OSPC_NFORMAT_E164, inbound.rpiduser);
        }

        if (ospGetPciUser(msg, inbound.pciuser, sizeof(inbound.pciuser)) == 0) {
            OSPPTransactionSetChargeInfo(trans, OSPC_NFORMAT_E164, inbound.pciuser);
        }

        if (ospGetDiversion(msg, inbound.divuser, sizeof(inbound.divuser), inbound.divhost, sizeof(inbound.divhost)) == 0) {
            ospConvertToOutAddress(inbound.divhost, divhostbuf, sizeof(divhostbuf));
        } else {
            divhostbuf[0] = '\0';
        }
        OSPPTransactionSetDiversion(trans, inbound.divuser, divhostbuf);

        if (ospGetUserAgent(msg, useragent, sizeof(useragent)) == 0) {
            OSPPTransactionSetUserAgent(trans, useragent);
        }

        OSPPTransactionSetProtocol(trans, OSPC_PROTTYPE_SOURCE, OSPC_PROTNAME_SIP);

        if (ospGetAVP(_osp_snid_avpid, _osp_snid_avptype, inbound.snid, sizeof(inbound.snid)) == 0) {
            OSPPTransactionSetNetworkIds(trans, inbound.snid, "");
        } else {
            inbound.snid[0] = '\0';
        }

        if (_osp_cinfo_avpid >= 0) {
            for (i = 0, avp = search_first_avp(_osp_cinfo_avptype, _osp_cinfo_avpid, NULL, 0);
                ((i < OSP_DEF_CINFONUM) && (avp != NULL));
                i++, avp = search_next_avp(avp, NULL))
            {
                get_avp_val(avp, &avpval);
                if ((avp->flags & AVP_VAL_STR) && (avpval.s.s && avpval.s.len)) {
                    snprintf(cinfo[i], sizeof(cinfo[i]), "%.*s", avpval.s.len, avpval.s.s);
                } else {
                    cinfo[i][0] = '\0';
                }
            }
            cinfonum = i;

            cinfostr[0] = '\0';
            for (i = 0; i < cinfonum; i++) {
                if (cinfo[cinfonum - i - 1][0] != '\0') {
                    OSPPTransactionSetCustomInfo(trans, i, cinfo[cinfonum - i - 1]);
                    snprintf(cinfostr + strlen(cinfostr), sizeof(cinfostr) - strlen(cinfostr), "custom_info%d '%s' ", i + 1, cinfo[cinfonum - i - 1]);
                }
            }
        }

        if (ospGetAVP(_osp_srcmedia_avpid, _osp_srcmedia_avptype, inbound.srcmedia, sizeof(inbound.srcmedia)) == 0) {
            OSPPTransactionSetSrcAudioAddr(trans, inbound.srcmedia);
        } else {
            inbound.srcmedia[0] = '\0';
        }

        inbound.date = 0;
        if (ospGetAVP(_osp_reqdate_avpid, _osp_reqdate_avptype, datebuf, sizeof(datebuf)) == 0) {
            if (ospStrToTime(datebuf, &inbound.date) == 0) {
                OSPPTransactionSetRequestDate(trans, inbound.date);
            }
        }

        if (_osp_sdpfp_avpid >= 0) {
            for (i = 0, avp = search_first_avp(_osp_sdpfp_avptype, _osp_sdpfp_avpid, NULL, 0);
                ((i < OSP_DEF_SDPFPNUM) && (avp != NULL));
                i++, avp = search_next_avp(avp, NULL))
            {
                get_avp_val(avp, &avpval);
                if ((avp->flags & AVP_VAL_STR) && (avpval.s.s && avpval.s.len)) {
                    snprintf(sdpfp[i], sizeof(sdpfp[i]), "%.*s", avpval.s.len, avpval.s.s);
                } else {
                    sdpfp[i][0] = '\0';
                }
            }
            sdpfpnum = i;

            for (i = 0; i < sdpfpnum; i++) {
                sdpfpstr[i] = sdpfp[sdpfpnum - i - 1];
            }

            OSPPTransactionSetFingerPrint(trans, sdpfpnum, (const char**)sdpfpstr);
        }

        ospReportIdentity(trans);

        LM_INFO("request auth and routing for: "
            "service '%d' "
            "source '%s' "
            "srcdev '%s' "
            "snid '%s' "
            "calling '%s' "
            "called '%s' "
            "preferred '%s' "
            "nprn '%s' "
            "npcic '%s' "
            "npdi '%d' "
            /*
            "spid '%s' "
            "ocn '%s' "
            "spn '%s' "
            "altspn '%s' "
            "mcc '%s' "
            "mnc '%s' "
            */
            "fromdisplay '%s' "
            "paiuser '%s' "
            "rpiduser '%s' "
            "pciuser '%s' "
            "divuser '%s' "
            "divhost '%s' "
            "srcmedia '%s' "
            "callid '%.*s' "
            "destcount '%d' "
            "%s\n",
            _osp_service_type,
            sourcebuf,
            srcdevbuf,
            inbound.snid,
            inbound.calling,
            inbound.called,
            (preferred[0] == NULL) ? "" : preferred[0],
            rn,
            cic,
            npdi,
            /*
            opname[OSPC_OPNAME_SPID],
            opname[OSPC_OPNAME_OCN],
            opname[OSPC_OPNAME_SPN],
            opname[OSPC_OPNAME_ALTSPN],
            opname[OSPC_OPNAME_MCC],
            opname[OSPC_OPNAME_MNC],
            */
            inbound.fromdisplay,
            inbound.paiuser,
            inbound.rpiduser,
            inbound.pciuser,
            inbound.divuser,
            divhostbuf,
            inbound.srcmedia,
            callids[0]->Length,
            callids[0]->Value,
            destcount,
            cinfostr);

        gettimeofday(&ts, NULL);

        /* try to request authorization */
        errcode = OSPPTransactionRequestAuthorisation(
            trans,             /* transaction handle */
            sourcebuf,         /* from the configuration file */
            srcdevbuf,         /* source device of call, protocol specific, in OSP format */
            inbound.calling,   /* calling number in nodotted e164 notation */
            OSPC_NFORMAT_E164, /* calling number format */
            inbound.called,    /* called number */
            OSPC_NFORMAT_E164, /* called number format */
            "",                /* optional username string, used if no number */
            callidnumber,      /* number of call ids, here always 1 */
            callids,           /* sized-1 array of call ids */
            preferred,         /* preferred destinations */
            &destcount,        /* max destinations, after call dest_count */
            &logsize,          /* size allocated for detaillog (next param) 0=no log */
            detaillog);        /* memory location for detaillog to be stored */

        gettimeofday(&te, NULL);

        timersub(&te, &ts, &td);
        LM_INFO("authreq cost = %lu.%06lu for call-id '%.*s'\n", td.tv_sec, td.tv_usec, callids[0]->Length, callids[0]->Value);

        if ((errcode == OSPC_ERR_NO_ERROR) &&
            (ospLoadRoutes(trans, destcount, &inbound) == 0))
        {
            LM_INFO("there are '%d' OSP routes, call_id '%.*s'\n",
                destcount,
                callids[0]->Length,
                callids[0]->Value);
            result = MODULE_RETURNCODE_TRUE;
        } else {
            LM_ERR("failed to request auth and routing (%d), call_id '%.*s'\n",
                errcode,
                callids[0]->Length,
                callids[0]->Value);
            switch (errcode) {
                case OSPC_ERR_HTTP_BAD_REQUEST:
                    result = -4000;
                    break;
                case OSPC_ERR_TRAN_BAD_REQUEST:
                    result = -4001;
                    break;
                case OSPC_ERR_HTTP_UNAUTHORIZED:
                    result = -4010;
                    break;
                case OSPC_ERR_TRAN_UNAUTHORIZED:
                    result = -4011;
                    break;
                case OSPC_ERR_TRAN_ROUTE_BLOCKED:
                    result = -4030;
                    break;
                case OSPC_ERR_TRAN_ROUTE_NOT_FOUND:
                    result = -4040;
                    break;
                case OSPC_ERR_TRAN_MAY_NOT_ORIGINATE:
                    result = -4050;
                    break;
                case OSPC_ERR_TRAN_CALLING_INVALID:
                    result = -4280;
                    break;
                case OSPC_ERR_SOCK_CONNECT_FAILED:
                    result = -4800;
                    break;
                case OSPC_ERR_SOCK_SELECT_FAILED:
                    result = -4801;
                    break;
                case OSPC_ERR_HTTP_SERVER_NOT_READY:
                    result = -4802;
                    break;
                case OSPC_ERR_TRAN_CALLED_FILTERING:
                    result = -4840;
                    break;
                case OSPC_ERR_HTTP_SERVICE_UNAVAILABLE:
                    result = -5030;
                    break;
                case OSPC_ERR_TRAN_DECLINE:
                    result = -6030;
                    break;
                case OSPC_ERR_NO_ERROR:
                    /* AuthRsp ok but ospLoadRoutes fails */
                    result = MODULE_RETURNCODE_ERROR;
                    break;
                default:
                    result = MODULE_RETURNCODE_FALSE;
                    break;
            }
        }
    }

    if (callids[0] != NULL) {
        OSPPCallIdDelete(&(callids[0]));
    }

    if (trans != -1) {
        OSPPTransactionDelete(trans);
    }

    return result;
}
コード例 #6
0
ファイル: orig_transaction.c プロジェクト: ryzhov/ATS0
/*
 * Request OSP authorization and routeing
 * param msg SIP message
 * param ignore1
 * param ignore2
 * return MODULE_RETURNCODE_TRUE success, MODULE_RETURNCODE_FALSE failure, MODULE_RETURNCODE_ERROR error
 */
int ospRequestRouting(
    struct sip_msg* msg,
    char* ignore1,
    char* ignore2)
{
    int errcode;
    time_t authtime;
    char calling[OSP_STRBUF_SIZE];
    char called[OSP_STRBUF_SIZE];
    char rn[OSP_STRBUF_SIZE];
    char cic[OSP_STRBUF_SIZE];
    int npdi;
    OSPE_OPERATOR_NAME type;
    char opname[OSPC_OPNAME_NUMBER][OSP_STRBUF_SIZE];
    char source[OSP_STRBUF_SIZE];
    char sourcebuf[OSP_STRBUF_SIZE];
    char srcdev[OSP_STRBUF_SIZE];
    char srcdevbuf[OSP_STRBUF_SIZE];
    char rpid[OSP_STRBUF_SIZE];
    char pai[OSP_STRBUF_SIZE];
    char divuser[OSP_STRBUF_SIZE];
    char divhost[OSP_STRBUF_SIZE];
    char divhostbuf[OSP_STRBUF_SIZE];
    char pci[OSP_STRBUF_SIZE];
    struct usr_avp* snidavp = NULL;
    int_str snidval;
    char snid[OSP_STRBUF_SIZE];
    struct usr_avp* cinfoavp = NULL;
    int_str cinfoval;
    unsigned int cinfonum = 0, i;
    char cinfo[OSP_DEF_CINFOS][OSP_STRBUF_SIZE];
    char cinfostr[OSP_STRBUF_SIZE];
    unsigned int callidnumber = 1;
    OSPT_CALL_ID* callids[callidnumber];
    unsigned int logsize = 0;
    char* detaillog = NULL;
    char tohost[OSP_STRBUF_SIZE];
    char tohostbuf[OSP_STRBUF_SIZE];
    const char* preferred[2] = { NULL };
    unsigned int destcount;
    OSPTTRANHANDLE trans = -1;
    int result = MODULE_RETURNCODE_FALSE;

    if ((errcode = OSPPTransactionNew(_osp_provider, &trans)) != OSPC_ERR_NO_ERROR) {
        LM_ERR("failed to create new OSP transaction (%d)\n", errcode);
    } else if (ospGetFromUserpart(msg, calling, sizeof(calling)) != 0) {
        LM_ERR("failed to extract calling number\n");
    } else if ((ospGetUriUserpart(msg, called, sizeof(called)) != 0) && (ospGetToUserpart(msg, called, sizeof(called)) != 0)) {
        LM_ERR("failed to extract called number\n");
    } else if (ospGetCallId(msg, &(callids[0])) != 0) {
        LM_ERR("failed to extract call id\n");
    } else if (ospGetSource(msg, source, sizeof(source)) != 0) {
        LM_ERR("failed to extract source address\n");
    } else if (ospGetSourceDevice(msg, srcdev, sizeof(srcdev)) != 0) {
        LM_ERR("failed to extract source deivce address\n");
    } else {
        authtime = time(NULL);

        ospConvertToOutAddress(source, sourcebuf, sizeof(sourcebuf));
        ospConvertToOutAddress(srcdev, srcdevbuf, sizeof(srcdevbuf));

        switch (_osp_service_type) {
        case 1:
            OSPPTransactionSetServiceType(trans, OSPC_SERVICE_NPQUERY);

            ospGetToHostpart(msg, tohost, sizeof(tohost));
            ospConvertToOutAddress(tohost, tohostbuf, sizeof(tohostbuf));
            preferred[0] = tohostbuf;

            destcount = 1;
            break;
        case 0:
        default:
            OSPPTransactionSetServiceType(trans, OSPC_SERVICE_VOICE);

            destcount = _osp_max_dests;
            break;
        }

        if (ospGetNpParameters(msg, rn, sizeof(rn), cic, sizeof(cic), &npdi) == 0) {
            OSPPTransactionSetNumberPortability(trans, rn, cic, npdi);
        }

        for (type = OSPC_OPNAME_START; type < OSPC_OPNAME_NUMBER; type++) {
            if (ospGetOperatorName(msg, type, opname[type], sizeof(opname[type])) == 0) {
                OSPPTransactionSetOperatorName(trans, type, opname[type]);
            }
        }

        if (ospGetRpidUserpart(msg, rpid, sizeof(rpid)) == 0) {
            OSPPTransactionSetRemotePartyId(trans, OSPC_NFORMAT_E164, rpid);
        }

        if (ospGetPaiUserpart(msg, pai, sizeof(pai)) == 0) {
            OSPPTransactionSetAssertedId(trans, OSPC_NFORMAT_E164, pai);
        }

        if (ospGetDiversion(msg, divuser, sizeof(divuser), divhost, sizeof(divhost)) == 0) {
            ospConvertToOutAddress(divhost, divhostbuf, sizeof(divhostbuf));
        } else {
            divhostbuf[0] = '\0';
        }
        OSPPTransactionSetDiversion(trans, divuser, divhostbuf);

        OSPPTransactionSetProtocol(trans, OSPC_PROTTYPE_SOURCE, OSPC_PROTNAME_SIP);

        if (ospGetPChargeInfoUserpart(msg, pci, sizeof(pci)) == 0) {
            OSPPTransactionSetChargeInfo(trans, OSPC_NFORMAT_E164, pci);
        }

        if ((_osp_snid_avpid >= 0) &&
            ((snidavp = search_first_avp(_osp_snid_avptype, _osp_snid_avpid, &snidval, 0)) != NULL) &&
            (snidavp->flags & AVP_VAL_STR) && (snidval.s.s && snidval.s.len))
        {
            snprintf(snid, sizeof(snid), "%.*s", snidval.s.len, snidval.s.s);
            snid[sizeof(snid) - 1] = '\0';
            OSPPTransactionSetNetworkIds(trans, snid, "");
        } else {
            snid[0] = '\0';
        }

        if (_osp_cinfo_avpid >= 0) {
            for (i = 0, cinfoavp = search_first_avp(_osp_cinfo_avptype, _osp_cinfo_avpid, NULL, 0);
                ((i < OSP_DEF_CINFOS) && (cinfoavp != NULL));
                i++, cinfoavp = search_next_avp(cinfoavp, NULL))
            {
                get_avp_val(cinfoavp, &cinfoval);
                if ((cinfoavp->flags & AVP_VAL_STR) && (cinfoval.s.s && cinfoval.s.len)) {
                    snprintf(cinfo[i], sizeof(cinfo[i]), "%.*s", cinfoval.s.len, cinfoval.s.s);
                    cinfo[i][sizeof(cinfo[i]) - 1] = '\0';
                } else {
                    cinfo[i][0] = '\0';
                }
            }
            cinfonum = i;

            cinfostr[0] = '\0';
            for (i = 0; i < cinfonum; i++) {
                if (cinfo[cinfonum - i - 1][0] != '\0') {
                    OSPPTransactionSetCustomInfo(trans, i, cinfo[cinfonum - i - 1]);
                    snprintf(cinfostr + strlen(cinfostr), sizeof(cinfostr) - strlen(cinfostr), "custom_info%d '%s' ", i + 1, cinfo[cinfonum - i - 1]);
                }
            }
            cinfostr[sizeof(cinfostr) - 1] = '\0';
        }

        LM_INFO("request auth and routing for: "
            "service_type '%d' "
            "source '%s' "
            "source_dev '%s' "
            "source_networkid '%s' "
            "calling '%s' "
            "called '%s' "
            "preferred '%s' "
            "nprn '%s' "
            "npcic '%s' "
            "npdi '%d' "
            /*
            "spid '%s' "
            "ocn '%s' "
            "spn '%s' "
            "altspn '%s' "
            "mcc '%s' "
            "mnc '%s' "
            */
            "rpid '%s' "
            "pai '%s' "
            "div_user '%s' "
            "div_host '%s' "
            "pci '%s' "
            "call_id '%.*s' "
            "dest_count '%d' "
            "%s\n",
            _osp_service_type,
            sourcebuf,
            srcdevbuf,
            snid,
            calling,
            called,
            (preferred[0] == NULL) ? "" : preferred[0],
            rn,
            cic,
            npdi,
            /*
            opname[OSPC_OPNAME_SPID],
            opname[OSPC_OPNAME_OCN],
            opname[OSPC_OPNAME_SPN],
            opname[OSPC_OPNAME_ALTSPN],
            opname[OSPC_OPNAME_MCC],
            opname[OSPC_OPNAME_MNC],
            */
            rpid,
            pai,
            divuser,
            divhostbuf,
            pci,
            callids[0]->Length,
            callids[0]->Value,
            destcount,
            cinfostr);

        /* try to request authorization */
        errcode = OSPPTransactionRequestAuthorisation(
            trans,             /* transaction handle */
            sourcebuf,         /* from the configuration file */
            srcdevbuf,         /* source device of call, protocol specific, in OSP format */
            calling,           /* calling number in nodotted e164 notation */
            OSPC_NFORMAT_E164, /* calling number format */
            called,            /* called number */
            OSPC_NFORMAT_E164, /* called number format */
            "",                /* optional username string, used if no number */
            callidnumber,      /* number of call ids, here always 1 */
            callids,           /* sized-1 array of call ids */
            preferred,         /* preferred destinations */
            &destcount,        /* max destinations, after call dest_count */
            &logsize,          /* size allocated for detaillog (next param) 0=no log */
            detaillog);        /* memory location for detaillog to be stored */

        if ((errcode == OSPC_ERR_NO_ERROR) &&
            (ospLoadRoutes(trans, destcount, source, srcdev, called, authtime, rpid, pai, divuser, divhostbuf, pci) == 0))
        {
            LM_INFO("there are '%d' OSP routes, call_id '%.*s'\n",
                destcount,
                callids[0]->Length,
                callids[0]->Value);
            result = MODULE_RETURNCODE_TRUE;
        } else {
            LM_ERR("failed to request auth and routing (%d), call_id '%.*s'\n",
                errcode,
                callids[0]->Length,
                callids[0]->Value);
            switch (errcode) {
                case OSPC_ERR_TRAN_ROUTE_BLOCKED:
                    result = -403;
                    break;
                case OSPC_ERR_TRAN_ROUTE_NOT_FOUND:
                    result = -404;
                    break;
                case OSPC_ERR_TRAN_CALLING_INVALID:
                    result = -428;
                    break;
                case OSPC_ERR_TRAN_CALLED_FILTERING:
                    result = -484;
                    break;
                case OSPC_ERR_NO_ERROR:
                    /* AuthRsp ok but ospLoadRoutes fails */
                    result = MODULE_RETURNCODE_ERROR;
                    break;
                default:
                    result = MODULE_RETURNCODE_FALSE;
                    break;
            }
        }
    }

    if (callids[0] != NULL) {
        OSPPCallIdDelete(&(callids[0]));
    }

    if (trans != -1) {
        OSPPTransactionDelete(trans);
    }

    return result;
}
コード例 #7
0
/*
 * Validate OSP token
 * param ignore1
 * param ignore2
 * return  MODULE_RETURNCODE_TRUE success, MODULE_RETURNCODE_FALSE failure
 */
int ospValidateHeader (
    struct sip_msg* msg, 
    char* ignore1, 
    char* ignore2)
{
    int errorcode; 
    OSPTTRANHANDLE transaction = -1;
    unsigned int authorized = 0;
    unsigned int timelimit = 0;
    void* detaillog = NULL;
    unsigned int logsize = 0;
    unsigned char* callidval = (unsigned char*)"";
    OSPTCALLID* callid = NULL;
    unsigned callidsize = 0;
    unsigned char token[OSP_TOKENBUF_SIZE];
    unsigned int tokensize = sizeof(token);
    osp_dest dest;
    int result = MODULE_RETURNCODE_FALSE;

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

    ospInitDestination(&dest);

    if ((errorcode = OSPPTransactionNew(_osp_provider, &transaction) != 0)) {
        LOG(L_ERR, "osp: ERROR: failed to create a new OSP transaction handle (%d)\n", errorcode);
    } else if ((ospGetRpidUserpart(msg, dest.calling, sizeof(dest.calling)) != 0) && 
        (ospGetFromUserpart(msg, dest.calling, sizeof(dest.calling)) != 0))
    {
        LOG(L_ERR, "osp: ERROR: failed to extract calling number\n");
    } else if ((ospGetUriUserpart(msg, dest.called, sizeof(dest.called)) != 0) &&
        (ospGetToUserpart(msg, dest.called, sizeof(dest.called)) != 0))
    {
        LOG(L_ERR, "osp: ERROR: failed to extract called number\n");
    } else if (ospGetCallId(msg, &callid) != 0) {
        LOG(L_ERR, "osp: ERROR: failed to extract call id\n");
    } else if (ospGetSourceAddress(msg, dest.source, sizeof(dest.source)) != 0) {
        LOG(L_ERR, "osp: ERROR: failed to extract source address\n");
    } else if (ospGetOspHeader(msg, token, &tokensize) != 0) {
        LOG(L_ERR, "osp: ERROR: failed to extract OSP authorization token\n");
    } else {
        LOG(L_INFO, 
            "osp: validate token for: "
            "transaction_handle '%i' "
            "e164_source '%s' "
            "e164_dest '%s' "
            "validate_call_id '%s' "
            "call_id '%.*s'\n",
            transaction,
            dest.calling,
            dest.called,
            _osp_validate_callid == 0 ? "No" : "Yes",
            callid->ospmCallIdLen,
            callid->ospmCallIdVal);

        if (_osp_validate_callid != 0) {
            callidsize = callid->ospmCallIdLen;
            callidval = callid->ospmCallIdVal;
        }

        errorcode = OSPPTransactionValidateAuthorisation(
            transaction,
            "",
            "",
            "",
            "",
            dest.calling,
            OSPC_E164,
            dest.called,
            OSPC_E164,
            callidsize,
            callidval,
            tokensize,
            token,
            &authorized,
            &timelimit,
            &logsize,
            detaillog,
            _osp_token_format);
    
        if (callid->ospmCallIdLen > sizeof(dest.callid) - 1) {
            dest.callidsize = sizeof(dest.callid) - 1;
        } else {
            dest.callidsize = callid->ospmCallIdLen;
        }
        memcpy(dest.callid, callid->ospmCallIdVal, dest.callidsize);
        dest.callid[dest.callidsize] = 0;
        dest.tid = ospGetTransactionId(transaction);
        dest.type = OSPC_DESTINATION;
        dest.authtime = time(NULL);
        strcpy(dest.host, _osp_device_ip);

        ospSaveTermDestination(&dest);

        if ((errorcode == 0) && (authorized == 1)) {
            LOG(L_DBG, 
                "osp: call is authorized for %d seconds, call_id '%.*s' transaction_id '%lld'",
                timelimit,
                dest.callidsize,
                dest.callid,
                dest.tid);
            ospRecordTermTransaction(msg, transaction, dest.source, dest.calling, dest.called, dest.authtime);
            result = MODULE_RETURNCODE_TRUE;
        } else {
            LOG(L_ERR, "osp: ERROR: token is invalid (%i)\n", errorcode);

            /* 
             * Update terminating status code to 401 and report terminating setup usage.
             * We may need to make 401 configurable, just in case a user decides to reply with
             * a different code.  Other options - trigger call setup usage reporting from the cpl
             * (after replying with an error code), or maybe use a different tm callback.
             */
            ospRecordEvent(0, 401);
        }
    }

    if (transaction != -1) {
        OSPPTransactionDelete(transaction);
    }

    if (callid != NULL) {
        OSPPCallIdDelete(&callid);
    }
    
    return result;
}
コード例 #8
0
ファイル: res_osp.c プロジェクト: wildzero-cw/callweaver
int cw_osp_next(struct cw_osp_result *result, int cause)
{
	int res = 0;
	int tokenlen;
	unsigned int dummy=0;
	unsigned int timelimit;
	unsigned int callidlen;
	char callidstr[OSPC_CALLID_MAXSIZE] = "";
	char callednum[2048]="";
	char callingnum[2048]="";
	char destination[2048]="";
	char token[2000];
	OSPE_DEST_PROT prot;
	OSPE_DEST_OSP_ENABLED ospenabled;

	result->tech[0] = '\0';
	result->dest[0] = '\0';
	result->token[0] = '\0';

	if (result->handle > -1) {
		dummy = 0;
		if (result->numresults) {
			tokenlen = sizeof(token);
			while(!res && result->numresults) {
				result->numresults--;
				callidlen = sizeof(callidstr);
				if (!OSPPTransactionGetNextDestination(result->handle, OSPC_FAIL_INCOMPATIBLE_DEST, 0, NULL, NULL, &timelimit, &callidlen, callidstr, 
									sizeof(callednum), callednum, sizeof(callingnum), callingnum, sizeof(destination), destination, 0, NULL, &tokenlen, token)) {
					if (!OSPPTransactionIsDestOSPEnabled (result->handle, &ospenabled) && (ospenabled == OSPE_OSP_FALSE)) {
						result->token[0] = 0;
					}
					else {
						cw_base64encode(result->token, token, tokenlen, sizeof(result->token) - 1);
					}
					if ((strlen(destination) > 2) && !OSPPTransactionGetDestProtocol(result->handle, &prot)) {
						res = 1;
						/* Strip leading and trailing brackets */
						destination[strlen(destination) - 1] = '\0';
						switch(prot) {
						case OSPE_DEST_PROT_H323_SETUP:
							cw_copy_string(result->tech, "H323", sizeof(result->tech));
							snprintf(result->dest, sizeof(result->dest), "%s@%s", callednum, destination + 1);
							break;
						case OSPE_DEST_PROT_SIP:
							cw_copy_string(result->tech, "SIP", sizeof(result->tech));
							snprintf(result->dest, sizeof(result->dest), "%s@%s", callednum, destination + 1);
							break;
						case OSPE_DEST_PROT_IAX:
							cw_copy_string(result->tech, "IAX", sizeof(result->tech));
							snprintf(result->dest, sizeof(result->dest), "%s@%s", callednum, destination + 1);
							break;
						default:
							cw_log(LOG_DEBUG, "Unknown destination protocol '%d', skipping...\n", prot);
							res = 0;
						}
					} else {
						cw_log(LOG_DEBUG, "Missing destination protocol\n");
						break;
					}
				}
			}
			
		}
		if (!res) {
			OSPPTransactionDelete(result->handle);
			result->handle = -1;
		}
		
	}
	return res;
}
コード例 #9
0
ファイル: res_osp.c プロジェクト: wildzero-cw/callweaver
int cw_osp_lookup(struct cw_channel *chan, char *provider, char *extension, char *callerid, struct cw_osp_result *result)
{
	int cres;
	int res = 0;
	int counts;
	int tokenlen;
	unsigned int dummy=0;
	unsigned int timelimit;
	unsigned int callidlen;
	char callidstr[OSPC_CALLID_MAXSIZE] = "";
	struct osp_provider *osp;
	char source[OSP_MAX] = ""; /* Same length as osp->source */
	char callednum[2048]="";
	char callingnum[2048]="";
	char destination[2048]="";
	char token[2000];
	char tmp[256]="", *l, *n;
	OSPE_DEST_PROT prot;
	OSPE_DEST_OSP_ENABLED ospenabled;
	char *devinfo = NULL;

	result->handle = -1;
	result->numresults = 0;
	result->tech[0] = '\0';
	result->dest[0] = '\0';
	result->token[0] = '\0';

	if (!provider || !strlen(provider))
		provider = "default";

	if (!callerid)
		callerid = "";
	cw_copy_string(tmp, callerid, sizeof(tmp));
	cw_callerid_parse(tmp, &n, &l);
	if (!l)
		l = "";
	else {
		cw_shrink_phone_number(l);
		if (!cw_isphonenumber(l))
			l = "";
	}
	callerid = l;

	if (chan) {
		cres = cw_autoservice_start(chan);
		if (cres < 0)
			return cres;
	}
	cw_mutex_lock(&osplock);
	osp = providers;
	while(osp) {
		if (!strcasecmp(osp->name, provider)) {
			if (OSPPTransactionNew(osp->handle, &result->handle)) {
				cw_log(LOG_WARNING, "Unable to create OSP Transaction handle!\n");
			} else {
				cw_copy_string(source, osp->source, sizeof(source));
				res = 1;
			}
			break;
		}
		osp = osp->next;
	}
	cw_mutex_unlock(&osplock);
	if (res) {
		res = 0;
		/* No more than 10 back */
		counts = 10;
		dummy = 0;
		devinfo = pbx_builtin_getvar_helper (chan, "OSPPEER");
		if (!devinfo) {
			devinfo = "";
		}
		if (!OSPPTransactionRequestAuthorisation(result->handle, source, devinfo, 
			  callerid,OSPC_E164, extension, OSPC_E164, NULL, 0, NULL, NULL, &counts, &dummy, NULL)) {
			if (counts) {
				tokenlen = sizeof(token);
				result->numresults = counts - 1;
				callidlen = sizeof(callidstr);
				if (!OSPPTransactionGetFirstDestination(result->handle, 0, NULL, NULL, &timelimit, &callidlen, callidstr, 
					sizeof(callednum), callednum, sizeof(callingnum), callingnum, sizeof(destination), destination, 0, NULL, &tokenlen, token)) {
					cw_log(LOG_DEBUG, "Got destination '%s' and called: '%s' calling: '%s' for '%s' (provider '%s')\n",
						destination, callednum, callingnum, extension, provider);
					/* Only support OSP server with only one duration limit */
					if (cw_channel_cmpwhentohangup (chan, timelimit) < 0) {
						cw_channel_setwhentohangup (chan, timelimit);	
					}
					do {
						if (!OSPPTransactionIsDestOSPEnabled (result->handle, &ospenabled) && (ospenabled == OSPE_OSP_FALSE)) {
							result->token[0] = 0;
						}
						else {
							cw_base64encode(result->token, token, tokenlen, sizeof(result->token) - 1);
						}
						if ((strlen(destination) > 2) && !OSPPTransactionGetDestProtocol(result->handle, &prot)) {
							res = 1;
							/* Strip leading and trailing brackets */
							destination[strlen(destination) - 1] = '\0';
							switch(prot) {
							case OSPE_DEST_PROT_H323_SETUP:
								cw_copy_string(result->tech, "H323", sizeof(result->tech));
								snprintf(result->dest, sizeof(result->dest), "%s@%s", callednum, destination + 1);
								break;
							case OSPE_DEST_PROT_SIP:
								cw_copy_string(result->tech, "SIP", sizeof(result->tech));
								snprintf(result->dest, sizeof(result->dest), "%s@%s", callednum, destination + 1);
								break;
							case OSPE_DEST_PROT_IAX:
								cw_copy_string(result->tech, "IAX", sizeof(result->tech));
								snprintf(result->dest, sizeof(result->dest), "%s@%s", callednum, destination + 1);
								break;
							default:
								cw_log(LOG_DEBUG, "Unknown destination protocol '%d', skipping...\n", prot);
								res = 0;
							}
							if (!res && result->numresults) {
								result->numresults--;
								callidlen = sizeof(callidstr);
								if (OSPPTransactionGetNextDestination(result->handle, OSPC_FAIL_INCOMPATIBLE_DEST, 0, NULL, NULL, &timelimit, &callidlen, callidstr, 
										sizeof(callednum), callednum, sizeof(callingnum), callingnum, sizeof(destination), destination, 0, NULL, &tokenlen, token)) {
										break;
								}
							}
						} else {
							cw_log(LOG_DEBUG, "Missing destination protocol\n");
							break;
						}
					} while(!res && result->numresults);
				}
			}
			
		}
		if (!res) {
			OSPPTransactionDelete(result->handle);
			result->handle = -1;
		}
		
	}
	if (!osp) 
		cw_log(LOG_NOTICE, "OSP Provider '%s' does not exist!\n", provider);
	if (chan) {
		cres = cw_autoservice_stop(chan);
		if (cres < 0)
			return cres;
	}
	return res;
}
コード例 #10
0
ファイル: orig_transaction.c プロジェクト: 4N7HR4X/kamailio
/*
 * Request OSP authorization and routeing
 * param msg SIP message
 * param ignore1
 * param ignore2
 * return MODULE_RETURNCODE_TRUE success, MODULE_RETURNCODE_FALSE failure
 */
int ospRequestRouting(
    struct sip_msg* msg, 
    char* ignore1, 
    char* ignore2)
{
    int errorcode;
    time_t authtime;
    char source[OSP_E164BUF_SIZE];
    char sourcedev[OSP_STRBUF_SIZE];
    char src[OSP_STRBUF_SIZE];
    char destination[OSP_E164BUF_SIZE];
    unsigned int callidnumber = 1;
    OSPTCALLID* callids[callidnumber];
    unsigned int logsize = 0;
    char* detaillog = NULL;
    const char** preferred = NULL;
    unsigned int destcount;
    OSPTTRANHANDLE transaction = -1;
    int result = MODULE_RETURNCODE_FALSE;

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

    authtime = time(NULL);

    destcount = _osp_max_dests;

    if ((errorcode = OSPPTransactionNew(_osp_provider, &transaction)) != OSPC_ERR_NO_ERROR) {
        LOG(L_ERR, "osp: ERROR: failed to create new OSP transaction (%d)\n", errorcode);
    } else if ((ospGetRpidUserpart(msg, source, sizeof(source)) != 0) &&
        (ospGetFromUserpart(msg, source, sizeof(source)) != 0)) 
    {
        LOG(L_ERR, "osp: ERROR: failed to extract calling number\n");
    } else if ((ospGetUriUserpart(msg, destination, sizeof(destination)) != 0) &&
        (ospGetToUserpart(msg, destination, sizeof(destination)) != 0)) 
    {
        LOG(L_ERR, "osp: ERROR: failed to extract called number\n");
    } else if (ospGetCallId(msg, &(callids[0])) != 0) {
        LOG(L_ERR, "osp: ERROR: failed to extract call id\n");
    } else if (ospGetSourceAddress(msg, sourcedev, sizeof(sourcedev)) != 0) {
        LOG(L_ERR, "osp: ERROR: failed to extract source address\n");
    } else {
        ospConvertAddress(sourcedev, src, sizeof(src));

        LOG(L_INFO,
            "osp: request auth and routing for: "
            "source '%s' "
            "source_port '%s' "
            "source_dev '%s' "
            "e164_source '%s' "
            "e164_dest '%s' "
            "call_id '%.*s' "
            "dest_count '%i'\n",
            _osp_device_ip,
            _osp_device_port,
            src,                        /* sourcedev in "[x.x.x.x]" or host.domain format */
            source,
            destination,
            callids[0]->ospmCallIdLen,
            callids[0]->ospmCallIdVal,
            destcount
        );    

        /* try to request authorization */
        errorcode = OSPPTransactionRequestAuthorisation(
            transaction,       /* transaction handle */
            _osp_device_ip,    /* from the configuration file */
            src,               /* source of call, protocol specific, in OSP format */
            source,            /* calling number in nodotted e164 notation */
            OSPC_E164,         /* calling number format */
            destination,       /* called number */
            OSPC_E164,         /* called number format */
            "",                /* optional username string, used if no number */
            callidnumber,      /* number of call ids, here always 1 */
            callids,           /* sized-1 array of call ids */
            preferred,         /* preferred destinations, here always NULL */
            &destcount,        /* max destinations, after call dest_count */
            &logsize,          /* size allocated for detaillog (next param) 0=no log */
            detaillog);        /* memory location for detaillog to be stored */

        if ((errorcode == OSPC_ERR_NO_ERROR) &&
            (ospLoadRoutes(transaction, destcount, _osp_device_ip, sourcedev, destination, authtime) == 0))
        {
            LOG(L_INFO,
                "osp: there are '%d' OSP routes, call_id '%.*s'\n",
                destcount,
                callids[0]->ospmCallIdLen,
                callids[0]->ospmCallIdVal);
            result = MODULE_RETURNCODE_TRUE;
        } else {
            LOG(L_ERR,
                "osp: ERROR: failed to request auth and routing (%i), call_id '%.*s\n",
                errorcode,
                callids[0]->ospmCallIdLen,
                callids[0]->ospmCallIdVal);
            switch (errorcode) {
                case OSPC_ERR_TRAN_ROUTE_BLOCKED:
                    result = -403;
                    break;
                case OSPC_ERR_TRAN_ROUTE_NOT_FOUND:
                    result = -404;
                    break;
                case OSPC_ERR_NO_ERROR:
                    /* AuthRsp ok but ospLoadRoutes fails */
                    result = -500;
                    break;
                default:
                    result = MODULE_RETURNCODE_FALSE;
                    break;
            }
        }
    }

    if (callids[0] != NULL) {
        OSPPCallIdDelete(&(callids[0]));
    }

    if (transaction != -1) {
        OSPPTransactionDelete(transaction);
    }
    
    return result;
}