Thu Apr 28 2011 17:13:38

Asterisk developer's documentation


app_osplookup.c File Reference

Open Settlement Protocol (OSP) Applications. More...

#include "asterisk.h"
#include <osp/osp.h>
#include <osp/osputils.h>
#include "asterisk/paths.h"
#include "asterisk/lock.h"
#include "asterisk/config.h"
#include "asterisk/utils.h"
#include "asterisk/causes.h"
#include "asterisk/channel.h"
#include "asterisk/app.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/cli.h"
#include "asterisk/astosp.h"
Include dependency graph for app_osplookup.c:

Go to the source code of this file.

Data Structures

struct  osp_callid
struct  osp_provider
struct  osp_result

Defines

#define OSP_AUDIT_URL   ((const char*)"localhost")
#define OSP_CALLID_H323   ((unsigned int)(1 << 0))
#define OSP_CALLID_IAX   ((unsigned int)(1 << 2))
#define OSP_CALLID_MAXNUM   ((unsigned int)3)
#define OSP_CALLID_SIP   ((unsigned int)(1 << 1))
#define OSP_CALLID_UNDEFINED   ((unsigned int)0)
#define OSP_CONFIG_FILE   ((const char*)"osp.conf")
#define OSP_CUSTOMER_ID   ((const char*)"")
#define OSP_DEF_AUTHPOLICY   ((enum osp_authpolicy)OSP_AUTH_YES)
#define OSP_DEF_DESTINATIONS   ((unsigned int)5)
#define OSP_DEF_MAXCONNECTIONS   ((unsigned int)20)
#define OSP_DEF_PROTOCOL   OSP_PROT_SIP
#define OSP_DEF_PROVIDER   ((const char*)"default")
#define OSP_DEF_RETRYDELAY   ((unsigned int)0)
#define OSP_DEF_RETRYLIMIT   ((unsigned int)2)
#define OSP_DEF_TIMELIMIT   ((unsigned int)0)
#define OSP_DEF_TIMEOUT   ((unsigned int)500)
#define OSP_DEVICE_ID   ((const char*)"")
#define OSP_GENERAL_CAT   ((const char*)"general")
#define OSP_HTTP_PERSISTENCE   ((int)1)
#define OSP_INTSTR_SIZE   ((unsigned int)16)
#define OSP_INVALID_HANDLE   ((int)-1)
#define OSP_LOCAL_VALIDATION   ((int)1)
#define OSP_MAX_CERTS   ((unsigned int)10)
#define OSP_MAX_MAXCONNECTIONS   ((unsigned int)1000)
#define OSP_MAX_RETRYDELAY   ((unsigned int)10)
#define OSP_MAX_RETRYLIMIT   ((unsigned int)100)
#define OSP_MAX_SRVS   ((unsigned int)10)
#define OSP_MAX_TIMEOUT   ((unsigned int)10000)
#define OSP_MIN_MAXCONNECTIONS   ((unsigned int)1)
#define OSP_MIN_RETRYDELAY   ((unsigned int)0)
#define OSP_MIN_RETRYLIMIT   ((unsigned int)0)
#define OSP_MIN_TIMEOUT   ((unsigned int)200)
#define OSP_NORSTR_SIZE   ((unsigned int)256)
#define OSP_PROT_H323   ((char*)"H323")
#define OSP_PROT_IAX   ((char*)"IAX")
#define OSP_PROT_OTHER   ((char*)"OTHER")
#define OSP_PROT_SIP   ((char*)"SIP")
#define OSP_SIP_HEADER   ((char*)"P-OSP-Auth-Token: ")
#define OSP_SSL_LIFETIME   ((unsigned int)300)
#define OSP_TECH_H323   ((char*)"H323")
#define OSP_TECH_IAX   ((char*)"IAX2")
#define OSP_TECH_SIP   ((char*)"SIP")
#define OSP_TECHSTR_SIZE   ((unsigned int)32)
#define OSP_TOKSTR_SIZE   ((unsigned int)4096)
#define OSP_UUID_SIZE   ((unsigned int)16)
#define OSP_UUIDSTR_SIZE   ((unsigned int)36)

Enumerations

enum  osp_authpolicy { OSP_AUTH_NO, OSP_AUTH_YES, OSP_AUTH_EXCLUSIVE }

Functions

static void __reg_module (void)
static void __unreg_module (void)
static OSPEFAILREASON asterisk2osp (int cause)
 Convert Asterisk status to TC code.
