00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
#ifndef _VXML_H
00133
#define _VXML_H
00134
00135
#ifdef P_USE_PRAGMA
00136
#pragma interface
00137
#endif
00138
00139
#include <queue>
00140
00141
#include <ptlib/pipechan.h>
00142
00143
#include <ptclib/pxml.h>
00144
#include <ptclib/delaychan.h>
00145
#include <ptclib/pwavfile.h>
00146
#include <ptclib/ptts.h>
00147
#include <ptclib/url.h>
00148
00149
00150
class PVXMLSession;
00151
class PVXMLDialog;
00152
class PVXMLSession;
00153
00154
class PVXMLTransferOptions;
00155
class PVXMLTransferResult;
00156
00157 class PVXMLGrammar :
public PObject
00158 {
00159
PCLASSINFO(
PVXMLGrammar,
PObject);
00160
public:
00161
PVXMLGrammar(
PXMLElement *
field);
00162 virtual BOOL
OnUserInput(
const char ) {
return TRUE; }
00163 virtual void Stop() { }
00164
00165 PString GetValue()
const {
return value; }
00166 PXMLElement *
GetField() {
return field; }
00167
00168 enum GrammarState {
00169
FILLED,
00170
NOINPUT,
00171
NOMATCH,
00172
HELP };
00173
00174 GrammarState GetState()
const {
return state; }
00175
00176
protected:
00177 PXMLElement * field;
00178 PString value;
00179 GrammarState state;
00180 };
00181
00182
00184
00185 class PVXMLMenuGrammar :
public PVXMLGrammar
00186 {
00187
PCLASSINFO(
PVXMLMenuGrammar,
PVXMLGrammar);
00188
public:
00189
PVXMLMenuGrammar(
PXMLElement * field);
00190 };
00191
00192
00194
00195 class PVXMLDigitsGrammar :
public PVXMLGrammar
00196 {
00197
PCLASSINFO(
PVXMLDigitsGrammar,
PVXMLGrammar);
00198
public:
00199
PVXMLDigitsGrammar(
PXMLElement * field, PINDEX
minDigits, PINDEX
maxDigits,
PString terminators);
00200 BOOL
OnUserInput(
const char ch);
00201
virtual void Stop();
00202
00203
protected:
00204 PINDEX minDigits;
00205 PINDEX maxDigits;
00206 PString terminators;
00207 };
00208
00209
00211
00212 class PVXMLCacheItem :
public PURL
00213 {
00214
PCLASSINFO(
PVXMLCacheItem,
PURL);
00215
public:
00216 PVXMLCacheItem(
const PURL & url)
00217 :
PURL(url)
00218 { }
00219
00220 PFilePath fn;
00221 PString contentType;
00222 PTime loadTime;
00223 BOOL
ok;
00224 };
00225
00226
00227
PLIST(PVXMLCache,
PVXMLCacheItem);
00228
00230
00231
class PVXMLChannel;
00232
00233 class PVXMLChannelInterface {
00234
public:
00235
virtual PWAVFile *
CreateWAVFile(
const PFilePath & fn, PFile::OpenMode mode,
int opts,
unsigned fmt) = 0;
00236
virtual void RecordEnd() = 0;
00237
virtual void OnEndRecording(
const PString & channelName) = 0;
00238
virtual void Trigger() = 0;
00239 };
00240
00242
00243 class PVXMLSession :
public PIndirectChannel,
public PVXMLChannelInterface
00244 {
00245
PCLASSINFO(
PVXMLSession,
PIndirectChannel);
00246
public:
00247
PVXMLSession(
PTextToSpeech * tts = NULL, BOOL autoDelete = FALSE);
00248
~PVXMLSession();
00249
00250 void SetFinishWhenEmpty(BOOL v)
00251 {
finishWhenEmpty = v; }
00252
00253
00254
void SetTextToSpeech(
PTextToSpeech * _tts, BOOL autoDelete = FALSE);
00255
void SetTextToSpeech(
const PString & ttsName);
00256
00257
virtual BOOL Load(
const PString & source);
00258
virtual BOOL LoadFile(
const PFilePath & file);
00259
virtual BOOL LoadURL(
const PURL & url);
00260
virtual BOOL LoadVXML(
const PString & xml);
00261 virtual BOOL
IsLoaded()
const {
return loaded; }
00262
00263
virtual BOOL Open(BOOL isPCM);
00264
virtual BOOL Open(
00265
PVXMLChannel * in,
00266
PVXMLChannel * out
00267 );
00268
virtual BOOL
Close();
00269
00270 BOOL
Execute();
00271
00272 PVXMLChannel *
GetIncomingChannel()
const {
return incomingChannel; }
00273 PVXMLChannel *
GetOutgoingChannel()
const {
return outgoingChannel; }
00274
00275 BOOL LoadGrammar(
PVXMLGrammar * grammar);
00276
00277
virtual BOOL PlayText(
const PString & text, PTextToSpeech::TextType type = PTextToSpeech::Default, PINDEX repeat = 1, PINDEX delay = 0);
00278
virtual BOOL PlayFile(
const PString & fn, PINDEX repeat = 1, PINDEX delay = 0, BOOL autoDelete = FALSE);
00279
virtual BOOL PlayData(
const PBYTEArray & data, PINDEX repeat = 1, PINDEX delay = 0);
00280
virtual BOOL PlayCommand(
const PString & data, PINDEX repeat = 1, PINDEX delay = 0);
00281
virtual BOOL PlayResource(
const PURL & url, PINDEX repeat = 1, PINDEX delay = 0);
00282
virtual BOOL PlaySilence(PINDEX msecs = 0);
00283
virtual BOOL PlaySilence(
const PTimeInterval & timeout);
00284
virtual void SetPause(BOOL pause);
00285
virtual void GetBeepData(
PBYTEArray & data,
unsigned ms);
00286
00287
virtual BOOL StartRecording(
const PFilePath & fn, BOOL recordDTMFTerm,
const PTimeInterval & recordMaxTime,
const PTimeInterval & recordFinalSilence);
00288
virtual BOOL
EndRecording();
00289
virtual BOOL
IsPlaying() const;
00290 virtual BOOL IsRecording() const;
00291
00292 virtual BOOL OnUserInput(const
PString & str);
00293
00294
PString GetXMLError() const;
00295
00296 virtual
void OnEndSession() { }
00297
00298
virtual PString GetVar(
const PString & str)
const;
00299
virtual void SetVar(
const PString & ostr,
const PString & val);
00300
virtual PString PVXMLSession::EvaluateExpr(
const PString & oexpr);
00301
00302
virtual BOOL RetrieveResource(
const PURL & url,
PBYTEArray & text,
PString & contentType);
00303
virtual BOOL RetrieveResource(
const PURL & url,
PBYTEArray & text,
PString & contentType,
PFilePath & fn);
00304
00305
PDECLARE_NOTIFIER(
PThread,
PVXMLSession, VXMLExecute);
00306
00307 virtual BOOL
DoTransfer(
const PVXMLTransferOptions &) {
return TRUE; }
00308
virtual void OnTransfer(
const PVXMLTransferResult &);
00309
00310 void SetCallingToken(
PString& token ) { callingCallToken = token; }
00311
00312
PXMLElement * FindHandler(
const PString & event);
00313
00314
00315
PWAVFile * CreateWAVFile(
const PFilePath & fn, PFile::OpenMode mode,
int opts,
unsigned fmt);
00316
void OnEndRecording(
const PString & channelName);
00317
void RecordEnd();
00318
void Trigger();
00319
00320
protected:
00321
void Initialise();
00322
00323
void AllowClearCall();
00324
void ProcessUserInput();
00325
void ProcessNode();
00326
void ProcessGrammar();
00327
00328 BOOL
TraverseAudio();
00329 BOOL
TraverseGoto();
00330 BOOL
TraverseGrammar();
00331 BOOL
TraverseRecord();
00332
00333 BOOL
TraverseIf();
00334 BOOL
TraverseExit();
00335 BOOL
TraverseVar();
00336 BOOL
TraverseSubmit();
00337 BOOL
TraverseMenu();
00338 BOOL TraverseChoice(
const PString & grammarResult);
00339
00340
void SayAs(
const PString & className,
const PString & text);
00341
static PTimeInterval StringToTime(
const PString & str);
00342
00343
PURL NormaliseResourceName(
const PString & src);
00344
00345
PXMLElement * FindForm(
const PString &
id);
00346
00347
virtual BOOL
TraverseTransfer();
00348
00349
00350
00351 PSyncPoint waitForEvent;
00352
00353 PMutex sessionMutex;
00354
00355 PXML xmlFile;
00356
00357 PVXMLGrammar *
activeGrammar;
00358 BOOL
listening;
00359 int timeout;
00360
00361 PStringToString sessionVars;
00362 PStringToString documentVars;
00363
00364 PMutex userInputMutex;
00365 std::queue<char>
userInputQueue;
00366
00367 BOOL
recording;
00368 PFilePath recordFn;
00369 BOOL
recordDTMFTerm;
00370 PTimeInterval recordMaxTime;
00371 PTimeInterval recordFinalSilence;
00372 PSyncPoint recordSync;
00373
00374 BOOL
loaded;
00375 BOOL
finishWhenEmpty;
00376 BOOL
allowFinish;
00377 PURL rootURL;
00378 BOOL
emptyAction;
00379
00380 PThread *
vxmlThread;
00381 BOOL
threadRunning;
00382 BOOL
forceEnd;
00383
00384 PVXMLChannel *
incomingChannel;
00385 PVXMLChannel *
outgoingChannel;
00386
00387 PTextToSpeech *
textToSpeech;
00388 BOOL
autoDeleteTextToSpeech;
00389
00390 PXMLElement *
currentForm;
00391 PXMLElement *
currentField;
00392 PXMLObject *
currentNode;
00393
00394 static PMutex cacheMutex;
00395 static PDirectory cacheDir;
00396 static PVXMLCache *
resourceCache;
00397 static PINDEX
cacheCount;
00398
00399
private:
00400
void ExecuteDialog();
00401
00402
PString callingCallToken;
00403
PSyncPoint transferSync;
00404
PSyncPoint answerSync;
00405
PString grammarResult;
00406
PString eventName;
00407 PINDEX defaultDTMF;
00408 };
00409
00410
00412
00413 class PVXMLQueueItem :
public PObject
00414 {
00415
PCLASSINFO(
PVXMLQueueItem,
PObject);
00416
public:
00417 PVXMLQueueItem(PINDEX _repeat = 1, PINDEX _delay = 0)
00418 :
repeat(_repeat),
delay(_delay)
00419 { }
00420
00421
virtual void Play(
PVXMLChannel & outgoingChannel) = 0;
00422
00423 virtual void OnStart() { }
00424 virtual void OnStop() { }
00425
00426 PINDEX
repeat;
00427 PINDEX
delay;
00428 };
00429
00430
00432
00433 class PVXMLQueueDataItem :
public PVXMLQueueItem
00434 {
00435
PCLASSINFO(
PVXMLQueueDataItem,
PVXMLQueueItem);
00436
public:
00437 PVXMLQueueDataItem(
const PBYTEArray & _data, PINDEX repeat = 1, PINDEX delay = 0)
00438 :
PVXMLQueueItem(repeat, delay),
data(_data)
00439 { }
00440
00441
void Play(
PVXMLChannel & outgoingChannel);
00442
00443
protected:
00444 PBYTEArray data;
00445 };
00446
00447 class PVXMLQueueChannelItem :
public PVXMLQueueItem
00448 {
00449
PCLASSINFO(
PVXMLQueueChannelItem,
PVXMLQueueItem);
00450
public:
00451 PVXMLQueueChannelItem(PINDEX repeat = 1, PINDEX delay = 0, BOOL _autoDelete = FALSE)
00452 :
PVXMLQueueItem(repeat, delay),
autoDelete(_autoDelete)
00453 { }
00454
00455
protected:
00456 BOOL
autoDelete;
00457 };
00458
00459
00460 class PVXMLQueueFilenameItem :
public PVXMLQueueChannelItem
00461 {
00462
PCLASSINFO(
PVXMLQueueFilenameItem,
PVXMLQueueChannelItem);
00463
public:
00464 PVXMLQueueFilenameItem(
const PFilePath & _fn, PINDEX _repeat = 1, PINDEX _delay = 0, BOOL _autoDelete = FALSE)
00465 :
PVXMLQueueChannelItem(_repeat, _delay, _autoDelete),
fn(_fn)
00466 { }
00467
00468
void Play(
PVXMLChannel & outgoingChannel);
00469
void OnStop();
00470
00471
protected:
00472 PFilePath fn;
00473 };
00474
00475 class PVXMLQueueCommandItem :
public PVXMLQueueChannelItem
00476 {
00477
PCLASSINFO(
PVXMLQueueCommandItem,
PVXMLQueueChannelItem);
00478
public:
00479 PVXMLQueueCommandItem(
const PString & _cmd,
const PString & _fmt,
unsigned _freq, PINDEX _repeat = 1, PINDEX _delay = 0, BOOL _autoDelete = FALSE)
00480 :
PVXMLQueueChannelItem(_repeat, _delay, _autoDelete),
cmd(_cmd),
format(_fmt),
sampleFrequency(_freq)
00481 {
pipeCmd = NULL; }
00482
00483
void Play(
PVXMLChannel & outgoingChannel);
00484
void OnStop();
00485
00486
protected:
00487 PPipeChannel *
pipeCmd;
00488 PString cmd;
00489 PString format;
00490 unsigned sampleFrequency;
00491 };
00492
00493 class PVXMLQueueURLItem :
public PVXMLQueueItem
00494 {
00495
PCLASSINFO(
PVXMLQueueURLItem,
PObject);
00496
public:
00497 PVXMLQueueURLItem(
const PURL & _url, PINDEX repeat = 1, PINDEX delay = 0)
00498 :
PVXMLQueueItem(repeat, delay),
url(_url)
00499 { }
00500
00501
void Play(
PVXMLChannel & outgoingChannel);
00502
00503
protected:
00504 PURL url;
00505 };
00506
00507
00508
PQUEUE(PVXMLQueue,
PVXMLQueueItem);
00509
00511
00512 class PVXMLChannel :
public PIndirectChannel
00513 {
00514
PCLASSINFO(
PVXMLChannel,
PIndirectChannel);
00515
public:
00516
PVXMLChannel(
00517
PVXMLChannelInterface & _vxml,
00518 BOOL incoming,
00519
const PString & fmtName,
00520 PINDEX
frameBytes,
00521
unsigned frameTime,
00522
unsigned wavFileType,
00523
const PString &
wavFilePrefix
00524 );
00525
~PVXMLChannel();
00526
00527
00528
virtual BOOL
IsOpen()
const;
00529
virtual BOOL
Close();
00530
virtual BOOL
Read(
void * buffer, PINDEX amount);
00531
virtual BOOL
Write(
const void * buf, PINDEX len);
00532
00533
00534
virtual PWAVFile *
CreateWAVFile(
const PFilePath & fn);
00535 PWAVFile *
GetWAVFile()
const
00536
{
return wavFile; }
00537
00538 const PString &
GetFormatName()
const {
return formatName; }
00539 BOOL
IsMediaPCM()
const {
return formatName ==
"PCM-16"; }
00540 unsigned GetWavFileType()
const {
return wavFileType; }
00541
virtual PString AdjustWavFilename(
const PString & fn);
00542
00543
00544
virtual BOOL WriteFrame(
const void * buf, PINDEX len) = 0;
00545
virtual BOOL IsSilenceFrame(
const void * buf, PINDEX len)
const = 0;
00546
00547 BOOL StartRecording(
const PFilePath & fn,
unsigned finalSilence = 2000);
00548 BOOL
EndRecording();
00549 BOOL
IsRecording()
const {
return recording; }
00550
00551
00552
virtual BOOL ReadFrame(
void * buffer, PINDEX amount) = 0;
00553
virtual PINDEX CreateSilenceFrame(
void * buffer, PINDEX amount) = 0;
00554 virtual void GetBeepData(
PBYTEArray &,
unsigned) { }
00555
00556
virtual void QueueFile(
const PString & fn, PINDEX repeat = 1, PINDEX delay = 0, BOOL autoDelete = FALSE);
00557
virtual void QueueResource(
const PURL & url, PINDEX repeat= 1, PINDEX delay = 0);
00558
virtual void QueueData(
const PBYTEArray & data, PINDEX repeat = 1, PINDEX delay = 0);
00559
virtual void QueueCommand(
const PString & data, PINDEX repeat = 1, PINDEX delay = 0);
00560
00561
virtual void QueueItem(
PVXMLQueueItem * newItem);
00562
virtual void FlushQueue();
00563 virtual BOOL
IsPlaying()
const {
return (
playQueue.GetSize() > 0) ||
playing ; }
00564
00565 void SetPause(BOOL _pause) {
paused = _pause; }
00566
00567
virtual void HandleDelay(PINDEX amount);
00568
00569 void SetName(
const PString & name) {
channelName = name; }
00570
00571
protected:
00572 PVXMLChannelInterface &
vxmlInterface;
00573 BOOL
isIncoming;
00574 PString formatName;
00575 unsigned sampleFrequency;
00576 PINDEX frameBytes;
00577 unsigned frameTime;
00578 unsigned wavFileType;
00579 PString wavFilePrefix;
00580
00581 PMutex channelMutex;
00582 PAdaptiveDelay delay;
00583 BOOL
closed;
00584 PINDEX
delayBytes;
00585
00586
00587 BOOL
recording;
00588 PWAVFile *
wavFile;
00589 unsigned finalSilence;
00590 unsigned silenceRun;
00591
00592
00593 BOOL
playing;
00594 PMutex queueMutex;
00595 PVXMLQueue
playQueue;
00596
00597 BOOL
paused;
00598 int silentCount;
00599 int totalData;
00600 PTimer delayTimer;
00601
00602
00603
00604 PString channelName;
00605 };
00606
00607
00609
00610 class PVXMLChannelPCM :
public PVXMLChannel
00611 {
00612
PCLASSINFO(
PVXMLChannelPCM,
PVXMLChannel);
00613
00614
public:
00615
PVXMLChannelPCM(
PVXMLSession & vxml, BOOL incoming);
00616
00617
protected:
00618
00619
virtual BOOL
WriteFrame(
const void * buf, PINDEX len);
00620
virtual BOOL
ReadFrame(
void * buffer, PINDEX amount);
00621
virtual PINDEX
CreateSilenceFrame(
void * buffer, PINDEX amount);
00622
virtual BOOL
IsSilenceFrame(
const void * buf, PINDEX len)
const;
00623
virtual void GetBeepData(
PBYTEArray & data,
unsigned ms);
00624
virtual void HandleDelay(PINDEX amount);
00625 };
00626
00627
00628 class PVXMLChannelG7231 :
public PVXMLChannel
00629 {
00630
PCLASSINFO(
PVXMLChannelG7231,
PVXMLChannel);
00631
public:
00632
PVXMLChannelG7231(
PVXMLSession & vxml, BOOL incoming);
00633
00634
00635
virtual BOOL
WriteFrame(
const void * buf, PINDEX len);
00636
virtual BOOL
ReadFrame(
void * buffer, PINDEX amount);
00637
virtual PINDEX
CreateSilenceFrame(
void * buffer, PINDEX amount);
00638
virtual BOOL
IsSilenceFrame(
const void * buf, PINDEX len)
const;
00639 };
00640
00641
00642 class PVXMLChannelG729 :
public PVXMLChannel
00643 {
00644
PCLASSINFO(
PVXMLChannelG729,
PVXMLChannel);
00645
public:
00646
PVXMLChannelG729(
PVXMLSession & vxml, BOOL incoming);
00647
00648
00649
virtual BOOL
WriteFrame(
const void * buf, PINDEX len);
00650
virtual BOOL
ReadFrame(
void * buffer, PINDEX amount);
00651
virtual PINDEX
CreateSilenceFrame(
void * buffer, PINDEX amount);
00652
virtual BOOL
IsSilenceFrame(
const void * buf, PINDEX len)
const;
00653 };
00654
00656
00657 class PVXMLTransferOptions :
public PObject
00658 {
00659
PCLASSINFO(
PVXMLTransferOptions,
PObject);
00660
public:
00661 PVXMLTransferOptions() { }
00662
00663 void SetCallingToken(
const PString & calling) { callingToken = calling; }
00664 PString GetCallingToken()
const {
return callingToken; }
00665
00666 void SetCalledToken(
const PString & called) { calledToken = called; }
00667 PString GetCalledToken( )
const {
return calledToken; }
00668
00669 void SetSourceDNR(
const PString & src) { source = src; }
00670 PString GetSourceDNR()
const {
return source; }
00671
00672 void SetDestinationDNR(
const PString & dest ) { destination = dest; }
00673 PString GetDestinationDNR()
const {
return destination; }
00674
00675 void SetTimeout(
unsigned int time) { timeout = time; }
00676 unsigned int GetTimeout()
const {
return timeout; }
00677
00678 void SetBridge(BOOL brdg) { bridge = brdg; }
00679 BOOL
GetBridge()
const {
return bridge; }
00680
00681
private:
00682
PString callingToken;
00683
PString calledToken;
00684
PString destination;
00685
PString source;
00686
unsigned int timeout;
00687 BOOL bridge;
00688 };
00689
00690 class PVXMLTransferResult :
public PString
00691 {
00692
PCLASSINFO(
PVXMLTransferResult,
PString);
00693
public:
00694 PVXMLTransferResult()
00695 { }
00696
00697 PVXMLTransferResult(
char * cstr)
00698 :
PString( cstr )
00699 { }
00700
00701 PVXMLTransferResult(
const PString & str )
00702 :
PString(str)
00703 {}
00704
00705 void SetName(
const PString & n)
00706 { name = n; }
00707
00708 PString GetName()
const
00709
{
return name; }
00710
00711
private:
00712
PString name;
00713 };
00714
00715
#endif
00716
00717
00718