Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
/*
 * Get routes from AuthRsp
 * param transaction Transaction handle
 * param destcount Expected destination count
 * param inbound Inbound info
 * return 0 success, -1 failure
 */
static int ospLoadRoutes(
    OSPTTRANHANDLE trans,
    int destcount,
    osp_inbound* inbound)
{
    int count;
    int errcode;
    osp_dest* dest;
    osp_dest dests[OSP_DEF_DESTS];
    char host[OSP_STRBUF_SIZE];
    char destdev[OSP_STRBUF_SIZE];
    OSPE_OPERATOR_NAME type;
    OSPE_DEST_OSPENABLED enabled;
    int result = 0;

    ospSetIdentity(trans);

    for (count = 0; count < destcount; count++) {
        /* This is necessary because we will save destinations in reverse order */
        dest = ospInitDestination(&dests[count]);

        if (dest == NULL) {
            result = -1;
            break;
        }

        dest->destcount = count + 1;

        if (count == 0) {
            errcode = OSPPTransactionGetFirstDestination(
                trans,
                sizeof(dest->validafter),
                dest->validafter,
                dest->validuntil,
                &dest->timelimit,
                &dest->callidsize,
                (void*)dest->callid,
                sizeof(dest->called),
                dest->called,
                sizeof(dest->calling),
                dest->calling,
                sizeof(host),
                host,
                sizeof(destdev),
                destdev,
                &dest->tokensize,
                dest->token);
        } else {
            errcode = OSPPTransactionGetNextDestination(
                trans,
                0,
                sizeof(dest->validafter),
                dest->validafter,
                dest->validuntil,
                &dest->timelimit,
                &dest->callidsize,
                (void*)dest->callid,
                sizeof(dest->called),
                dest->called,
                sizeof(dest->calling),
                dest->calling,
                sizeof(host),
                host,
                sizeof(destdev),
                destdev,
                &dest->tokensize,
                dest->token);
        }

        if (errcode != OSPC_ERR_NO_ERROR) {
            LM_ERR("failed to load routes (%d) expected '%d' current '%d'\n",
                errcode,
                destcount,
                count);
            result = -1;
            break;
        }

        ospConvertToInAddress(host, dest->host, sizeof(dest->host));

        errcode = OSPPTransactionGetNumberPortabilityParameters(trans,
            sizeof(dest->nprn),
            dest->nprn,
            sizeof(dest->npcic),
            dest->npcic,
            &dest->npdi);
        if (errcode != OSPC_ERR_NO_ERROR) {
            LM_DBG("cannot get number portability parameters (%d)\n", errcode);
            dest->nprn[0] = '\0';
            dest->npcic[0] = '\0';
            dest->npdi = 0;
        }

        for (type = OSPC_OPNAME_START; type < OSPC_OPNAME_NUMBER; type++) {
            errcode = OSPPTransactionGetOperatorName(trans,
                type,
                sizeof(dest->opname[type]),
                dest->opname[type]);
            if (errcode != OSPC_ERR_NO_ERROR) {
                LM_DBG("cannot get operator name '%d' (%d)\n", type, errcode);
                dest->opname[type][0] = '\0';
            }
        }

        errcode = OSPPTransactionGetDestProtocol(trans, &dest->protocol);
        if (errcode != OSPC_ERR_NO_ERROR) {
            /* This does not mean an ERROR. The OSP server may not support OSP 2.1.1 */
            LM_DBG("cannot get dest protocol (%d)\n", errcode);
            dest->protocol = OSPC_PROTNAME_SIP;
        }
        switch (dest->protocol) {
            case OSPC_PROTNAME_Q931:
            case OSPC_PROTNAME_LRQ:
            case OSPC_PROTNAME_IAX:
            case OSPC_PROTNAME_T37:
            case OSPC_PROTNAME_T38:
            case OSPC_PROTNAME_SKYPE:
            case OSPC_PROTNAME_SMPP:
            case OSPC_PROTNAME_XMPP:
                if (_osp_non_sip) {
                    dest->supported = 1;
                } else {
                    dest->supported = 0;
                }
                break;
            case OSPC_PROTNAME_SIP:
            case OSPC_PROTNAME_UNDEFINED:
            case OSPC_PROTNAME_UNKNOWN:
            default:
                dest->supported = 1;
                break;
        }

        errcode = OSPPTransactionIsDestOSPEnabled(trans, &enabled);
        if (errcode != OSPC_ERR_NO_ERROR) {
            /* This does not mean an ERROR. The OSP server may not support OSP 2.1.1 */
            LM_DBG("cannot get dest OSP version (%d)\n", errcode);
        } else if (enabled == OSPC_DOSP_FALSE) {
            /* Destination device does not support OSP. Do not send token to it */
            dest->token[0] = '\0';
            dest->tokensize = 0;
        }

        errcode = OSPPTransactionGetDestinationNetworkId(trans, sizeof(dest->dnid), dest->dnid);
        if (errcode != OSPC_ERR_NO_ERROR) {
            /* This does not mean an ERROR. The OSP server may not support OSP 2.1.1 */
            LM_DBG("cannot get dest network ID (%d)\n", errcode);
            dest->dnid[0] = '\0';
        }

        errcode = OSPPTransactionGetCNAM(trans, sizeof(dest->cnam), dest->cnam);
        if (errcode != OSPC_ERR_NO_ERROR) {
            LM_DBG("cannot get CNAM (%d)\n", errcode);
            dest->cnam[0] = '\0';
        }

        OSPPTransactionGetServiceType(trans, &dest->srvtype);

        dest->type = OSPC_ROLE_SOURCE;
        dest->transid = ospGetTransactionId(trans);

        LM_INFO("get destination '%d': "
            "validafter '%s' "
            "validuntil '%s' "
            "timelimit '%d' seconds "
            "callid '%.*s' "
            "calling '%s' "
            "called '%s' "
            "host '%s' "
            "nprn '%s' "
            "npcic '%s' "
            "npdi '%d' "
            /*
            "spid '%s' "
            "ocn '%s' "
            "spn '%s' "
            "altspn '%s' "
            "mcc '%s' "
            "mnc '%s' "
            */
            "cnam '%s' "
            "service '%d' "
            "protocol '%d' "
            "supported '%d' "
            "networkid '%s' "
            "tokensize '%d'\n",
            count,
            dest->validafter,
            dest->validuntil,
            dest->timelimit,
            dest->callidsize,
            dest->callid,
            dest->calling,
            dest->called,
            host,
            dest->nprn,
            dest->npcic,
            dest->npdi,
            /*
            dest->opname[OSPC_OPNAME_SPID],
            dest->opname[OSPC_OPNAME_OCN],
            dest->opname[OSPC_OPNAME_SPN],
            dest->opname[OSPC_OPNAME_ALTSPN],
            dest->opname[OSPC_OPNAME_MCC],
            dest->opname[OSPC_OPNAME_MNC],
            */
            dest->cnam,
            dest->srvtype,
            dest->protocol,
            dest->supported,
            dest->dnid,
            dest->tokensize);
    }

    /*
     * Save destination in reverse order,
     * when we start searching avps the destinations
     * will be in order
     */
    if (result == 0) {
        if (ospSaveInboundInfo(inbound) == -1) {
            ospRecordEvent(0, 500);
            result = -1;
        } else {
            for(count = destcount -1; count >= 0; count--) {
                if (ospSaveOrigDestination(&dests[count]) == -1) {
                    LM_ERR("failed to save originate destination\n");
                    /* Report terminate CDR */
                    ospRecordEvent(0, 500);
                    result = -1;
                    break;
                }
            }
        }
    }

    return result;
}
Ejemplo n.º 3
0
/*
 * Get routes from AuthRsp
 * param transaction Transaction handle
 * param destcount Expected destination count
 * param source Source IP
 * param sourcedev Source device IP
 * param origcalled Original called number
 * param authtime Request authorization time
 * return 0 success, -1 failure
 */
