PTLib  Version 2.12.9
 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,
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 
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 
304 
307 
308  PTextToSpeech * m_textToSpeech;
311 
318  bool m_bargeIn;
320 
323 
326 
327  std::queue<char> m_userInputQueue;
329 
330  enum {
339 
340  enum {
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:
376 };
377 
379 
381 {
383  public:
384  PBoolean Open(const PString & arg);
385  bool OnStart(PVXMLChannel & incomingChannel);
386  PBoolean OnFrame(PBoolean isSilence);
387 
388  protected:
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:
427  PINDEX m_repeat;
428  PINDEX m_delay;
432  bool m_delayDone; // very tacky flag used to indicate when the post-play delay has been done
433 };
434 
436 
438 {
439  PCLASSINFO(PVXMLPlayableStop, PVXMLPlayable);
440  public:
441  virtual bool OnStart();
442 };
443 
445 
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:
454 };
455 
457 
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:
468 };
469 
471 
472 #if P_DTMF
473 
474 #include <ptclib/dtmf.h>
475 
477 {
479  public:
480  virtual PBoolean Open(PVXMLChannel & chan, const PString & arg, PINDEX delay, PINDEX repeat, PBoolean autoDelete);
481  protected:
483 };
484 
485 #endif // P_DTMF
486 
487 
489 
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:
500 };
501 
503 
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:
514 };
515 
517 
519 {
521  public:
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:
531 };
532 
534 
535 PQUEUE(PVXMLQueue, PVXMLPlayable);
536 
538 
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:
599 
603 
606  bool m_closed;
607  bool m_paused;
608  PINDEX m_totalData;
609 
610  // Incoming audio variables
612 
613  // Outgoing audio variables
614  PVXMLQueue m_playQueue;
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 
635 
636 
637 #endif // P_VXML
638 
639 #endif // PTLIB_VXML_H
640 
641 
642 // End of file ////////////////////////////////////////////////////////////////