Fri Jul 15 2011 11:59:06

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 __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Open Settlement Protocol Applications" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .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_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP )
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 __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Open Settlement Protocol Applications" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .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_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [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.