static char * handle_cli_osp_show (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int load_module (void)
static int osp_auth (const char *provider, int *transaction, const char *source, const char *calling, const char *called, const char *token, unsigned int *timelimit)
 OSP Authentication function.
static int osp_check_destination (struct osp_provider *provider, const char *called, const char *calling, char *destination, unsigned int tokenlen, const char *token, OSPEFAILREASON *reason, struct osp_result *result)
 Choose min duration limit.
static unsigned int osp_choose_timelimit (unsigned int in, unsigned int out)
 Choose min duration limit.
static void osp_convert_address (const char *src, char *dst, int buffersize)
 Convert address to "[x.x.x.x]" or "host.domain" format.
static int osp_create_callid (unsigned int type, struct osp_callid *callid)
 Create a call ID according to the type.
static int osp_create_provider (struct ast_config *cfg, const char *provider)
 Create OSP provider handle according to configuration.
static int osp_create_transaction (const char *provider, int *transaction, unsigned int sourcesize, char *source)
 Create OSP transaction handle.
static int osp_create_uuid (unsigned char *uuid, unsigned int *buffersize)
 Create a UUID.
static int osp_finish (int handle, int recorded, int cause, time_t start, time_t connect, time_t end, unsigned int release)
 OSP Finish function.
static int osp_get_provider (const char *name, struct osp_provider **provider)
 Get OSP provider by name.
static int osp_load (int reload)
static int osp_lookup (const char *provider, const char *srcdev, const char *calling, const char *called, unsigned int callidtypes, struct osp_result *result)
 OSP Lookup function.
static int osp_next (const char *provider, int cause, struct osp_result *result)
 OSP Lookup Next function.
static int osp_unload (void)
static int osp_uuid2str (unsigned char *uuid, char *buffer, unsigned int buffersize)
 UUID to string.
static int osp_validate_token (int transaction, const char *source, const char *destination, const char *calling, const char *called, const char *token, unsigned int *timelimit)
 Validate OSP token of inbound call.
static int ospauth_exec (struct ast_channel *chan, void *data)
 OSP Application OSPAuth.
static int ospfinished_exec (struct ast_channel *chan, void *data)
 OSP Application OSPFinish.
static int osplookup_exec (struct ast_channel *chan, void *data)
 OSP Application OSPLookup.
static int ospnext_exec (struct ast_channel *chan, void *data)
 OSP Application OSPNext.
static int reload (void)
static int unload_module (void)

Variables

static struct ast_module_info
__MODULE_INFO_SECTION 
__mod_info = { __MODULE_INFO_GLOBALS .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Open Settlement Protocol Applications" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, }
static const char * app1 = "OSPAuth"
static const char * app2 = "OSPLookup"
static const char * app3 = "OSPNext"
static const char * app4 = "OSPFinish"
static struct ast_module_infoast_module_info = &__mod_info
static struct ast_cli_entry cli_osp []
static const char * descrip1 = " SUCCESS | FAILED | ERROR\n"
static const char * descrip2 = " SUCCESS | FAILED | ERROR\n"
static const char * descrip3 = " SUCCESS | FAILED | ERROR\n"
static const char * descrip4 = " SUCCESS | FAILED | ERROR \n"
static int osp_hardware = 0
static int osp_initialized = 0
static unsigned int osp_tokenformat = TOKEN_ALGO_SIGNED
static ast_mutex_t osplock = AST_MUTEX_INIT_VALUE
static struct osp_providerospproviders = NULL
static const char * synopsis1 = "OSP authentication"
static const char * synopsis2 = "Lookup destination by OSP"
static const char * synopsis3 = "Lookup next destination by OSP"
static const char * synopsis4 = "Record OSP entry"

Detailed Description

Open Settlement Protocol (OSP) Applications.

Author:
Mark Spencer <markster@digium.com>
ExtRef:
The OSP Toolkit: http://www.transnexus.com
ExtRef:
OpenSSL http://www.openssl.org

Definition in file app_osplookup.c.


Define Documentation

#define OSP_AUDIT_URL   ((const char*)"localhost")

Definition at line 114 of file app_osplookup.c.

Referenced by osp_create_provider().

#define OSP_CALLID_H323   ((unsigned int)(1 << 0))

Definition at line 72 of file app_osplookup.c.

Referenced by osp_create_callid(), osplookup_exec(), and ospnext_exec().

#define OSP_CALLID_IAX   ((unsigned int)(1 << 2))

Definition at line 74 of file app_osplookup.c.

Referenced by osp_create_callid(), and osplookup_exec().

#define OSP_CALLID_MAXNUM   ((unsigned int)3)

Definition at line 75 of file app_osplookup.c.

Referenced by osp_lookup().

#define OSP_CALLID_SIP   ((unsigned int)(1 << 1))

Definition at line 73 of file app_osplookup.c.

Referenced by osp_create_callid(), and osplookup_exec().

#define OSP_CALLID_UNDEFINED   ((unsigned int)0)

Definition at line 71 of file app_osplookup.c.

Referenced by osplookup_exec(), and ospnext_exec().

#define OSP_CONFIG_FILE   ((const char*)"osp.conf")

Definition at line 96 of file app_osplookup.c.

Referenced by osp_load().

#define OSP_CUSTOMER_ID   ((const char*)"")

Definition at line 118 of file app_osplookup.c.

Referenced by osp_create_provider().

#define OSP_DEF_AUTHPOLICY   ((enum osp_authpolicy)OSP_AUTH_YES)

Definition at line 113 of file app_osplookup.c.

Referenced by osp_create_provider().

#define OSP_DEF_DESTINATIONS   ((unsigned int)5)

Definition at line 120 of file app_osplookup.c.

Referenced by osp_lookup().

#define OSP_DEF_MAXCONNECTIONS   ((unsigned int)20)

Definition at line 101 of file app_osplookup.c.

Referenced by osp_create_provider().

#define OSP_DEF_PROTOCOL   OSP_PROT_SIP

Definition at line 122 of file app_osplookup.c.

Referenced by osp_create_provider().

#define OSP_DEF_PROVIDER   ((const char*)"default")

Definition at line 98 of file app_osplookup.c.

Referenced by ospauth_exec(), osplookup_exec(), and ospnext_exec().

#define OSP_DEF_RETRYDELAY   ((unsigned int)0)

Definition at line 104 of file app_osplookup.c.

Referenced by osp_create_provider().

#define OSP_DEF_RETRYLIMIT   ((unsigned int)2)

Definition at line 107 of file app_osplookup.c.

Referenced by osp_create_provider().

#define OSP_DEF_TIMELIMIT   ((unsigned int)0)
#define OSP_DEF_TIMEOUT   ((unsigned int)500)

Definition at line 110 of file app_osplookup.c.

Referenced by osp_create_provider().

#define OSP_DEVICE_ID   ((const char*)"")

Definition at line 119 of file app_osplookup.c.

Referenced by osp_create_provider().

#define OSP_GENERAL_CAT   ((const char*)"general")

Definition at line 97 of file app_osplookup.c.

Referenced by osp_load().

#define OSP_HTTP_PERSISTENCE   ((int)1)

Definition at line 117 of file app_osplookup.c.

Referenced by osp_create_provider().

#define OSP_INTSTR_SIZE   ((unsigned int)16)

Definition at line 56 of file app_osplookup.c.

Referenced by ospauth_exec(), and ospfinished_exec().

#define OSP_INVALID_HANDLE   ((int)-1)
#define OSP_LOCAL_VALIDATION   ((int)1)

Definition at line 115 of file app_osplookup.c.

Referenced by osp_create_provider().

#define OSP_MAX_CERTS   ((unsigned int)10)

Definition at line 99 of file app_osplookup.c.

Referenced by osp_create_provider().

#define OSP_MAX_MAXCONNECTIONS   ((unsigned int)1000)

Definition at line 103 of file app_osplookup.c.

Referenced by osp_create_provider().

#define OSP_MAX_RETRYDELAY   ((unsigned int)10)

Definition at line 106 of file app_osplookup.c.

Referenced by osp_create_provider().

#define OSP_MAX_RETRYLIMIT   ((unsigned int)100)

Definition at line 109 of file app_osplookup.c.

Referenced by osp_create_provider().

#define OSP_MAX_SRVS   ((unsigned int)10)

Definition at line 100 of file app_osplookup.c.

Referenced by osp_create_provider().

#define OSP_MAX_TIMEOUT   ((unsigned int)10000)

Definition at line 112 of file app_osplookup.c.

Referenced by osp_create_provider().

#define OSP_MIN_MAXCONNECTIONS   ((unsigned int)1)

Definition at line 102 of file app_osplookup.c.

Referenced by osp_create_provider().

#define OSP_MIN_RETRYDELAY   ((unsigned int)0)

Definition at line 105 of file app_osplookup.c.

Referenced by osp_create_provider().

#define OSP_MIN_RETRYLIMIT   ((unsigned int)0)

Definition at line 108 of file app_osplookup.c.

Referenced by osp_create_provider().

#define OSP_MIN_TIMEOUT   ((unsigned int)200)

Definition at line 111 of file app_osplookup.c.

Referenced by osp_create_provider().

#define OSP_NORSTR_SIZE   ((unsigned int)256)

Definition at line 57 of file app_osplookup.c.

Referenced by osp_auth(), osp_lookup(), osp_next(), and osp_validate_token().

#define OSP_PROT_H323   ((char*)"H323")

Definition at line 78 of file app_osplookup.c.

Referenced by osp_check_destination(), and osp_create_provider().

#define OSP_PROT_IAX   ((char*)"IAX")

Definition at line 80 of file app_osplookup.c.

Referenced by osp_check_destination(), and osp_create_provider().

#define OSP_PROT_OTHER   ((char*)"OTHER")

Definition at line 81 of file app_osplookup.c.

Referenced by osp_create_provider().

#define OSP_PROT_SIP   ((char*)"SIP")

Definition at line 79 of file app_osplookup.c.

Referenced by osp_check_destination(), and osp_create_provider().

#define OSP_SIP_HEADER   ((char*)"P-OSP-Auth-Token: ")

Definition at line 92 of file app_osplookup.c.

Referenced by osplookup_exec(), and ospnext_exec().

#define OSP_SSL_LIFETIME   ((unsigned int)300)

Definition at line 116 of file app_osplookup.c.

Referenced by osp_create_provider().

#define OSP_TECH_H323   ((char*)"H323")

Definition at line 87 of file app_osplookup.c.

Referenced by osp_check_destination(), osplookup_exec(), and ospnext_exec().

#define OSP_TECH_IAX   ((char*)"IAX2")

Definition at line 89 of file app_osplookup.c.

Referenced by osp_check_destination(), osplookup_exec(), and ospnext_exec().

#define OSP_TECH_SIP   ((char*)"SIP")

Definition at line 88 of file app_osplookup.c.

Referenced by osp_check_destination(), osplookup_exec(), and ospnext_exec().

#define OSP_TECHSTR_SIZE   ((unsigned int)32)

Definition at line 59 of file app_osplookup.c.

#define OSP_TOKSTR_SIZE   ((unsigned int)4096)
#define OSP_UUID_SIZE   ((unsigned int)16)

Definition at line 60 of file app_osplookup.c.

Referenced by osp_create_uuid().

#define OSP_UUIDSTR_SIZE   ((unsigned int)36)

Definition at line 61 of file app_osplookup.c.

Referenced by osp_uuid2str().


Enumeration Type Documentation

Enumerator:
OSP_AUTH_NO 
OSP_AUTH_YES 
OSP_AUTH_EXCLUSIVE 

Definition at line 64 of file app_osplookup.c.

                    {
   OSP_AUTH_NO,      /* Accept any call */
   OSP_AUTH_YES,     /* Accept call with valid OSP token or without OSP token */
   OSP_AUTH_EXCLUSIVE   /* Only accept call with valid OSP token */
};

Function Documentation

static void __reg_module ( void  ) [static]

Definition at line 2046 of file app_osplookup.c.

static void __unreg_module ( void  ) [static]

Definition at line 2046 of file app_osplookup.c.

static OSPEFAILREASON asterisk2osp ( int  cause) [static]

Convert Asterisk status to TC code.

Parameters:
causeAsterisk hangup cause
Returns:
OSP TC code

Definition at line 690 of file app_osplookup.c.

References cause.

Referenced by osp_finish(), and osp_next().

{
   return (OSPEFAILREASON)cause;
}
static char* handle_cli_osp_show ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 1863 of file app_osplookup.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), osp_provider::authpolicy, osp_provider::cacerts, osp_provider::cacount, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, osp_provider::defaultprotocol, ast_cli_args::fd, osp_provider::handle, osp_provider::localcert, osp_provider::maxconnections, osp_provider::name, osp_provider::next, osplock, ospproviders, osp_provider::privatekey, osp_provider::retrydelay, osp_provider::retrylimit, osp_provider::source, osp_provider::spcount, osp_provider::srvpoints, osp_provider::timeout, and ast_cli_entry::usage.

{
   int i;
   int found = 0;
   struct osp_provider* p;
   const char* provider = NULL;
   const char* tokenalgo;

   switch (cmd) {
   case CLI_INIT:
      e->command = "osp show";
      e->usage =
         "Usage: osp show\n"
         "       Displays information on Open Settlement Protocol support\n";
      return NULL;
   case CLI_GENERATE:
      return NULL;
   }

   if ((a->argc < 2) || (a->argc > 3))
      return CLI_SHOWUSAGE;
   if (a->argc > 2) 
      provider = a->argv[2];
   if (!provider) {
      switch (osp_tokenformat) {
      case TOKEN_ALGO_BOTH:
         tokenalgo = "Both";
         break;
      case TOKEN_ALGO_UNSIGNED:
         tokenalgo = "Unsigned";
         break;
      case TOKEN_ALGO_SIGNED:
      default:
         tokenalgo = "Signed";
         break;
      }
      ast_cli(a->fd, "OSP: %s %s %s\n",
         osp_initialized ? "Initialized" : "Uninitialized", osp_hardware ? "Accelerated" : "Normal", tokenalgo);
   }

   ast_mutex_lock(&osplock);
   p = ospproviders;
   while(p) {
      if (!provider || !strcasecmp(p->name, provider)) {
         if (found) {
            ast_cli(a->fd, "\n");
         }
         ast_cli(a->fd, " == OSP Provider '%s' == \n", p->name);
         ast_cli(a->fd, "Local Private Key: %s\n", p->privatekey);
         ast_cli(a->fd, "Local Certificate: %s\n", p->localcert);
         for (i = 0; i < p->cacount; i++) {
            ast_cli(a->fd, "CA Certificate %d:  %s\n", i + 1, p->cacerts[i]);
         }
         for (i = 0; i < p->spcount; i++) {
            ast_cli(a->fd, "Service Point %d:   %s\n", i + 1, p->srvpoints[i]);
         }
         ast_cli(a->fd, "Max Connections:   %d\n", p->maxconnections);
         ast_cli(a->fd, "Retry Delay:       %d seconds\n", p->retrydelay);
         ast_cli(a->fd, "Retry Limit:       %d\n", p->retrylimit);
         ast_cli(a->fd, "Timeout:           %d milliseconds\n", p->timeout);
         ast_cli(a->fd, "Source:            %s\n", strlen(p->source) ? p->source : "<unspecified>");
         ast_cli(a->fd, "Auth Policy        %d\n", p->authpolicy);
         ast_cli(a->fd, "Default protocol   %s\n", p->defaultprotocol);
         ast_cli(a->fd, "OSP Handle:        %d\n", p->handle);
         found++;
      }
      p = p->next;
   }
   ast_mutex_unlock(&osplock);

   if (!found) {
      if (provider) {
         ast_cli(a->fd, "Unable to find OSP provider '%s'\n", provider);
      } else {
         ast_cli(a->fd, "No OSP providers configured\n");
      }
   }
   return CLI_SUCCESS;
}
static int osp_auth ( const char *  provider,
int *  transaction,
const char *  source,
const char *  calling,
const char *  called,
const char *  token,
unsigned int *  timelimit 
) [static]

OSP Authentication function.

Parameters:
providerOSP provider context name
transactionOSP transaction handle, output
sourceSource of inbound call
callingCalling number
calledCalled number
tokenOSP token, may be empty
timelimitCall duration limit, output
Returns:
1 Authenricated, 0 Unauthenticated, -1 Error

Definition at line 707 of file app_osplookup.c.

References ast_debug, ast_strlen_zero(), osp_provider::authpolicy, OSP_AUTH_EXCLUSIVE, OSP_AUTH_NO, OSP_AUTH_YES, osp_create_transaction(), OSP_DEF_TIMELIMIT, osp_get_provider(), OSP_INVALID_HANDLE, OSP_NORSTR_SIZE, and osp_validate_token().

Referenced by ospauth_exec().

{
   int res;
   struct osp_provider* p = NULL;
   char dest[OSP_NORSTR_SIZE];

   *transaction = OSP_INVALID_HANDLE;
   *timelimit = OSP_DEF_TIMELIMIT;

   if ((res = osp_get_provider(provider, &p)) <= 0) {
      ast_debug(1, "OSP: Unabe to find OSP provider '%s'\n", provider);
      return res;
   }

   switch (p->authpolicy) {
   case OSP_AUTH_NO:
      res = 1;
      break;
   case OSP_AUTH_EXCLUSIVE:
      if (ast_strlen_zero(token)) {
         res = 0;
      } else if ((res = osp_create_transaction(provider, transaction, sizeof(dest), dest)) <= 0) {
         ast_debug(1, "OSP: Unable to generate transaction handle\n");
         *transaction = OSP_INVALID_HANDLE;
         res = 0;
      } else if((res = osp_validate_token(*transaction, source, dest, calling, called, token, timelimit)) <= 0) {
         OSPPTransactionRecordFailure(*transaction, OSPC_FAIL_CALL_REJECTED);
      }
      break;
   case OSP_AUTH_YES:
   default:
      if (ast_strlen_zero(token)) {
         res = 1;
      } else if ((res = osp_create_transaction(provider, transaction, sizeof(dest), dest)) <= 0) {
         ast_debug(1, "OSP: Unable to generate transaction handle\n");
         *transaction = OSP_INVALID_HANDLE;
         res = 0;
      } else if((res = osp_validate_token(*transaction, source, dest, calling, called, token, timelimit)) <= 0) {
         OSPPTransactionRecordFailure(*transaction, OSPC_FAIL_CALL_REJECTED);
      }
      break;
   }

   return res;
}
static int osp_check_destination ( struct osp_provider provider,
const char *  called,
const char *  calling,
char *  destination,
unsigned int  tokenlen,
const char *  token,
OSPEFAILREASON *  reason,
struct osp_result result 
) [static]

Choose min duration limit.

Parameters:
providerOSP provider
calledCalled number
callingCalling number
destinationDestination IP in '[x.x.x.x]' format
tokenlenOSP token length
tokenOSP token
reasonFailure reason, output
resultOSP lookup results, in/output
Returns:
1 Success, 0 Failed, -1 Error

Definition at line 591 of file app_osplookup.c.

References ast_base64encode(), ast_copy_string(), ast_debug, ast_log(), osp_result::called, osp_result::calling, osp_provider::defaultprotocol, osp_result::dest, enabled, LOG_WARNING, osp_result::networkid, OSP_PROT_H323, OSP_PROT_IAX, OSP_PROT_SIP, OSP_TECH_H323, OSP_TECH_IAX, OSP_TECH_SIP, osp_result::outhandle, osp_result::tech, and osp_result::token.

Referenced by osp_lookup(), and osp_next().

{
   int res;
   OSPE_DEST_OSPENABLED enabled;
   OSPE_DEST_PROTOCOL protocol;
   int error;

   if (strlen(destination) <= 2) {
      ast_debug(1, "OSP: Wrong destination format '%s'\n", destination);
      *reason = OSPC_FAIL_NORMAL_UNSPECIFIED;
      return -1;
   }

   if ((error = OSPPTransactionIsDestOSPEnabled(result->outhandle, &enabled)) != OSPC_ERR_NO_ERROR) {
      ast_debug(1, "OSP: Unable to get destination OSP version, error '%d'\n", error);
      *reason = OSPC_FAIL_NORMAL_UNSPECIFIED;
      return -1;
   }

   if (enabled == OSPC_DOSP_FALSE) {
      result->token[0] = '\0';
   } else {
      ast_base64encode(result->token, (const unsigned char*)token, tokenlen, sizeof(result->token) - 1);
   }

   if ((error = OSPPTransactionGetDestNetworkId(result->outhandle, result->networkid)) != OSPC_ERR_NO_ERROR) {
      ast_debug(1, "OSP: Unable to get destination network ID, error '%d'\n", error);
      result->networkid[0] = '\0';
   }

   if ((error = OSPPTransactionGetDestProtocol(result->outhandle, &protocol)) != OSPC_ERR_NO_ERROR) {
      ast_debug(1, "OSP: Unable to get destination protocol, error '%d'\n", error);
      *reason = OSPC_FAIL_NORMAL_UNSPECIFIED;
      result->token[0] = '\0';
      result->networkid[0] = '\0';
      return -1;
   }

   res = 1;
   /* Strip leading and trailing brackets */
   destination[strlen(destination) - 1] = '\0';
   switch(protocol) {
   case OSPC_DPROT_Q931:
      ast_debug(1, "OSP: protocol '%s'\n", OSP_PROT_H323);
      ast_copy_string(result->tech, OSP_TECH_H323, sizeof(result->tech));
      ast_copy_string(result->dest, destination + 1, sizeof(result->dest));
      ast_copy_string(result->called, called, sizeof(result->called));
      ast_copy_string(result->calling, calling, sizeof(result->calling));
      break;
   case OSPC_DPROT_SIP:
      ast_debug(1, "OSP: protocol '%s'\n", OSP_PROT_SIP);
      ast_copy_string(result->tech, OSP_TECH_SIP, sizeof(result->tech));
      ast_copy_string(result->dest, destination + 1, sizeof(result->dest));
      ast_copy_string(result->called, called, sizeof(result->called));
      ast_copy_string(result->calling, calling, sizeof(result->calling));
      break;
   case OSPC_DPROT_IAX:
      ast_debug(1, "OSP: protocol '%s'\n", OSP_PROT_IAX);
      ast_copy_string(result->tech, OSP_TECH_IAX, sizeof(result->tech));
      ast_copy_string(result->dest, destination + 1, sizeof(result->dest));
      ast_copy_string(result->called, called, sizeof(result->called));
      ast_copy_string(result->calling, calling, sizeof(result->calling));
      break;
   case OSPC_DPROT_UNDEFINED:
   case OSPC_DPROT_UNKNOWN:
      ast_debug(1, "OSP: unknown/undefined protocol '%d'\n", protocol);
      ast_debug(1, "OSP: use default protocol '%s'\n", provider->defaultprotocol);

      ast_copy_string(result->tech, provider->defaultprotocol, sizeof(result->tech));
      ast_copy_string(result->dest, destination + 1, sizeof(result->dest));
      ast_copy_string(result->called, called, sizeof(result->called));
      ast_copy_string(result->calling, calling, sizeof(result->calling));
      break;
   case OSPC_DPROT_LRQ:
   default:
      ast_log(LOG_WARNING, "OSP: unsupported protocol '%d'\n", protocol);
      *reason = OSPC_FAIL_PROTOCOL_ERROR;
      result->token[0] = '\0';
      result->networkid[0] = '\0';
      res = 0;
      break;
   }

   return res;
}
static unsigned int osp_choose_timelimit ( unsigned int  in,
unsigned int  out 
) [static]

Choose min duration limit.

Parameters:
inInbound duration limit
outOutbound duration limit
Returns:
min duration limit

Definition at line 566 of file app_osplookup.c.

References OSP_DEF_TIMELIMIT.

Referenced by osp_lookup(), and osp_next().

{
   if (in == OSP_DEF_TIMELIMIT) {
      return out;
   } else if (out == OSP_DEF_TIMELIMIT) {
      return in;
   } else {
      return in < out ? in : out;
   }
}
static void osp_convert_address ( const char *  src,
char *  dst,
int  buffersize 
) [static]

Convert address to "[x.x.x.x]" or "host.domain" format.

Parameters:
srcSource address string
dstDestination address string
buffersizeSize of dst buffer

Definition at line 481 of file app_osplookup.c.

References inet_aton().

Referenced by osp_lookup(), and osp_validate_token().

{
   struct in_addr inp;

   if (inet_aton(src, &inp) != 0) {
      snprintf(dst, buffersize, "[%s]", src);
   } else {
      snprintf(dst, buffersize, "%s", src);
   }
}
static int osp_create_callid ( unsigned int  type,
struct osp_callid callid 
) [static]

Create a call ID according to the type.

Parameters:
typeCall ID type
callidCall ID buffer
Returns:
1 Created, 0 Not create, -1 Error

Definition at line 819 of file app_osplookup.c.

References osp_callid::buf, osp_callid::len, OSP_CALLID_H323, OSP_CALLID_IAX, OSP_CALLID_SIP, and osp_create_uuid().

Referenced by osp_lookup().

{
   int res;

   callid->len = sizeof(callid->buf);
   switch (type) {
   case OSP_CALLID_H323:
      res = osp_create_uuid(callid->buf, &callid->len);
      break;
   case OSP_CALLID_SIP:
   case OSP_CALLID_IAX:
      res = 0;
   default:
      res = -1;
      break;
   }

   if ((res != 1) && (callid->len != 0)) {
      callid->buf[0] = '\0';
      callid->len = 0;
   }

   return res;
}
static int osp_create_provider ( struct ast_config cfg,
const char *  provider 
) [static]

Create OSP provider handle according to configuration.

Parameters:
cfgOSP configuration
providerOSP provider context name
Returns:
1 Success, 0 Failed, -1 Error

Definition at line 181 of file app_osplookup.c.

References ast_calloc, ast_config_AST_KEY_DIR, ast_copy_string(), ast_debug, ast_free, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_variable_browse(), osp_provider::authpolicy, osp_provider::cacerts, osp_provider::cacount, osp_provider::defaultprotocol, osp_provider::handle, ast_variable::lineno, osp_provider::localcert, LOG_ERROR, LOG_WARNING, osp_provider::maxconnections, ast_variable::name, osp_provider::name, osp_provider::next, ast_variable::next, OSP_AUDIT_URL, OSP_AUTH_EXCLUSIVE, OSP_AUTH_NO, OSP_AUTH_YES, OSP_CUSTOMER_ID, OSP_DEF_AUTHPOLICY, OSP_DEF_MAXCONNECTIONS, OSP_DEF_PROTOCOL, OSP_DEF_RETRYDELAY, OSP_DEF_RETRYLIMIT, OSP_DEF_TIMEOUT, OSP_DEVICE_ID, OSP_HTTP_PERSISTENCE, OSP_INVALID_HANDLE, OSP_LOCAL_VALIDATION, OSP_MAX_CERTS, OSP_MAX_MAXCONNECTIONS, OSP_MAX_RETRYDELAY, OSP_MAX_RETRYLIMIT, OSP_MAX_SRVS, OSP_MAX_TIMEOUT, OSP_MIN_MAXCONNECTIONS, OSP_MIN_RETRYDELAY, OSP_MIN_RETRYLIMIT, OSP_MIN_TIMEOUT, OSP_PROT_H323, OSP_PROT_IAX, OSP_PROT_OTHER, OSP_PROT_SIP, OSP_SSL_LIFETIME, osplock, ospproviders, osp_provider::privatekey, osp_provider::retrydelay, osp_provider::retrylimit, osp_provider::source, osp_provider::spcount, osp_provider::srvpoints, osp_provider::timeout, and ast_variable::value.

Referenced by osp_load().

{
   int res = 0;
   struct ast_variable* v;
   struct osp_provider* p;
   OSPTPRIVATEKEY privatekey;
   OSPT_CERT localcert;
   OSPT_CERT cacerts[OSP_MAX_CERTS];
   const OSPT_CERT* pcacerts[OSP_MAX_CERTS];
   const char* psrvpoints[OSP_MAX_SRVS];
   int t, i, j, error = OSPC_ERR_NO_ERROR;

   if (!(p = ast_calloc(1, sizeof(*p)))) {
      ast_log(LOG_ERROR, "Out of memory\n");
      return -1;
   }

   /* ast_calloc has set 0 in p */
   ast_copy_string(p->name, provider, sizeof(p->name));
   snprintf(p->privatekey, sizeof(p->privatekey), "%s/%s-privatekey.pem", ast_config_AST_KEY_DIR, provider);
   snprintf(p->localcert, sizeof(p->localcert), "%s/%s-localcert.pem", ast_config_AST_KEY_DIR, provider);
   snprintf(p->cacerts[0], sizeof(p->cacerts[0]), "%s/%s-cacert_0.pem", ast_config_AST_KEY_DIR, provider);
   p->maxconnections = OSP_DEF_MAXCONNECTIONS;
   p->retrydelay = OSP_DEF_RETRYDELAY;
   p->retrylimit = OSP_DEF_RETRYLIMIT;
   p->timeout = OSP_DEF_TIMEOUT;
   p->authpolicy = OSP_DEF_AUTHPOLICY;
   p->defaultprotocol = OSP_DEF_PROTOCOL;
   p->handle = OSP_INVALID_HANDLE;

   v = ast_variable_browse(cfg, provider);
   while(v) {
      if (!strcasecmp(v->name, "privatekey")) {
         if (v->value[0] == '/') {
            ast_copy_string(p->privatekey, v->value, sizeof(p->privatekey));
         } else {
            snprintf(p->privatekey, sizeof(p->privatekey), "%s/%s", ast_config_AST_KEY_DIR, v->value);
         }
         ast_debug(1, "OSP: privatekey '%s'\n", p->privatekey);
      } else if (!strcasecmp(v->name, "localcert")) {
         if (v->value[0] == '/') {
            ast_copy_string(p->localcert, v->value, sizeof(p->localcert));
         } else {
            snprintf(p->localcert, sizeof(p->localcert), "%s/%s", ast_config_AST_KEY_DIR, v->value);
         }
         ast_debug(1, "OSP: localcert '%s'\n", p->localcert);
      } else if (!strcasecmp(v->name, "cacert")) {
         if (p->cacount < OSP_MAX_CERTS) {
            if (v->value[0] == '/') {
               ast_copy_string(p->cacerts[p->cacount], v->value, sizeof(p->cacerts[0]));
            } else {
               snprintf(p->cacerts[p->cacount], sizeof(p->cacerts[0]), "%s/%s", ast_config_AST_KEY_DIR, v->value);
            }
            ast_debug(1, "OSP: cacert[%d]: '%s'\n", p->cacount, p->cacerts[p->cacount]);
            p->cacount++;
         } else {
            ast_log(LOG_WARNING, "OSP: Too many CA Certificates at line %d\n", v->lineno);
         }
      } else if (!strcasecmp(v->name, "servicepoint")) {
         if (p->spcount < OSP_MAX_SRVS) {
            ast_copy_string(p->srvpoints[p->spcount], v->value, sizeof(p->srvpoints[0]));
            ast_debug(1, "OSP: servicepoint[%d]: '%s'\n", p->spcount, p->srvpoints[p->spcount]);
            p->spcount++;
         } else {
            ast_log(LOG_WARNING, "OSP: Too many Service Points at line %d\n", v->lineno);
         }
      } else if (!strcasecmp(v->name, "maxconnections")) {
         if ((sscanf(v->value, "%30d", &t) == 1) && (t >= OSP_MIN_MAXCONNECTIONS) && (t <= OSP_MAX_MAXCONNECTIONS)) {
            p->maxconnections = t;
            ast_debug(1, "OSP: maxconnections '%d'\n", t);
         } else {
            ast_log(LOG_WARNING, "OSP: maxconnections should be an integer from %d to %d, not '%s' at line %d\n",
               OSP_MIN_MAXCONNECTIONS, OSP_MAX_MAXCONNECTIONS, v->value, v->lineno);
         }
      } else if (!strcasecmp(v->name, "retrydelay")) {
         if ((sscanf(v->value, "%30d", &t) == 1) && (t >= OSP_MIN_RETRYDELAY) && (t <= OSP_MAX_RETRYDELAY)) {
            p->retrydelay = t;
            ast_debug(1, "OSP: retrydelay '%d'\n", t);
         } else {
            ast_log(LOG_WARNING, "OSP: retrydelay should be an integer from %d to %d, not '%s' at line %d\n",
               OSP_MIN_RETRYDELAY, OSP_MAX_RETRYDELAY, v->value, v->lineno);
         }
      } else if (!strcasecmp(v->name, "retrylimit")) {
         if ((sscanf(v->value, "%30d", &t) == 1) && (t >= OSP_MIN_RETRYLIMIT) && (t <= OSP_MAX_RETRYLIMIT)) {
            p->retrylimit = t;
            ast_debug(1, "OSP: retrylimit '%d'\n", t);
         } else {
            ast_log(LOG_WARNING, "OSP: retrylimit should be an integer from %d to %d, not '%s' at line %d\n",
               OSP_MIN_RETRYLIMIT, OSP_MAX_RETRYLIMIT, v->value, v->lineno);
         }
      } else if (!strcasecmp(v->name, "timeout")) {
         if ((sscanf(v->value, "%30d", &t) == 1) && (t >= OSP_MIN_TIMEOUT) && (t <= OSP_MAX_TIMEOUT)) {
            p->timeout = t;
            ast_debug(1, "OSP: timeout '%d'\n", t);
         } else {
            ast_log(LOG_WARNING, "OSP: timeout should be an integer from %d to %d, not '%s' at line %d\n",
               OSP_MIN_TIMEOUT, OSP_MAX_TIMEOUT, v->value, v->lineno);
         }
      } else if (!strcasecmp(v->name, "source")) {
         ast_copy_string(p->source, v->value, sizeof(p->source));
         ast_debug(1, "OSP: source '%s'\n", p->source);
      } else if (!strcasecmp(v->name, "authpolicy")) {
         if ((sscanf(v->value, "%30d", &t) == 1) && ((t == OSP_AUTH_NO) || (t == OSP_AUTH_YES) || (t == OSP_AUTH_EXCLUSIVE))) {
            p->authpolicy = t;
            ast_debug(1, "OSP: authpolicy '%d'\n", t);
         } else {
            ast_log(LOG_WARNING, "OSP: authpolicy should be %d, %d or %d, not '%s' at line %d\n",
               OSP_AUTH_NO, OSP_AUTH_YES, OSP_AUTH_EXCLUSIVE, v->value, v->lineno);
         }
      } else if (!strcasecmp(v->name, "defaultprotocol")) {
         if (!strcasecmp(v->value, OSP_PROT_SIP)) {
            p->defaultprotocol = OSP_PROT_SIP;
            ast_debug(1, "OSP: default protocol '%s'\n", p->defaultprotocol);
         } else if (!strcasecmp(v->value, OSP_PROT_H323)) {
            p->defaultprotocol = OSP_PROT_H323;
            ast_debug(1, "OSP: default protocol '%s'\n", p->defaultprotocol);
         } else if (!strcasecmp(v->value, OSP_PROT_IAX)) {
            p->defaultprotocol = OSP_PROT_IAX;
            ast_debug(1, "OSP: default protocol '%s'\n", p->defaultprotocol);
         } else {
            ast_log(LOG_WARNING, "OSP: default protocol should be %s, %s, %s, or %s not '%s' at line %d\n",
               OSP_PROT_SIP, OSP_PROT_H323, OSP_PROT_IAX, OSP_PROT_OTHER, v->value, v->lineno);
         }
      }
      v = v->next;
   }

   error = OSPPUtilLoadPEMPrivateKey((unsigned char*)p->privatekey, &privatekey);
   if (error != OSPC_ERR_NO_ERROR) {
      ast_log(LOG_WARNING, "OSP: Unable to load privatekey '%s', error '%d'\n", p->privatekey, error);
      ast_free(p);
      return 0;
   }

   error = OSPPUtilLoadPEMCert((unsigned char*)p->localcert, &localcert);
   if (error != OSPC_ERR_NO_ERROR) {
      ast_log(LOG_WARNING, "OSP: Unable to load localcert '%s', error '%d'\n", p->localcert, error);
      if (privatekey.PrivateKeyData) {
         ast_free(privatekey.PrivateKeyData);
      }
      ast_free(p);
      return 0;
   }

   if (p->cacount < 1) {
      snprintf(p->cacerts[p->cacount], sizeof(p->cacerts[0]), "%s/%s-cacert.pem", ast_config_AST_KEY_DIR, provider);
      ast_debug(1, "OSP: cacert[%d]: '%s'\n", p->cacount, p->cacerts[p->cacount]);
      p->cacount++;
   }
   for (i = 0; i < p->cacount; i++) {
      error = OSPPUtilLoadPEMCert((unsigned char*)p->cacerts[i], &cacerts[i]);
      if (error != OSPC_ERR_NO_ERROR) {
         ast_log(LOG_WARNING, "OSP: Unable to load cacert '%s', error '%d'\n", p->cacerts[i], error);
         for (j = 0; j < i; j++) {
            if (cacerts[j].CertData) {
               ast_free(cacerts[j].CertData);
            }
         }
         if (localcert.CertData) {
            ast_free(localcert.CertData);
         }
         if (privatekey.PrivateKeyData) {
            ast_free(privatekey.PrivateKeyData);
         }
         ast_free(p);
         return 0;
      }
      pcacerts[i] = &cacerts[i];
   }

   for (i = 0; i < p->spcount; i++) {
      psrvpoints[i] = p->srvpoints[i];
   }

   error = OSPPProviderNew(
      p->spcount,
      psrvpoints,
      NULL,
      OSP_AUDIT_URL,
      &privatekey,
      &localcert,
      p->cacount,
      pcacerts,
      OSP_LOCAL_VALIDATION,
      OSP_SSL_LIFETIME,
      p->maxconnections,
      OSP_HTTP_PERSISTENCE,
      p->retrydelay,
      p->retrylimit,
      p->timeout,
      OSP_CUSTOMER_ID,
      OSP_DEVICE_ID,
      &p->handle);
   if (error != OSPC_ERR_NO_ERROR) {
      ast_log(LOG_WARNING, "OSP: Unable to create provider '%s', error '%d'\n", provider, error);
      ast_free(p);
      res = -1;
   } else {
      ast_debug(1, "OSP: provider '%s'\n", provider);
      ast_mutex_lock(&osplock);
      p->next = ospproviders;
      ospproviders = p;
      ast_mutex_unlock(&osplock);
      res = 1;
   }

   for (i = 0; i < p->cacount; i++) {
      if (cacerts[i].CertData) {
         ast_free(cacerts[i].CertData);
      }
   }
   if (localcert.CertData) {
      ast_free(localcert.CertData);
   }
   if (privatekey.PrivateKeyData) {
      ast_free(privatekey.PrivateKeyData);
   }

   return res;
}
static int osp_create_transaction ( const char *  provider,
int *  transaction,
unsigned int  sourcesize,
char *  source 
) [static]

Create OSP transaction handle.

Parameters:
providerOSP provider context name
transactionOSP transaction handle, output
sourcesizeSize of source buffer, in/output
sourceSource of provider, output
Returns:
1 Success, 0 Failed, -1 Error

Definition at line 441 of file app_osplookup.c.

References ast_copy_string(), ast_debug, ast_mutex_lock(), ast_mutex_unlock(), osp_provider::handle, osp_provider::name, osp_provider::next, OSP_INVALID_HANDLE, osplock, ospproviders, and osp_provider::source.

Referenced by osp_auth(), and osp_lookup().

{
   int res = 0;
   struct osp_provider* p;
   int error;

   ast_mutex_lock(&osplock);
   p = ospproviders;
   while(p) {
      if (!strcasecmp(p->name, provider)) {
         error = OSPPTransactionNew(p->handle, transaction);
         if (error == OSPC_ERR_NO_ERROR) {
            ast_debug(1, "OSP: transaction '%d'\n", *transaction);
            ast_copy_string(source, p->source, sourcesize);
            ast_debug(1, "OSP: source '%s'\n", source);
            res = 1;
         } else {
            *transaction = OSP_INVALID_HANDLE;
            ast_debug(1, "OSP: Unable to create transaction handle, error '%d'\n", error);
            res = -1;
         }
         break;
      }
      p = p->next;
   }
   ast_mutex_unlock(&osplock);

   return res;
}
static int osp_create_uuid ( unsigned char *  uuid,
unsigned int *  buffersize 
) [static]

Create a UUID.

Parameters:
uuidUUID buffer
buffersizeUUID buffer size
Returns:
1 Created, -1 Error

Definition at line 766 of file app_osplookup.c.

References ast_random(), and OSP_UUID_SIZE.

Referenced by osp_create_callid().

{
   int i, res;
   long int* tmp;

   if (*buffersize >= OSP_UUID_SIZE) {
      tmp = (long int*)uuid;
      for (i = 0; i < OSP_UUID_SIZE / sizeof(long int); i++) {
         tmp[i] = ast_random();
      }
      *buffersize = OSP_UUID_SIZE;
      res = 1;
   } else {
      res = -1;
   }

   return res;
}
static int osp_finish ( int  handle,
int  recorded,
int  cause,
time_t  start,
time_t  connect,
time_t  end,
unsigned int  release 
) [static]

OSP Finish function.

Parameters:
handleOSP in/outbound transaction handle
recordedIf failure reason has been recorded
causeAsterisk hangup cause
startCall start time
connectCall connect time
endCall end time
releaseWho release first, 0 source, 1 destination
Returns:
1 Success, 0 Failed, -1 Error

Definition at line 1192 of file app_osplookup.c.

References ast_debug, asterisk2osp(), dummy(), and OSP_INVALID_HANDLE.

Referenced by ospfinished_exec().

{
   int res;
   OSPEFAILREASON reason;
   time_t alert = 0;
   unsigned isPddInfoPresent = 0;
   unsigned pdd = 0;
   unsigned int dummy = 0;
   int error;

   if (handle == OSP_INVALID_HANDLE) {
      return 0;
   }

   if (!recorded) {
      reason = asterisk2osp(cause);
      OSPPTransactionRecordFailure(handle, reason);
   }

   error = OSPPTransactionReportUsage(
      handle,
      difftime(end, connect),
      start,
      end,
      alert,
      connect,
      isPddInfoPresent,
      pdd,
      release,
      NULL,
      -1,
      -1,
      -1,
      -1,
      &dummy,
      NULL);
   if (error == OSPC_ERR_NO_ERROR) {
      ast_debug(1, "OSP: Usage reported\n");
      res = 1;
   } else {
      ast_debug(1, "OSP: Unable to report usage, error '%d'\n", error);
      res = -1;
   }
   OSPPTransactionDelete(handle);

   return res;
}
static int osp_get_provider ( const char *  name,
struct osp_provider **  provider 
) [static]

Get OSP provider by name.

Parameters:
nameOSP provider context name
providerOSP provider structure
Returns:
1 Success, 0 Failed, -1 Error

Definition at line 410 of file app_osplookup.c.

References ast_debug, ast_mutex_lock(), ast_mutex_unlock(), osp_provider::name, osp_provider::next, osplock, and ospproviders.

Referenced by osp_auth(), osp_lookup(), and osp_next().

{
   int res = 0;
   struct osp_provider* p;

   ast_mutex_lock(&osplock);
   p = ospproviders;
   while(p) {
      if (!strcasecmp(p->name, name)) {
         *provider = p;
         ast_debug(1, "OSP: find provider '%s'\n", name);
         res = 1;
         break;
      }
      p = p->next;
   }
   ast_mutex_unlock(&osplock);

   return res;
}
static int osp_load ( int  reload) [static]

Definition at line 1772 of file app_osplookup.c.

References ast_category_browse(), ast_config_destroy(), ast_config_load, ast_debug, ast_log(), ast_true(), ast_variable_retrieve(), CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, LOG_ERROR, LOG_WARNING, OSP_CONFIG_FILE, osp_create_provider(), OSP_GENERAL_CAT, and osp_unload().

Referenced by load_module(), and reload().

{
   const char* t;
   unsigned int v;
   struct ast_config* cfg;
   struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
   int error = OSPC_ERR_NO_ERROR;

   if ((cfg = ast_config_load(OSP_CONFIG_FILE, config_flags)) == CONFIG_STATUS_FILEUNCHANGED) {
      return 0;
   } else if (cfg == CONFIG_STATUS_FILEINVALID) {
      ast_log(LOG_ERROR, "Config file %s is in an invalid format.  Aborting.\n", OSP_CONFIG_FILE);
      return 0;
   }

   if (cfg) {
      if (reload)
         osp_unload();

      t = ast_variable_retrieve(cfg, OSP_GENERAL_CAT, "accelerate");
      if (t && ast_true(t)) {
         if ((error = OSPPInit(1)) != OSPC_ERR_NO_ERROR) {
            ast_log(LOG_WARNING, "OSP: Unable to enable hardware accelleration\n");
            OSPPInit(0);
         } else {
            osp_hardware = 1;
         }
      } else {
         OSPPInit(0);
      }
      ast_debug(1, "OSP: osp_hardware '%d'\n", osp_hardware);

      t = ast_variable_retrieve(cfg, OSP_GENERAL_CAT, "tokenformat");
      if (t) {
         if ((sscanf(t, "%30d", &v) == 1) &&
            ((v == TOKEN_ALGO_SIGNED) || (v == TOKEN_ALGO_UNSIGNED) || (v == TOKEN_ALGO_BOTH)))
         {
            osp_tokenformat = v;
         } else {
            ast_log(LOG_WARNING, "tokenformat should be an integer from %d, %d or %d, not '%s'\n",
               TOKEN_ALGO_SIGNED, TOKEN_ALGO_UNSIGNED, TOKEN_ALGO_BOTH, t);
         }
      }
      ast_debug(1, "OSP: osp_tokenformat '%d'\n", osp_tokenformat);

      t = ast_category_browse(cfg, NULL);
      while(t) {
         if (strcasecmp(t, OSP_GENERAL_CAT)) {
            osp_create_provider(cfg, t);
         }
         t = ast_category_browse(cfg, t);
      }

      osp_initialized = 1;

      ast_config_destroy(cfg);
   } else {
      ast_log(LOG_WARNING, "OSP: Unable to find configuration. OSP support disabled\n");
      return 0;
   }
   ast_debug(1, "OSP: osp_initialized '%d'\n", osp_initialized);

   return 1;
}
static int osp_lookup ( const char *  provider,
const char *  srcdev,
const char *  calling,
const char *  called,
unsigned int  callidtypes,
struct osp_result result 
) [static]

OSP Lookup function.

Parameters:
providerOSP provider context name
srcdevSource device of outbound call
callingCalling number
calledCalled number
callidtypesCall ID types
resultLookup results
Returns:
1 Found , 0 No route, -1 Error

Definition at line 856 of file app_osplookup.c.

References ast_debug, osp_callid::buf, osp_result::called, osp_result::calling, osp_result::dest, dummy(), osp_result::inhandle, osp_result::intimelimit, osp_callid::len, osp_result::networkid, osp_result::numresults, OSP_CALLID_MAXNUM, osp_check_destination(), osp_choose_timelimit(), osp_convert_address(), osp_create_callid(), osp_create_transaction(), OSP_DEF_DESTINATIONS, OSP_DEF_TIMELIMIT, osp_get_provider(), OSP_INVALID_HANDLE, OSP_NORSTR_SIZE, OSP_TOKSTR_SIZE, osp_result::outcallid, osp_result::outhandle, osp_result::outtimelimit, osp_provider::source, osp_result::tech, osp_result::token, and type.

Referenced by osplookup_exec().

{
   int res;
   struct osp_provider* p = NULL;
   char source[OSP_NORSTR_SIZE];
   char callingnum[OSP_NORSTR_SIZE];
   char callednum[OSP_NORSTR_SIZE];
   char destination[OSP_NORSTR_SIZE];
   unsigned int tokenlen;
   char token[OSP_TOKSTR_SIZE];
   char src[OSP_NORSTR_SIZE];
   char dev[OSP_NORSTR_SIZE];
   unsigned int i, type;
   struct osp_callid callid;
   unsigned int callidnum;
   OSPT_CALL_ID* callids[OSP_CALLID_MAXNUM];
   unsigned int dummy = 0;
   OSPEFAILREASON reason;
   int error;

   result->outhandle = OSP_INVALID_HANDLE;
   result->tech[0] = '\0';
   result->dest[0] = '\0';
   result->called[0] = '\0';
   result->calling[0] = '\0';
   result->token[0] = '\0';
   result->networkid[0] = '\0';
   result->numresults = 0;
   result->outtimelimit = OSP_DEF_TIMELIMIT;

   if ((res = osp_get_provider(provider, &p)) <= 0) {
      ast_debug(1, "OSP: Unabe to find OSP provider '%s'\n", provider);
      return res;
   }

   if ((res = osp_create_transaction(provider, &result->outhandle, sizeof(source), source)) <= 0) {
      ast_debug(1, "OSP: Unable to generate transaction handle\n");
      result->outhandle = OSP_INVALID_HANDLE;
      if (result->inhandle != OSP_INVALID_HANDLE) {
         OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NORMAL_UNSPECIFIED);
      }
      return -1;
   }

   callidnum = 0;
   callids[0] = NULL;
   for (i = 0; i < OSP_CALLID_MAXNUM; i++) {
      type = 1 << i;
      if (callidtypes & type) {
         error = osp_create_callid(type, &callid);
         if (error == 1) {
            callids[callidnum] = OSPPCallIdNew(callid.len, callid.buf);
            callidnum++;
         }
      }
   }

   osp_convert_address(source, src, sizeof(src));
   osp_convert_address(srcdev, dev, sizeof(dev));
   result->numresults = OSP_DEF_DESTINATIONS;
   error = OSPPTransactionRequestAuthorisation(
      result->outhandle,
      src,
      dev,
      calling ? calling : "",
      OSPC_NFORMAT_E164,
      called,
      OSPC_NFORMAT_E164,
      NULL,
      callidnum,
      callids,
      NULL,
      &result->numresults,
      &dummy,
      NULL);

   for (i = 0; i < callidnum; i++) {
      OSPPCallIdDelete(&callids[i]);
   }

   if (error != OSPC_ERR_NO_ERROR) {
      ast_debug(1, "OSP: Unable to request authorization, error '%d'\n", error);
      result->numresults = 0;
      if (result->inhandle != OSP_INVALID_HANDLE) {
         OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NORMAL_UNSPECIFIED);
      }
      return -1;
   }

   if (!result->numresults) {
      ast_debug(1, "OSP: No more destination\n");
      if (result->inhandle != OSP_INVALID_HANDLE) {
         OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
      }
      return 0;
   }

   result->outcallid.len = sizeof(result->outcallid.buf);
   tokenlen = sizeof(token);
   error = OSPPTransactionGetFirstDestination(
      result->outhandle,
      0,
      NULL,
      NULL,
      &result->outtimelimit,
      &result->outcallid.len,
      result->outcallid.buf,
      sizeof(callednum),
      callednum,
      sizeof(callingnum),
      callingnum,
      sizeof(destination),
      destination,
      0,
      NULL,
      &tokenlen,
      token);
   if (error != OSPC_ERR_NO_ERROR) {
      ast_debug(1, "OSP: Unable to get first route, error '%d'\n", error);
      result->numresults = 0;
      result->outtimelimit = OSP_DEF_TIMELIMIT;
      if (result->inhandle != OSP_INVALID_HANDLE) {
         OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
      }
      return -1;
   }

   result->numresults--;
   result->outtimelimit = osp_choose_timelimit(result->intimelimit, result->outtimelimit);
   ast_debug(1, "OSP: outtimelimit '%d'\n", result->outtimelimit);
   ast_debug(1, "OSP: called '%s'\n", callednum);
   ast_debug(1, "OSP: calling '%s'\n", callingnum);
   ast_debug(1, "OSP: destination '%s'\n", destination);
   ast_debug(1, "OSP: token size '%d'\n", tokenlen);

   if ((res = osp_check_destination(p, callednum, callingnum, destination, tokenlen, token, &reason, result)) > 0) {
      return 1;
   }

   if (!result->numresults) {
      ast_debug(1, "OSP: No more destination\n");
      result->outtimelimit = OSP_DEF_TIMELIMIT;
      OSPPTransactionRecordFailure(result->outhandle, reason);
      if (result->inhandle != OSP_INVALID_HANDLE) {
         OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
      }
      return 0;
   }

   while(result->numresults) {
      result->outcallid.len = sizeof(result->outcallid.buf);
      tokenlen = sizeof(token);
      error = OSPPTransactionGetNextDestination(
         result->outhandle,
         reason,
         0,
         NULL,
         NULL,
         &result->outtimelimit,
         &result->outcallid.len,
         result->outcallid.buf,
         sizeof(callednum),
         callednum,
         sizeof(callingnum),
         callingnum,
         sizeof(destination),
         destination,
         0,
         NULL,
         &tokenlen,
         token);
      if (error == OSPC_ERR_NO_ERROR) {
         result->numresults--;
         result->outtimelimit = osp_choose_timelimit(result->intimelimit, result->outtimelimit);
         ast_debug(1, "OSP: outtimelimit '%d'\n", result->outtimelimit);
         ast_debug(1, "OSP: called '%s'\n", callednum);
         ast_debug(1, "OSP: calling '%s'\n", callingnum);
         ast_debug(1, "OSP: destination '%s'\n", destination);
         ast_debug(1, "OSP: token size '%d'\n", tokenlen);

         if ((res = osp_check_destination(p, callednum, callingnum, destination, tokenlen, token, &reason, result)) > 0) {
            break;
         } else if (!result->numresults) {
            ast_debug(1, "OSP: No more destination\n");
            OSPPTransactionRecordFailure(result->outhandle, reason);
            if (result->inhandle != OSP_INVALID_HANDLE) {
               OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
            }
            res = 0;
            break;
         }
      } else {
         ast_debug(1, "OSP: Unable to get route, error '%d'\n", error);
         result->numresults = 0;
         result->outtimelimit = OSP_DEF_TIMELIMIT;
         if (result->inhandle != OSP_INVALID_HANDLE) {
            OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NORMAL_UNSPECIFIED);
         }
         res = -1;
         break;
      }
   }
   return res;
}
static int osp_next ( const char *  provider,
int  cause,
struct osp_result result 
) [static]

