Logo Search packages:      
Sourcecode: bayonne version File versions  Download package

bayonne.h

// Copyright (C) 2000-2001 Open Source Telecom Corporation.
//  
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software 
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

#ifndef     __CCXX_BAYONNE_H__
#define     __CCXX_BAYONNE_H__

#ifndef     __CCXX_SCRIPT_H__
#include <cc++/script.h>
#endif

#ifdef      COMMON_XML_PARSING
#ifndef     __CCXX_XML_H__
#include <cc++/xml.h>
#endif
#endif

#ifndef     __CCXX_URL_H__
#include <cc++/url.h>
#endif

#ifndef     __CCXX_SLOG_H__
#include <cc++/slog.h>
#endif

#ifndef     __CCXX_DSO_H__
#include <cc++/file.h>
#endif

#ifndef     __CCXX_SOCKET_H__
#include <cc++/socket.h>
#endif

#ifndef     __CCXX_AUDIO_H__
#include <cc++/audio.h>
#endif

#ifndef     COMMON_XML_PARSING
#undef      XML_SCRIPTS
#endif

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <climits>

#ifndef     PIPE_BUF
#define     PIPE_BUF    512
#endif

#ifdef      __FreeBSD__
#undef      read
#undef      write
#undef      readv
#undef      writev
#endif