static int ospLoadRoutes(
    OSPTTRANHANDLE transaction, 
    int destcount, 
    char* source, 
    char* sourcedev, 
    char* origcalled, 
    time_t authtime)
{
    int count;
    int errorcode;
    osp_dest* dest;
    osp_dest dests[OSP_DEF_DESTS];
    OSPE_DEST_PROT protocol;
    OSPE_DEST_OSP_ENABLED enabled;
    int result = 0;
    
    LOG(L_DBG, "osp: ospLoadRoutes\n");

    for (count = 0; count < destcount; count++) {
        /* This is necessary becuase we will save destinations in reverse order */
        dest = ospInitDestination(&dests[count]);

        if (dest == NULL) {
            result = -1;
            break;
        }

        dest->destinationCount = count + 1;
        strncpy(dest->origcalled, origcalled, sizeof(dest->origcalled) - 1);

        if (count == 0) {
            errorcode = OSPPTransactionGetFirstDestination(
                transaction,
                sizeof(dest->validafter),
                dest->validafter,
                dest->validuntil,
                &dest->timelimit,
                &dest->callidsize,
                (void*)dest->callid,
                sizeof(dest->called),
                dest->called,
                sizeof(dest->calling),
                dest->calling,
                sizeof(dest->host),
                dest->host,
                sizeof(dest->destdev),
                dest->destdev,
                &dest->tokensize,
                dest->token);
        } else {
            errorcode = OSPPTransactionGetNextDestination(
                transaction,
                0,
                sizeof(dest->validafter),
                dest->validafter,
                dest->validuntil,
                &dest->timelimit,
                &dest->callidsize,
                (void*)dest->callid,
                sizeof(dest->called),
                dest->called,
                sizeof(dest->calling),
                dest->calling,
                sizeof(dest->host),
                dest->host,
                sizeof(dest->destdev),
                dest->destdev,
                &dest->tokensize,
                dest->token);
        }
        
        if (errorcode != OSPC_ERR_NO_ERROR) {
            LOG(L_ERR, 
                "osp: ERROR: failed to load routes (%d) expected '%d' current '%d'\n", 
                errorcode, 
                destcount, 
                count);
            result = -1;
            break;
        }

        errorcode = OSPPTransactionGetDestProtocol(transaction, &protocol);
        if (errorcode != OSPC_ERR_NO_ERROR) {
            /* This does not mean an ERROR. The OSP server may not support OSP 2.1.1 */
            LOG(L_DBG, "osp: cannot get dest protocol (%d)\n", errorcode);
            protocol = OSPE_DEST_PROT_SIP;
        }
        switch (protocol) {
            case OSPE_DEST_PROT_H323_LRQ:
            case OSPE_DEST_PROT_H323_SETUP:
            case OSPE_DEST_PROT_IAX:
                dest->supported = 0;
                break;
            case OSPE_DEST_PROT_SIP:
            case OSPE_DEST_PROT_UNDEFINED:
            case OSPE_DEST_PROT_UNKNOWN:
            default:
                dest->supported = 1;
                break;
        }

        errorcode = OSPPTransactionIsDestOSPEnabled(transaction, &enabled);
        if (errorcode != OSPC_ERR_NO_ERROR) {
            /* This does not mean an ERROR. The OSP server may not support OSP 2.1.1 */
            LOG(L_DBG, "osp: cannot get dest OSP version (%d)\n", errorcode);
        } else if (enabled == OSPE_OSP_FALSE) {
            /* Destination device does not support OSP. Do not send token to it */
            dest->token[0] = '\0';
            dest->tokensize = 0;
        }

        errorcode = OSPPTransactionGetDestNetworkId(transaction, dest->networkid);
        if (errorcode != OSPC_ERR_NO_ERROR) {
            /* This does not mean an ERROR. The OSP server may not support OSP 2.1.1 */
            LOG(L_DBG, "osp: cannot get dest network ID (%d)\n", errorcode);
            dest->networkid[0] = '\0';
        }

        strncpy(dest->source, source, sizeof(dest->source) - 1);
        strncpy(dest->srcdev, sourcedev, sizeof(dest->srcdev) - 1);
        dest->type = OSPC_SOURCE;
        dest->transid = ospGetTransactionId(transaction);
        dest->authtime = authtime;

        LOG(L_INFO,
            "osp: get destination '%d': "
            "valid after '%s' "
            "valid until '%s' "
            "time limit '%i' seconds "
            "call id '%.*s' "
            "calling number '%s' "
            "called number '%s' "
            "host '%s' "
            "supported '%d' "
            "network id '%s' "
            "token size '%i'\n",
            count, 
            dest->validafter, 
            dest->validuntil, 
            dest->timelimit, 
            dest->callidsize, 
            dest->callid, 
            dest->calling, 
            dest->called, 
            dest->host, 
            dest->supported,
            dest->networkid, 
            dest->tokensize);
    }

    /* 
     * Save destination in reverse order,
     * when we start searching avps the destinations
     * will be in order 
     */
    if (result == 0) {
        for(count = destcount -1; count >= 0; count--) {
            ospSaveOrigDestination(&dests[count]);
        }
    }

    return result;
}