OSP Lookup Next function.

Parameters:
providerOSP provider name
causeAsterisk hangup cuase
resultLookup results, in/output
Returns:
1 Found , 0 No route, -1 Error

Definition at line 1074 of file app_osplookup.c.

References ast_debug, asterisk2osp(), osp_callid::buf, osp_result::called, osp_result::calling, osp_result::dest, osp_result::inhandle, osp_result::intimelimit, osp_callid::len, osp_result::networkid, osp_result::numresults, osp_check_destination(), osp_choose_timelimit(), OSP_DEF_TIMELIMIT, osp_get_provider(), OSP_INVALID_HANDLE, OSP_NORSTR_SIZE, OSP_TOKSTR_SIZE, osp_result::outcallid, osp_result::outhandle, osp_result::outtimelimit, osp_result::tech, and osp_result::token.

Referenced by ospnext_exec().

{
   int res;
   struct osp_provider* p = NULL;
   char callingnum[OSP_NORSTR_SIZE];
   char callednum[OSP_NORSTR_SIZE];
   char destination[OSP_NORSTR_SIZE];
   unsigned int tokenlen;
   char token[OSP_TOKSTR_SIZE];
   OSPEFAILREASON reason;
   int error;

   result->tech[0] = '\0';
   result->dest[0] = '\0';
   result->called[0] = '\0';
   result->calling[0] = '\0';
   result->token[0] = '\0';
   result->networkid[0] = '\0';
   result->outtimelimit = OSP_DEF_TIMELIMIT;

   if ((res = osp_get_provider(provider, &p)) <= 0) {
      ast_debug(1, "OSP: Unabe to find OSP provider '%s'\n", provider);
      return res;
   }

   if (result->outhandle == OSP_INVALID_HANDLE) {
      ast_debug(1, "OSP: Transaction handle undefined\n");
      result->numresults = 0;
      if (result->inhandle != OSP_INVALID_HANDLE) {
         OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NORMAL_UNSPECIFIED);
      }
      return -1;
   }

   reason = asterisk2osp(cause);

   if (!result->numresults) {
      ast_debug(1, "OSP: No more destination\n");
      OSPPTransactionRecordFailure(result->outhandle, reason);
      if (result->inhandle != OSP_INVALID_HANDLE) {
         OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
      }
      return 0;
   }

   while(result->numresults) {
      result->outcallid.len = sizeof(result->outcallid.buf);
      tokenlen = sizeof(token);
      error = OSPPTransactionGetNextDestination(
         result->outhandle,
         reason,
         0,
         NULL,
         NULL,
         &result->outtimelimit,
         &result->outcallid.len,
         result->outcallid.buf,
         sizeof(callednum),
         callednum,
         sizeof(callingnum),
         callingnum,
         sizeof(destination),
         destination,
         0,
         NULL,
         &tokenlen,
         token);
      if (error == OSPC_ERR_NO_ERROR) {
         result->numresults--;
         result->outtimelimit = osp_choose_timelimit(result->intimelimit, result->outtimelimit);
         ast_debug(1, "OSP: outtimelimit '%d'\n", result->outtimelimit);
         ast_debug(1, "OSP: called '%s'\n", callednum);
         ast_debug(1, "OSP: calling '%s'\n", callingnum);
         ast_debug(1, "OSP: destination '%s'\n", destination);
         ast_debug(1, "OSP: token size '%d'\n", tokenlen);

         if ((res = osp_check_destination(p, callednum, callingnum, destination, tokenlen, token, &reason, result)) > 0) {
            res = 1;
            break;
         } else if (!result->numresults) {
            ast_debug(1, "OSP: No more destination\n");
            OSPPTransactionRecordFailure(result->outhandle, reason);
            if (result->inhandle != OSP_INVALID_HANDLE) {
               OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
            }
            res = 0;
            break;
         }
      } else {
         ast_debug(1, "OSP: Unable to get route, error '%d'\n", error);
         result->token[0] = '\0';
         result->numresults = 0;
         result->outtimelimit = OSP_DEF_TIMELIMIT;
         if (result->inhandle != OSP_INVALID_HANDLE) {
            OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NORMAL_UNSPECIFIED);
         }
         res = -1;
         break;
      }
   }

   return res;
}
static int osp_unload ( void  ) [static]