#ifdef      CCXX_NAMESPACES 
namespace ost {
#endif

/* Bayonne uses a universal event record for all driver plugins and
   state handlers.  Not all drivers impliment the entire set of events
   and some drivers have specific events associated with their unique
   characteristcs.  However, most events are considered "universal".
*/

class Trunk;
class TrunkImage;
class Service;
class phTone;
class TrunkGroup;
class Module;
class Request;

#define     MAX_DIGITS  48

typedef enum
{
      SELECT_FIRST,
      SELECT_LAST
} seltype_t;

typedef enum
{
      MAP_PREFIX,
      MAP_SUFFIX,
      MAP_ABSOLUTE
} mapmode_t;

typedef enum
{
      JOIN_RECV,
      JOIN_XMIT,
      JOIN_FULL
} joinmode_t;

typedef enum
{
      PULSE_DIALER,
      DTMF_DIALER,
      MF_DIALER
} dialmode_t;

typedef enum {
      MODULE_GENERIC,
      MODULE_DELIVERY,
      MODULE_SENDFILE,
      MODULE_SENDFAX,
      MODULE_NOTIFY,
      MODULE_FIFO,
      MODULE_TGI,
      MODULE_URL,
      MODULE_NET,
      MODULE_REPLY,
#ifdef      XML_SCRIPTS
      MODULE_XML,
#endif
      MODULE_SWITCH,
      MODULE_THREAD,
      MODULE_PLAY,
      MODULE_RECORD,
      MODULE_SQL,
      MODULE_ANY
}     modtype_t;

typedef enum {
      // step change requests
      TRUNK_STEP_HANGUP = 0,
      TRUNK_STEP_SLEEP,
      TRUNK_STEP_ACCEPT,
      TRUNK_STEP_REJECT,
      TRUNK_STEP_ANSWER,
      TRUNK_STEP_COLLECT,
      TRUNK_STEP_PLAY,
      TRUNK_STEP_PLAYWAIT,
      TRUNK_STEP_RECORD,
      TRUNK_STEP_TONE,
      TRUNK_STEP_DIALXFER,
      TRUNK_STEP_SOFTDIAL,
      TRUNK_STEP_FLASH,
      TRUNK_STEP_JOIN,
      TRUNK_STEP_RTP,
      TRUNK_STEP_DUPLEX,
      TRUNK_STEP_DETECT,
      TRUNK_STEP_REQUIRES,
      TRUNK_STEP_LOADER,
      TRUNK_STEP_TRANSFER,    // pbx internal transfer
      TRUNK_STEP_INTERCOM,    // pbx internal intercom
      TRUNK_STEP_PICKUP,      // pbx internal line pickup
      TRUNK_STEP_THREAD,
      TRUNK_STEP_SENDFAX,
      TRUNK_STEP_RECVFAX,
      TRUNK_STEP_REROUTE,
      TRUNK_STEP_CONFERENCE,
      TRUNK_STEP_EXIT = TRUNK_STEP_HANGUP,
      TRUNK_STEP_DRIVER
} trunkstep_t;

typedef     enum {
      // notify script from state handler
      TRUNK_SIGNAL_STEP = 0,

      TRUNK_SIGNAL_EXIT,
      TRUNK_SIGNAL_HANGUP=TRUNK_SIGNAL_EXIT,
      TRUNK_SIGNAL_ERROR,
      TRUNK_SIGNAL_TIMEOUT,
      TRUNK_SIGNAL_DTMF,

      TRUNK_SIGNAL_0,
      TRUNK_SIGNAL_1,
      TRUNK_SIGNAL_2,
      TRUNK_SIGNAL_3,

      TRUNK_SIGNAL_4,
      TRUNK_SIGNAL_5,
      TRUNK_SIGNAL_6,
      TRUNK_SIGNAL_7,

      TRUNK_SIGNAL_8,
      TRUNK_SIGNAL_9,
      TRUNK_SIGNAL_STAR,
      TRUNK_SIGNAL_POUND,

      TRUNK_SIGNAL_A,
      TRUNK_SIGNAL_OVERRIDE = TRUNK_SIGNAL_A,
      TRUNK_SIGNAL_B,
      TRUNK_SIGNAL_FLASH = TRUNK_SIGNAL_B,
      TRUNK_SIGNAL_C,
      TRUNK_SIGNAL_IMMEDIATE = TRUNK_SIGNAL_C,
      TRUNK_SIGNAL_D,
      TRUNK_SIGNAL_PRIORITY = TRUNK_SIGNAL_D,

      TRUNK_SIGNAL_SILENCE,
      TRUNK_SIGNAL_BUSY,
      TRUNK_SIGNAL_CANCEL,
      TRUNK_SIGNAL_FAIL = TRUNK_SIGNAL_CANCEL,
      TRUNK_SIGNAL_INVALID = TRUNK_SIGNAL_CANCEL,
      TRUNK_SIGNAL_SIGNAL,

      TRUNK_SIGNAL_NOANSWER,
      TRUNK_SIGNAL_RING,
      TRUNK_SIGNAL_ANSWER = TRUNK_SIGNAL_RING,
      TRUNK_SIGNAL_PICKUP = TRUNK_SIGNAL_RING,
      TRUNK_SIGNAL_TONE,
      TRUNK_SIGNAL_EVENT,

      TRUNK_SIGNAL_TIME,
      TRUNK_SIGNAL_MAXTIME = TRUNK_SIGNAL_TIME,
      TRUNK_SIGNAL_CHILD,
      TRUNK_SIGNAL_DRIVER,

      TRUNK_SIGNAL_GOTO = 65
}     trunksignal_t;

typedef enum {
      // primary state handlers

      TRUNK_ENTER_STATE = 100,// newly entered handler state
      TRUNK_EXIT_STATE, // exiting prior state (unused)
      TRUNK_STOP_STATE, // request state termination
      TRUNK_NOTIFICATION,     // death notify event
      TRUNK_SERVICE_SUCCESS,  // service completion successful
      TRUNK_SERVICE_FAILURE,  // service completion failed
      TRUNK_SERVICE_LOOKUP,   // lookup transaction
      TRUNK_SERVICE_LOGIN,    // login transaction
      TRUNK_SIGNAL_NOTIFY,    // signal between trunks
      TRUNK_SEND_MESSAGE,     // event message ipc
      TRUNK_JOIN_TRUNKS,      // join two trunks together
      TRUNK_PART_TRUNKS,      // split two trunks that were joined
      TRUNK_NULL_EVENT, // used to push pipe driven systems
      TRUNK_CHILD_START,      // notify parent of child startup
      TRUNK_CHILD_FAIL, // notify parent child start failed
      TRUNK_CHILD_EXIT, // notify child channel died

      // tgi/integration control state handlers

      TRUNK_EXIT_SHELL = 200, // tgi completion event
      TRUNK_START_SCRIPT,     // start of script
      TRUNK_RING_START, // smdi/integrated answer
      TRUNK_RING_REDIRECT,    // smdi/integrated answer options
      TRUNK_STOP_DISCONNECT,  // integrated hangup notification

      // in the future these will be used

      TRUNK_START_INCOMING = TRUNK_RING_START,
      TRUNK_START_OUTGOING = TRUNK_START_SCRIPT,

      // primary "mode" selection controls

      TRUNK_MAKE_TEST =  300, // request driver perform line test
      TRUNK_MAKE_BUSY,  // request driver lockout line
      TRUNK_MAKE_IDLE,  // request driver reset line
      TRUNK_MAKE_STEP,  // pass step event internally
      TRUNK_MAKE_STANDBY,     // standby mode for carrier grade events

      // basic trunk events

      TRUNK_LINE_WINK = 400,  // used for line disconnect notification
      TRUNK_TIMER_EXPIRED,    // driver specific port timer expired
      TRUNK_TIMER_EXIT,
      TRUNK_TIMER_SYNC,
      TRUNK_RINGING_ON, // some drivers distinguish start/stop
      TRUNK_RINGING_OFF,      // default ring event
      TRUNK_TEST_IDLE,  // some drivers have line test completion
      TRUNK_TEST_FAILURE,     // some drivers notify errors
      TRUNK_ON_HOOK,          // some drivers notify on hook
      TRUNK_OFF_HOOK,         // some drivers notify off hook
      TRUNK_CALLER_ID,  // caller id parse request
      TRUNK_RINGING_DID,      // did digit ring signal
      TRUNK_CALL_DETECT,      // ISDN call detected notification
      TRUNK_CALL_CONNECT,     // ISDN call connection notification
      TRUNK_CALL_RELEASE,     // ISDN call release notification
      TRUNK_CALL_ACCEPT,      // ISDN incoming call accepted
      TRUNK_CALL_ANSWERED,    // ISDN connect sent to the network
      TRUNK_CALL_HOLD,  // ISDN call placed on hold
      TRUNK_CALL_NOHOLD,      // ISDN call hold was rejected
      TRUNK_CALL_DIGITS,      // requested digits received
      TRUNK_CALL_OFFER, // ISDN call offered
      TRUNK_CALL_ANI,         // ANI received
      TRUNK_CALL_ACTIVE,      // ISDN call taken off hold
      TRUNK_CALL_NOACTIVE,    // ISDN call hold retrieve failed
      TRUNK_CALL_BILLING,     // ISDN call billing acknowledge
      TRUNK_CALL_RESTART,     // ISDN call restart, success or failure
      TRUNK_CALL_SETSTATE,    // ISDN acknowledge state change
      TRUNK_CALL_FAILURE,     // ISDN midcall failure
      TRUNK_CALL_ALERTING,    // ISDN call alerting
      TRUNK_CALL_INFO,  // ISDN call info message
      TRUNK_CALL_BUSY,  // ISDN conjestion message
      TRUNK_CALL_DIVERT,      // ISDN call diversion notification
      TRUNK_CALL_FACILITY,    // ISDN call facility
      TRUNK_CALL_FRAME, // ISDN call frame
      TRUNK_CALL_NOTIFY,      // ISDN call notify
      TRUNK_CALL_NSI,         // ISDN call nsi message
      TRUNK_CALL_RINGING,     // digital T1 incoming call
      TRUNK_CALL_DISCONNECT,  // digital T1 circuit break
      TRUNK_DEVICE_OPEN,      // device open
      TRUNK_DEVICE_CLOSE,     // device close
      TRUNK_DEVICE_BLOCKED,   // channel blocked
      TRUNK_DEVICE_UNBLOCKED, // channel unblocked

      // basic audio processing events

      TRUNK_AUDIO_IDLE = 500, // audio reset or completion event
      TRUNK_INPUT_PENDING,    // some drivers monitor audio i/o status
      TRUNK_OUTPUT_PENDING,   // some drivers monitor audio i/p status
      TRUNK_AUDIO_BUFFER,     // some drivers return audio buffers
      TRUNK_TONE_IDLE,  // tone generator completion event
      TRUNK_DTMF_KEYDOWN,     // some drivers distinguish tone down
      TRUNK_DTMF_KEYUP, // default dtmf event
      TRUNK_TONE_START, // tone detected
      TRUNK_TONE_STOP,  // some drivers have tone completion event
      TRUNK_VOX_DETECT, // speaker detected
      TRUNK_VOX_SILENCE,      // silence detected
      TRUNK_AUDIO_START,      // some drivers may "vox" compress
      TRUNK_AUDIO_STOP, // some drivers may "vox" compress
      TRUNK_CPA_DIALTONE,     // dialtone heard on the line
      TRUNK_CPA_BUSYTONE,
      TRUNK_CPA_RINGING,
      TRUNK_CPA_RINGBACK = TRUNK_CPA_RINGING,
      TRUNK_CPA_INTERCEPT,
      TRUNK_CPA_NODIALTONE,
      TRUNK_CPA_NORINGBACK,
      TRUNK_CPA_NOANSWER,
      TRUNK_CPA_CONNECT,
      TRUNK_CPA_FAILURE,
      TRUNK_CPA_GRUNT,
      TRUNK_CPA_REORDER,
      TRUNK_DSP_READY,  // dsp resource became available
      TRUNK_CPA_STOPPED,

      // basic station processing event extensions

      TRUNK_START_RINGING = 600,    // ring for incoming lines
      TRUNK_START_TRANSFER,         // transfer mode ring
      TRUNK_START_INTERCOM,         // intercom mode ring
      TRUNK_START_RECALL,           // transfer recall mode ring
      TRUNK_START_DIALING,          // initiate outgoing call
      TRUNK_STOP_RINGING,           // cancel a ring request
      TRUNK_STATION_OFFHOOK,
      TRUNK_STATION_ONHOOK,
      TRUNK_STATION_FLASH,
      TRUNK_STATION_ANSWER,         // answering ringing port
      TRUNK_STATION_PICKUP,         // pickup foreign port
      TRUNK_STATION_CONNECT,        // autoanswer mode

      // driver specific events and anomolies

      TRUNK_DRIVER_SPECIFIC=8000    // very oddball events
} trunkevent_t;

typedef enum
{
      DSP_MODE_INACTIVE = 0,  // dsp is idle
      DSP_MODE_VOICE,         // standard voice processing
      DSP_MODE_CALLERID,      // caller id support
      DSP_MODE_DATA,          // fsk modem mode
      DSP_MODE_FAX,           // fax support
      DSP_MODE_TDM,           // TDM bus with echo cancellation
      DSP_MODE_RTP,           // VoIP full duplex
      DSP_MODE_DUPLEX,  // mixed play/record
      DSP_MODE_JOIN,          // support of joined channels
      DSP_MODE_CONF,          // in conference
      DSP_MODE_TONE           // tone processing
} dspmode_t;

typedef enum
{
      DTMF_MODE_LINE = 0,
      DTMF_MODE_SCRIPT,
      DTMF_MODE_ON,
      DTMF_MODE_OFF
} dtmfmode_t;

typedef enum
{
      TRUNK_MODE_INCOMING = 0,
      TRUNK_MODE_OUTGOING,
      TRUNK_MODE_INACTIVE,
      TRUNK_MODE_UNAVAILABLE
} trunkmode_t;
 
typedef enum
{
      STAT_MAX_INCOMING,
      STAT_MAX_OUTGOING,
      STAT_TOT_INCOMING,
      STAT_TOT_OUTGOING,
      STAT_ACTIVE_CALLS,
      STAT_NOW_INCOMING,
      STAT_NOW_OUTGOING,
      STAT_SYS_INCOMING,
      STAT_SYS_OUTGOING,
      STAT_SYS_UPTIME,
      STAT_SYS_ACTIVITY,
      STAT_CURRENT_CALLS,
      STAT_CMAX_INCOMING,
      STAT_CMAX_OUTGOING
} statitem_t;

typedef     enum
{
      PLAY_MODE_NORMAL,
      PLAY_MODE_ONE,
      PLAY_MODE_ANY,
      PLAY_MODE_TEMP,
      PLAY_MODE_TEXT,
      PLAY_MODE_FILE,
      PLAY_MODE_MOH
} playmode_t;

typedef enum
{
      TTS_GATEWAY_TEXT,
      TTS_GATEWAY_FILE
} ttsmode_t;

#define TRUNK_CAP_VOICE       0x00000001
#define     TRUNK_CAP_DIAL          0x00000002
#define TRUNK_CAP_SENDFAX     0x00000004
#define     TRUNK_CAP_RECVFAX 0x00000008
#define     TRUNK_CAP_DATA          0x00000010
#define     TRUNK_CAP_TTS           0x00000020
#define     TRUNK_CAP_ASR           0x00000040
#define     TRUNK_CAP_STATION 0x00000080

typedef     struct
{
      
      int pid;
      unsigned seq;
      void *data;
}     execdata_t;

typedef enum
{
      SPEED_FAST,
      SPEED_SLOW,
      SPEED_NORMAL
}     trunkspeed_t;

typedef     union
{
      struct
      {
            unsigned rings;
            timeout_t timeout;
            const char *transfer;
            Trunk *intercom;
            const char *station;    // if answer to fax tone, station id
            const char *fax;  // fax branch script vector
      }     answer;
      struct
      {
            char pathname[256];
            const char *station;    // fax station id
      }     fax;
      struct
      {
            char list[256];
            char *name;
            const char *extension;
            unsigned long offset;
            unsigned long limit;
            unsigned short term;
            playmode_t mode;
            timeout_t timeout, maxtime;
            unsigned repeat;
            unsigned volume;
            float gain, pitch;
            trunkspeed_t speed;
            const char *voice;
            const char *text;
            const char *cache;
            bool lock;
      }     play;
      struct
      {
            char *name, *save;
            const char *encoding;
            const char *annotation;
            const char *extension;
            const char *text;
            timeout_t timeout;
            unsigned long offset;
            unsigned short term;
            unsigned long silence;
            unsigned long trim;
            unsigned long minsize;
            unsigned volume;
            float gain;
            short frames;
            bool append;
            bool info;
            char filepath[65];
            char savepath[65];
            char altinfo[128];
      }     record;
      struct
      {
            char digits[65];
            char *digit;
                  char *callingdigit;
            bool exit;
            dialmode_t dialer;
            timeout_t interdigit;
            timeout_t digittimer;
            timeout_t timeout;
            timeout_t offhook;
            timeout_t onhook;
            unsigned pulsecount;
      }     dialxfer;
      struct
      {
            timeout_t timeout;
            unsigned count;
            unsigned short term;
            unsigned short ignore;
            void *map;
            void *var;
      }     collect;
      struct
      {
            timeout_t wakeup;
            unsigned rings;
            unsigned loops;
            const char *save;
      }     sleep;
      struct
      {
            timeout_t wakeup, duration;
            unsigned loops;
            phTone *tone;
            unsigned freq1, freq2;
            int ampl1, ampl2;
            Trunk *dialing;
            bool recall;
      }     tone;
      struct
      {
            Trunk *src;
            const char *msg;
            unsigned seq;
      }     send;
      struct
      {
            timeout_t wakeup, maxwait;
            bool hangup;
            joinmode_t direction;
            Trunk *trunk, *waiting;
            phTone *tone;
            float inpgain, outgain;
            char *recfn;
            const char *encoding;
            const char *annotation;
            const char *extension;
            unsigned count;
            unsigned seq;
            trunkevent_t reason;
      }     join;
      struct
      {
            TrunkImage *image;
            const char *url;
            const char *section;
            const char *parent;
            const char *fail;
            const char *database;
            char **vars;
            bool post, attach, gosub;
            timeout_t timeout;
            char userid[64];
            char filepath[256];
      }     load;
      struct
      {
            Trunk *answer;
            const char *transfer;
      }     intercom;
      struct
      {
            char option[10];
            char forwarddest[16 + 1];
            char backwarddest[16 + 1];
            char context[24 + 1];
            char backcontext[24 + 1];
      }       reroute;
      struct
      {
            char name[256];
            int option;
            unsigned int size;
            int attributes;
            unsigned int fixed;
      }     conference;

}     trunkdata_t;

typedef struct
{
      trunkevent_t id;  // event id
      union
      {
            struct
            {
                  unsigned digit: 4;
                  unsigned duration: 12;
                  unsigned e1: 8;
                  unsigned e2: 8;
            } dtmf;
            struct
            {
                  unsigned tone: 8;
                  unsigned energy: 8;
                  unsigned duration: 16;
                  char *name;
            } tone;
            struct
            {
                  unsigned seq;
                  Trunk *src;
                  const char *msg;
            } send;
            struct
            {
                  unsigned digit:  4;
                  unsigned duration: 24;
            } ring;
            struct
            {
                  unsigned seq;
                  bool result;
                  char *data;
            } lookup;
            struct
            {
                  unsigned tid;
                  const char *transfer;
            } intercom;
            trunkevent_t reason;
            unsigned span;
            unsigned card;
            unsigned tid;
            bool ok;
            int status;
            Trunk *trunk;
            void *data;
            char **argv;
            char *error;
            timeout_t duration;
            trunkstep_t step;
            char dn[8];
            dspmode_t dsp;
      } parm;
} TrunkEvent;

#pragma pack(1)

typedef     struct {
      time_t      update;
      char name[16];
      struct in_addr addr;
      unsigned long uptime;
      unsigned long calls;
      unsigned char version;
      unsigned char buddies;
      unsigned char spansize;
      unsigned short ports;
      char stat[840];
}     statnode_t;

#pragma pack()

/* This is used to bind user defined "functions" which may be loaded
   in a DSO module.
*/

bool getLogical(const char *string);
timeout_t getSecTimeout(const char *string);
timeout_t getMSTimeout(const char *string);

/**
 * A call statistic class is used to manipulate call stats with a mutex
 * lock to prevent errors during "adjustment" periods.
 *
 * @author David Sugar <dyfet@ostel.com>
 * @short call statistic collection object.
 */
00701 class CallStat : public Mutex
{
protected:
      static unsigned long upincoming, upoutgoing;
      static time_t uptime;

      int capacity;
      struct
      {
            int incoming;
            int outgoing;
      }     active, max, lastmax;

      struct
      {
            long incoming;
            long outgoing;
      }     total, lasttotal;

public:
      CallStat();

      /**
       * Get current call capacity.
       *
       * @return capacity of this stat item.
       */
00728       inline int getCapacity(void)
            {return capacity;};

      /**
       * get a stat item.
       *
       * @param statitem to request.
       * @return item value.
       */
      long getStat(statitem_t item);

      /**
       * Get a stat record at once.
       *
       * @param pointer to stats to copy.
       */
      void getStat(unsigned long *save);

      /**
       * inc active incoming call count.
       */
      void incIncoming(void);

      /**
       * dec active incoming call count.
       */
      void decIncoming(void);

      /**
       * inc active outging call count.
       */
      void incOutgoing(void);

      /**
       * dec active outgoing call count.
       */
      void decOutgoing(void);

      /**
       * Update stats, active to last.
       */
      void update(void);
};

/**
 * Phrasebook modules are used to convert things like numbers into
 * sets of prompts that form spoken words.  Translations are dso based
 * and are represented by the "languages" plugin.  A translator for
 * spanish may handle not just numbers, dates, etc, but also the
 * selection of masculine and feminine forms of numbers based on
 * usage, etc.  The translator classes provide some basic mechanics
 * for phrasebook tts in Bayonne.
 *
 * @author David Sugar <dyfet@ostel.com>
 * @short phrase translations dso base for tts.
 */
00784 class Translator : protected Keydata
{
private:
      friend Translator *getTranslator(const char *name);
      static Translator *first;
      Translator *next;

protected:
      /**
       * Return the language this translator supports.
       *
       * @return language supported.
       */
      virtual char *getName(void) = 0;

      /**
       * get play buffer object.
       *
       * @return put buffer
       * @param trunk object
       */
      char *getPlayBuffer(Trunk *trunk);

      Translator(const char *conf);

public:
      /**
       * Perform a phrasebook translation of the current script
       * statement and issue play request.
       *
       * @return ccscript error message or NULL.
       * @param trunk object for phrasebook.
       */
      virtual char *speak(Trunk *trunk) = 0;
};

/* Bayonne config file istanciation classes.  In Bayonne these are
   created as keydata objects out of bayonne.conf during process
   startup automatically.  This is Bayonne runtime configuration magic.
*/

/**
 * Load /etc/bayonne [tones] key values for user defined tone sets.
 *
 * @author David Sugar <dyfet@ostel.com>
 * @short Load and build user defined tones.
 */
00831 class KeyTones : protected Keydata
{
public:
      /**
       * Initialize tone data.
       */
      KeyTones();
};

/**
 * Load localization rules from [localize].
 * May have defaults appropriate to US.
 *
 * @author David Sugar <dyfet@ostel.com>
 * @short Load localization rules.
 */
00847 class KeyLocal : public Keydata
{
public:
      /**
       * Load local rule set.
       */
      KeyLocal();
};

/**
 * Load /etc/bayonne [handlers] for special gateway support applications.
 *
 * @author David Sugar <dyfet@ostel.com>
 * @short Load handlers configuration data.
 */
00862 class KeyHandlers : public Keydata
{
public:
      /**
       * Initialize handlers.
       */
      KeyHandlers();
};

/**
 * Load /etc/bayonne [voices] to select and map voice libraries to
 * different translators.
 *
 * @author David Sugar <dyfet@ostel.com>
 * @short Load interpreter imports to use.
 */
00878 class KeyVoices : public Keydata
{
public:
      /**
       * Initialize keyimports data.
       */
      KeyVoices();
};

/**
 * Load /etc/bayonne [imports] to provide interpreter pre-loading of
 * external modules.  This speeds startup.
 *
 * @author David Sugar <dyfet@ostel.com>
 * @short Load interpreter imports to use.
 */
00894 class KeyImports : public Keydata
{
public:
        /**
         * Initialize keyimports data.
         */
        KeyImports();
};


/**
 * Load /etc/bayoone [paths] key value pairs.  Has internal defaults
 * if section or file is missing.
 *
 * @author David Sugar <dyfet@ostel.com>
 * @short Load keypaths path location configuration data.
 */
00911 class KeyPaths : public Keydata
{
public:
      /**
       * Initialize keypath data.
       */
      KeyPaths();

      /**
       * Get the driver and tgi base directories.
       */
00922       inline const char *getLibexec(void)
            {return getLast("libexec");};

      /**
       * Get library tgi exec search path.
       */
00928       inline const char *getTgipath(void)
            {return getLast("tgipath");};

      /**
       * Get prefix for DSO modules at install.
       */
00934       inline const char *getLibpath(void)
            {return getLast("libpath");};

      /**
       * Get the primary working storage for writable messages.
       */
00940       inline const char *getDatafiles(void)
            {return getLast("datafiles");};

      /**
       * Get the wrappers working space for inter-system bridging.
       */
00946       inline const char *getWrappers(void)
            {return getLast("wrappers");};

      /**
       * Get the runfile directory.
       */
00952       inline const char *getRunfiles(void)
            {return getLast("runfiles");};

      /**
       * Get the spool directory.
       */
00958       inline const char *getSpool(void)
            {return getLast("spool");};

      /**
       * Get the primary script prefix directory.
       */
00964       inline const char *getScriptFiles(void)
            {return getLast("scripts");};

      /**
       * Get the prompt directory.
       */
00970       inline const char *getPromptFiles(void)
            {return getLast("prompts");};

      /**
       * Get the pre-cache directory.
       */
00976       inline const char *getCache(void)
            {return getLast("cache");};

      /**
       * Set auto-location prefix.
       */
      void setPrefix(char *path);
};

/**
 * Load /etc/bayonne [network] key value pairs.  These are used to
 * specify dilu access methods and bindings.
 *
 * @author David Sugar <dyfet@ostel.com>
 * @short Load database access bindings.
 */
00992 class KeyNetwork : public Keydata
{
public:
      /**
       * Initialize keydatabase data.
       */
      KeyNetwork();

      /**
       * Get refresh timer in seconds for inter-node activity.
       *
       * @return refresh in seconds.
       */
01005       unsigned getRefresh(void)
            {return atoi(getLast("refresh"));};

      /**
       * Get time delay for declairing a node "dead".
       *
       * @return time delay in seconds.
       */
01013       unsigned getTimeToLive(void)
            {return atoi(getLast("live"));};

      /**
       * Get time to elect a new buddy.
       *
       * @return time to elect in seconds.
       */
01021       unsigned getTimeToElect(void)
            {return atoi(getLast("elect"));};

      /**
       * Get time to expire a buddy.
       *
       * @return time to expire a buddy.
       */
01029       unsigned getTimeToExpire(void)
            {return atoi(getLast("expire"));};

      /**
       * Get broadcast address to use.
       *
       * @return broadcast address.
       */
      InetHostAddress getBroadcast(void);

      /**
       * Get bind address to use.
       *
       * @return binding address.
       */
      InetAddress getAddress(void);

      /**
       * Get bind address for monitoring module.
       *
       * @return monitor address.
       */
      InetAddress getMonitorAddress(void);

      /**
       * Get port for binding.
       *
       * @return port.
       */
      tpport_t getPort(void);

      /**
       * Get port for monitoring module.
       *
       * @return monitor port.
       */
      tpport_t getMonitorPort(void);

      /**
       * Get the host for bayonnedb broadcast.
       *
       * @return broadcast address.
       */
      InetHostAddress getDBHost(void);

      /**
       * Get the database port number.
       *
       * @return db port number.
       */
      tpport_t getDBPort(void);
};

#ifdef      XML_SCRIPTS
/**
 * Load proxy settings and provide access to proxy info.
 *
 * @author David Sugar <dyfet@ostel.com>
 * @short Load proxy info
 */
class KeyProxy : public Keydata
{
public:
      /**
       * Initialize proxy settings.
       */
      KeyProxy();

