/* * 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; }
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; }
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; }
/* * 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; }