Definition at line 1837 of file app_osplookup.c.

References ast_free, ast_mutex_lock(), ast_mutex_unlock(), osp_provider::handle, osp_provider::next, osplock, and ospproviders.

Referenced by osp_load(), and unload_module().

{
   struct osp_provider* p;
   struct osp_provider* next;

   if (osp_initialized) {
      ast_mutex_lock(&osplock);
      p = ospproviders;
      while(p) {
         next = p->next;
         OSPPProviderDelete(p->handle, 0);
         ast_free(p);
         p = next;
      }
      ospproviders = NULL;
      ast_mutex_unlock(&osplock);

      OSPPCleanup();

      osp_tokenformat = TOKEN_ALGO_SIGNED;
      osp_hardware = 0;
      osp_initialized = 0;
   }
   return 0;
}
static int osp_uuid2str ( unsigned char *  uuid,
char *  buffer,
unsigned int  buffersize 
) [static]

UUID to string.

Parameters:
uuidUUID
bufferString buffer
buffersizeString buffer size
Returns:
1 Successed, -1 Error

Definition at line 794 of file app_osplookup.c.

References OSP_UUIDSTR_SIZE.

Referenced by osplookup_exec(), and ospnext_exec().

{
   int res;

   if (buffersize > OSP_UUIDSTR_SIZE) {
      snprintf(buffer, buffersize, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
         uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],
         uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);
      res = 1;
   } else {
      res = -1;
   }

   return res;
}
static int osp_validate_token ( int  transaction,
const char *  source,
const char *  destination,
const char *  calling,
const char *  called,
const char *  token,
unsigned int *  timelimit 
) [static]