      /**
       * Get proxy host for http.
       *
         * @return address of proxy or NULL
       */
      const char *getHTTPServer(void);

      /**
       * Get proxy port number.
       *
       * @return port number or 0 if not set.
       */
      tpport_t getHTTPPort(void);

      /**
       * Get server connect timeout value.
       *
       * @return timeout interval.
       *
       */
      timeout_t getTimeout(void);
};    
#endif

/**
 * Load /etc/bayonne [memory] key value pairs.  This is used to
 * configurate space management properties of the runtime environment
 * including audio buffering, page size allocations, etc.
 *
 * @author David Sugar <dyfet@ostel.com>
 * @short Load memory related options.
 */
01129 class KeyMemory : public Keydata
{
public:
      /**
       * Initialize keymemory data.
       */
      KeyMemory();

      /**
       * Get default symbol space size for variables.
       *
       * @return number of bytes of storage for new symbols.
       */
01142       inline int getSymbolSize(void)
            {return atoi(getLast("symbols"));};

      /**
       * Get default page allocation size to use for "paged" memory
       * allocations.
       *
       * @return page size for default paging.
       */
01151       inline int getPageSize(void)
            {return atoi(getLast("page"));};

      /**
       * Get maximum users.
       *
       * @return maximum users.
       */
01159       inline size_t getUserCount(void)
            {return atoi(getLast("users"));};

      /**
       * Get maximum preferences per user.
       *
       * @return maximum preferences.
       */
01167       inline size_t getPrefCount(void)
            {return atoi(getLast("prefs"));};
};

/**
 * Load /etc/bayonne [thread] key value pairs.  Has internal defaults
 * if section or file is missing.
 *
 * @author David Sugar <dyfet@ostel.com>
 * @short Load keythreads priority and session count configuration.
 */
01178 class KeyThreads : public Keydata
{
public:
      /**
       * Initialize keythread data.
       */
      KeyThreads();

      /**
       * Get relative priority to run service threads at.
       *
       * @return service thread priority (relative).
       */
01191       inline int priService(void)
            {return atoi(getLast("services"));};

      /**
       * Get the relative priority to run scheduler at.
       *
       * @return scheduler priority (relative).
       */
01199       inline int priScheduler(void)
            {return atoi(getLast("scheduler"));};

      /**
       * Get the relative priority to run gui at.
       *
       * @return gui priority (relative).
       */
01207       inline int priGUI(void)
            {return atoi(getLast("gui"));};

      /**
       * Get the relative priority to run rtp at.
       *
       * @return rtp priority (relative).
       */
01215       inline int priRTP(void)
            {return atoi(getLast("rtp"));};

      /**
       * Get number of milliseconds to delay each script step.
       *
       * @return millisecond delay interval.
       */
01223       inline int getStepDelay(void)
            {return atoi(getLast("stepdelay"));};

      /**
       * Get the minimal step interval.
       *
       * @return millisecond minimal interval.
       */
01231       inline int getStepInterval(void)
            {return atoi(getLast("stepinterval"));};

      /**
       * Get the reset delay required for settling the DSP.
       *
       * @return millisecond delay from dsp reset.
       */
01239       inline int getResetDelay(void)
            {return atoi(getLast("resetdelay"));};

      /**
       * Get default stack size for threads.
       *
       * @return stack size in "k" increments.
       */
      size_t getStack(void);

      /**
       * Get count of service pool threads to use.
       *
       * @return thread count for service pool.
       */
      int getServices(void);

      /**
       * Get the execution priority of the resolver thread.
       *
       * @return priority of resolver.
       */
      int priResolver(void);

      /**
       * Get the execution interval of the resolver thread, or
       * 0 if no resolver scheduler.
       *
       * @return number of minutes for interval.
       */
      int getResolver(void);

      /**
       * Get relative priority to run audio streams at.
       *
       * @return audio thread priority (relative).
       */
01276       inline int priAudio(void)
            {return atoi(getLast("audio"));};

      /**
       * Get the auditing flag.
       *
       * @return thread auditing flag.
       */
01284       inline bool getAudit(void)
            {return getLogical(getLast("audit"));};
      /**
       * Get relative priority to run gateway (TGI) sessions at.
       *
       * @return tgi gateway process priority (niceness).
       */
01291       inline int priGateway(void)
            {return atoi(getLast("gateways"));};

      /**
       * Get the relative priority to run network management sessions.
       *
       * @return priority for management threads.
       */
01299       inline int priManager(void)
            {return atoi(getLast("managers"));};

      /**
       * Get the relative priority for network service thread.
       *
       * @return priority for lookup thread.
       */
01307       inline int priNetwork(void)
            {return atoi(getLast("network"));};

      /**
       * Get the relative priority for switch integration module.
       *
       * @return priority for switch integration.
       */
01315       inline int priSwitch(void)
            {return atoi(getLast("switch"));};

#ifdef      XML_SCRIPTS
      /**
       * Get the relative priority of the XML parser thread.
       *
       * @return priority for XML service.
       */
      inline int priXML(void)
            {return atoi(getLast("xml"));};
#endif

      /**
       * Scheduler execution interval.
       *
       * @return scheduler interval in minutes.
       */
01333       inline int getInterval(void)
            {return atoi(getLast("interval"));};

      /**
       * Scheduler network node rebroadcast frequency.
       *
       * @return node broadcast update interval in seconds.
       */
01341       inline int getRefresh(void)
            {return atoi(getLast("refresh"));};

      /**
       * Get number of tgi gateway proccesses to make available.
       *
       * @return number of tgi gateway processes.
       */
      int getGateways(void);
      
      /**
       * Get default Bayonne system priority (niceness) to start
       * under before we adjust any relative priorities.
       *
       * @return primary "nice" process priority.
       */
01357       inline int getPriority(void)
            {return atoi(getLast("priority"));};

      /**
       * Get scheduling policy to use.
       *
       * @return policy id, or "0" for default.
       */
      int getPolicy(void);

      /**
       * Get memory locking and local pages.
       *
       * @return number of k of stack to pre-allocate.
       */
01372       inline int getPages(void)
            {return atoi(getLast("pages"));};
};

/**
 * This keydata object holds audit related configuration data such as
 * the logpath to use for audit logs, address of servers, etc.
 *
 * @author David Sugar <dyfet@ostel.com>
 * @short Audit module configuration data.
 */
01383 class Auditdata : public Keydata
{
private:
      friend class Audit;

      Auditdata();
};

/**
 * A base class for plugins that are used to modify policies.  These are
 * typically used for outbound calling systems, to process distribution
 * lists, etc.
 *
 * @author David Sugar <dyfet@ostel.com>
 * @short Policy expansion class.
 */
01399 class Policy
{
private:
      friend class TrunkGroup;

      Policy *next;
      TrunkGroup *group;

protected:
      Policy(TrunkGroup *grp);
      
      virtual Request *loPriority(void)
            {return NULL;};

      virtual Request *hiPriority(void)
            {return NULL;};
};

/**
 * Requests are used to queue service requests to a trunk group.  These
 * are usually for scripts that will perform some form of outbound
 * dialing.  Requests are queued until either they can be serviced, or
 * they are expired.
 *
 * @author David Sugar <dyfet@ostel.com>
 * @short Request service.
 */
01426 class Request
{
private:
      friend class TrunkGroup;

      static unsigned seq;

      unsigned id;
      Request *next;
      time_t expires;
      TrunkGroup *group;

      char *argv[33];
      char buffer[512];
      char tagid[65];
      char parent[65];

      void detach(void);

public:
      Request(TrunkGroup *grp, const char *text, unsigned expire, const char *tag = NULL, const char *pid = NULL);
      ~Request()
            {detach();};

      inline const char *getParent(void)
            {return (const char *)parent;};

      inline char **getList(void)
            {return argv;};

      inline char *getTag(void)
            {return tagid;};

      bool isExpired(void);

      friend void cancel(TrunkGroup *group, const char *tag);
      friend Request *request(TrunkGroup *group, char **argv, unsigned timeout, const char *tag = NULL, const char *pid = NULL);
      friend Request *locate(TrunkGroup *group, const char *tag, int *pos);
};

/**
 * Trunk "groups" provide keydata configuration information that apply
 * to a group of trunk ports represented under a common "group" identity.
 * These are initially given a [trunks] section for default group values
 * followed by a specific entry.  The [server] groups key lists the active
 * trunk groups.  A special default group is also created.
 *
 * @author David Sugar <dyfet@ostel.com>
 * @short Trunk group configuration.
 */
01476 class TrunkGroup : public Keydata, public CallStat
{
private:
      friend class KeyServer;
      friend class Scheduler;
      friend class Audit;
      friend class TestDebug;
      friend class Request;
      friend class Policy;
      friend class Trunk;
      static TrunkGroup *first;
      TrunkGroup *next;
      char schedule[65];
      char planned[65];
      unsigned trump;
      Request *reqfirst, *reqlast;
      Policy *polFirst;
      unsigned members;

      void setSchedule(const char *str);

      friend inline const char *getGroups(void)
            {return TrunkGroup::first->getLast("groups");};

      friend void cancel(TrunkGroup *group, const char *tag);
      friend Request *locate(TrunkGroup *group, const char *tag, int *pos = NULL);


public:
      /**
       * Create a trunk group data key from the bayonne.conf file.
       *
       * @param name of trunk group to load.
       */
      TrunkGroup(char *name = NULL);

      /**
       * Get the name of this trunk group.
       *
       * @return name of trunk group.
       */
01517       inline const char *getName(void)
            {return getLast("name");};

      /**
       * Get the number of rings before answering.
       *
       * @return number of rings to answer.
       */
01525       inline unsigned getAnswer(void)
            {return atoi(getLast("answer"));};

      /**
       * Get the accepting state option for this trunk.
       *
       * @return true if should accept.
       */
      bool getAccept(void);

      /**
       * Get dialtone detect state for the trunk.
       *
       * @return true if dialtone detect should be enabled.
       */
      bool getDetect(void);

      /**
       * Get the number of milliseconds for active caller id.
       *
       * @return number of milliseconds of caller id.
       */
01547       inline timeout_t getCallerid(void)
            {return getMSTimeout(getLast("callerid"));};

      /**
       * Get pickup gaurd time for this trunk group.
       *
       * @return number of milliseconds for call pickup.
       */
01555       inline timeout_t getPickup(void)
            {return getMSTimeout(getLast("pickup"));};

      /**
       * Get handling for trunk group "pending requests".
       *
       * @return symbol or timer value.
       */
01563       inline const char *chkRequest(void)
            {return getLast("requests");};

      /**
       * Get a trunk group port selection method.
       *
       * @return select method.
       */
      seltype_t getSelect(void);

      /**
       * Get trunk threashold for requests to be posted.
       *
       * @return threashold.
       */
01578       inline unsigned getThreashold(void)
            {return atoi(getLast("threashold"));};

      /**
       * Get call progress analysis timeout for dialing.
       *
       * @return timeout in seconds.
       */
01586       inline unsigned getAnalysis(void)
            {return atoi(getLast("analysis"));};

      /**
       * Get ready timer for trunk before handling requests when
       * idle.
       *
       * @return ready timer in milliseconds.
       */
01595       inline timeout_t getReady(void)
            {return getMSTimeout(getLast("ready"));};
      
      /**
       * Get the initial idle timer for this group.
       *
       * @return idle time initial.
       */
01603       inline timeout_t getIdleTime(void)
            {return getMSTimeout(getLast("idletime"));};

      /**
       * Get the trunk seizure timer for dialtone detect.
       *
       * @return siezure time for dialtone.
       */
01611       inline unsigned getSiezeTime(void)
            {return atoi(getLast("siezetime"));};

      /**
       * Get the time delay of each ring.
       *
       * @return ring time between rings.
       */
01619       inline unsigned getRingTime(void)
            {return atoi(getLast("ringtime"));};

      /**
       * Get call progress minimum digits
       *
       * @return number of digits (only for dialogic drivers).
       */
01627       inline unsigned getMinDigits(void)
            {return atoi(getLast("mindigits"));};

      /**
       * Get call progress time out to get more digits
       *
       * @return Timeout in seconds
       */
01635       inline unsigned getMDigTimeOut(void)
            {return atoi(getLast("mdigtimeout"));};

      /**
       * Get disconnect gaurd time before answering.
       *
       * @return gaurd time in milliseconds.
       */
01643       inline timeout_t getHangup(void)
            {return getMSTimeout(getLast("hangup"));};

      /**
       * Get default hook flash time for this trunk group.
       *
       * @return hookflash time in milliseconds.
       */
01651       inline timeout_t getFlash(void)
            {return getMSTimeout(getLast("flash"));};

      /**
       * Get dialtone wait time for this trunk group.
       *
       * @return dialtone wait time in milliseconds.
       */
01659       inline timeout_t getDialtone(void)
            {return getMSTimeout(getLast("dialtone"));};

      /**
       * Get dialing speed in milliseconds.
       *
       * @return dialspeed in milliseconds.
       */
01667       inline timeout_t getDialspeed(void)
            {return getMSTimeout(getLast("dialspeed"));};

      /**
       * Get the telephone number associated with this trunk group
       * if one is associated with it.
       *
       * @return telephone number if known.
       */
      const char *getNumber(void);

      /**
       * Get the name of the script to "schedule" for this group.
       *
       * @return name of scheduled script.
       * @param buffer to copy schedule information into.
       */
      const char *getSchedule(char *buf);

      /**
       * Get the name of the script to "schedule" for a given
       * call redirection mode for this group.  If no redirect
       * option is found, then getSchedule is invoked.
       *
       * @return name of scheduled script.
       * @param redirect identifer.
       * @param buffer to copy schedule information into.
       */
      const char *getRedirect(const char *redirect, char *buf);

      /**
       * Used when mapping trunk groups to activated trunks.
       */
01700       inline void incCapacity(void)
            {++capacity;};

      /**
       * Get the next active request pending for this group.
       *
       * @return next request queued or NULL.
       */
      Request *getRequest(void);

      /**
       * Find a named trunk group.
       *
       * @return trunk group object if found.
       */
      friend TrunkGroup *getGroup(const char *name = NULL);

      /**
       * Get next group record.
       *
       * @return next group link.
       */
01722       inline TrunkGroup *getNext(void)
            {return next;};
};

/**
 * This class is a cache for server specific configuration information
 * which may be configured from /etc/bayonne.conf [server].
 *
 * @author David Sugar <dyfet@ostel.com>
 * @short load server configuration data.
 */
01733 class KeyServer : public Keydata
{
private:
      unsigned uid, gid;
      const char *altdir;
      const char *phrdir;

public:
      /**
       * Load active server configuration.
       */
      KeyServer();

      /**
       * Get the name of the node identifier.
       *
       * @return node id.
       */
01751       inline const char *getNode(void)
            {return getLast("node");};

      /**
       * Return default script attach login state.
       *
       * @return login id.
       */
01759       inline const char *getLogin(void)
            {return getLast("login");};

      /**
       * Return policy search order.
       *
       * @return policy search order.
       */
01767       inline const char *getPolicyOrder(void)
            {return getLast("policy");};

      /**
       * Get the remote access password.
       *
       * @return remote access password.
       */
01775       inline const char *getPassword(void)
            {return getLast("password");};

      /**
       * Get tgi token seperator.
       *
       * @return token seperator.
       */
01783       inline const char *getToken(void)
            {return getLast("token");};

      /**
       * Load all active trunk group records.
       */
      void loadGroups(bool test);

      /**
       * Get default trunk group schedule name.
       *
       * @return schedule name.
       */
01796       inline const char *getDefault(void)
            {return getLast("default");};

      /**
       * get group id.
       *
       * @return gid
       */
01804       inline unsigned getGid(void)
            {return gid;};

      /**
       * get user id.
       *
       * @return uid
       */
01812       inline unsigned getUid(void)
            {return uid;};

      /**
       * set the user's id if you can.
       */
      void setUid(void);

      /**
       * set the user's gid if you can.
       */
      void setGid(void);

      /**
       * Get number of nodes.
       *
       * @return node count.
       */
01830       inline int getNodeCount(void)
            {return atoi(getLast("nodes"));};

      /**
       * Get alternate home config directory for root startup.
       *
       * @return alternate directory or NULL.
       */
01838       inline const char *getPrefix(void)
            {return altdir;};

      /**
       * Get local phrasebook config directory.
       *
       * @return alternate phrasebook.
       */
01846       inline const char *getPhrases(void)
            {return phrdir;};
};

/**
 * This class is used to load and manage "plugin" modules as called for
 * in /etc/bayonne.conf [plugins].
 *
 * @author David Sugar <dyfet@ostel.com>
 * @short Load and manage plugins support.
 */
01857 class Plugins : public Keydata
{
private:
      unsigned pidcount;
      int pids[32];

public:
      /**
       * Load plugins key data and initialize.
       */
      Plugins();

      /**
       * Unload all active DSO modules for plugins.
       */
      ~Plugins();

      /**
       * Get the name of the driver API being used.
       *
       * @return driver api name.
       */
      char *getDriverName(void);

#ifdef      XML_SCRIPTS
      /**
       * Load an XML parser module.
       */
      void loadXML(void);
#endif

      /**
       * Load a debug module or stub interface.
       */
      void loadDebug(void);

      /**
       * Load a monitor module or stub interface.
       */
      void loadMonitor(void);

      /**
       * Attempt to load a DSO IVR API driver subsystem on top of the
       * Bayonne server.  On failure a DSO exception is thrown.
       */
      DSO *loadDriver(void);

      /**
       * Attempt to load an optional switch integration module for
       * GNU Bayonne.
       */
      void loadSwitch(void);

      /**
       * Attempt to load an optional text to speech plugin module for
       * GNU Bayonne.
       */
      void loadTTS(void);

      /**
       * Attempt to load a sql query module for Bayonne.
       */
      void loadSQL(void);

      /**
       * Load automatic application extensions module.
       */
      void loadExtensions(void);

      /**
       * Attempt to load DSO based generic functions into the server.
       */
      void loadPreload(void);

      /**
       * Attempt to load DSO based protocol modules into the server.
       */
      void loadModules(void);

      /**
       * Attempt to load TGI based resident interpreters.
       */
      void loadTGI(void);

      /**
       * Attempt to load DSO network management interfaces.
       */
      void loadManagers(void);

      /**
       * Attempt to load DSO based TTS translation modules into server.
       */
      void loadTranslators(const char *lcp = NULL);

      /**
       * Attemot to load DSO based audit logging facilities into server.
       */
      void loadAuditing(void);
};

/**
 * We derive a Bayonne server version of ScriptCommand, aaScript,
 * which holds most common elements of the script engine for Bayonne
 * use.  Individual drivers may further derive sub-dialects.
 *
 * @author David Sugar <dyfet@ostel.com>
 * @short Bayonne script dialect.
 */
01965 class aaScript : public ScriptCommand 
{
protected:
      /**
       * New GetTrapMask() used to set DTMF bit when dtmf digits
       * are also requested in ^traps.
       *
       * @return trap mask to apply.
       * @param trap name being evaluated.
       */
      unsigned long getTrapMask(const char *trapname);

public:
      /**
       * Default scripting environment.
       */
      aaScript();

      /**
       * Used to bind "generic" modules to aaScript.
       *
       * @param Module to bind.
       */
      void addModule(Module *module, const char *alias = NULL);

      /**
       * Add unused commands to aaScript for compiler clean-ness.
       *
       * @param names of commands to add.
       */
      void addDummy(const char *names);

      int mapicmp(const char *s1, const char *s2);
        int mapnicmp(const char *s1, const char *s2, size_t n);
};

/**
 * We derive a Bayonne compiler and script image container, aaImage,
 * to hold active script sets for the trunk class script engine.  This
 * class is almost never further derived in drivers, though the driver
 * "getScript" method is used to load it.
 *
 * @author David Sugar <dyfet@ostel.com>
 * @short Bayonne script image.
 */
02010 class aaImage : public ScriptImage
{
protected:
      /**
       * Used to parse and determine if a given directory file
       * should be "compiled".  Usually tests for *.scr.
       *
       * @return true if this file should be compiled.
       * @param file name to test.
       */
      virtual bool isScript(char *scriptname);

      /**
       * Used to scan and compile a script collection from a specified
       * directory for modules, "pass 1".
       *
       * @param directory to scan.
       */
      void scanDir1(char *path);

      /**
       * Used to scan for default .scr scripts unless overriden by
       * module specific scripts in pass 1.
       *
       * @param directory to scan.
       */
      void scanDir2(char *path);

        /**
         * used to create dialect specific pre-precessor directives.  A
       * virtual in ccScript 2.1.1, useless otherwise...
         *
         * @return true if directive claimed.
         * @param directive
         * @param script object being built
         */
        bool preProcess(const char *directive, Name *script);

public:
      /**
       * Default image compiler.
       */
      aaImage(aaScript *script);
};

/**
 * The mixer object is a resource for conferences.
 *
 * @author David Sugar <dyfet@ostel.com>
 * @short Bayonne conference mixer.
 */
02061 class Mixer : protected Mutex
{
private:
      friend class Conference;
      void addGroup(void);
      void delGroup(void);

protected:
      Mixer();
      unsigned avail, members, groups;

public:
      unsigned getAvail(void)
            {return avail;};

      unsigned getMembers(void)
            {return members;};

      unsigned getGroups(void)
            {return groups;};

      virtual bool setMixer(int groups, int members) = 0;

      virtual Conference *getConference(int group) = 0;
};

/**
 * The conference object references a conference generic resource.
 * These may be created and destroyed as needed, typically thru
 * the management of an advance conference resource scheduler.
 *
 * @author David Sugar <dyfet@ostel.com>
 * @short Bayonne conference resource.
 */
02095 class Conference : protected Mutex
{
protected:
      Mixer *mixer;
      unsigned limit;
      unsigned members;
      int *membership;

      virtual ~Conference();

      Conference(Mixer *m);
public:
      inline virtual Mixer *getMixer(void)
            {return mixer;};

      int *getMembership(void)
            {return membership;};

      Trunk *getTrunk(unsigned member);

      unsigned getMembers(void)
            {return members;};

      unsigned getLimit(void)
            {return limit;};

      virtual bool setConference(unsigned max) = 0;
};

#ifdef      XML_SCRIPTS
/**
 * This class is used to hold user loaded XML script files as
 * returned for an XML parser stage.
 *
 * @author David Sugar <dyfet@ostel.com>
 * @short script images per trunk
 */
class TrunkImage : public ScriptImage, protected URLStream, protected XMLStream
{
private:
      char *attrib[65];


#ifdef      COMMON_64_CLEAN
      int read(unsigned char *buffer, size_t len);
#else
      int read(unsigned char *buffer, int len);
#endif

