PTLib  Version 2.14.3
 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: 32948 $
25  * $Author: rjongbloed $
26  * $Date: 2014-10-10 10:30:31 +1100 (Fri, 10 Oct 2014) $
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,
80  };
81 
82  GrammarState GetState() const { return m_state; }
83 
84  void SetSessionTimeout();
85  void SetTimeout(const PTimeInterval & timeout);
86 
87  protected:
89 
97 };
98 
99 
101 
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 
115 {
116  PCLASSINFO(PVXMLDigitsGrammar, PVXMLGrammar);
117  public:
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;
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 
171 };
172 
174 
175 class PVXMLChannel;
176 
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 
207  void UnLockVXMLChannel() { m_sessionMutex.Signal(); }
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 
241  };
242  virtual bool OnTransfer(const PString & /*destination*/, TransferType /*type*/) { return false; }
243  void SetTransferComplete(bool state);
244 
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  void ClearBargeIn();
298  void FlushInput();
299 
300  void SayAs(const PString & className, const PString & text);
301  void SayAs(const PString & className, const PString & text, const PString & voice);
302 
303  PURL NormaliseResourceName(const PString & src);
304 
306 
309 
310  PTextToSpeech * m_textToSpeech;
313 
320  bool m_bargeIn;
322 
325 
328 
329  std::queue<char> m_userInputQueue;
331 
332  enum {
341 
342  enum {
350 };
351 
352 
354 
355 class PVXMLRecordable : public PObject
356 {
357  PCLASSINFO(PVXMLRecordable, PObject);
358  public:
359  PVXMLRecordable();
360 
361  virtual PBoolean Open(const PString & arg) = 0;
362 
363  virtual bool OnStart(PVXMLChannel & incomingChannel) = 0;
364  virtual void OnStop() { }
365 
366  virtual PBoolean OnFrame(PBoolean /*isSilence*/) { return false; }
367 
368  const PTimeInterval & GetFinalSilence() const { return m_finalSilence; }
369  void SetFinalSilence(const PTimeInterval & v) { m_finalSilence = v > 0 ? v : 60000; }
370 
371  const PTimeInterval & GetMaxDuration() const { return m_maxDuration; }
372  void SetMaxDuration(const PTimeInterval & v) { m_maxDuration = v > 0 ? v : 86400000; }
373 
374  protected:
379 };
380 
382 
384 {
386  public:
387  PBoolean Open(const PString & arg);
388  bool OnStart(PVXMLChannel & incomingChannel);
389  PBoolean OnFrame(PBoolean isSilence);
390 
391  protected:
393 };
394 
396 
397 class PVXMLPlayable : public PObject
398 {
399  PCLASSINFO(PVXMLPlayable, PObject);
400  public:
401  PVXMLPlayable();
402 
403  virtual PBoolean Open(PVXMLChannel & chan, const PString & arg, PINDEX delay, PINDEX repeat, PBoolean autoDelete);
404 
405  virtual bool OnStart() = 0;
406  virtual bool OnRepeat();
407  virtual bool OnDelay();
408  virtual void OnStop();
409 
410  virtual void SetRepeat(PINDEX v)
411  { m_repeat = v; }
412 
413  virtual PINDEX GetRepeat() const
414  { return m_repeat; }
415 
416  virtual PINDEX GetDelay() const
417  { return m_delay; }
418 
419  void SetFormat(const PString & fmt)
420  { m_format = fmt; }
421 
422  void SetSampleFrequency(unsigned rate)
423  { m_sampleFrequency = rate; }
424 
425  friend class PVXMLChannel;
426 
427  protected:
430  PINDEX m_repeat;
431  PINDEX m_delay;
435  bool m_delayDone; // very tacky flag used to indicate when the post-play delay has been done
436 };
437 
439 
441 {
442  PCLASSINFO(PVXMLPlayableStop, PVXMLPlayable);
443  public:
444  virtual bool OnStart();
445 };
446 
448 
450 {
451  PCLASSINFO(PVXMLPlayableURL, PVXMLPlayable);
452  public:
453  virtual PBoolean Open(PVXMLChannel & chan, const PString & arg, PINDEX delay, PINDEX repeat, PBoolean autoDelete);
454  virtual bool OnStart();
455  protected:
457 };
458 
460 
462 {
463  PCLASSINFO(PVXMLPlayableData, PVXMLPlayable);
464  public:
465  virtual PBoolean Open(PVXMLChannel & chan, const PString & arg, PINDEX delay, PINDEX repeat, PBoolean autoDelete);
466  void SetData(const PBYTEArray & data);
467  virtual bool OnStart();
468  virtual bool OnRepeat();
469  protected:
471 };
472 
474 
475 #if P_DTMF
476 
477 #include <ptclib/dtmf.h>
478 
480 {
482  public:
483  virtual PBoolean Open(PVXMLChannel & chan, const PString & arg, PINDEX delay, PINDEX repeat, PBoolean autoDelete);
484  protected:
486 };
487 
488 #endif // P_DTMF
489 
490 
492 
494 {
495  PCLASSINFO(PVXMLPlayableCommand, PVXMLPlayable);
496  public:
497  virtual PBoolean Open(PVXMLChannel & chan, const PString & arg, PINDEX delay, PINDEX repeat, PBoolean autoDelete);
498  virtual bool OnStart();
499  virtual void OnStop();
500 
501  protected:
503 };
504 
506 
508 {
509  PCLASSINFO(PVXMLPlayableFile, PVXMLPlayable);
510  public:
511  virtual PBoolean Open(PVXMLChannel & chan, const PString & arg, PINDEX delay, PINDEX repeat, PBoolean autoDelete);
512  virtual bool OnStart();
513  virtual bool OnRepeat();
514  virtual void OnStop();
515  protected:
517 };
518 
520 
522 {
524  public:
526  virtual PBoolean Open(PVXMLChannel & chan, const PString & arg, PINDEX delay, PINDEX repeat, PBoolean autoDelete);
527  virtual PBoolean Open(PVXMLChannel & chan, const PStringArray & filenames, PINDEX delay, PINDEX repeat, PBoolean autoDelete);
528  virtual bool OnStart();
529  virtual bool OnRepeat();
530  virtual void OnStop();
531  protected:
534 };
535 
537 
538 PQUEUE(PVXMLQueue, PVXMLPlayable);
539 
541 
543 {
544  PCLASSINFO(PVXMLChannel, PDelayChannel);
545  public:
546  PVXMLChannel(unsigned frameDelay, PINDEX frameSize);
547  ~PVXMLChannel();
548 
549  virtual PBoolean Open(PVXMLSession * session);
550 
551  // overrides from PIndirectChannel
552  virtual PBoolean IsOpen() const;
553  virtual PBoolean Close();
554  virtual PBoolean Read(void * buffer, PINDEX amount);
555  virtual PBoolean Write(const void * buf, PINDEX len);
556 
557 #if P_WAVFILE
558  // new functions
559  virtual PWAVFile * CreateWAVFile(const PFilePath & fn, PBoolean recording = false);
560 #endif
561 
562  const PString & GetMediaFormat() const { return mediaFormat; }
563  PBoolean IsMediaPCM() const { return mediaFormat == "PCM-16"; }
564  virtual PString AdjustWavFilename(const PString & fn);
565 
566  // Incoming channel functions
567  virtual PBoolean WriteFrame(const void * buf, PINDEX len) = 0;
568  virtual PBoolean IsSilenceFrame(const void * buf, PINDEX len) const = 0;
569 
570  virtual bool QueueRecordable(PVXMLRecordable * newItem);
571  bool EndRecording(bool timedOut);
572  bool IsRecording() const { return m_recordable != NULL; }
573 
574  // Outgoing channel functions
575  virtual PBoolean ReadFrame(void * buffer, PINDEX amount) = 0;
576  virtual PINDEX CreateSilenceFrame(void * buffer, PINDEX amount) = 0;
577  virtual void GetBeepData(PBYTEArray &, unsigned) { }
578 
579  virtual PBoolean QueueResource(const PURL & url, PINDEX repeat= 1, PINDEX delay = 0);
580 
581  virtual PBoolean QueuePlayable(const PString & type, const PString & str, PINDEX repeat = 1, PINDEX delay = 0, PBoolean autoDelete = false);
582  virtual PBoolean QueuePlayable(PVXMLPlayable * newItem);
583  virtual PBoolean QueueData(const PBYTEArray & data, PINDEX repeat = 1, PINDEX delay = 0);
584 
585  virtual PBoolean QueueFile(const PString & fn, PINDEX repeat = 1, PINDEX delay = 0, PBoolean autoDelete = false)
586  { return QueuePlayable("File", fn, repeat, delay, autoDelete); }
587 
588  virtual PBoolean QueueCommand(const PString & cmd, PINDEX repeat = 1, PINDEX delay = 0)
589  { return QueuePlayable("Command", cmd, repeat, delay, true); }
590 
591  virtual void FlushQueue();
592  virtual PBoolean IsPlaying() const { return m_currentPlayItem != NULL || m_playQueue.GetSize() > 0; }
593 
594  void SetPause(PBoolean pause) { m_paused = pause; }
595 
596  unsigned GetSampleFrequency() const { return m_sampleFrequency; }
597 
598  void SetSilence(unsigned msecs);
599 
600  protected:
602 
606 
609  bool m_closed;
610  bool m_paused;
611  PINDEX m_totalData;
612 
613  // Incoming audio variables
615 
616  // Outgoing audio variables
617  PVXMLQueue m_playQueue;
620 };
621 
622 
624 
625 class PVXMLNodeHandler : public PObject
626 {
627  PCLASSINFO(PVXMLNodeHandler, PObject);
628  public:
629  // Return true for process node, false to skip and move to next sibling
630  virtual bool Start(PVXMLSession & /*session*/, PXMLElement & /*node*/) const { return true; }
631 
632  // Return true to move to next sibling, false to stay at this node.
633  virtual bool Finish(PVXMLSession & /*session*/, PXMLElement & /*node*/) const { return true; }
634 };
635 
636 
638 
639 
640 #endif // P_VXML
641 
642 #endif // PTLIB_VXML_H
643 
644 
645 // End of file ////////////////////////////////////////////////////////////////