Validate OSP token of inbound call.

Parameters:
transactionOSP transaction handle
sourceSource of inbound call
destinationDestination of inbound call
callingCalling number
calledCalled number
tokenOSP token, may be empty
timelimitCall duration limit, output
Returns:
1 Success, 0 Failed, -1 Error

Definition at line 506 of file app_osplookup.c.

References ast_base64decode(), ast_debug, dummy(), osp_convert_address(), OSP_NORSTR_SIZE, and OSP_TOKSTR_SIZE.

Referenced by osp_auth().

{
   int res;
   int tokenlen;
   unsigned char tokenstr[OSP_TOKSTR_SIZE];
   char src[OSP_NORSTR_SIZE];
   char dst[OSP_NORSTR_SIZE];
   unsigned int authorised;
   unsigned int dummy = 0;
   int error;

   tokenlen = ast_base64decode(tokenstr, token, strlen(token));
   osp_convert_address(source, src, sizeof(src));
   osp_convert_address(destination, dst, sizeof(dst));
   error = OSPPTransactionValidateAuthorisation(
      transaction,
      src,
      dst,
      NULL,
      NULL,
      calling ? calling : "",
      OSPC_NFORMAT_E164,
      called,
      OSPC_NFORMAT_E164,
      0,
      NULL,
      tokenlen,
      (char*)tokenstr,
      &authorised,
      timelimit,
      &dummy,
      NULL,
      osp_tokenformat);
   if (error != OSPC_ERR_NO_ERROR) {
      ast_debug(1, "OSP: Unable to validate inbound token, error '%d'\n", error);
      res = -1;
   } else if (authorised) {
      ast_debug(1, "OSP: Authorised\n");
      res = 1;
   } else {
      ast_debug(1, "OSP: Unauthorised\n");
      res = 0;
   }

   return res;
}
static int ospauth_exec ( struct ast_channel chan,
void *  data 
) [static]