      friend class Trunk;

protected:
#ifdef      COMMON_ASYNC_OVERRIDE
      int aRead(char *buffer, size_t len, timeout_t timeout);
#endif

      void close(void)
            {return URLStream::close();};

      typedef     struct
      {
            Name *script;
            Line *last;
            unsigned line;
            unsigned long addmask, submask, trapmask;
            unsigned char loopid[65], looplevel[65];
            unsigned trap;
            void *data; // extra state data in derived use
      } Compile;

      Compile *main, *current;

      /**
       * Get a scriptname object for a named script segment.
       *
       * @param name of script segment to allocate.
       */
      void getCompile(const char *name = "#");

      /**
       * Set the compiler for a specific event chain in the script.
       *
       * @param 0 for main else trap event chain.
       */
      void setCompile(unsigned trap);

      /**
       * Cleanup a compile phase operation.
       *
       * @param pointer to compile session.
       */
      void putCompile(Compile *cc);

      /**
       * Add a statement to the active session.
       *
       * @param mask of bits.
       * @param keyword method to invoke.
       * @param command arguments.
       */
      void addCompile(unsigned long mask, const char *cmd, const char **args);

      /**
       * Initialize token and parsing.
       *
       * @param attributes.
       */
      void setToken(const unsigned char **attrib);

