PTLib Version 2.12.9

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
vxml.h
Go to the documentation of this file.
1 /*
2 * vxml.h
3 *
4 * VXML engine for pwlib library
5 *
6 * Copyright (C) 2002 Equivalence Pty. Ltd.
7 *
8 * The contents of this file are subject to the Mozilla Public License
9 * Version 1.0 (the "License"); you may not use this file except in
10 * compliance with the License. You may obtain a copy of the License at
11 * http://www.mozilla.org/MPL/
12 *
13 * Software distributed under the License is distributed on an "AS IS"
14 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
15 * the License for the specific language governing rights and limitations
16 * under the License.
17 *
18 * The Original Code is Portable Windows Library.
19 *
20 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
21 *
22 * Contributor(s): ______________________________________.
23 *
24 * $Revision: 30043 $
25 * $Author: rjongbloed $
26 * $Date: 2013-06-25 12:34:24 +1000 (Tue, 25 Jun 2013) $
27 */
28
29 #ifndef PTLIB_VXML_H
30 #define PTLIB_VXML_H
31
32 #ifdef P_USE_PRAGMA
33 #pragma interface
34 #endif
35
36
37 #include <ptclib/pxml.h>
38
39 #if P_VXML
40
41 #include <ptlib/pfactory.h>
42 #include <ptlib/pipechan.h>
43 #include <ptclib/delaychan.h>
44 #include <ptclib/pwavfile.h>
45 #include <ptclib/ptts.h>
46 #include <ptclib/url.h>
47
48 #include <queue>
49
50
51 class PVXMLSession;
52 class PVXMLDialog;
53 class PVXMLSession;
54
55 // these are the same strings as the Opal equivalents, but as this is PWLib, we can't use Opal contants
56 #define VXML_PCM16 "PCM-16"
57 #define VXML_G7231 "G.723.1"
58 #define VXML_G729 "G.729"
59
60
62
63 class PVXMLGrammar : public PObject
64 {
65 PCLASSINFO(PVXMLGrammar, PObject);
66 public:
67 PVXMLGrammar(PVXMLSession & session, PXMLElement & field);
68
69 virtual void OnUserInput(const char ch) = 0;
70 virtual void Start();
71 virtual bool Process();
72
73 enum GrammarState {
74 Idle,
75 Started,
76 Filled,
77 NoInput,
78 NoMatch,
79 Help
80 };
81
82 GrammarState GetState() const { return m_state; }
83
84 void SetSessionTimeout();
85 void SetTimeout(const PTimeInterval & timeout);
86
87 protected:
88 PDECLARE_NOTIFIER(PTimer, PVXMLGrammar, OnTimeout);
89
90 PVXMLSession & m_session;
91 PXMLElement & m_field;
92 PString m_value;
93 GrammarState m_state;
94 PTimeInterval m_timeout;
95 PTimer m_timer;
96 PMutex m_mutex;
97 };
98
99
101
102 class PVXMLMenuGrammar : public PVXMLGrammar
103 {
104 PCLASSINFO(PVXMLMenuGrammar, PVXMLGrammar);
105 public:
106 PVXMLMenuGrammar(PVXMLSession & session, PXMLElement & field);
107 virtual void OnUserInput(const char ch);
108 virtual bool Process();
109 };
110
111
113
114 class PVXMLDigitsGrammar : public PVXMLGrammar
115 {
116 PCLASSINFO(PVXMLDigitsGrammar, PVXMLGrammar);
117 public:
118 PVXMLDigitsGrammar(
119 PVXMLSession & session,
120 PXMLElement & field,
121 PINDEX minDigits,
122 PINDEX maxDigits,
123 PString terminators
124 );
125
126 virtual void OnUserInput(const char ch);
127
128 protected:
129 PINDEX m_minDigits;
130 PINDEX m_maxDigits;
131 PString m_terminators;
132 };
133
134
136
137 class PVXMLCache : public PSafeObject
138 {
139 public:
140 PVXMLCache();
141
142 virtual bool Get(
143 const PString & prefix,
144 const PString & key,
145 const PString & fileType,
146 PFilePath & filename
147 );
148
149 virtual bool PutWithLock(
150 const PString & prefix,
151 const PString & key,
152 const PString & fileType,
153 PFile & file
154 );
155
156 void SetDirectory(
157 const PDirectory & directory
158 );
159
160 const PDirectory & GetDirectory() const
161 { return m_directory; }
162
163 protected:
164 virtual PFilePath CreateFilename(
165 const PString & prefix,
166 const PString & key,
167 const PString & fileType
168 );
169
170 PDirectory m_directory;
171 };
172
174
175 class PVXMLChannel;
176
177 class PVXMLSession : public PIndirectChannel
178 {
179 PCLASSINFO(PVXMLSession, PIndirectChannel);
180 public:
181 PVXMLSession(PTextToSpeech * tts = NULL, PBoolean autoDelete = false);
182 virtual ~PVXMLSession();
183
184 // new functions
185 PTextToSpeech * SetTextToSpeech(PTextToSpeech * tts, PBoolean autoDelete = false);
186 PTextToSpeech * SetTextToSpeech(const PString & ttsName);
187 PTextToSpeech * GetTextToSpeech() const { return m_textToSpeech; }
188
189 void SetCache(PVXMLCache & cache);
190 PVXMLCache & GetCache();
191
192 void SetRecordDirectory(const PDirectory & dir) { m_recordDirectory = dir; }
193 const PDirectory & GetRecordDirectory() const { return m_recordDirectory; }
194
195 virtual PBoolean Load(const PString & source);
196 virtual PBoolean LoadFile(const PFilePath & file, const PString & firstForm = PString::Empty());
197 virtual PBoolean LoadURL(const PURL & url);
198 virtual PBoolean LoadVXML(const PString & xml, const PString & firstForm = PString::Empty());
199 virtual PBoolean IsLoaded() const { return m_xml.IsLoaded(); }
200
201 virtual PBoolean Open(const PString & mediaFormat);
202 virtual PBoolean Close();
203
204 virtual PBoolean Execute();
205
206 PVXMLChannel * GetAndLockVXMLChannel();
207 void UnLockVXMLChannel() { m_sessionMutex.Signal(); }
208 PMutex & GetSessionMutex() { return m_sessionMutex; }
209
210 virtual PBoolean LoadGrammar(PVXMLGrammar * grammar);
211
212 virtual PBoolean PlayText(const PString & text, PTextToSpeech::TextType type = PTextToSpeech::Default, PINDEX repeat = 1, PINDEX delay = 0);
213
214 virtual PBoolean PlayFile(const PString & fn, PINDEX repeat = 1, PINDEX delay = 0, PBoolean autoDelete = false);
215 virtual PBoolean PlayData(const PBYTEArray & data, PINDEX repeat = 1, PINDEX delay = 0);
216 virtual PBoolean PlayCommand(const PString & data, PINDEX repeat = 1, PINDEX delay = 0);
217 virtual PBoolean PlayResource(const PURL & url, PINDEX repeat = 1, PINDEX delay = 0);
218 virtual PBoolean PlayTone(const PString & toneSpec, PINDEX repeat = 1, PINDEX delay = 0);
219 virtual PBoolean PlayElement(PXMLElement & element);
220
221 //virtual PBoolean PlayMedia(const PURL & url, PINDEX repeat = 1, PINDEX delay = 0);
222 virtual PBoolean PlaySilence(PINDEX msecs = 0);
223 virtual PBoolean PlaySilence(const PTimeInterval & timeout);
224
225 virtual PBoolean PlayStop();
226
227 virtual void SetPause(PBoolean pause);
228 virtual void GetBeepData(PBYTEArray & data, unsigned ms);
229
230 virtual void OnUserInput(const PString & str);
231
232 PString GetXMLError() const;
233
234 virtual void OnEndDialog();
235 virtual void OnEndSession();
236
237 enum TransferType {
238 BridgedTransfer,
239 BlindTransfer,
240 ConsultationTransfer
241 };
242 virtual bool OnTransfer(const PString & /*destination*/, TransferType /*type*/) { return false; }
243 void SetTransferComplete(bool state);
244
245 const PStringToString & GetVariables() { return m_variables; }
246 virtual PCaselessString GetVar(const PString & str) const;
247 virtual void SetVar(const PString & ostr, const PString & val);
248 virtual PString EvaluateExpr(const PString & oexpr);
249
250 static PTimeInterval StringToTime(const PString & str, int dflt = 0);
251
252 PDECLARE_NOTIFIER(PThread, PVXMLSession, VXMLExecute);
253
254 bool SetCurrentForm(const PString & id, bool fullURI);
255 bool GoToEventHandler(PXMLElement & element, const PString & eventName);
256
257 // overrides from VXMLChannelInterface
258 virtual void OnEndRecording(PINDEX bytesRecorded, bool timedOut);
259 virtual void Trigger();
260
261
262 virtual PBoolean TraverseAudio(PXMLElement & element);
263 virtual PBoolean TraverseBreak(PXMLElement & element);
264 virtual PBoolean TraverseValue(PXMLElement & element);
265 virtual PBoolean TraverseSayAs(PXMLElement & element);
266 virtual PBoolean TraverseGoto(PXMLElement & element);
267 virtual PBoolean TraverseGrammar(PXMLElement & element);
268 virtual PBoolean TraverseRecord(PXMLElement & element);
269 virtual PBoolean TraversedRecord(PXMLElement & element);
270 virtual PBoolean TraverseIf(PXMLElement & element);
271 virtual PBoolean TraverseExit(PXMLElement & element);
272 virtual PBoolean TraverseVar(PXMLElement & element);
273 virtual PBoolean TraverseSubmit(PXMLElement & element);
274 virtual PBoolean TraverseMenu(PXMLElement & element);
275 virtual PBoolean TraversedMenu(PXMLElement & element);
276 virtual PBoolean TraverseChoice(PXMLElement & element);
277 virtual PBoolean TraverseProperty(PXMLElement & element);
278 virtual PBoolean TraverseDisconnect(PXMLElement & element);
279 virtual PBoolean TraverseForm(PXMLElement & element);
280 virtual PBoolean TraversedForm(PXMLElement & element);
281 virtual PBoolean TraversePrompt(PXMLElement & element);
282 virtual PBoolean TraversedPrompt(PXMLElement & element);
283 virtual PBoolean TraverseField(PXMLElement & element);
284 virtual PBoolean TraversedField(PXMLElement & element);
285 virtual PBoolean TraverseTransfer(PXMLElement & element);
286 virtual PBoolean TraversedTransfer(PXMLElement & element);
287
288 __inline PVXMLChannel * GetVXMLChannel() const { return (PVXMLChannel *)readChannel; }
289
290 protected:
291 virtual bool InternalLoadVXML(const PString & xml, const PString & firstForm);
292
293 virtual bool ProcessNode();
294 virtual bool ProcessEvents();
295 virtual bool ProcessGrammar();
296 virtual bool NextNode(bool processChildren);
297
298 void SayAs(const PString & className, const PString & text);
299 void SayAs(const PString & className, const PString & text, const PString & voice);
300
301 PURL NormaliseResourceName(const PString & src);
302
303 PMutex m_sessionMutex;
304
305 PURL m_rootURL;
306 PXML m_xml;
307
308 PTextToSpeech * m_textToSpeech;
309 PVXMLCache * m_ttsCache;
310 bool m_autoDeleteTextToSpeech;
311
312 PThread * m_vxmlThread;
313 bool m_abortVXML;
314 PSyncPoint m_waitForEvent;
315 PXMLObject * m_currentNode;
316 bool m_xmlChanged;
317 bool m_speakNodeData;
318 bool m_bargeIn;
319 bool m_bargingIn;
320
321 PVXMLGrammar * m_grammar;
322 char m_defaultMenuDTMF;
323
324 PStringToString m_variables;
325 PString m_variableScope;
326
327 std::queue<char> m_userInputQueue;
328 PMutex m_userInputMutex;
329
330 enum {
331 NotRecording,
332 RecordingInProgress,
333 RecordingComplete
334 } m_recordingStatus;
335 bool m_recordStopOnDTMF;
336 PString m_recordingName;
337 PTime m_recordingStartTime;
338 PDirectory m_recordDirectory;
339
340 enum {
341 NotTransfering,
342 TransferInProgress,
343 TransferFailed,
344 TransferSuccessful
345 } m_transferStatus;
346 PTime m_transferStartTime;
347 };
348
349
351
352 class PVXMLRecordable : public PObject
353 {
354 PCLASSINFO(PVXMLRecordable, PObject);
355 public:
356 PVXMLRecordable();
357
358 virtual PBoolean Open(const PString & arg) = 0;
359
360 virtual bool OnStart(PVXMLChannel & incomingChannel) = 0;
361 virtual void OnStop() { }
362
363 virtual PBoolean OnFrame(PBoolean /*isSilence*/) { return false; }
364
365 const PTimeInterval & GetFinalSilence() const { return m_finalSilence; }
366 void SetFinalSilence(const PTimeInterval & v) { m_finalSilence = v > 0 ? v : 60000; }
367
368 const PTimeInterval & GetMaxDuration() const { return m_maxDuration; }
369 void SetMaxDuration(const PTimeInterval & v) { m_maxDuration = v > 0 ? v : 86400000; }
370
371 protected:
372 PSimpleTimer m_silenceTimer;
373 PSimpleTimer m_recordTimer;
374 PTimeInterval m_finalSilence;
375 PTimeInterval m_maxDuration;
376 };
377
379
380 class PVXMLRecordableFilename : public PVXMLRecordable
381 {
382 PCLASSINFO(PVXMLRecordableFilename, PVXMLRecordable);
383 public:
384 PBoolean Open(const PString & arg);
385 bool OnStart(PVXMLChannel & incomingChannel);
386 PBoolean OnFrame(PBoolean isSilence);
387
388 protected:
389 PFilePath m_fileName;
390 };
391
393
394 class PVXMLPlayable : public PObject
395 {
396 PCLASSINFO(PVXMLPlayable, PObject);
397 public:
398 PVXMLPlayable();
399
400 virtual PBoolean Open(PVXMLChannel & chan, const PString & arg, PINDEX delay, PINDEX repeat, PBoolean autoDelete);
401
402 virtual bool OnStart() = 0;
403 virtual bool OnRepeat();
404 virtual bool OnDelay();
405 virtual void OnStop();
406
407 virtual void SetRepeat(PINDEX v)
408 { m_repeat = v; }
409
410 virtual PINDEX GetRepeat() const
411 { return m_repeat; }
412
413 virtual PINDEX GetDelay() const
414 { return m_delay; }
415
416 void SetFormat(const PString & fmt)
417 { m_format = fmt; }
418
419 void SetSampleFrequency(unsigned rate)
420 { m_sampleFrequency = rate; }
421
422 friend class PVXMLChannel;
423
424 protected:
425 PVXMLChannel * m_vxmlChannel;
426 PChannel * m_subChannel;
427 PINDEX m_repeat;
428 PINDEX m_delay;
429 PString m_format;
430 unsigned m_sampleFrequency;
431 bool m_autoDelete;
432 bool m_delayDone; // very tacky flag used to indicate when the post-play delay has been done
433 };
434
436
437 class PVXMLPlayableStop : public PVXMLPlayable
438 {
439 PCLASSINFO(PVXMLPlayableStop, PVXMLPlayable);
440 public:
441 virtual bool OnStart();
442 };
443
445
446 class PVXMLPlayableURL : public PVXMLPlayable
447 {
448 PCLASSINFO(PVXMLPlayableURL, PVXMLPlayable);
449 public:
450 virtual PBoolean Open(PVXMLChannel & chan, const PString & arg, PINDEX delay, PINDEX repeat, PBoolean autoDelete);
451 virtual bool OnStart();
452 protected:
453 PURL m_url;
454 };
455
457
458 class PVXMLPlayableData : public PVXMLPlayable
459 {
460 PCLASSINFO(PVXMLPlayableData, PVXMLPlayable);
461 public:
462 virtual PBoolean Open(PVXMLChannel & chan, const PString & arg, PINDEX delay, PINDEX repeat, PBoolean autoDelete);
463 void SetData(const PBYTEArray & data);
464 virtual bool OnStart();
465 virtual bool OnRepeat();
466 protected:
467 PBYTEArray m_data;
468 };
469
471
472 #if P_DTMF
473
474 #include <ptclib/dtmf.h>
475
476 class PVXMLPlayableTone : public PVXMLPlayableData
477 {
478 PCLASSINFO(PVXMLPlayableTone, PVXMLPlayableData);
479 public:
480 virtual PBoolean Open(PVXMLChannel & chan, const PString & arg, PINDEX delay, PINDEX repeat, PBoolean autoDelete);
481 protected:
482 PTones m_tones;
483 };
484
485 #endif // P_DTMF
486
487
489
490 class PVXMLPlayableCommand : public PVXMLPlayable
491 {
492 PCLASSINFO(PVXMLPlayableCommand, PVXMLPlayable);
493 public:
494 virtual PBoolean Open(PVXMLChannel & chan, const PString & arg, PINDEX delay, PINDEX repeat, PBoolean autoDelete);
495 virtual bool OnStart();
496 virtual void OnStop();
497
498 protected:
499 PString m_command;
500 };
501
503
504 class PVXMLPlayableFile : public PVXMLPlayable
505 {
506 PCLASSINFO(PVXMLPlayableFile, PVXMLPlayable);
507 public:
508 virtual PBoolean Open(PVXMLChannel & chan, const PString & arg, PINDEX delay, PINDEX repeat, PBoolean autoDelete);
509 virtual bool OnStart();
510 virtual bool OnRepeat();
511 virtual void OnStop();
512 protected:
513 PFilePath m_filePath;
514 };
515
517
518 class PVXMLPlayableFileList : public PVXMLPlayableFile
519 {
520 PCLASSINFO(PVXMLPlayableFileList, PVXMLPlayableFile);
521 public:
522 PVXMLPlayableFileList();
523 virtual PBoolean Open(PVXMLChannel & chan, const PString & arg, PINDEX delay, PINDEX repeat, PBoolean autoDelete);
524 virtual PBoolean Open(PVXMLChannel & chan, const PStringArray & filenames, PINDEX delay, PINDEX repeat, PBoolean autoDelete);
525 virtual bool OnStart();
526 virtual bool OnRepeat();
527 virtual void OnStop();
528 protected:
529 PStringArray m_fileNames;
530 PINDEX m_currentIndex;
531 };
532
534
535 PQUEUE(PVXMLQueue, PVXMLPlayable);
536
538
539 class PVXMLChannel : public PDelayChannel
540 {
541 PCLASSINFO(PVXMLChannel, PDelayChannel);
542 public:
543 PVXMLChannel(unsigned frameDelay, PINDEX frameSize);
544 ~PVXMLChannel();
545
546 virtual PBoolean Open(PVXMLSession * session);
547
548 // overrides from PIndirectChannel
549 virtual PBoolean IsOpen() const;
550 virtual PBoolean Close();
551 virtual PBoolean Read(void * buffer, PINDEX amount);
552 virtual PBoolean Write(const void * buf, PINDEX len);
553
554 #if P_WAVFILE
555 // new functions
556 virtual PWAVFile * CreateWAVFile(const PFilePath & fn, PBoolean recording = false);
557 #endif
558
559 const PString & GetMediaFormat() const { return mediaFormat; }
560 PBoolean IsMediaPCM() const { return mediaFormat == "PCM-16"; }
561 virtual PString AdjustWavFilename(const PString & fn);
562
563 // Incoming channel functions
564 virtual PBoolean WriteFrame(const void * buf, PINDEX len) = 0;
565 virtual PBoolean IsSilenceFrame(const void * buf, PINDEX len) const = 0;
566
567 virtual bool QueueRecordable(PVXMLRecordable * newItem);
568 bool EndRecording(bool timedOut);
569 bool IsRecording() const { return m_recordable != NULL; }
570
571 // Outgoing channel functions
572 virtual PBoolean ReadFrame(void * buffer, PINDEX amount) = 0;
573 virtual PINDEX CreateSilenceFrame(void * buffer, PINDEX amount) = 0;
574 virtual void GetBeepData(PBYTEArray &, unsigned) { }
575
576 virtual PBoolean QueueResource(const PURL & url, PINDEX repeat= 1, PINDEX delay = 0);
577
578 virtual PBoolean QueuePlayable(const PString & type, const PString & str, PINDEX repeat = 1, PINDEX delay = 0, PBoolean autoDelete = false);
579 virtual PBoolean QueuePlayable(PVXMLPlayable * newItem);
580 virtual PBoolean QueueData(const PBYTEArray & data, PINDEX repeat = 1, PINDEX delay = 0);
581
582 virtual PBoolean QueueFile(const PString & fn, PINDEX repeat = 1, PINDEX delay = 0, PBoolean autoDelete = false)
583 { return QueuePlayable("File", fn, repeat, delay, autoDelete); }
584
585 virtual PBoolean QueueCommand(const PString & cmd, PINDEX repeat = 1, PINDEX delay = 0)
586 { return QueuePlayable("Command", cmd, repeat, delay, true); }
587
588 virtual void FlushQueue();
589 virtual PBoolean IsPlaying() const { return m_currentPlayItem != NULL || m_playQueue.GetSize() > 0; }
590
591 void SetPause(PBoolean pause) { m_paused = pause; }
592
593 unsigned GetSampleFrequency() const { return m_sampleFrequency; }
594
595 void SetSilence(unsigned msecs);
596
597 protected:
598 PVXMLSession * m_vxmlSession;
599
600 unsigned m_sampleFrequency;
601 PString mediaFormat;
602 PString wavFilePrefix;
603
604 PMutex m_channelWriteMutex;
605 PMutex m_channelReadMutex;
606 bool m_closed;
607 bool m_paused;
608 PINDEX m_totalData;
609
610 // Incoming audio variables
611 PVXMLRecordable * m_recordable;
612
613 // Outgoing audio variables
614 PVXMLQueue m_playQueue;
615 PVXMLPlayable * m_currentPlayItem;
616 PSimpleTimer m_silenceTimer;
617 };
618
619
621
622 class PVXMLNodeHandler : public PObject
623 {
624 PCLASSINFO(PVXMLNodeHandler, PObject);
625 public:
626 // Return true for process node, false to skip and move to next sibling
627 virtual bool Start(PVXMLSession & /*session*/, PXMLElement & /*node*/) const { return true; }
628
629 // Return true to move to next sibling, false to stay at this node.
630 virtual bool Finish(PVXMLSession & /*session*/, PXMLElement & /*node*/) const { return true; }
631 };
632
633
634 typedef PFactory<PVXMLNodeHandler, PCaselessString> PVXMLNodeFactory;
635
636
637 #endif // P_VXML
638
639 #endif // PTLIB_VXML_H
640
641
642 // End of file ////////////////////////////////////////////////////////////////