OSP Application OSPAuth.

Parameters:
chanChannel
dataParameter
Returns:
0 Success, -1 Failed

Definition at line 1255 of file app_osplookup.c.

References AST_APP_ARG, ast_debug, AST_DECLARE_APP_ARGS, AST_LIST_TRAVERSE, ast_log(), AST_OSP_ERROR, AST_OSP_FAILED, AST_OSP_SUCCESS, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_var_name(), ast_var_value(), ast_channel::cid, ast_callerid::cid_num, ast_var_t::entries, ast_channel::exten, LOG_ERROR, osp_auth(), OSP_DEF_PROVIDER, OSP_DEF_TIMELIMIT, OSP_INTSTR_SIZE, pbx_builtin_setvar_helper(), status, and ast_channel::varshead.

Referenced by load_module().

{
   int res;
   const char* provider = OSP_DEF_PROVIDER;
   struct varshead* headp;
   struct ast_var_t* current;
   const char* source = "";
   const char* token = "";
   int handle;
   unsigned int timelimit;
   char buffer[OSP_INTSTR_SIZE];
   const char* status;
   char* tmp;

   AST_DECLARE_APP_ARGS(args,
      AST_APP_ARG(provider);
      AST_APP_ARG(options);
   );

   if (!(tmp = ast_strdupa(data))) {
      ast_log(LOG_ERROR, "Out of memory\n");
      return -1;
   }

   AST_STANDARD_APP_ARGS(args, tmp);

   if (!ast_strlen_zero(args.provider)) {
      provider = args.provider;
   }
   ast_debug(1, "OSPAuth: provider '%s'\n", provider);

   headp = &chan->varshead;
   AST_LIST_TRAVERSE(headp, current, entries) {
      if (!strcasecmp(ast_var_name(current), "OSPPEERIP")) {
         source = ast_var_value(current);
      } else if (!strcasecmp(ast_var_name(current), "OSPINTOKEN")) {
         token = ast_var_value(current);
      }
   }

   ast_debug(1, "OSPAuth: source '%s'\n", source);
   ast_debug(1, "OSPAuth: token size '%zd'\n", strlen(token));

   if ((res = osp_auth(provider, &handle, source, chan->cid.cid_num, chan->exten, token, &timelimit)) > 0) {
      status = AST_OSP_SUCCESS;
   } else {
      timelimit = OSP_DEF_TIMELIMIT;
      if (!res) {
         status = AST_OSP_FAILED;
      } else {
         status = AST_OSP_ERROR;
      }
   }

   snprintf(buffer, sizeof(buffer), "%d", handle);
   pbx_builtin_setvar_helper(chan, "OSPINHANDLE", buffer);
   ast_debug(1, "OSPAuth: OSPINHANDLE '%s'\n", buffer);
   snprintf(buffer, sizeof(buffer), "%d", timelimit);
   pbx_builtin_setvar_helper(chan, "OSPINTIMELIMIT", buffer);
   ast_debug(1, "OSPAuth: OSPINTIMELIMIT '%s'\n", buffer);
   pbx_builtin_setvar_helper(chan, "OSPAUTHSTATUS", status);
   ast_debug(1, "OSPAuth: %s\n", status);

   if(res <= 0) {
      res = -1;
   } else {
      res = 0;
   }

   return res;
}
static int ospfinished_exec ( struct ast_channel chan,
void *  data 
) [static]

OSP Application OSPFinish.

Parameters:
chanChannel
dataParameter
Returns:
0 Success, -1 Failed

Definition at line 1657 of file app_osplookup.c.

References ast_cdr::answer, AST_APP_ARG, AST_CAUSE_NO_ROUTE_DESTINATION, AST_CAUSE_NORMAL_CLEARING, ast_check_hangup(), ast_debug, AST_DECLARE_APP_ARGS, AST_LIST_TRAVERSE, ast_log(), AST_OSP_ERROR, AST_OSP_FAILED, AST_OSP_SUCCESS, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_var_name(), ast_var_value(), cause, ast_channel::cdr, ast_var_t::entries, LOG_ERROR, osp_finish(), OSP_INTSTR_SIZE, OSP_INVALID_HANDLE, pbx_builtin_setvar_helper(), ast_cdr::start, status, and ast_channel::varshead.

Referenced by load_module().