      /**
       * Fetch a local token.
       *
       * @return token.
       */
      const char *getToken(void);

      /**
       * Trap default mask to apply.
       *
       * @return default mask.
       */
      virtual unsigned long getDefaultMask(void)
            {return 3;};

      /**
       * Used to extract a specific attribute for an element.
       *
       * @return attribute value.
       * @param list of attributes.
       * @param attribute identifier.
       * @param default if not found.
       */
      const char *getAttribute(const char *key, const char *value = NULL);

public:
      /**
       * Construct a new script image, normally done in the plugin.
       */
      TrunkImage();

      virtual ~TrunkImage()
            {purge();};

      /**
       * Initial proxy setup.
       *
       * @param address of proxy server.
       * @param port number of proxy server.
       */
      void setProxy(const char *addr, tpport_t port)
            {URLStream::setProxy(addr, port);};

      /**
       * Load and parse an XML resource into a ccScript runtime
       * engine.  The plugin impliments a derived class which 
       * performs a specific dialect.
       *
       * @param true on success, false on failure.
       * @param pointer to collected data structure.
       */
      virtual bool loader(Trunk *trk, trunkdata_t *data) = 0;

      /**
       * Access to the purge method of the script image.
       */
      void purge(void);

      /**
       * Access to the image paged memory allocator.
       *
       * @return pointer to allocated workspace.
       * @param size requested.
       */
      void *alloc(unsigned size) 
            {return MemPager::alloc(size);};
};
#endif

/**
 * We derive a Bayonne server version of ScriptInterp, "Trunk",
 * which holds most common elements of the script engine for Bayonne
 * use.  This is also the base of the channel port structure for
 * Bayonne.  Drivers will further derive this as "DriverTrunk".
 *
 * @author David Sugar <dyfet@ostel.com>
 * @short Bayonne channel port script engine.
 */
02282 class Trunk : public ScriptInterp
{
private:
      friend class TestDebug;
      friend class aaScript;
      friend class Translator;
      friend class ScriptInterface;
      friend class Service;
      friend class AudioService;
      friend class Fifo;
      friend class Driver;
      friend class Module;
      friend class RPCTransaction;

      typedef union
      {
            Symbol sym;
            char data[sizeof(Symbol) + 12];
      }       Number;

      typedef union
      {
            Symbol bin;
            char data[sizeof(Symbol) + MAX_DIGITS];
      }       Digit;

protected:
      phTone *tonetmp;

private:
      unsigned member;
      Line  *cdrv;
      int cdrc;
#ifdef      XML_SCRIPTS
      TrunkImage *altimage;
      Module *altmodule;
#endif
      char apppath[64];

      bool scrPolicy(void);
      bool scrConfig(void);
      bool scrSend(void);
      bool scrStart(void);
#ifdef      HAVE_TGI
      bool scrLibexec(void);
#endif
      bool scrControl(void);
      bool scrHangup(void);
      bool scrDebug(void);
      bool scrAlog(void);
      bool scrAudit(void);
      bool scrSleep(void);

#ifdef      SCRIPT_IF_OVERRIDE
public:
      static bool hasVoice(ScriptInterp *interp, const char *v);
      static bool hasAppVoice(ScriptInterp *interp, const char *v);
      static bool hasSysVoice(ScriptInterp *interp, const char *v);
      static bool hasAltVoice(ScriptInterp *interp, const char *v);
      static bool hasGroup(ScriptInterp *interp, const char *v);
      static bool hasPlugin(ScriptInterp *interp, const char *v);
      static bool isNode(ScriptInterp *interp, const char *v);
      static bool isService(ScriptInterp *interp, const char *v);
      static bool ifDTMF(ScriptInterp *interp, const char *v);
      static bool ifFeature(ScriptInterp *interp, const char *v);
      static bool isExtension(ScriptInterp *interp, const char *v);
      static bool isStation(ScriptInterp *interp, const char *v);
      static bool isVirtual(ScriptInterp *interp, const char *v);
      static bool isHunt(ScriptInterp *interp, const char *v);
      static bool isActiveUser(ScriptInterp *interp, const char *v);
      static bool isDnd(ScriptInterp *interp, const char *v);
#endif

protected:
      bool scrCommit(void);
      bool scrChange(void);
      bool scrPassword(void);
      bool scrLogin(void);
      bool scrLogout(void);
      bool scrSync(void);
      bool scrAnswer(void);
      bool scrDial(void);
      bool scrTransfer(void);
      bool scrHold(void);
      bool scrOptions(void);
      bool scrRedirect(void);

private:
      bool scrTone(void);
      bool scrAccept(void);
      bool scrReject(void);
      bool scrCollect(void);
      bool scrFlash(void);
      bool scrSlog(void);
      bool scrSay(void);
      bool scrCleardigits(void);
      bool scrAssign(void);
      bool scrAltPlay(void);
      bool scrAltSpeak(void);
      bool scrPlay(void);
      bool scrSendFax(void);
      bool scrRecvFax(void);
#ifdef      XML_SCRIPTS
      bool scrLoad(void);
#endif
#ifdef      HAVE_TGI
      bool scrCopy(void);
#endif
      bool scrMove(void);
      bool scrErase(void);
      bool scrRecord(void);
      bool scrSpeak(void);
      bool scrModule(void);
      bool scrDummy(void);
      bool scrSchedule(void);
      bool scrSignal(void);
      bool scrIdle(void);
      bool scrBusy(void);
      bool scrExamine(void);
      bool scrService(void);
      bool scrUserinfo(void);
      bool scrHuntinfo(void);
      bool scrStatinfo(void);

protected:

#ifdef      XML_SCRIPTS
      Name *getScriptImage(const char *name);
#endif

      void setExclusive(bool enable)
            {globals.setExclusive(enable);};

      Number numbers[6];
      static ScriptSymbol globals;
      static char digit[16];
      ScriptInterface *script;
      TrunkGroup *group;
      int id;
      unsigned span;
      time_t starttime, idletime, synctimer, exittimer;

      volatile unsigned seq;
      int idle_timer;
      unsigned rings, digits;

      Service *thread;
      trunkdata_t data;
      execdata_t tgi;
      Digit dtmf;
      char buffer[65];
      char extNumber[5];
      bool dialgroup[10];

      struct
      {
            bool offhook: 1;
            bool dtmf: 1;
            bool script: 1;
            bool reset: 1;
            bool timer : 1;
            bool audio: 1;
            bool once : 1;
            bool ready : 1;
            bool echo : 1;
            unsigned onexit : 1;
            trunkmode_t trunk: 2;
            dspmode_t dsp: 4;
            dtmfmode_t digits: 2;
            bool dnd : 1;
            bool cid : 1;     // captured cid state
            bool sent : 1;    // cid info sent
      } flags;

      /**
       * Set idle count of the driver.
       */
      void setIdle(bool mode);

      /**
       * Set symbol constants on attach.
       */
      virtual void initSyms(void) = 0;

      /**
       * Our default mask includes timeout.
       *
       * @return default mask.
       */
02471       unsigned long getTrapDefault(void)
            {return 0x00000007;};

      /**
       * Replace a symbol if a valid value is passed for a replacement.
       *
       * @param symbol name.
       * @param replacement value.
       */
      void repSymbol(const char *id, const char *data);

      /**
       * This provides an interface to internal symbol definitions.
       *
       * @return symbol entry.
       * @param symbol name.
       * @param allocation size if not found.
       */
      Symbol *getEntry(const char *symname, int size);

#ifndef     SCRIPT_SG_VARIABLES
        /**
         * Provides interface for setting local or global variable
         * passed by reference to drivers and such.
         *
         * @return true if successful
         * @param symbol name.
         * @param symbol size to allocate if new.
         * @param symbol value.
         */
        bool setVariable(const char *id, int size, const char *value = NULL);

        /**
         * Accesses local or global variable by direct name reference.
         *
         * @return content
         * @param symbol name.
         */
        const char *getVariable(const char *id);
#endif

      /**
       * A derived Commit handler, allows "clear %digits", etc.
       *
       * @param symbol entry.
       */
      void commit(Symbol *sym);

public:
      /**
       * Flag if admin user.
       */
      bool isAdmin(void);

      /**
       * Get a fax station identifier for a script.
       *
       * @return pointer to station id string.
       */
      const char *getStation(void);

      /**
       * Get a "timeout" option.  This is like getValue, however
       * the default timeout supplied is from the constant table,
       * and special options for numeric times of various types can
       * be used.
       *
       * @return default timeout in milli-seconds.
       * @param optional string to parse rather than option.
       */
      timeout_t getTimeout(const char *keyword = NULL);

      /**
       * Extract an extension reference, either directly, or from
       * an encoded global/local session identifier.
       *
       * @return extension number or NULL if invalid.
       * @param extension number or session id.
       */
      static const char *getExtReference(const char *ref);

      /**
       * Get a "interdigit" timeout option.  This is like getValue,
       * however the interdigit value supplied is from the const table.
       *
       * @return interdigit timeout in milli-seconds.
       */
      timeout_t getInterdigit(const char *keyword = NULL);

      /**
       * Get a dtmf bit "mask".
       *
       * @return dtmf bit mask of digits.
       */
      unsigned short getDigitMask(const char *keyword = NULL);

protected:
      /**
       * Notify the script subsystem of a completion event.
       *
       * @param completion event signal id.
       */
      bool trunkSignal(trunksignal_t);

      /**
       * This function sets dtmf detection based on the script
       * interpreter's current trap mask.  This is often used as
       * the initial handler for setting dtmf detection when
       * entering each trunk driver's state.
       */
      virtual void setDTMFDetect(void);

      /**
       * Set actual dtmf detection in the derived trunk class driver.
       * This typically is called by the "initial" state handler when
       * entering a trunk driver call processing state when an implicit
       * setting is required (such as "collect", which forces enable).
       *
       * @param true to enable DTMF detection.
       */
02591       virtual void setDTMFDetect(bool enable)
            {flags.dtmf = enable;};

      /**
       * This is used to reset service threads and generally cleanup
       * the session handler.  It is a virtual since driver specific
       * implimentations may vary.
       */
      virtual void stopServices(void);

      /**
       * Used to perform state transitions when trunk is in "step"
       * state, from the Bayonne script engine.  This call is used
         * rather than "postEvent" with TRUNK_MAKE_STEP since the Bayonne
       * engine is already in the context of the callback thread
       * and invoked from a postEvent initiated call.  Hence, this
       * saves the overhead rather of a recursive postEvent call.
       *
       * @param new state to use.
       */
      virtual void trunkStep(trunkstep_t step) = 0;

      /**
       * This is used to see if the total timer has expired.
       *
       * @return true if should hangup.
       */
      bool idleHangup();

      /**
       * This is used to determine if the trunk is currently "idle"
       * and for how long.
       *
       * @return number of seconds idle.
       */
      virtual unsigned long getIdleTime(void) = 0;

      /**
       * Compute a prefix path based on prefix passed
       *
       * @return prefix path.
       */
      const char *getPrefixPath(void);

      /**
       * This is used to post a step update back to the script engine.
       */
02638       inline bool scriptStep(void)
            {return ScriptInterp::step();};     

      /**
       * We override ScriptInterp::Attach with our own that adds
       * additional support.  This attach initializes a series of
       * required and default "variables" for the script interpreter.
       *
       * @return true on success
       * @param name of script to start.
       */
      bool attach(const char *scrname);

      /**
       * We override ScriptInterp::Detach with our own that adds
       * additional support to purge the variable pool.
       */
      void detach(void);

      /**
       * We get the scheduled or dnis or callerid map table values.
       *
       * @return argument list for startup.
       * @param buffer for defaults.
       */
      char **getInitial(char **args);

      /**
       * Set a list of keyword values into the variable space of the
       * script interpreter.
       *
       * @param list of keyword pairs.
       */
      void setList(char **list);

      /**
       * Accept method for accept scripts.
       */
02676       virtual void accept(void)
            {return;};

      /**
       * Get the voice library extension set to use.
       */
02682       virtual const char *getLibexec(void)
            {return ".au";};

      /**
       * Get the default audio encoding format to use.
       */
02688       virtual const char *getDefaultEncoding(void)
            {return "ulaw";};

      /**
       * Reject method for reject scripts.  In case needed.
       */
02694       virtual void reject(void)
            {return;};

      /**
       * Enter a state and post it's identifier in local sym.
       */
      void enterState(const char *state);

      Trunk(int port, int card = 0, int span = 0);
public:
      /**
       * Get the timeslot port number.
       *
       * @return driver port.
       */
02709       unsigned getId(void)
            {return id;};
      /**
       * Get the trunk sequence number.
       *
       * @return sequence.
       */
02716       inline unsigned getSequence(void)
            {return seq;};

      /**
       * Set the sleep save marker for sleeping tasks.
       *
       * @param sym name.
       */
02724       inline void setSave(const char *save)
            {data.sleep.save = save;};

      /**
       * Get driver capabilities.
       *
       * @return capability mask.
       */
02732       virtual unsigned long getCapabilities(void)
            {return TRUNK_CAP_VOICE | TRUNK_CAP_DIAL;};

      /**
       * Get global symbol stace.
       *
       * @return pointer to global symbols.
       */
02740       static inline ScriptSymbol *getGlobals(void)
            {return &globals;};

      /**
       * Load user preferences.
       */
      static void load(const char *id);

      /**
       * Load line preferences.
       */
      static void loadPref(const char *id, const char *prefix, const char *dir);

      /**
       * Save user preferences.
       */
      static void save(const char *id);

      /**
       * Save line preferences.
       */
      static void savePref(const char *id, const char *prefix, const char *dir);

      /**
       * Sync session settings.
       */
      static void sync(bool force = false);

      /**
       * Init password database.
       */
      static void initPassword(void);

      /**
       * Init trunk line database.
       */
      static void initLines(void);

      /**
       * Get the device logical name number.
       *
       * @param Buffer to store name.
       */
      virtual void getName(char *buffer) = 0;

      /**
       * Invoke a runtime state handler for a trunk driver.  This
       * must be in an event in the derived TrunkDriver class.
       *
       * @return true if event claimed.
       * @param derived method to call.
       */
      virtual bool postEvent(TrunkEvent *event) = 0;

      /**
       * Receive an event message from a foreign trunk and process it
       * locally.
       *
       * @return true if event message valid.
       */
      bool recvEvent(TrunkEvent *event);

      /**
       * Compute the DTMF digit id of a character.
       *
       * @return dtmf digit or -1.
       */
      int getDigit(char digit);

      /**
       * See if trunk is idle and available.
       *
       * @return true if ready.
       */
      bool isReady(void);

#ifdef      HAVE_TGI
      /**
       * Perform a gateway TTS operation on behalf of the current
       * trunk.
       *
       * @param filename or text string.
       * @param mode argument.
       */
      void libtts(const char *msg, ttsmode_t mode);
#endif

      /**
       * Make getOnce() into a public.
       */
02830       inline bool getOnce(void)
            {return ScriptInterp::getOnce();};

      /**
       * Get group membership.
       *
       * @return member id.
       */
02838       inline unsigned getMemberId(void)
            {return member;};

      /**
       * Process a soft tone buffer.
       *
       * @return soft tone object.
       */
      phTone *getTone(void);

      /**
       * Fetch the command interpreter in public context.
       *
       * @return command interpreter.
       */
02853       inline ScriptCommand *getCommand(void)
            {return ScriptInterp::getCommand();};

      /**
       * Fetch the current trunk mode flag.
       *
       * @return trunk call mode.
       */
02861       inline trunkmode_t getTrunkMode(void)
            {return flags.trunk;};
};

/**
 * The system fifo is a class that both handles a fifo "control interface"
 * and that can process string commands as events through the Bayonne
 * driver.  The Fifo is used by tgi and may be used by other system
 * services.
 *
 * @author David Sugar <dyfet@ostel.com>
 * @short Bayonne fifo command executive.
 */
02874 class Fifo : public Mutex, public Script
{
protected:
      char schedule[33];

      bool assignRing(char **args);
      bool assignDial(char **args);
      bool sendEvent(char **args);
      bool clearRing(char **args);
      bool clearDial(char **args);
      bool clearRDGroup(char **args);
      bool exitPid(char **args);
      bool waitPid(char **args);
      bool setSymbol(char **argv);
      bool putSymbol(char **argv);

      bool login(char **argv);
      bool startScript(char **argv);
      bool testScript(char **argv);
      bool ringScript(char **argv);
      bool redirectScript(char **argv);
      bool setSpan(char **argv);
      bool setCard(char **argv);
      bool busyLine(char **argv);
      bool idleLine(char **argv);
      bool hangupLine(char **argv);
      bool reqScript(char **argv);
      bool setSchedule(char **argv);
      bool postKey(char **argv);
      bool setMixer(char **argv);
      bool setLimit(char **argv);
      bool mapFiles(char **argv);
      bool submit(char **argv);
      bool reload(char **argv);
      bool saveId(char **argv);
      bool createId(char **argv);
      bool deleteId(char **argv);

public:
      /**
       * Issue a "command" request either from the fifo port itself
       * or from a service thread.
       *
       * @return true if command successful.
       * @param request string as would be passed by fifo.
       * @param fd optional output redirection.
       */
      bool command(const char *cmdstring, std::ostream *fd = NULL);
};

/**
 * The audit class is associated with the "audit" dso object which is used
 * to distribute audit reports.  Audit reports can include call detail
 * information as a call "terminates", and also "alog" commands.  These
 * are handled by a DSO so that alternate processing can be supplied,
 * such as seperate threads or even broadcast to an audit "server" as
 * may be needed by very high port capacity systems.  The default dso
 * simply appends to an audit file.  In fact, multiple audit dso's can
 * be "stacked".
 *
 * @author David Sugar <dyfet@ostel.com>
 * @short Bayonne audit logging interface.
 */
02937 class Audit : public Mutex
{
private:
      friend void audit(Trunk *trunk, char *detail);
      friend void alog(Trunk *trunk, char *detail);
      friend class Scheduler;

      static Audit *first;
      Audit *next;

protected:
      static Auditdata keys;

      /**
       * Post an audit record detail line as built by "audit"
       *
       * @param detail line.
       */
      virtual void reportAudit(Trunk *trunk, char *detail) = 0;

      /**
       * Post a cdr line as built by "cdr"
       *
       * @param detail line.
       */
02962       virtual void reportCDR(Trunk *trunk, char *detail)
            {reportAudit(trunk, detail);};

      /**
       * Proccess current call stats, invoked by scheduler.
       */
02968       virtual void reportStats(void)
            {return;};

      /**
       * A quick access to the trunk group members.
       *
       * @return trunkgroup first.
       */
02976       inline TrunkGroup *getFirst(void)
            {return TrunkGroup::first;};

      /**
       * A quick access to the next trunk group member.
       *
       * @return trunkgroup next.
       * @param trunk group.
       */
02985       inline TrunkGroup *getNext(TrunkGroup *grp)
            {return grp->next;};

      /**
       * Constructor protected for abstract class.
       */
      Audit();
};

#define     MAX_SPANS   64
#define     MAX_CARDS   64

/**
 * The driver class represents an abstract means of accessing the
 * internals of a Bayonne driver plug-in module.
 *
 * @author David Sugar <dyfet@ostel.com>
 * @short Bayonne driver interface class.
 */
03004 class Driver : public aaScript
{
protected:
      friend class TrunkGroup;
      friend class Trunk;

      TrunkGroup **groups, *spans[MAX_SPANS], *cards[MAX_CARDS], *stacards[MAX_CARDS];
      char *status;
      bool active;
      unsigned portCount, downCount;
      unsigned extCount, trkCount, tieCount, numCount;
      Trunk **extIndex;
      volatile unsigned idleCount;

public:
      enum {      capDaemon = 0x0001,
            capPSTN = 0x0002,
            capJoin = 0x00004,
            capSpans = 0x0008,
            capSpeed = 0x0010,      // driver can do rate adj
            capPitch = 0x0020,      // driver can pitch adj
            capGain = 0x0040, // driver can gain adj
            capSwitch = 0x2000,
            capConference = 0x4000,
            capOffline = 0x8000,
            capReroute = 0x10000};

      /**
       * Second tick interval counter.
       */
      virtual void secTick(void);

      /**
       * Return driver capabilities.
       */
03039       virtual unsigned getCaps(void)
            {return capDaemon | capPSTN;};

      /**
       * Create an instance of the driver.
       */
      Driver();

      /**
       * Set extension numbering scheme.
       */
      virtual bool setExtNumbering(unsigned);

      /**
       * Get current extension numbering scheme.
       *
       * @return extension number size.
       */
03057       unsigned getExtNumbering(void)
            {return numCount;};

      /**
       * Lookup the extension index entry.
       *
       * @param extension number.
       * @return NULL or index entry reference.
       */
      virtual Trunk **getExtIndex(const char *num);

      /**
       * Report if driver is idle.
       */
      bool isIdle(void);

      /**
       * Report if driver is down.
       */
      bool isDown(void);      

      /**
       * Start a driver; start service threads, build device nodes,
       * etc.
       * 
       * @return number of active device ports.
       */
      virtual int start(void) = 0;

      /**
       * Shutdown the driver, service threads, etc.
       */
      virtual void stop(void) = 0;

      /**
       * Get a local copy of the status string.
       *
       * @param local status buffer.
       */
      void getStatus(char *buffer);

      /**
       * Load a script image.  Usually this is not driver specific,
       * though it can be made to be so.
       *
       * @return ScriptImage base abstract.
       */
      virtual aaImage *getImage(void);

      /**
       * Get total number of port identifiers (timeslots) used by
       * the current driver.
       *
       * @return trunk timeslots/ports allocated.
       */
      virtual unsigned getTrunkCount(void) = 0;

      /**
       * Get active number of ports actually deployed by the current
       * driver.
       *
       * @return actual trunks used.
       */
03120       virtual unsigned getTrunkUsed(void) 
            {return getTrunkCount();};

      /**
       * Set the trunk group by span and card as well as port.
       */
      void setTrunkGroup(int id, int card, int span);

      /**
       * Get the trunk group of an identified port.
       * 
       * @return trunk group pointer.
       * @param id
       */
03134       TrunkGroup *getTrunkGroup(int id)
            {return groups[id];}; 

      TrunkGroup *getSpanGroup(int id)
            {return spans[id];};

      TrunkGroup *getCardGroup(int id)
            {return cards[id];};

      TrunkGroup *getStaGroup(int id)
            {return stacards[id];};

      /**
       * Get the trunk group member trunk.
       *
       * @return trunk group port id.
       * @param trunk group to locate.
       * @param member id to locate.
       */
      int getTrunkMember(TrunkGroup *grp, unsigned member);
      
      /**
       * Get an individual port from the driver by timeslot/id.
       *
       * @return trunk port object.
       */
      virtual Trunk *getTrunkPort(int id) = 0;

      /**
       * Get a trunk by a id or global id string.
       *
       * @param trunk or port reference id.
       * @return trunk port object.
       */
      Trunk *getTrunkId(const char *id);

      /**
       * Get a trunk by extension reference.
       *
       * @param extension number.
       * @return trunk port object.
       */
      Trunk *getExtNumber(const char *ext);

      /**
       * Set a physical port to an extension number in the dialing plan.
       *
       * @param physical extension port.
       * @param extension number to associate.
       */
      bool setExtNumber(unsigned id, const char *ext);

      /**
       * Set or assign a virtual extension number in the dialing plan.
       *
       * @param physical extension port tp associate with.
       * @param virtual extension number.
       */
      bool setExtVirtual(unsigned id, const char *ext);

      /**
       * Clear an extension number entry.
       *
       * @param extension to clear.
       */
      bool clrExtNumber(const char *ext);

      /**
       * Get a trunk by trunk reference.
       *
       * @param trunk number
       * @return trunk port object.
       */
03207       virtual Trunk *getTrkNumber(const char *trk)
            {return getTrunkId(trk);};

      /**
       * Get a trunk by tie trunk reference.
       *
       * @param tie trunk id
       * @return trunk port object.
       */
03216       virtual Trunk *getTieNumber(const char *tie)
            {return NULL;};

      /**
       * Get the extension count.
       *
       * @return total extension count.
       */
03224       unsigned getExtCount(void)
            {return extCount;};

      /**
       * Get the total trunk count. 
       *
       * @return trunk count.
       */
03232       unsigned getTrkCount(void)
            {return trkCount;};

      /**
       * Get thr total tie line count.
       *
       * @return tie count.
       */
03240       unsigned getTieCount(void)
            {return tieCount;};
      
      /**
       * Get an individual conference resource.
       *
       * @return conference number.
       */
03248       virtual Conference *getConference(int id)
            {return NULL;};

      /**
       * Get an individual mixer resource by number.
       *
       * @return conference mixer.
       */
03256       virtual Mixer *getMixer(int id)
            {return NULL;};

      /**
       * Get the driver's chip count/conference unit capacity.
       *
       * @return conference mixer resources.
       */
03264       virtual unsigned getMixers(void)
            {return 0;};

      /**
       * Get the total conference groups available.
       *
       * @return conference groups.
       */
03272       virtual unsigned getGroups(void)
            {return 0;};

      /**
       * Span event operations.
       *
       * @return true if success.
       * @param span to effect.
       * @param event to pass.
       */
      virtual bool spanEvent(unsigned span, TrunkEvent *event);

      /**
       * card event operations.
       *
       * Card event operations.
       *
       * @return true if successful.
       * @param card to effect.
       * @param event to pass.
       */
03293       virtual bool cardEvent(unsigned card, TrunkEvent *event)
            {return false;};
};

/**
 * DSO class for installing a monitoring plugin.
 *
 * @author Mark Lipscombe <markl@gasupnow.com>
 * @short Monitoring DSO interface.
 */
03303 class Monitor : protected Mutex, protected Script
{
public:
      /**
       * Register object.
       */
      Monitor();

      /**
       * Monitoring interface for event processing tracing
       */
03314       virtual void monitorEvent(Trunk *trunk, TrunkEvent *event)
            {return;};

      /**
       * Monitoring interface for state handlers
       */
03320       virtual void monitorState(Trunk *trunk, char *state)
            {return;};

      /**
       * Monitoring interface for script steps
       */
03326       virtual void monitorStep(Trunk *trunk, Line *line)
            {monitorState(trunk, "step");};
};

/**
 * New DSO class for installing a "debugging"/regression test plugin.
 *
 * @author David Sugar <dyfet@ostel.com>
 * @short Regression test/debug DSO interface.
 */
03336 class Debug : protected Mutex, protected Script
{
public:
      /**
       * Register DSO debug object.
       */
      Debug();

      /**
       * Stack trace support.
       */
      static void stackTrace(int signo);

      /**
       * Regression test interface called in server startup.
       *
       * @return true to force exit after test.
       */
03354       virtual bool debugTest(void)
            {return false;};

      /**
       * Interface for "final" handling of debug.
       *
       * @return true if ignore final exit.
       */
03362       virtual bool debugFinal(int signo)
            {return false;};

      /**
       * Debug interface for event processing "taps".
       */
03368       virtual void debugEvent(Trunk *trunk, TrunkEvent *event)
            {return;};

      /**
       * Debug interface for state handler entry "taps".
       */
03374       virtual void debugState(Trunk *trunk, char *state)
            {return;};

      /**
       * Debug service loop code "tap".
       */
03380       virtual void debugService(Trunk *trunk, char *msg)
            {return;};

      /**
       * Debug interface for "debug" script step.
       */
03386       virtual void debugScript(Trunk *trunk, char *msg)
            {return;};

      /**
       * Debug interface for script step "tap".
       */
03392       virtual void debugStep(Trunk *trunk, Line *line)
            {debugState(trunk, "step");};

      /**
       * Debug interface for fifo "debug" statement.
       */
03398       virtual bool debugFifo(char **argv)
            {return true;};

      /**
       * Debug interface for login/logout changes.
       */
03404       virtual void debugLogin(Trunk *trunk)
            {return;};
};

/**
 * AudioService holds the logic for processing audio channels.
 *
 * @author David Sugar <dyfet@ostel.com>
 * @short audio service processing.
 */
03414 class AudioService
{
private: 
      char filename[256];

protected:
      Trunk *trunk;
      /**
       * Compute and get a prompt file name.
       *
       * @param partial name.
       * @return full path.
       */
      char *getPrompt(char *name, const char *voice = NULL);

      /**
       * Fetch the next prompt for the play list.
       *
       * @return get partial name.
       */
      char *getPlayfile(void);

      /**
       * Construct the object.
       */
      AudioService(void);
};

/**
 * Services are threads used to support a trunk class, such as audio
 * services used for audio, etc.
 *
 * @author David Sugar <dyfet@ostel.com>
 * @short service thread support.
 */
03449 class Service : public Semaphore, public Thread, public AudioService
{
protected:
      volatile bool stopped;
      trunkdata_t *data;
      TrunkGroup *group;

      /**
       * Signal "successful" completion result.
       */
      void success(void);

      /**
       * Signal "failure" completion result.
       */
      void failure(void);

      /**
       * Mark required dsp reset.
       */
03469       inline void dspReset(void)
            {trunk->flags.reset = true;};

      /**
       * Set audio marker.
       */
03475       inline void setAudio(void)
            {trunk->flags.audio = true;};

      /**
       * Clear audio marker.
       */
03481       inline void clrAudio(void)
            {trunk->flags.audio = false;};

public:
      /**
       * Create a service thread on an existing trunk object.
       *
       * @param trunk object to use.
       * @param process priority.
       */
      Service(Trunk *trunk, int pri);

      /**
       * request to stop a service and obtain default "delay" time
       * to use for reset interval.
       *
       * @return delay in milliseconds.
       */
      virtual timeout_t stop(void);

      /**
       * Indicate if the service thread is exiting and/or can be
       * deleted now.  If false, then it will be cleaned by the
       * scheduler thread.
       *
       * @return false if held to scheduler.
       */
03508       virtual bool isExiting(void)
            {return true;};

      /**
       * Invoke termination.
       */
03514       void endService(void)
            {terminate();};

      /**
       * Termination of service.
       */
03520       virtual ~Service()
            {terminate();}
};

#ifdef      XML_SCRIPTS
/**
 * XML server class to perform execution of a plugin xml parser on
 * behalf of an existing trunk class.
 *
 * @short threaded XML plugin executive.
 * @author David Sugar <dyfet@ostel.com>
 */
class XMLService : public Service
{
private:
      void run(void);

public:
      XMLService(Trunk *trk);
      ~XMLService();
};
#endif

/**
 * Server classes are used for threaded entities such as network
 * management interfaces, which may be started and stopped under
 * server control.  Sometimes server is mixed into other dso
 * classes to stabilize start/stop of service threads.
 *
 * @short threaded server service.
 * @author David Sugar <dyfet@ostel.com>
 */
03552 class Server : public Thread
{
private:
      static Server *first;
      Server *next;
      friend void startServers(void);
      friend void stopServers(void);

protected:
      Server(int pri);

      /**
       * Used for stopServers call interface.
       */
03566       virtual void stop(void)
            {terminate();};
};

/**
 * The Sync class is used to create dso objects which have entites
 * that are repetitivly called through the scheduler thread.  These
 * are sometimes used to update disk based databases from memory, or
 * perform other interval timed operations.
 */
03576 class Sync
{
private:
      friend class Scheduler;

      static Sync *first;
      Sync *next;
      time_t runtime;

protected:
      /**
       * Abstract class, protected constructor.
       */
      Sync(void);

      /**
       * Return if ready for update.  If not, the current update
       * interval may be skipped entirely.
       */
03595       virtual bool isScheduled(void)
            {return true;};

      /**
       * Return execution interval of this sync object.  How many
       * xx minutes before attempting a new sync.
       */
03602       virtual unsigned getInterval(void)
            {return 10;};

      /**
       * Operation to perform when scheduled.
       */
      virtual void schedule(void) = 0;

      /**
       * Return name used in slog event when scheduling item.
       */
      virtual char *getSyncName(void) = 0;
};

/**
 * The tone class is used to build sampled single and dual frequency
 * tones that may be fed to the telephony device.  Tones are defined
 * in the "tones" section of bayonne.conf.
 *
 * @short generated sample tone.
 * @author David Sugar.
 */
03624 class phTone
{
private:
      friend class KeyTones;
      friend phTone *getphTone(const char *name);
      static phTone *first;
      static int ulaw[256];
      static unsigned char alaw[256];
      phTone *next;

protected:
      char name[33];
      unsigned char *samples;
      timeout_t duration, playtime;
      unsigned freq1, freq2;

public:
      static unsigned char linear2ulaw(int sample);
      static inline unsigned char linear2alaw(int sample)
            {return alaw[linear2ulaw(sample)];};

      /**
       * Create single frequency tone.
       *
       * @param name of tone.
       * @param duration in milliseconds.
       * @param frequency of tone.
       */
      phTone(const char *name, timeout_t duration, unsigned f);

      /**
       * Create dual frequency tone.
       *
       * @param name of tone.
       * @param duration in milliseconds.
       * @param first frequency.
       * @param second frequency.
       */
      phTone(const char *name, timeout_t duration, unsigned f1, unsigned f2);

      ~phTone();

      /**
       * If the telephony card is capable of generating it's own
       * tones, then it can use the clear method to remove any
       * allocated memory for sampled data.
       */
      void clear(void);

      /**
       * Fetch the sample area of the tone.
       *
       * @return sample area.
       */
03678       inline unsigned char *getSamples(void)
            {return samples;};

      /**
       * Get the duration of the tone.
       *
       * @return duration of tone.
       */
03686       inline timeout_t getDuration(void)
            {return duration;};

        /**
         * Get the playtime of the tone.
         *
         * @return duration of tone.
         */
03694         inline timeout_t getPlaytime(void)
                {return playtime;};
};

/**
 * This class is used for interfacing to DSO loaded TGI interpreters.
 *
 * @short TGI interpreter module.
 * @author David Sugar <dyfet@ostel.com>
 */
class TGI
{
private:
      static TGI *first;
      TGI *next;

protected:
      TGI();

