00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef __CCXX_BAYONNE_H__
00018 #define __CCXX_BAYONNE_H__
00019
00020 #ifndef __CCXX_SCRIPT_H__
00021 #include <cc++/script.h>
00022 #endif
00023
00024 #ifndef __CCXX_XML_H__
00025 #include <cc++/xml.h>
00026 #endif
00027
00028 #ifndef __CCXX_URL_H__
00029 #include <cc++/url.h>
00030 #endif
00031
00032 #ifndef __CCXX_SLOG_H__
00033 #include <cc++/slog.h>
00034 #endif
00035
00036 #ifndef __CCXX_DSO_H__
00037 #include <cc++/file.h>
00038 #endif
00039
00040 #ifndef __CCXX_SOCKET_H__
00041 #include <cc++/socket.h>
00042 #endif
00043
00044 #ifndef __CCXX_AUDIO_H__
00045 #include <cc++/audio.h>
00046 #endif
00047
00048 #include <stdlib.h>
00049
00050 #ifdef __FreeBSD__
00051 #undef read
00052 #undef write
00053 #undef readv
00054 #undef writev
00055 #endif
00056
00057 #ifndef COMMON_TPPORT_TYPE_DEFINED
00058 typedef short tpport_t;
00059 #endif
00060
00061 00062 00063 00064 00065
00066
00067 class Trunk;
00068 class TrunkImage;
00069 class Service;
00070 class phTone;
00071 class TrunkGroup;
00072 class Module;
00073 class Request;
00074
00075 typedef enum
00076 {
00077 SELECT_FIRST,
00078 SELECT_LAST
00079 } seltype_t;
00080
00081 typedef enum
00082 {
00083 MAP_PREFIX,
00084 MAP_SUFFIX,
00085 MAP_ABSOLUTE
00086 } mapmode_t;
00087
00088 typedef enum {
00089 MODULE_GENERIC,
00090 MODULE_DELIVERY,
00091 MODULE_SENDFILE,
00092 MODULE_SENDFAX,
00093 MODULE_NOTIFY,
00094 MODULE_FIFO,
00095 MODULE_TGI,
00096 MODULE_URL,
00097 MODULE_NET,
00098 MODULE_REPLY,
00099 MODULE_ASR,
00100 MODULE_TTS,
00101 MODULE_XML,
00102 MODULE_ANY
00103 } modtype_t;
00104
00105 typedef enum {
00106
00107 TRUNK_STEP_HANGUP = 0,
00108 TRUNK_STEP_SLEEP,
00109 TRUNK_STEP_ANSWER,
00110 TRUNK_STEP_COLLECT,
00111 TRUNK_STEP_PLAY,
00112 TRUNK_STEP_PLAYWAIT,
00113 TRUNK_STEP_RECORD,
00114 TRUNK_STEP_TONE,
00115 TRUNK_STEP_DIALXFER,
00116 TRUNK_STEP_FLASH,
00117 TRUNK_STEP_JOIN,
00118 TRUNK_STEP_RTP,
00119 TRUNK_STEP_DUPLEX,
00120 TRUNK_STEP_DETECT,
00121 TRUNK_STEP_REQUIRES,
00122 TRUNK_STEP_LOADER,
00123 TRUNK_STEP_EXIT = TRUNK_STEP_HANGUP,
00124 TRUNK_STEP_DRIVER
00125 } trunkstep_t;
00126
00127 typedef enum {
00128
00129 TRUNK_SIGNAL_STEP = 0,
00130 TRUNK_SIGNAL_EXIT,
00131 TRUNK_SIGNAL_HANGUP=TRUNK_SIGNAL_EXIT,
00132 TRUNK_SIGNAL_ERROR,
00133 TRUNK_SIGNAL_TIMEOUT,
00134 TRUNK_SIGNAL_DTMF,
00135 TRUNK_SIGNAL_0,
00136 TRUNK_SIGNAL_1,
00137 TRUNK_SIGNAL_2,
00138 TRUNK_SIGNAL_3,
00139 TRUNK_SIGNAL_4,
00140 TRUNK_SIGNAL_5,
00141 TRUNK_SIGNAL_6,
00142 TRUNK_SIGNAL_7,
00143 TRUNK_SIGNAL_8,
00144 TRUNK_SIGNAL_9,
00145 TRUNK_SIGNAL_STAR,
00146 TRUNK_SIGNAL_POUND,
00147 TRUNK_SIGNAL_A,
00148 TRUNK_SIGNAL_B,
00149 TRUNK_SIGNAL_C,
00150 TRUNK_SIGNAL_D,
00151 TRUNK_SIGNAL_DIALTONE,
00152 TRUNK_SIGNAL_BUSY,
00153 TRUNK_SIGNAL_CANCEL,
00154 TRUNK_SIGNAL_SIGNAL,
00155 TRUNK_SIGNAL_DRIVER
00156 } trunksignal_t;
00157
00158 typedef enum {
00159
00160
00161 TRUNK_ENTER_STATE = 100,
00162 TRUNK_EXIT_STATE,
00163 TRUNK_STOP_STATE,
00164 TRUNK_NOTIFICATION,
00165 TRUNK_SERVICE_SUCCESS,
00166 TRUNK_SERVICE_FAILURE,
00167 TRUNK_SERVICE_LOOKUP,
00168 TRUNK_SERVICE_LOGIN,
00169 TRUNK_SIGNAL_NOTIFY,
00170 TRUNK_JOIN_TRUNKS,
00171 TRUNK_PART_TRUNKS,
00172 TRUNK_NULL_EVENT,
00173
00174
00175
00176 TRUNK_EXIT_SHELL = 200,
00177 TRUNK_START_SCRIPT,
00178 TRUNK_RING_START,
00179 TRUNK_RING_REDIRECT,
00180 TRUNK_STOP_DISCONNECT,
00181
00182
00183
00184 TRUNK_START_INCOMING = TRUNK_RING_START,
00185 TRUNK_START_OUTGOING = TRUNK_START_SCRIPT,
00186
00187
00188
00189 TRUNK_MAKE_TEST = 300,
00190 TRUNK_MAKE_BUSY,
00191 TRUNK_MAKE_IDLE,
00192 TRUNK_MAKE_STEP,
00193
00194
00195
00196 TRUNK_LINE_WINK = 400,
00197 TRUNK_TIMER_EXPIRED,
00198 TRUNK_RINGING_ON,
00199 TRUNK_RINGING_OFF,
00200 TRUNK_TEST_IDLE,
00201 TRUNK_TEST_FAILURE,
00202 TRUNK_ON_HOOK,
00203 TRUNK_OFF_HOOK,
00204 TRUNK_CALLER_ID,
00205 TRUNK_RINGING_DID,
00206 TRUNK_CALL_DETECT,
00207 TRUNK_CALL_CONNECT,
00208 TRUNK_CALL_RELEASE,
00209 TRUNK_CALL_ACCEPT,
00210 TRUNK_CALL_RINGING,
00211 TRUNK_CALL_DISCONNECT,
00212
00213
00214
00215 TRUNK_AUDIO_IDLE = 500,
00216 TRUNK_INPUT_PENDING,
00217 TRUNK_OUTPUT_PENDING,
00218 TRUNK_AUDIO_BUFFER,
00219 TRUNK_TONE_IDLE,
00220 TRUNK_DTMF_KEYDOWN,
00221 TRUNK_DTMF_KEYUP,
00222 TRUNK_TONE_START,
00223 TRUNK_TONE_STOP,
00224 TRUNK_FSK_DETECT,
00225 TRUNK_FAX_DETECT,
00226 TRUNK_VOX_DETECT,
00227 TRUNK_AUDIO_START,
00228 TRUNK_AUDIO_STOP,
00229 TRUNK_CPA_DIALTONE,
00230 TRUNK_CPA_BUSYTONE,
00231 TRUNK_CPA_RINGING,
00232 TRUNK_CPA_RINGBACK = TRUNK_CPA_RINGING,
00233 TRUNK_CPA_INTERCEPT,
00234 TRUNK_CPA_NODIALTONE,
00235 TRUNK_CPA_NORINGBACK,
00236 TRUNK_CPA_NOANSWER,
00237 TRUNK_CPA_CONNECT,
00238 TRUNK_CPA_FAILURE,
00239 TRUNK_DSP_READY,
00240
00241
00242
00243 TRUNK_DRIVER_SPECIFIC=8000
00244 } trunkevent_t;
00245
00246 typedef enum
00247 {
00248 DSP_MODE_INACTIVE = 0,
00249 DSP_MODE_VOICE,
00250 DSP_MODE_CALLERID,
00251 DSP_MODE_DATA,
00252 DSP_MODE_FAX,
00253 DSP_MODE_TDM,
00254 DSP_MODE_RTP,
00255 DSP_MODE_DUPLEX,
00256 DSP_MODE_JOIN,
00257 DSP_MODE_CONF,
00258 DSP_MODE_TONE
00259 } dspmode_t;
00260
00261 typedef enum
00262 {
00263 TRUNK_MODE_INCOMING = 0,
00264 TRUNK_MODE_OUTGOING,
00265 TRUNK_MODE_INACTIVE,
00266 TRUNK_MODE_UNAVAILABLE
00267 } trunkmode_t;
00268
00269 typedef enum
00270 {
00271 STAT_MAX_INCOMING,
00272 STAT_MAX_OUTGOING,
00273 STAT_TOT_INCOMING,
00274 STAT_TOT_OUTGOING,
00275 STAT_ACTIVE_CALLS
00276 } statitem_t;
00277
00278 typedef enum
00279 {
00280 PLAY_MODE_NORMAL,
00281 PLAY_MODE_ONE,
00282 PLAY_MODE_ANY,
00283 PLAY_MODE_TEMP
00284 } playmode_t;
00285
00286 typedef enum
00287 {
00288 TTS_GATEWAY_TEXT,
00289 TTS_GATEWAY_FILE
00290 } ttsmode_t;
00291
00292 #define TRUNK_CAP_VOICE 0x00000001
00293 #define TRUNK_CAP_DIAL 0x00000002
00294 #define TRUNK_CAP_SENDFAX 0x00000004
00295 #define TRUNK_CAP_RECVFAX 0x00000008
00296 #define TRUNK_CAP_DATA 0x00000010
00297 #define TRUNK_CAP_TTS 0x00000020
00298 #define TRUNK_CAP_ASR 0x00000040
00299
00300 typedef union
00301 {
00302 scriptsymbol_t sym;
00303 char data[sizeof(scriptsymbol_t) + 12];
00304 } numbersymbol_t;
00305
00306 typedef union
00307 {
00308 scriptsymbol_t bin;
00309 char data[sizeof(scriptsymbol_t) + 32];
00310 } digitsymbol_t;
00311
00312 typedef struct
00313 {
00314
00315 int pid;
00316 unsigned seq;
00317 void *data;
00318 } execdata_t;
00319
00320 typedef union
00321 {
00322 struct
00323 {
00324 int rings;
00325 int timeout;
00326 } answer;
00327 struct
00328 {
00329 char list[256];
00330 char *name;
00331 unsigned long offset;
00332 unsigned long limit;
00333 unsigned char volume;
00334 unsigned short term;
00335 playmode_t mode;
00336 timeout_t timeout;
00337 unsigned repeat;
00338 } play;
00339 struct
00340 {
00341 char *name;
00342 timeout_t timeout;
00343 unsigned long offset;
00344 unsigned short term;
00345 unsigned char volume;
00346 unsigned long trim;
00347 bool append;
00348 } record;
00349 struct
00350 {
00351 char digits[65];
00352 char *digit;
00353 timeout_t interdigit;
00354 bool exit;
00355 timeout_t timeout;
00356 timeout_t offhook;
00357 timeout_t onhook;
00358 } dialxfer;
00359 struct
00360 {
00361 timeout_t timeout;
00362 unsigned count;
00363 unsigned short term;
00364 unsigned short ignore;
00365 } collect;
00366 struct
00367 {
00368 timeout_t wakeup;
00369 unsigned rings;
00370 unsigned loops;
00371 } sleep;
00372 struct
00373 {
00374 timeout_t wakeup;
00375 unsigned loops;
00376 phTone *tone;
00377 } tone;
00378 struct
00379 {
00380 timeout_t wakeup;
00381 Trunk *trunk;
00382 phTone *tone;
00383 } join;
00384 struct
00385 {
00386 struct in_addr addr;
00387 unsigned short bind, port, term;
00388 audioencoding_t codec;
00389 } rtp;
00390 struct
00391 {
00392 TrunkImage *image;
00393 const char *url;
00394 const char *section;
00395 char **vars;
00396 bool post;
00397 timeout_t timeout;
00398 } load;
00399 } trunkdata_t;
00400
00401 typedef struct
00402 {
00403 trunkevent_t id;
00404 union
00405 {
00406 struct
00407 {
00408 unsigned digit: 4;
00409 unsigned duration: 12;
00410 unsigned e1: 8;
00411 unsigned e2: 8;
00412 } dtmf;
00413 struct
00414 {
00415 unsigned tone: 8;
00416 unsigned energy: 8;
00417 unsigned duration: 16;
00418 } tone;
00419 struct
00420 {
00421 unsigned digit: 4;
00422 unsigned duration: 24;
00423 } ring;
00424 struct
00425 {
00426 unsigned seq;
00427 bool result;
00428 char *data;
00429 } lookup;
00430 int status;
00431 Trunk *trunk;
00432 void *data;
00433 char **argv;
00434 char *error;
00435 timeout_t duration;
00436 trunkstep_t step;
00437 char dn[8];
00438 dspmode_t dsp;
00439 } parm;
00440 } TrunkEvent;
00441
00442 #pragma pack(1)
00443
00444 typedef struct {
00445 time_t update;
00446 char name[16];
00447 struct in_addr addr;
00448 unsigned char version;
00449 unsigned char buddies;
00450 unsigned char ports;
00451 char stat[255];
00452 } statnode_t;
00453
00454 #pragma pack()
00455
00456 00457 00458
00459
00460 typedef char *(*functioncall_t)(scriptsymbol_t *sym, char **args);
00461
00462 typedef struct
00463 {
00464 char *name;
00465 functioncall_t function;
00466 } FUNCTIONS;
00467
00468
00469 bool getLogical(const char *string);
00470
00478 class CallStat : public Mutex
00479 {
00480 protected:
00481 int capacity;
00482 struct
00483 {
00484 int incoming;
00485 int outgoing;
00486 } active, max, lastmax;
00487
00488 struct
00489 {
00490 long incoming;
00491 long outgoing;
00492 } total, lasttotal;
00493
00494 public:
00495 CallStat();
00496
00502 inline int getCapacity(void)
00503 {return capacity;};
00504
00511 long getStat(statitem_t item);
00512
00516 void incIncoming(void);
00517
00521 void decIncoming(void);
00522
00526 void incOutgoing(void);
00527
00531 void decOutgoing(void);
00532
00536 void Update(void);
00537 };
00538
00551 class Translator : protected Keydata
00552 {
00553 private:
00554 friend Translator *getTranslator(char *name);
00555 static Translator *first;
00556 Translator *next;
00557
00558 protected:
00564 virtual char *getName(void) = 0;
00565
00572 char *getPlayBuffer(Trunk *trunk);
00573
00574 void scanDir(const char *etcdir, const char *language, const char *lib);
00575
00576 Translator(const char *conf, const char *lib);
00577
00578 public:
00586 virtual char *Speak(Trunk *trunk) = 0;
00587 };
00588
00602 class Functions
00603 {
00604 protected:
00610 virtual char *getName(void) = 0;
00611
00617 void Load(FUNCTIONS *map);
00618 };
00619
00620 00621 00622 00623
00624
00631 class KeyTones : protected Keydata
00632 {
00633 public:
00637 KeyTones();
00638 };
00639
00647 class KeyLocal : public Keydata
00648 {
00649 public:
00653 KeyLocal();
00654 };
00655
00662 class KeyHandlers : public Keydata
00663 {
00664 public:
00668 KeyHandlers();
00669 };
00670
00678 class KeyPaths : public Keydata
00679 {
00680 public:
00684 KeyPaths();
00685
00689 inline const char *getLibexec(void)
00690 {return getLast("libexec");};
00691
00695 inline const char *getTgipath(void)
00696 {return getLast("tgipath");};
00697
00701 inline const char *getLibpath(void)
00702 {return getLast("libpath");};
00703
00707 inline const char *getDatafiles(void)
00708 {return getLast("datafiles");};
00709
00713 inline const char *getWrappers(void)
00714 {return getLast("wrappers");};
00715
00719 inline const char *getRunfiles(void)
00720 {return getLast("runfiles");};
00721
00725 inline const char *getSpool(void)
00726 {return getLast("spool");};
00727
00731 inline const char *getScriptFiles(void)
00732 {return getLast("scripts");};
00733
00737 inline const char *getPromptFiles(void)
00738 {return getLast("prompts");};
00739
00743 inline const char *getCache(void)
00744 {return getLast("precache");};
00745 };
00746
00754 class KeyNetwork : public Keydata
00755 {
00756 public:
00760 KeyNetwork();
00761
00767 unsigned getRefresh(void)
00768 {return atoi(getLast("refresh"));};
00769
00775 unsigned getTimeToLive(void)
00776 {return atoi(getLast("live"));};
00777
00783 unsigned getTimeToElect(void)
00784 {return atoi(getLast("elect"));};
00785
00791 unsigned getTimeToExpire(void)
00792 {return atoi(getLast("expire"));};
00793
00799 InetHostAddress getBroadcast(void);
00800
00806 InetAddress getAddress(void);
00807
00813 tpport_t getPort(void);
00814
00820 InetHostAddress getDBHost(void);
00821
00827 tpport_t getDBPort(void);
00828 };
00829
00836 class KeyProxy : public Keydata
00837 {
00838 public:
00842 KeyProxy();
00843
00849 const char *getHTTPServer(void);
00850
00856 tpport_t getHTTPPort(void);
00857 };
00858
00866 class KeyMailbox : public Keydata
00867 {
00868 public:
00872 KeyMailbox();
00873
00879 inline unsigned getCount(void)
00880 {return atoi(getLast("count"));};
00881
00887 inline unsigned getLimit(void)
00888 {return atoi(getLast("limit"));};
00889
00896 inline unsigned getQuota(void)
00897 {return atoi(getLast("quota"));};
00898
00904 inline unsigned getMinimum(void)
00905 {return atoi(getLast("minimum"));};
00906
00912 inline unsigned getMaximum(void)
00913 {return atoi(getLast("maximum"));};
00914
00920 inline const char *getPassword(void)
00921 {return getLast("password");};
00922 };
00923
00932 class KeyMemory : public Keydata
00933 {
00934 public:
00938 KeyMemory();
00939
00945 inline int getSymbolSize(void)
00946 {return atoi(getLast("symbols"));};
00947
00954 inline int getPageSize(void)
00955 {return atoi(getLast("page"));};
00956 };
00957
00965 class KeyFeed : public Keydata
00966 {
00967 public:
00971 KeyFeed();
00972
00978 inline unsigned getBuffers(void)
00979 {return atoi(getLast("buffers"));};
00980 };
00981
00982
00990 class KeyThreads : public Keydata
00991 {
00992 public:
00996 KeyThreads();
00997
01003 inline int priService(void)
01004 {return atoi(getLast("services"));};
01005
01011 inline int priScheduler(void)
01012 {return atoi(getLast("scheduler"));};
01013
01019 inline int priGUI(void)
01020 {return atoi(getLast("gui"));};
01021
01027 inline int priRTP(void)
01028 {return atoi(getLast("rtp"));};
01029
01035 inline int getStepDelay(void)
01036 {return atoi(getLast("stepdelay"));};
01037
01043 inline int getStepInterval(void)
01044 {return atoi(getLast("stepinterval"));};
01045
01051 inline int getResetDelay(void)
01052 {return atoi(getLast("resetdelay"));};
01053
01059 size_t getStack(void);
01060
01066 int getServices(void);
01067
01073 int priResolver(void);
01074
01081 int getResolver(void);
01082
01088 inline int priAudio(void)
01089 {return atoi(getLast("audio"));};
01090
01096 inline int priFeed(void)
01097 {return atoi(getLast("feed"));};
01098
01104 inline bool getAudit(void)
01105 {return getLogical(getLast("audit"));};
01111 inline int priGateway(void)
01112 {return atoi(getLast("gateways"));};
01113
01119 inline int priManager(void)
01120 {return atoi(getLast("managers"));};
01121
01127 inline int priNetwork(void)
01128 {return atoi(getLast("network"));};
01129
01135 inline int priXML(void)
01136 {return atoi(getLast("xml"));};
01137
01143 inline int getInterval(void)
01144 {return atoi(getLast("interval"));};
01145
01151 inline int getRefresh(void)
01152 {return atoi(getLast("refresh"));};
01153
01159 int getGateways(void);
01160
01167 inline int getPriority(void)
01168 {return atoi(getLast("priority"));};
01169
01175 int getPolicy(void);
01176
01182 inline int getPages(void)
01183 {return atoi(getLast("pages"));};
01184 };
01185
01193 class Auditdata : public Keydata
01194 {
01195 private:
01196 friend class Audit;
01197
01198 Auditdata();
01199 };
01200
01209 class Policy
01210 {
01211 private:
01212 friend class TrunkGroup;
01213
01214 Policy *next;
01215 TrunkGroup *group;
01216
01217 protected:
01218 Policy(TrunkGroup *grp);
01219
01220 virtual Request *loPriority(void)
01221 {return NULL;};
01222
01223 virtual Request *hiPriority(void)
01224 {return NULL;};
01225 };
01226
01236 class Request
01237 {
01238 private:
01239 friend class TrunkGroup;
01240
01241 static unsigned seq;
01242
01243 unsigned id;
01244 Request *next;
01245 time_t expires;
01246 TrunkGroup *group;
01247
01248 char *argv[33];
01249 char buffer[512];
01250 char tagid[65];
01251
01252 void Detach(void);
01253
01254 public:
01255 Request(TrunkGroup *grp, const char *text, unsigned expire, const char *tag = NULL);
01256 ~Request()
01257 {Detach();};
01258
01259 inline char **getList(void)
01260 {return argv;};
01261
01262 inline char *getTag(void)
01263 {return tagid;};
01264
01265 bool isExpired(void);
01266
01267 friend void cancel(TrunkGroup *group, const char *tag);
01268 friend Request *request(TrunkGroup *group, char **argv, unsigned timeout, const char *tag = NULL);
01269 friend Request *locate(TrunkGroup *group, const char *tag, int *pos);
01270 };
01271
01282 class TrunkGroup : public Keydata, public CallStat
01283 {
01284 private:
01285 friend class KeyServer;
01286 friend class Scheduler;
01287 friend class Audit;
01288 friend class TestDebug;
01289 friend class Request;
01290 friend class Policy;
01291 friend class Trunk;
01292 static TrunkGroup *first;
01293 TrunkGroup *next;
01294 char schedule[65];
01295 char planned[65];
01296 unsigned trump;
01297 Request *reqfirst, *reqlast;
01298 Policy *polFirst;
01299 unsigned members;
01300
01301 void setSchedule(const char *str);
01302
01303 friend inline const char *getGroups(void)
01304 {return TrunkGroup::first->getLast("groups");};
01305
01306 friend void cancel(TrunkGroup *group, const char *tag);
01307 friend Request *locate(TrunkGroup *group, const char *tag, int *pos = NULL);
01308
01309
01310 public:
01316 TrunkGroup(char *name = NULL);
01317
01323 inline const char *getName(void)
01324 {return getLast("name");};
01325
01331 inline unsigned getAnswer(void)
01332 {return atoi(getLast("answer"));};
01333
01339 bool getDetect(void);
01340
01346 inline unsigned getCallerid(void)
01347 {return atoi(getLast("callerid"));};
01348
01354 inline unsigned getPickup(void)
01355 {return atoi(getLast("pickup"));};
01356
01362 inline const char *chkRequest(void)
01363 {return getLast("requests");};
01364
01370 seltype_t getSelect(void);
01371
01377 inline unsigned getThreashold(void)
01378 {return atoi(getLast("threashold"));};
01379
01385 inline unsigned getAnalysis(void)
01386 {return atoi(getLast("analysis"));};
01387
01394 inline timeout_t getReady(void)
01395 {return atol(getLast("ready"));};
01396
01402 inline unsigned getIdleTime(void)
01403 {return atoi(getLast("idletime"));};
01404
01410 inline unsigned getSiezeTime(void)
01411 {return atoi(getLast("siezetime"));};
01412
01418 inline unsigned getRingTime(void)
01419 {return atoi(getLast("ringtime"));};
01420
01426 inline int getHangup(void)
01427 {return atoi(getLast("hangup"));};
01428
01434 inline timeout_t getFlash(void)
01435 {return atol(getLast("flash"));};
01436
01442 inline timeout_t getDialtone(void)
01443 {return atol(getLast("dialtone"));};
01444
01450 inline timeout_t getDialspeed(void)
01451 {return atol(getLast("dialspeed"));};
01452
01459 const char *getNumber(void);
01460
01467 const char *getSchedule(char *buf);
01468
01478 const char *getRedirect(const char *redirect, char *buf);
01479
01483 inline void incCapacity(void)
01484 {++capacity;};
01485
01491 Request *getRequest(void);
01492
01498 friend TrunkGroup *getGroup(const char *name);
01499 };
01500
01508 class KeyServer : public Keydata
01509 {
01510 private:
01511 unsigned uid, gid;
01512 const char *altdir;
01513 const char *phrdir;
01514
01515 public:
01519 KeyServer();
01520
01526 inline const char *getNode(void)
01527 {return getLast("node");};
01528
01534 inline const char *getPassword(void)
01535 {return getLast("password");};
01536
01542 inline const char *getToken(void)
01543 {return getLast("token");};
01544
01548 void loadGroups(bool test);
01549
01555 inline const char *getDefault(void)
01556 {return getLast("default");};
01557
01563 inline unsigned getGid(void)
01564 {return gid;};
01565
01571 inline unsigned getUid(void)
01572 {return uid;};
01573
01577 void setUid(void);
01578
01582 void setGid(void);
01583
01589 inline int getNodeCount(void)
01590 {return atoi(getLast("nodes"));};
01591
01597 inline const char *getPrefix(void)
01598 {return altdir;};
01599
01605 inline const char *getPhrases(void)
01606 {return phrdir;};
01607 };
01608
01616 class Plugins : public Keydata
01617 {
01618 public:
01622 Plugins();
01623
01627 ~Plugins();
01628
01634 char *getDriverName(void);
01635
01639 void loadXML(void);
01640
01644 void loadDebug(void);
01645
01650 DSO *loadDriver(void);
01651
01655 void loadExtensions(void);
01656
01660 void loadFunctions(void);
01661
01665 void loadMaps(void);
01666
01670 void loadModules(void);
01671
01675 void loadServices(void);
01676
01680 void loadFeeds(void);
01681
01685 void loadTGI(void);
01686
01690 void loadManagers(void);
01691
01695 void loadTranslators(void);
01696
01700 void loadAuditing(void);
01701 };
01702
01711 class aaScript : public ScriptCommand
01712 {
01713 private:
01714 friend class Functions;
01715
01716 #pragma pack(1)
01717 typedef struct _functions
01718 {
01719 struct _functions *next;
01720 functioncall_t function;
01721 char name[1];
01722 } functions_t;
01723 #pragma pack()
01724
01725 functions_t *functions[KEYWORD_INDEX_SIZE];
01726
01727 protected:
01735 unsigned long getTrapMask(const char *trapname);
01736
01744 void addFunction(char *name, functioncall_t function);
01745
01746 public:
01753 functioncall_t getFunction(char *name);
01754
01758 aaScript();
01759
01765 void addModule(Module *module);
01766
01772 void addDummy(const char *names);
01773 };
01774
01784 class aaImage : public ScriptImage
01785 {
01786 protected:
01794 virtual bool isScript(char *scriptname);
01795
01802 void scanDir(char *path);
01803
01804 public:
01808 aaImage(aaScript *script);
01809 };
01810
01817 class Mixer : protected Mutex
01818 {
01819 private:
01820 friend class Conference;
01821 void addGroup(void);
01822 void delGroup(void);
01823
01824 protected:
01825 Mixer();
01826 unsigned avail, members, groups;
01827
01828 public:
01829 unsigned getAvail(void)
01830 {return avail;};
01831
01832 unsigned getMembers(void)
01833 {return members;};
01834
01835 unsigned getGroups(void)
01836 {return groups;};
01837
01838 virtual bool setMixer(int groups, int members) = 0;
01839
01840 virtual Conference *getConference(int group) = 0;
01841 };
01842
01851 class Conference : protected Mutex
01852 {
01853 protected:
01854 Mixer *mixer;
01855 unsigned limit;
01856 unsigned members;
01857 int *membership;
01858
01859 virtual ~Conference();
01860
01861 Conference(Mixer *m);
01862 public:
01863 inline virtual Mixer *getMixer(void)
01864 {return mixer;};
01865
01866 int *getMembership(void)
01867 {return membership;};
01868
01869 Trunk *getTrunk(unsigned member);
01870
01871 unsigned getMembers(void)
01872 {return members;};
01873
01874 unsigned getLimit(void)
01875 {return limit;};
01876
01877 virtual bool setConference(unsigned max) = 0;
01878 };
01879
01887 class TrunkImage : public ScriptImage, protected URLStream, protected XMLStream
01888 {
01889 private:
01890 char *attrib[65];
01891
01892 int Read(unsigned char *buffer, int len);
01893
01894 protected:
01895 void Close(void)
01896 {return URLStream::Close();};
01897
01898 typedef struct
01899 {
01900 scriptname_t *script;
01901 scriptline_t *last;
01902 unsigned line;
01903 unsigned long addmask, submask, trapmask;
01904 unsigned char loopid[65], looplevel[65];
01905 unsigned trap;
01906 void *data;
01907 } compile_t;
01908
01909 compile_t *main, *current;
01910
01916 void getCompile(const char *name = "#");
01917
01923 void setCompile(unsigned trap);
01924
01930 void putCompile(compile_t *cc);
01931
01939 void addCompile(unsigned long mask, const char *cmd, const char **args);
01940
01946 void setToken(const unsigned char **attrib);
01947
01953 const char *getToken(void);
01954
01960 virtual unsigned long getDefaultMask(void)
01961 {return 3;};
01962
01971 const char *getAttribute(const char *key, const char *value = NULL);
01972
01973 public:
01977 TrunkImage();
01978
01979 virtual ~TrunkImage()
01980 {Purge();};
01981
01988 void setProxy(const char *addr, tpport_t port)
01989 {URLStream::setProxy(addr, port);};
01990
01999 virtual bool Loader(trunkdata_t *data) = 0;
02000
02004 void Purge(void);
02005
02012 void *alloc(unsigned size)
02013 {return MemPager::alloc(size);};
02014 };
02015
02025 class Trunk : public ScriptInterp
02026 {
02027 private:
02028 friend class TestDebug;
02029 friend class aaScript;
02030 friend class Translator;
02031 friend class ScriptInterface;
02032 friend class Service;
02033 friend class AudioService;
02034 friend class Fifo;
02035 friend class PortManager;
02036
02037 unsigned member;
02038 char *cdrv[33];
02039 int cdrc;
02040 numbersymbol_t numbers[5];
02041 TrunkImage *altimage;
02042
02043 bool scrStart(void);
02044 bool scrRequest(void);
02045 bool scrLibexec(void);
02046 bool scrHangup(void);
02047 bool scrDebug(void);
02048 bool scrImport(void);
02049 bool scrExport(void);
02050 bool scrFunction(void);
02051 bool scrAlog(void);
02052 bool scrAudit(void);
02053 bool scrPause(void);
02054 bool scrSleep(void);
02055 bool scrSync(void);
02056 bool scrTone(void);
02057 bool scrAnswer(void);
02058 bool scrCollect(void);
02059 bool scrFlash(void);
02060 bool scrSay(void);
02061 bool scrCleardigits(void);
02062 bool scrAssign(void);
02063 bool scrInsert(void);
02064 bool scrDelete(void);
02065 bool scrReplace(void);
02066 bool scrPrefix(void);
02067 bool scrChop(void);
02068 bool scrTrim(void);
02069 bool scrPlay(void);
02070 bool scrSend(void);
02071 bool scrLoad(void);
02072 bool scrRecord(void);
02073 bool scrDial(void);
02074 bool scrDTMF(void);
02075 bool scrTransfer(void);
02076 bool scrHold(void);
02077 bool scrSpeak(void);
02078 bool scrMap(void);
02079 bool scrModule(void);
02080 bool scrDummy(void);
02081 bool scrSchedule(void);
02082 bool scrSignal(void);
02083 bool scrIdle(void);
02084
02085 scriptname_t *getScriptImage(const char *name);
02086
02087 protected:
02088 static ScriptSymbol globals;
02089 static char digit[16];
02090 ScriptInterface *script;
02091 TrunkGroup *group;
02092 PortManager *manager;
02093 int id;
02094 time_t start, idle;
02095
02096 int idle_timer;
02097 int rings;
02098 int digits;
02099
02100 Service *thread;
02101 trunkdata_t data;
02102 execdata_t tgi;
02103 digitsymbol_t dtmf;
02104 char buffer[65];
02105
02106 struct
02107 {
02108 bool offhook: 1;
02109 bool dtmf: 1;
02110 bool script: 1;
02111 bool reset: 1;
02112 bool timer : 1;
02113 bool audio: 1;
02114 bool once : 1;
02115 bool ready : 1;
02116 bool echo : 1;
02117 unsigned temp : 1;
02118 trunkmode_t trunk: 2;
02119 dspmode_t dsp: 4;
02120 } flags;
02121
02127 unsigned long getTrapDefault(void)
02128 {return 0x00000007;};
02129
02138 void setConstant(const char *id, const char *data);
02139
02146 void repSymbol(const char *id, const char *data);
02147
02155 scriptsymbol_t *getEntry(const char *symname, int size);
02156
02162 void Commit(scriptsymbol_t *sym);
02163
02173 timeout_t getTimeout(void);
02174
02181 timeout_t getInterdigit(void);
02182
02188 unsigned short getDigitMask(void);
02189
02195 bool TrunkSignal(trunksignal_t);
02196
02203 virtual void setDTMFDetect(void);
02204
02213 virtual void setDTMFDetect(bool enable)
02214 {flags.dtmf = enable;};
02215
02221 virtual void stopServices(void);
02222
02233 virtual void TrunkStep(trunkstep_t step) = 0;
02234
02240 bool idleHangup();
02241
02248 virtual unsigned long getIdleTime(void) = 0;
02249
02253 bool ScriptStep(void);
02254
02263 bool Attach(const char *scrname);
02264
02269 void Detach(void);
02270
02274 unsigned long getMask(void);
02275
02282 char **getInitial(char **args);
02283
02290 void setList(char **list);
02291
02292 Trunk(int port);
02293 public:
02299 virtual unsigned long getCapabilities(void)
02300 {return TRUNK_CAP_VOICE | TRUNK_CAP_DIAL;};
02301
02307 virtual void getName(char *buffer) = 0;
02308
02316 virtual bool postEvent(TrunkEvent *event) = 0;
02317
02323 int getDigit(char digit);
02324
02330 bool isReady(void);
02331
02339 void libexec(char **argv, unsigned timeout);
02340
02348 void libtts(const char *msg, ttsmode_t mode);
02349
02353 inline bool getOnce(void)
02354 {return ScriptInterp::getOnce();};
02355
02361 inline unsigned getMemberId(void)
02362 {return member;};
02363
02364 };
02365
02374 class PortManager
02375 {
02376 private:
02377 Trunk *trunk;
02378
02379 protected:
02380 ~PortManager()
02381 {trunk->manager = NULL;};
02382
02388 PortManager(Trunk *trk);
02389
02395 inline void postStep(trunkstep_t step)
02396 {trunk->TrunkStep(step);};
02397
02404 inline bool postEvent(TrunkEvent *event)
02405 {return trunk->postEvent(event);};
02406
02412 inline trunkdata_t *getData(void)
02413 {return &trunk->data;};
02414
02420 inline execdata_t *getExec(void)
02421 {return &trunk->tgi;};
02422 public:
02426 virtual bool Step(void) = 0;
02427
02433 virtual unsigned long getMask(void) = 0;
02434
02441 virtual bool postSignal(trunksignal_t signal) = 0;
02442
02449 virtual bool postAccept(const char *name) = 0;
02450
02454 virtual void postDetach(void) = 0;
02455 };
02456
02466 class Fifo : public fifostream, public Mutex
02467 {
02468 protected:
02469 char schedule[33];
02470
02471 bool exitPid(char **args);
02472 bool waitPid(char **args);
02473 bool setSymbol(char **argv);
02474 bool putSymbol(char **argv);
02475
02476 bool login(char **argv);
02477 bool startScript(char **argv);
02478 bool ringScript(char **argv);
02479 bool redirectScript(char **argv);
02480 bool busyLine(char **argv);
02481 bool idleLine(char **argv);
02482 bool hangupLine(char **argv);
02483 bool reqScript(char **argv);
02484 bool setSchedule(char **argv);
02485 bool postKey(char **argv);
02486 bool setMixer(char **argv);
02487 bool setLimit(char **argv);
02488 bool mapFiles(char **argv);
02489 bool submit(char **argv);
02490 bool reload(char **argv);
02491
02492 public:
02501 bool Command(const char *cmdstring, ostream *fd = NULL);
02502 };
02503
02517 class Audit : public Mutex
02518 {
02519 private:
02520 friend void audit(Trunk *trunk, char *detail);
02521 friend void alog(Trunk *trunk, char *detail);
02522 friend class Scheduler;
02523
02524 static Audit *first;
02525 Audit *next;
02526
02527 protected:
02528 static Auditdata keys;
02529
02535 virtual void ReportAudit(Trunk *trunk, char *detail) = 0;
02536
02542 virtual void ReportCDR(Trunk *trunk, char *detail)
02543 {ReportAudit(trunk, detail);};
02544
02548 virtual void ReportStats(void)
02549 {return;};
02550
02556 inline TrunkGroup *getFirst(void)
02557 {return TrunkGroup::first;};
02558
02565 inline TrunkGroup *getNext(TrunkGroup *grp)
02566 {return grp->next;};
02567
02571 Audit();
02572 };
02573
02581 class Driver : public aaScript
02582 {
02583 protected:
02584 friend class TrunkGroup;
02585
02586 TrunkGroup **groups;
02587 char *status;
02588 bool active;
02589
02590 public:
02594 Driver();
02595
02602 virtual int Start(void) = 0;
02603
02607 virtual void Stop(void) = 0;
02608
02614 void getStatus(char *buffer);
02615
02622 virtual aaImage *getImage(void);
02623
02630 virtual int getTrunkCount(void) = 0;
02631
02638 virtual int getTrunkUsed(void)
02639 {return getTrunkCount();};
02640
02647 TrunkGroup *getTrunkGroup(int id)
02648 {return groups[id];};
02649
02657 int getTrunkMember(TrunkGroup *grp, unsigned member);
02658
02664 virtual Trunk *getTrunkPort(int id) = 0;
02665
02671 virtual Conference *getConference(int id)
02672 {return NULL;};
02673
02679 virtual Mixer *getMixer(int id)
02680 {return NULL;};
02681
02687 virtual unsigned getMixers(void)
02688 {return 0;};
02689
02695 virtual unsigned getGroups(void)
02696 {return 0;};
02697 };
02698
02705 class Debug : protected Mutex
02706 {
02707 public:
02711 Debug();
02712
02718 virtual bool DebugTest(void)
02719 {return false;};
02720
02724 virtual void DebugEvent(Trunk *trunk, TrunkEvent *event)
02725 {return;};
02726
02730 virtual void DebugState(Trunk *trunk, char *state)
02731 {return;};
02732
02736 virtual void DebugService(Trunk *trunk, char *msg)
02737 {return;};
02738
02742 virtual void DebugScript(Trunk *trunk, char *msg)
02743 {return;};
02744
02748 virtual void DebugStep(Trunk *trunk, scriptline_t *line)
02749 {DebugState(trunk, "step");};
02750
02754 virtual bool DebugFifo(char **argv)
02755 {return true;};
02756 };
02757
02764 class AudioService
02765 {
02766 private:
02767 char filename[256];
02768
02769 protected:
02770 Trunk *trunk;
02777 char *getPrompt(char *name);
02778
02784 char *getPlayfile(void);
02785
02789 AudioService(void);
02790 };
02791
02799 class Service : public Semaphore, public Thread, public AudioService
02800 {
02801 protected:
02802 volatile bool stopped;
02803 trunkdata_t *data;
02804 TrunkGroup *group;
02805
02809 void Success(void);
02810
02814 void Failure(void);
02815
02819 inline void dspReset(void)
02820 {trunk->flags.reset = true;};
02821
02825 inline void setAudio(void)
02826 {trunk->flags.audio = true;};
02827
02831 inline void clrAudio(void)
02832 {trunk->flags.audio = false;};
02833
02834 public:
02841 Service(Trunk *trunk, int pri);
02842
02849 virtual timeout_t Stop(void);
02850
02858 virtual bool isExiting(void)
02859 {return true;};
02860
02864 void endService(void)
02865 {Terminate();};
02866
02870 virtual ~Service()
02871 {Terminate();}
02872 };
02873
02881 class XMLService : public Service
02882 {
02883 private:
02884 void Run(void);
02885
02886 public:
02887 XMLService(Trunk *trk);
02888 ~XMLService();
02889 };
02890
02900 class Server : public Thread
02901 {
02902 private:
02903 static Server *first;
02904 Server *next;
02905 friend void startServers(void);
02906 friend void stopServers(void);
02907
02908 protected:
02909 Server(int pri);
02910
02914 virtual void Stop(void)
02915 {Terminate();};
02916 };
02917
02924 class Sync
02925 {
02926 private:
02927 friend class Scheduler;
02928
02929 static Sync *first;
02930 Sync *next;
02931 time_t runtime;
02932
02933 protected:
02937 Sync(void);
02938
02943 virtual bool isScheduled(void)
02944 {return true;};
02945
02950 virtual unsigned getInterval(void)
02951 {return 10;};
02952
02956 virtual void Schedule(void) = 0;
02957
02961 virtual char *getSyncName(void) = 0;
02962 };
02963
02972 class phTone
02973 {
02974 private:
02975 friend phTone *getphTone(const char *name);
02976 static phTone *first;
02977 static int ulaw[256];
02978 phTone *next;
02979 char name[33];
02980 unsigned char *samples;
02981 timeout_t duration;
02982 unsigned freq1, freq2;
02983
02984 public:
02992 phTone(const char *name, timeout_t duration, unsigned f);
02993
03002 phTone(const char *name, timeout_t duration, unsigned f1, unsigned f2);
03003
03004 ~phTone();
03005
03011 void Clear(void);
03012
03018 inline unsigned char *getSamples(void)
03019 {return samples;};
03020
03026 inline timeout_t getDuration(void)
03027 {return duration;};
03028 };
03029
03036 class TGI
03037 {
03038 private:
03039 static TGI *first;
03040 TGI *next;
03041
03042 protected:
03043 TGI();
03044
03052 virtual bool getExtension(char *ext)
03053 {return false;};
03054
03055 public:
03065 virtual void Script(char *cmd, char **args)
03066 {return;};
03067
03076 virtual int Parse(int fd, int port, char *cmd)
03077 {return -1;};
03078
03079 friend void getInterp(char *cmd, char **args);
03080 friend TGI *getInterp(char *cmd);
03081 };
03082
03083 extern Module *tts, *asr;
03084
03094 class Module
03095 {
03096 private:
03097 friend class Fifo;
03098 friend class AudioService;
03099 friend class TrunkGroup;
03100 friend class Network;
03101 friend class aaImage;
03102
03103 static Module *modFirst, *sesFirst, *cmdFirst, *urlFirst, *reqFirst, *netFirst;
03104 Module *modNext, *sesNext, *cmdNext, *urlNext, *reqNext, *netNext;
03105
03106 protected:
03107 Module();
03108
03109 inline Module *getFirst(void)
03110 {return modFirst;};
03111
03117 virtual const char *getExtension(void)
03118 {return NULL;};
03119
03125 virtual modtype_t getType(void) = 0;
03126
03130 void addSession(void);
03131
03135 void addCommand(void);
03136
03140 void addPrompts(void);
03141
03145 void addNetwork(void);
03146
03150 void addRequest(void);
03151
03155 inline void enableTTS(void)
03156 {tts = this;};
03157
03161 inline void enableASR(void)
03162 {asr = this;};
03163
03164
03165
03169 virtual char *getPrompt(const char *original)
03170 {return NULL;};
03171
03175 virtual void Expires(Request *request)
03176 {return;};
03177
03181 virtual void Running(Request *request)
03182 {return;};
03183
03187 virtual void Cancelled(Request *request)
03188 {return;};
03189
03199 virtual int Accept(char *buffer, socklen_t len, statnode_t *node)
03200 {return 0;};
03201
03207 virtual void Failover(statnode_t *node)
03208 {return;};
03209
03213 virtual void Broadcast(void)
03214 {return;};
03215
03216 friend void broadcast(char *msgbuf, unsigned msglen);
03217 friend void cancel(TrunkGroup *grp, const char *tag);
03218 public:
03219 inline Module *getNext(void)
03220 {return modNext;};
03221
03227 virtual char *getName(void) = 0;
03228
03236 virtual char *Dispatch(Trunk *trunk)
03237 {return NULL;};
03238
03246 virtual unsigned Sleep(Trunk *trunk)
03247 {return 0;};
03248
03255 virtual void Detach(Trunk *trunk)
03256 {return;};
03257
03265 virtual void Attach(Trunk *trunk)
03266 {return;};
03267
03274 virtual TrunkImage *getXML(void)
03275 {return NULL;};
03276
03284 virtual AudioSample *getPhrase(Trunk *trunk, const char *phrase)
03285 {return NULL;};
03286
03297 virtual const char *getSpeech(Trunk *trunk, char **domain, unsigned long mask, AudioSample *sample)
03298 {return NULL;};
03299
03303 virtual void Reload(void)
03304 {return;};
03305
03309 virtual bool Command(char **argv, ostream *out)
03310 {return false;};
03311
03312 friend Module *getModule(modtype_t mod, const char *name = NULL);
03313 friend void detachModules(Trunk *trunk);
03314 friend void attachModules(Trunk *trunk);
03315 };
03316
03326 class Session
03327 {
03328 private:
03329 friend class Scheduler;
03330 static Mutex mutex;
03331 static Session *first;
03332 static Session *last;
03333 Session *next, *prev;
03334 static void Clean(void);
03335
03336 protected:
03337 Session();
03338 virtual ~Session()
03339 {Unlink();};
03340
03344 void Unlink(void);
03345
03352 virtual time_t getExpires(void) = 0;
03353 };
03354
03363 class AudioFeed : private ThreadLock
03364 {
03365 private:
03366 static AudioFeed *first;
03367 AudioFeed *next;
03368 unsigned char *buffers;
03369 volatile unsigned char *current;
03370 size_t feedsize, bufsize;
03371 bool active;
03372
03373 protected:
03374 const char *name;
03375
03376 public:
03377 AudioFeed(const char *name, unsigned buffers);
03378 ~AudioFeed();
03379 bool Enable(void);
03380 void Disable(void);
03381 unsigned char *getBuffer(unsigned char *prior = NULL, unsigned size = 120);
03382 void putBuffer(unsigned char *buffer, unsigned size = 120);
03383
03384 friend AudioFeed *getAudioFeed(const char *name);
03385 };
03386
03395 class Map : private MemPager
03396 {
03397 private:
03398 static ThreadLock lock;
03399 static Map *first, *last;
03400
03401 typedef struct _sym
03402 {
03403 struct _sym *next;
03404 char *key;
03405 char **values;
03406 } mapsym_t;
03407
03408 typedef struct
03409 {
03410 mapsym_t *keys[127];
03411 } mapkey_t;
03412
03413 mapkey_t *digits[32];
03414
03415 Map *next, *prev;
03416 char *name;
03417
03418 unsigned getKey(const char *key, unsigned len = 0);
03419 char **getList(const char *key, unsigned len);
03420 ~Map();
03421
03422 public:
03423 Map(const char *path, const char *name);
03424
03425 friend char **getMap(const char *map, const char *key, mapmode_t mode);
03426 friend void endMaps(void);
03427 };
03428
03437 class Protocol : public Keydata, public InetHostAddress, public ThreadLock
03438 {
03439 private:
03440 friend class Resolver;
03441 static Protocol *first;
03442 Protocol *next;
03443 Semaphore *sessions;
03444 tpport_t port;
03445
03446 void Update(InetHostAddress addr);
03447 public:
03448 Protocol(const char *keypath, tpport_t port);
03449 ~Protocol();
03450
03456 InetHostAddress getAddress(void);
03457
03463 inline tpport_t getPort(void)
03464 {return port;};
03465
03472 inline Semaphore *getSessions(void)
03473 {return sessions;};
03474 };
03475
03476 statnode_t *getNodes(const char *name);
03477 timeout_t getTimeout(const char *string);
03478
03479 extern bool aliases;
03480 extern bool running;
03481 extern Keydata application;
03482 extern KeyServer keyserver;
03483 extern KeyThreads keythreads;
03484 extern KeyMemory keymemory;
03485 extern KeyPaths keypaths;
03486 extern KeyLocal keylocal;
03487 extern KeyNetwork keynetwork;
03488 extern KeyMailbox keymailbox;
03489 extern KeyProxy keyproxy;
03490 extern KeyTones keytones;
03491 extern KeyFeed keyfeed;
03492 extern KeyHandlers keyhandlers;
03493 extern Plugins plugins;
03494 extern Driver *driver;
03495 extern Debug *debug;
03496 extern Module *asr, *tts;
03497 extern Fifo fifo;
03498 #endif
03499