{
   int res = 1;
   int cause = 0;
   struct varshead* headp;
   struct ast_var_t* current;
   int inhandle = OSP_INVALID_HANDLE;
   int outhandle = OSP_INVALID_HANDLE;
   int recorded = 0;
   time_t start, connect, end;
   unsigned int release;
   char buffer[OSP_INTSTR_SIZE];
   const char* status;
   char* tmp;

   AST_DECLARE_APP_ARGS(args,
      AST_APP_ARG(cause);
      AST_APP_ARG(options);
   );

   if (!(tmp = ast_strdupa(data))) {
      ast_log(LOG_ERROR, "Out of memory\n");
      return -1;
   }

   AST_STANDARD_APP_ARGS(args, tmp);

   headp = &chan->varshead;
   AST_LIST_TRAVERSE(headp, current, entries) {
      if (!strcasecmp(ast_var_name(current), "OSPINHANDLE")) {
         if (sscanf(ast_var_value(current), "%30d", &inhandle) != 1) {
            inhandle = OSP_INVALID_HANDLE;
         }
      } else if (!strcasecmp(ast_var_name(current), "OSPOUTHANDLE")) {
         if (sscanf(ast_var_value(current), "%30d", &outhandle) != 1) {
            outhandle = OSP_INVALID_HANDLE;
         }
      } else if (!recorded &&
         (!strcasecmp(ast_var_name(current), "OSPAUTHSTATUS") ||
         !strcasecmp(ast_var_name(current), "OSPLOOKUPSTATUS") ||
         !strcasecmp(ast_var_name(current), "OSPNEXTSTATUS")))
      {
         if (strcasecmp(ast_var_value(current), AST_OSP_SUCCESS)) {
            recorded = 1;
         }
      }
   }
   ast_debug(1, "OSPFinish: OSPINHANDLE '%d'\n", inhandle);
   ast_debug(1, "OSPFinish: OSPOUTHANDLE '%d'\n", outhandle);
   ast_debug(1, "OSPFinish: recorded '%d'\n", recorded);

   if (!ast_strlen_zero(args.cause) && sscanf(args.cause, "%30d", &cause) != 1) {
      cause = 0;
   }
   ast_debug(1, "OSPFinish: cause '%d'\n", cause);

   if (chan->cdr) {
      start = chan->cdr->start.tv_sec;
      connect = chan->cdr->answer.tv_sec;
      if (connect) {
         end = time(NULL);
      } else {
         end = connect;
      }
   } else {
      start = 0;
      connect = 0;
      end = 0;
   }
   ast_debug(1, "OSPFinish: start '%ld'\n", start);
   ast_debug(1, "OSPFinish: connect '%ld'\n", connect);
   ast_debug(1, "OSPFinish: end '%ld'\n", end);

   release = ast_check_hangup(chan) ? 0 : 1;

   if (osp_finish(outhandle, recorded, cause, start, connect, end, release) <= 0) {
      ast_debug(1, "OSPFinish: Unable to report usage for outbound call\n");
   }
   switch (cause) {
   case AST_CAUSE_NORMAL_CLEARING:
      break;
   default:
      cause = AST_CAUSE_NO_ROUTE_DESTINATION;
      break;
   }
   if (osp_finish(inhandle, recorded, cause, start, connect, end, release) <= 0) {
      ast_debug(1, "OSPFinish: Unable to report usage for inbound call\n");
   }
   snprintf(buffer, sizeof(buffer), "%d", OSP_INVALID_HANDLE);
   pbx_builtin_setvar_helper(chan, "OSPOUTHANDLE", buffer);
   pbx_builtin_setvar_helper(chan, "OSPINHANDLE", buffer);

   if (res > 0) {
      status = AST_OSP_SUCCESS;
   } else if (!res) {
      status = AST_OSP_FAILED;
   } else {
      status = AST_OSP_ERROR;
   }
   pbx_builtin_setvar_helper(chan, "OSPFINISHSTATUS", status);

   if(!res) {
      res = -1;
   } else {
      res = 0;
   }

   return res;
}
static int osplookup_exec ( struct ast_channel chan,
void *  data 
) [static]

OSP Application OSPLookup.

Parameters:
chanChannel
dataParameter
Returns:
0 Success, -1 Failed

Definition at line 1335 of file app_osplookup.c.

References AST_APP_ARG, ast_autoservice_start(), ast_autoservice_stop(), ast_debug, AST_DECLARE_APP_ARGS, AST_LIST_TRAVERSE, ast_log(), AST_OSP_ERROR, AST_OSP_FAILED, AST_OSP_SUCCESS, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_var_name(), ast_var_value(), osp_callid::buf, osp_result::called, osp_result::calling, ast_channel::cid, ast_callerid::cid_num, osp_result::dest, exten, osp_result::inhandle, osp_result::intimelimit, osp_callid::len, LOG_ERROR, LOG_WARNING, osp_result::networkid, osp_result::numresults, OSP_CALLID_H323, OSP_CALLID_IAX, OSP_CALLID_SIP, OSP_CALLID_UNDEFINED, OSP_DEF_PROVIDER, OSP_DEF_TIMELIMIT, OSP_INVALID_HANDLE, osp_lookup(), OSP_SIP_HEADER, OSP_TECH_H323, OSP_TECH_IAX, OSP_TECH_SIP, OSP_TOKSTR_SIZE, osp_uuid2str(), osp_result::outcallid, osp_result::outhandle, osp_result::outtimelimit, pbx_builtin_setvar_helper(), status, osp_result::tech, osp_result::token, and ast_channel::varshead.

Referenced by load_module().

{
   int res, cres;
   const char* provider = OSP_DEF_PROVIDER;
   struct varshead* headp;
   struct ast_var_t* current;
   const char* srcdev = "";
   const char* snetid = "";
   char buffer[OSP_TOKSTR_SIZE];
   unsigned int callidtypes = OSP_CALLID_UNDEFINED;
   struct osp_result result;
   const char* status;
   char* tmp;

   AST_DECLARE_APP_ARGS(args,
      AST_APP_ARG(exten);
      AST_APP_ARG(provider);
      AST_APP_ARG(options);
   );

   if (ast_strlen_zero(data)) {
      ast_log(LOG_WARNING, "OSPLookup: Arg required, OSPLookup(exten[|provider[|options]])\n");
      return -1;
   }

   if (!(tmp = ast_strdupa(data))) {
      ast_log(LOG_ERROR, "Out of memory\n");
      return -1;
   }

   AST_STANDARD_APP_ARGS(args, tmp);

   ast_debug(1, "OSPLookup: exten '%s'\n", args.exten);

   if (!ast_strlen_zero(args.provider)) {
      provider = args.provider;
   }
   ast_debug(1, "OSPlookup: provider '%s'\n", provider);

   if (args.options) {
      if (strchr(args.options, 'h')) {
         callidtypes |= OSP_CALLID_H323;
      }
      if (strchr(args.options, 's')) {
         callidtypes |= OSP_CALLID_SIP;
      }
      if (strchr(args.options, 'i')) {
         callidtypes |= OSP_CALLID_IAX;
      }
   }
   ast_debug(1, "OSPLookup: call id types '%d'\n", callidtypes);

   result.inhandle = OSP_INVALID_HANDLE;
   result.intimelimit = OSP_DEF_TIMELIMIT;

   headp = &chan->varshead;
   AST_LIST_TRAVERSE(headp, current, entries) {
      if (!strcasecmp(ast_var_name(current), "OSPINHANDLE")) {
         if (sscanf(ast_var_value(current), "%30d", &result.inhandle) != 1) {
            result.inhandle = OSP_INVALID_HANDLE;
         }
      } else if (!strcasecmp(ast_var_name(current), "OSPINTIMELIMIT")) {
         if (sscanf(ast_var_value(current), "%30d", &result.intimelimit) != 1) {
            result.intimelimit = OSP_DEF_TIMELIMIT;
         }
      } else if (!strcasecmp(ast_var_name(current), "OSPINNETWORKID")) {
         snetid = ast_var_value(current);
      } else if (!strcasecmp(ast_var_name(current), "OSPPEERIP")) {
         srcdev = ast_var_value(current);
      }
   }
   ast_debug(1, "OSPLookup: OSPINHANDLE '%d'\n", result.inhandle);
   ast_debug(1, "OSPLookup: OSPINTIMELIMIT '%d'\n", result.intimelimit);
   ast_debug(1, "OSPLookup: OSPINNETWORKID '%s'\n", snetid);
   ast_debug(1, "OSPLookup: source device '%s'\n", srcdev);

   if ((cres = ast_autoservice_start(chan)) < 0) {
      return -1;
   }

   if ((res = osp_lookup(provider, srcdev, chan->cid.cid_num, args.exten, callidtypes, &result)) > 0) {
      status = AST_OSP_SUCCESS;
   } else {
      result.tech[0] = '\0';
      result.dest[0] = '\0';
      result.called[0] = '\0';
      result.calling[0] = '\0';
      result.token[0] = '\0';
      result.networkid[0] = '\0';
      result.numresults = 0;
      result.outtimelimit = OSP_DEF_TIMELIMIT;
      result.outcallid.buf[0] = '\0';
      result.outcallid.len = 0;
      if (!res) {
         status = AST_OSP_FAILED;
      } else {
         status = AST_OSP_ERROR;
      }
   }

   snprintf(buffer, sizeof(buffer), "%d", result.outhandle);
   pbx_builtin_setvar_helper(chan, "OSPOUTHANDLE", buffer);
   ast_debug(1, "OSPLookup: OSPOUTHANDLE '%s'\n", buffer);
   pbx_builtin_setvar_helper(chan, "OSPTECH", result.tech);
   ast_debug(1, "OSPLookup: OSPTECH '%s'\n", result.tech);
   pbx_builtin_setvar_helper(chan, "OSPDEST", result.dest);
   ast_debug(1, "OSPLookup: OSPDEST '%s'\n", result.dest);
   pbx_builtin_setvar_helper(chan, "OSPCALLED", result.called);
   ast_debug(1, "OSPLookup: OSPCALLED '%s'\n", result.called);
   pbx_builtin_setvar_helper(chan, "OSPCALLING", result.calling);
   ast_debug(1, "OSPLookup: OSPCALLING '%s'\n", result.calling);
   pbx_builtin_setvar_helper(chan, "OSPOUTTOKEN", result.token);
   ast_debug(1, "OSPLookup: OSPOUTTOKEN size '%zd'\n", strlen(result.token));
   snprintf(buffer, sizeof(buffer), "%d", result.numresults);
   pbx_builtin_setvar_helper(chan, "OSPRESULTS", buffer);
   ast_debug(1, "OSPLookup: OSPRESULTS '%s'\n", buffer);
   snprintf(buffer, sizeof(buffer), "%d", result.outtimelimit);
   pbx_builtin_setvar_helper(chan, "OSPOUTTIMELIMIT", buffer);
   ast_debug(1, "OSPLookup: OSPOUTTIMELIMIT '%s'\n", buffer);
   snprintf(buffer, sizeof(buffer), "%d", callidtypes);
   pbx_builtin_setvar_helper(chan, "OSPOUTCALLIDTYPES", buffer);
   ast_debug(1, "OSPLookup: OSPOUTCALLIDTYPES '%s'\n", buffer);
   pbx_builtin_setvar_helper(chan, "OSPLOOKUPSTATUS", status);
   ast_debug(1, "OSPLookup: %s\n", status);

   if (!strcasecmp(result.tech, OSP_TECH_H323)) {
      if ((callidtypes & OSP_CALLID_H323) && (result.outcallid.len != 0)) {
         osp_uuid2str(result.outcallid.buf, buffer, sizeof(buffer));
      } else {
         buffer[0] = '\0';
      }
      pbx_builtin_setvar_helper(chan, "OSPOUTCALLID", buffer);
      snprintf(buffer, sizeof(buffer), "%s/%s@%s", result.tech, result.called, result.dest);
      pbx_builtin_setvar_helper(chan, "OSPDIALSTR", buffer);
   } else if (!strcasecmp(result.tech, OSP_TECH_SIP)) {
      snprintf(buffer, sizeof(buffer), "%s/%s@%s", result.tech, result.called, result.dest);
      pbx_builtin_setvar_helper(chan, "OSPDIALSTR", buffer);
      if (!ast_strlen_zero(result.token)) {
         snprintf(buffer, sizeof(buffer), "%s%s", OSP_SIP_HEADER, result.token);
         pbx_builtin_setvar_helper(chan, "_SIPADDHEADER", buffer);
         ast_debug(1, "OSPLookup: SIPADDHEADER size '%zd'\n", strlen(buffer));
      }
   } else if (!strcasecmp(result.tech, OSP_TECH_IAX)) {
      snprintf(buffer, sizeof(buffer), "%s/%s/%s", result.tech, result.dest, result.called);
      pbx_builtin_setvar_helper(chan, "OSPDIALSTR", buffer);
   }

   if ((cres = ast_autoservice_stop(chan)) < 0) {
      return -1;
   }

   if(res <= 0) {
      res = -1;
   } else {
      res = 0;
   }

   return res;
}
static int ospnext_exec ( struct ast_channel chan,
void *  data 
) [static]