      /**
       * Check a file extension to see if it belongs to a first
       * stage tgi script interpreter (avoids second fork).
       *
       * @return true if claimed.
       * @param extension.
       */
03720       virtual bool getExtension(char *ext)
            {return false;};

public:
      /**
       * Check command for interpreter and, if is, execute it.  If
       * so it doesn't return but uses "exit".  This is a "second"
       * stage tgi mod interface and is effective for single session
       * interpreter libraries.
       *
       * @param script name resolved.
       * @param argument list.
       */
03733       virtual void script(char *cmd, char **args)
            {return;};

      /**
       * Execute a first stage interpreter, uses local functions.
       *
       * @return shell exit code.
       * @param fifo file descriptor.
       * @param port number.
       * @param unparsed command string.
       */
03744       virtual int parse(int fd, int port, char *cmd)
            {return -1;};     

      friend void getInterp(char *cmd, char **args);
      friend TGI *getInterp(char *cmd);
};

/**
 * The tts syth classes intercept core functions as needed to create
 * an interface to a native text to speech subsystem, usually by
 * manipulating data.play.
 */
03756 class TTS
{
protected:
      friend class Plugins;

      TTS();

public:
      virtual const char *getName(void) = 0;

      virtual const char *getVoices(void)
            {return "none";};

      virtual bool synth(unsigned id, trunkdata_t *data) = 0;
};

/**
 * Modules are used for protocol modules and detached threads used to
 * service key Bayonne protocols and interfaces.  These are done as
 * loadable modules and may be replaced with application specific
 * interfaces.
 *
 * @short Module interface class.
 * @author David Sugar <dyfet@ostel.com>
 */
03781 class Module : public Script
{
private:
      friend class Fifo;
      friend class AudioService;
      friend class TrunkGroup;
      friend class Network;
      friend class aaImage;
      friend class aaScript;
      friend class Trunk;

      Method prior;
      static Module *modFirst, *sesFirst, *cmdFirst, *urlFirst, *reqFirst, *netFirst, *symFirst;
      Module *modNext, *sesNext, *cmdNext, *urlNext, *reqNext, *netNext, *symNext;

protected:
      static Module *modImport;

      Module();

      inline Module *getFirst(void)
            {return modFirst;};

      inline bool executePrior(Trunk *trunk)
            {return trunk->execute(prior);};

      /**
       * Preprocessor import directives...
       *
       * @param token
       */
03812       virtual void import(const char *token)
            {return;};

      /**
       * Get alternate script extensions.
       *
       * @return extension if used.
       */
03820       virtual const char *getExtension(void)
            {return NULL;};

      /**
       * Get a global symbol space for this module.
       *
       * @return global symbol space if used.
       */
03828       virtual Script::Symbol *getSymbol(Trunk *trk, const char  *map, unsigned size)
            {return NULL;};

      /**
       * Get the "type" identifer of this module.
       *
       * @return type id.
       */
      virtual modtype_t getType(void) = 0;

      /**
       * Add a symbol space for this module.
       */
      void addSymbols(void);

      /**
       * Add as a session handling module.
       */
      void addSession(void);

      /**
       * Add fifo command handling module.
       */
      void addCommand(void);

      /**
       * Add module as url processing.
       */
      void addPrompts(void);

      /**
       * Add module for net processing.
       */
      void addNetwork(void);

      /**
       * Add request handler back-end.
       */
      void addRequest(void);

      /**
       * Set service thread in trunk object.
       *
       * @param trunk
       * @param service object
       */
      void setThread(Trunk *trunk, Service *svc);
      
      /**
       * Parse a url/prompt file into a fixed file path.
       */
03879       virtual char *getPrompt(const char *original)
            {return NULL;};

      /**
       * Notify an expired request.
       */
03885       virtual void expires(Request *request)
            {return;};

      /**
       * Notify a running request.
       */
03891       virtual void running(Request *request)
            {return;};

      /**
       * Notify a cancelled request.
       */
03897       virtual void cancelled(Request *request)
            {return;};

      /**
       * Notify when a module network packet has been received and
       * offer reply possibility.
       *
       * @return != 0 to claim packet, >0 if reply.
       * @param packet buffer.
       * @param packet length.
       * @param node entity.
       */
03909       virtual int accept(char *buffer, socklen_t len, statnode_t *node)
            {return 0;};

      /**
       * Notify when a heartbeat dies...
       *
       * @param node that heartbeat died on.
       */
03917       virtual void failover(statnode_t *node)
            {return;};

      /**
       * Network synchronization to broadcast messages from a module thread.
       */
03923       virtual void broadcast(void)
            {return;};

      friend void broadcast(char *msgbuf, unsigned msglen);
      friend void cancel(TrunkGroup *grp, const char *tag);
public:
      inline Module *getNext(void)
            {return modNext;};

      /**
       * Get the "name" identifer of this module.
       *
       * @return name string.
       */
      virtual char *getName(void) = 0;

      /**
       * Execute the script request.  Usually this involves creating
       * a detached service thread.
       *
       * @return error message or NULL.
       * @param trunk object to reference.
       */
03946       virtual char *dispatch(Trunk *trunk)
            {return NULL;};

      /**
       * Fetch the data pointer of a trunk.
       */
03952       inline trunkdata_t *getData(Trunk *trunk)
            {return &trunk->data;};

      /**
       * Post execute commit for modules that schedule delay.
       *
       * @param trunk object to reference.
       */
03960       virtual void commit(Trunk *trunk)
            {return;};

      /**
       * This is used to determine if a timeout/sleep should occur
       * or if script advance is immediate.
       *
       * @return number of seconds in sleep state.
       * @param trunk object to reference.
       */
03970       virtual unsigned sleep(Trunk *trunk)
            {return 0;};

      /**
       * Notify for detach.  As each call is detached, this will
       * get called.
       *
       * @param trunk to detach from.
       */
03979       virtual void detach(Trunk *trunk)
            {return;};

      /**
       * Notify for attach.  This can be used to set constants in
       * the trunks symbol space for this module's use at call
       * setup.
       *
       * @param trunk to attach to.
       */
03989       virtual void attach(Trunk *trunk)
            {return;};

#ifdef      XML_SCRIPTS
      /**
       * Create an XML parser resource.  This produces a trunkimage
       * instance.
       *
       * @return resource made by new.
       */
      virtual TrunkImage *getXML(void)
            {return NULL;};
#endif

      /**
       * reload provisioning interface for fifos.
       */
04006       virtual void reload(void)
            {return;};

      /**
       * fifo command extension.
       */
04012       virtual bool command(char **argv, std::ostream *out)
            {return false;};

      friend Module *getModule(modtype_t mod, const char *name = NULL);
      friend void detachModules(Trunk *trunk);
      friend void attachModules(Trunk *trunk);
};

/**
 * Sessions are used for "garbage collected" entities which may be
 * detached and removed after an expiration time rather than falling
 * out of scope immediately.  This process is managed by the scheduler
 * thread.
 *
 * @short Garbage collectable objects.
 * @author David Sugar <dyfet@ostel.com>
 */
04029 class Session
{
private:
      friend class Scheduler;
      static Mutex mutex;
      static Session *first;
      static Session *last;
      Session *next, *prev;
      static void clean(void);

protected:
      Session();
      virtual ~Session()
            {unlink();};

      /**
       * Unlink the session object.
       */
      void unlink(void);

      /**
       * Indicate if and when this session is to be "garbage collected"
       * by UNIX timestamp.
       *
       * @return 0 if still running, else garbage collection period.
       */
      virtual time_t getExpires(void) = 0;
};

/**
 * Protocols are used for processing transactional requests such as
 * those performed thru modules, but thru a TCP protocol.  These support
 * the resolver thread.
 *
 * @short resolved network protocol session interface.
 * @author David Sugar <dyfet@ostel.com>
 */
04066 class Protocol : public Keydata, public InetHostAddress, public ThreadLock
{
private:
      friend class Resolver;
      static Protocol *first;
      Protocol *next;
      Semaphore *sessions;
      tpport_t port;

      void update(InetHostAddress addr);
public:
      Protocol(const char *keypath, tpport_t port);
      ~Protocol();

      /**
       * Get inet host address for this service.
       *
       * @return inet host address of server.
       */
      InetHostAddress getAddress(void);

      /**
       * Get inet port address of this service.
       *
       * @return inet port address of service.
       */
04092       inline tpport_t getPort(void)
            {return port;};

      /**
       * Get client connection limiting semaphore that is used as the
       * starting semaphore for the client connection thread.
       *
       * @return semaphore session limiter.
       */
04101       inline Semaphore *getSessions(void)
            {return sessions;};
};

/**
 * The transaction logger can cache transaction results for a given
 * trunk so that one can later retrieve these results in a rpc service
 * that monitors transaction results initiated through ccScript services.
 * This allows a rpc service to asynchronously request a Bayonne script
 * to run, and then later find out what happened.
 *
 * @short transaction log for rpc services
 * @author David Sugar <dyfet@ostel.com>
 */
04115 class RPCTransaction : protected MemPager, protected ThreadLock
{
private:
      typedef struct _tlog
      {
            struct _tlog *next;
            time_t      expires;    // expire transaction
            bool running;           // exiting flag
            char id[16];            // trunk seq id
            char info[32];          // info result
      }     tlog;

      tlog *flist, *hash[KEYWORD_INDEX_SIZE];
      unsigned count;

      unsigned getIndex(const char *id);

public:
      RPCTransaction();

      void expire(void);
      bool isRunning(const char *id);
      char *getInfo(const char *id, char *buffer);
      void setInfo(const char *id, const char *info);
      void stop(const char *id);
      const char *start(const char *pid, char **args, time_t timeout, const char *login = "none");
};

void control(const char *ctrlstring);
void loader(const char *path, const char *ext);
statnode_t *getNodes(const char *name);
bool isUser(const char *id);
bool isFHS(void);
bool hasTTS(void);

extern unsigned numbering;
extern bool aliases;
extern bool running;
extern Keydata application;
extern KeyServer keyserver;
extern KeyThreads keythreads;
extern KeyMemory keymemory;
extern KeyPaths keypaths;
extern KeyImports keyimports;
extern KeyVoices keyvoices;
extern KeyLocal keylocal;
extern KeyNetwork keynetwork;
#ifdef      XML_SCRIPTS
extern KeyProxy keyproxy;
#endif
extern KeyHandlers keyhandlers;
extern Plugins plugins;
extern Driver *driver;
extern TTS *tts;
extern Debug *debug;
extern Monitor *monitor;
extern Fifo fifo;
extern ThreadLock cachelock;
extern RPCTransaction rpclog;

#ifdef      CCXX_NAMESPACES
};
#endif

#endif

Generated by  Doxygen 1.6.0   Back to index