OSP Application OSPNext.

Parameters:
chanChannel
dataParameter
Returns:
0 Success, -1 Failed

Definition at line 1503 of file app_osplookup.c.

References AST_APP_ARG, ast_debug, AST_DECLARE_APP_ARGS, AST_LIST_TRAVERSE, ast_log(), AST_OSP_ERROR, AST_OSP_FAILED, AST_OSP_SUCCESS, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_var_name(), ast_var_value(), osp_callid::buf, osp_result::called, osp_result::calling, cause, osp_result::dest, osp_result::inhandle, osp_result::intimelimit, osp_callid::len, LOG_ERROR, LOG_WARNING, osp_result::networkid, osp_result::numresults, OSP_CALLID_H323, OSP_CALLID_UNDEFINED, OSP_DEF_PROVIDER, OSP_DEF_TIMELIMIT, OSP_INVALID_HANDLE, osp_next(), OSP_SIP_HEADER, OSP_TECH_H323, OSP_TECH_IAX, OSP_TECH_SIP, OSP_TOKSTR_SIZE, osp_uuid2str(), osp_result::outcallid, osp_result::outhandle, osp_result::outtimelimit, pbx_builtin_setvar_helper(), status, osp_result::tech, osp_result::token, and ast_channel::varshead.

Referenced by load_module().

{
   int res;
   const char* provider = OSP_DEF_PROVIDER;
   int cause = 0;
   struct varshead* headp;
   struct ast_var_t* current;
   struct osp_result result;
   char buffer[OSP_TOKSTR_SIZE];
   unsigned int callidtypes = OSP_CALLID_UNDEFINED;
   const char* status;
   char* tmp;

   AST_DECLARE_APP_ARGS(args,
      AST_APP_ARG(cause);
      AST_APP_ARG(provider);
      AST_APP_ARG(options);
   );

   if (ast_strlen_zero(data)) {
      ast_log(LOG_WARNING, "OSPNext: Arg required, OSPNext(cause[|provider[|options]])\n");
      return -1;
   }

   if (!(tmp = ast_strdupa(data))) {
      ast_log(LOG_ERROR, "Out of memory\n");
      return -1;
   }

   AST_STANDARD_APP_ARGS(args, tmp);

   if (!ast_strlen_zero(args.cause) && sscanf(args.cause, "%30d", &cause) != 1) {
      cause = 0;
   }
   ast_debug(1, "OSPNext: cause '%d'\n", cause);

   if (!ast_strlen_zero(args.provider)) {
      provider = args.provider;
   }
   ast_debug(1, "OSPlookup: provider '%s'\n", provider);

   result.inhandle = OSP_INVALID_HANDLE;
   result.outhandle = OSP_INVALID_HANDLE;
   result.intimelimit = OSP_DEF_TIMELIMIT;
   result.numresults = 0;

   headp = &chan->varshead;
   AST_LIST_TRAVERSE(headp, current, entries) {
      if (!strcasecmp(ast_var_name(current), "OSPINHANDLE")) {
         if (sscanf(ast_var_value(current), "%30d", &result.inhandle) != 1) {
            result.inhandle = OSP_INVALID_HANDLE;
         }
      } else if (!strcasecmp(ast_var_name(current), "OSPOUTHANDLE")) {
         if (sscanf(ast_var_value(current), "%30d", &result.outhandle) != 1) {
            result.outhandle = OSP_INVALID_HANDLE;
         }
      } else if (!strcasecmp(ast_var_name(current), "OSPINTIMELIMIT")) {
         if (sscanf(ast_var_value(current), "%30d", &result.intimelimit) != 1) {
            result.intimelimit = OSP_DEF_TIMELIMIT;
         }
      } else if (!strcasecmp(ast_var_name(current), "OSPOUTCALLIDTYPES")) {
         if (sscanf(ast_var_value(current), "%30d", &callidtypes) != 1) {
            callidtypes = OSP_CALLID_UNDEFINED;
         }
      } else if (!strcasecmp(ast_var_name(current), "OSPRESULTS")) {
         if (sscanf(ast_var_value(current), "%30d", &result.numresults) != 1) {
            result.numresults = 0;
         }
      }
   }
   ast_debug(1, "OSPNext: OSPINHANDLE '%d'\n", result.inhandle);
   ast_debug(1, "OSPNext: OSPOUTHANDLE '%d'\n", result.outhandle);
   ast_debug(1, "OSPNext: OSPINTIMELIMIT '%d'\n", result.intimelimit);
   ast_debug(1, "OSPNext: OSPOUTCALLIDTYPES '%d'\n", callidtypes);
   ast_debug(1, "OSPNext: OSPRESULTS '%d'\n", result.numresults);

   if ((res = osp_next(provider, cause, &result)) > 0) {
      status = AST_OSP_SUCCESS;
   } else {
      result.tech[0] = '\0';
      result.dest[0] = '\0';
      result.called[0] = '\0';
      result.calling[0] = '\0';
      result.token[0] = '\0';
      result.networkid[0] = '\0';
      result.numresults = 0;
      result.outtimelimit = OSP_DEF_TIMELIMIT;
      result.outcallid.buf[0] = '\0';
      result.outcallid.len = 0;
      if (!res) {
         status = AST_OSP_FAILED;
      } else {
         status = AST_OSP_ERROR;
      }
   }

   pbx_builtin_setvar_helper(chan, "OSPTECH", result.tech);
   ast_debug(1, "OSPNext: OSPTECH '%s'\n", result.tech);
   pbx_builtin_setvar_helper(chan, "OSPDEST", result.dest);
   ast_debug(1, "OSPNext: OSPDEST '%s'\n", result.dest);
   pbx_builtin_setvar_helper(chan, "OSPCALLED", result.called);
   ast_debug(1, "OSPNext: OSPCALLED'%s'\n", result.called);
   pbx_builtin_setvar_helper(chan, "OSPCALLING", result.calling);
   ast_debug(1, "OSPNext: OSPCALLING '%s'\n", result.calling);
   pbx_builtin_setvar_helper(chan, "OSPOUTTOKEN", result.token);
   ast_debug(1, "OSPNext: OSPOUTTOKEN size '%zd'\n", strlen(result.token));
   snprintf(buffer, sizeof(buffer), "%d", result.numresults);
   pbx_builtin_setvar_helper(chan, "OSPRESULTS", buffer);
   ast_debug(1, "OSPNext: OSPRESULTS '%s'\n", buffer);
   snprintf(buffer, sizeof(buffer), "%d", result.outtimelimit);
   pbx_builtin_setvar_helper(chan, "OSPOUTTIMELIMIT", buffer);
   ast_debug(1, "OSPNext: OSPOUTTIMELIMIT '%s'\n", buffer);
   pbx_builtin_setvar_helper(chan, "OSPNEXTSTATUS", status);
   ast_debug(1, "OSPNext: %s\n", status);

   if (!strcasecmp(result.tech, OSP_TECH_H323)) {
      if ((callidtypes & OSP_CALLID_H323) && (result.outcallid.len != 0)) {
         osp_uuid2str(result.outcallid.buf, buffer, sizeof(buffer));
      } else {
         buffer[0] = '\0';
      }
      pbx_builtin_setvar_helper(chan, "OSPOUTCALLID", buffer);
      snprintf(buffer, sizeof(buffer), "%s/%s@%s", result.tech, result.called, result.dest);
      pbx_builtin_setvar_helper(chan, "OSPDIALSTR", buffer);
   } else if (!strcasecmp(result.tech, OSP_TECH_SIP)) {
      snprintf(buffer, sizeof(buffer), "%s/%s@%s", result.tech, result.called, result.dest);
      pbx_builtin_setvar_helper(chan, "OSPDIALSTR", buffer);
      if (!ast_strlen_zero(result.token)) {
         snprintf(buffer, sizeof(buffer), "%s%s", OSP_SIP_HEADER, result.token);
         pbx_builtin_setvar_helper(chan, "_SIPADDHEADER", buffer);
         ast_debug(1, "OSPLookup: SIPADDHEADER size '%zd'\n", strlen(buffer));
      }
   } else if (!strcasecmp(result.tech, OSP_TECH_IAX)) {
      snprintf(buffer, sizeof(buffer), "%s/%s/%s", result.tech, result.dest, result.called);
      pbx_builtin_setvar_helper(chan, "OSPDIALSTR", buffer);
   }

   if(res <= 0) {
      res = -1;
   } else {
      res = 0;
   }

   return res;
}
static int reload ( void  ) [static]

Definition at line 2035 of file app_osplookup.c.

References osp_load().

{
   osp_load(1);

   return 0;
}
static int unload_module ( void  ) [static]

Variable Documentation

struct ast_module_info __MODULE_INFO_SECTION __mod_info = { __MODULE_INFO_GLOBALS .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Open Settlement Protocol Applications" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, } [static]

Definition at line 2046 of file app_osplookup.c.

const char* app1 = "OSPAuth" [static]

Definition at line 1943 of file app_osplookup.c.

const char* app2 = "OSPLookup" [static]

Definition at line 1955 of file app_osplookup.c.

const char* app3 = "OSPNext" [static]

Definition at line 1980 of file app_osplookup.c.

const char* app4 = "OSPFinish" [static]

Definition at line 1990 of file app_osplookup.c.

Definition at line 2046 of file app_osplookup.c.

struct ast_cli_entry cli_osp[] [static]
Initial value:
 {
   AST_CLI_DEFINE(handle_cli_osp_show, "Displays OSF information")
}

Definition at line 2001 of file app_osplookup.c.

const char* descrip1 = " SUCCESS | FAILED | ERROR\n" [static]

Definition at line 1945 of file app_osplookup.c.

const char* descrip2 = " SUCCESS | FAILED | ERROR\n" [static]

Definition at line 1957 of file app_osplookup.c.

const char* descrip3 = " SUCCESS | FAILED | ERROR\n" [static]

Definition at line 1982 of file app_osplookup.c.

const char* descrip4 = " SUCCESS | FAILED | ERROR \n" [static]

Definition at line 1992 of file app_osplookup.c.

int osp_hardware = 0 [static]

Definition at line 169 of file app_osplookup.c.

int osp_initialized = 0 [static]

Definition at line 168 of file app_osplookup.c.

unsigned int osp_tokenformat = TOKEN_ALGO_SIGNED [static]

Definition at line 171 of file app_osplookup.c.

ast_mutex_t osplock = AST_MUTEX_INIT_VALUE [static]
const char* synopsis1 = "OSP authentication" [static]

Definition at line 1944 of file app_osplookup.c.

const char* synopsis2 = "Lookup destination by OSP" [static]

Definition at line 1956 of file app_osplookup.c.

const char* synopsis3 = "Lookup next destination by OSP" [static]

Definition at line 1981 of file app_osplookup.c.

const char* synopsis4 = "Record OSP entry" [static]

Definition at line 1991 of file app_osplookup.c.