1 /*
2  * lid.h
3  *
4  * Line Interface Device
5  *
6  * Open Phone Abstraction Library
7  *
8  * Copyright (c) 1999-2001 Equivalence Pty. Ltd.
9  *
10  * The contents of this file are subject to the Mozilla Public License
11  * Version 1.0 (the "License"); you may not use this file except in
12  * compliance with the License. You may obtain a copy of the License at
13  * http://www.mozilla.org/MPL/
14  *
15  * Software distributed under the License is distributed on an "AS IS"
16  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17  * the License for the specific language governing rights and limitations
18  * under the License.
19  *
20  * The Original Code is Open H323 Library.
21  *
22  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
23  *
24  * Portions of this code were written with the assisance of funding from
25  * Quicknet Technologies, Inc. http://www.quicknet.net.
26  *
27  * Contributor(s): ______________________________________.
28  *
29  * $Revision: 24178 $
30  * $Author: rjongbloed $
31  * $Date: 2010-04-05 19:10:56 -0500 (Mon, 05 Apr 2010) $
32  */
33 
34 #ifndef OPAL_LIDS_LID_H
35 #define OPAL_LIDS_LID_H
36 
37 #ifdef P_USE_PRAGMA
38 #pragma interface
39 #endif
40 
41 #include <opal/buildopts.h>
42 
43 #include <opal/mediafmt.h>
44 
45 
46 ///////////////////////////////////////////////////////////////////////////////
47 
48 /** Line Interface Device abstraction.
49     Note all functions in this device abstraction are assumed to be thread atomic.
50  */
51 class OpalLineInterfaceDevice : public PObject
52 {
53   PCLASSINFO(OpalLineInterfaceDevice, PObject);
54 
55   public:
56     /**Construct a new line interface device.
57       */
58     OpalLineInterfaceDevice();
59 
60     /**Open the line interface device.
61       */
62     virtual PBoolean Open(
63       const PString & device      ///<  Device identifier name.
64     ) = 0;
65 
66     /**Determine if the line interface device is open.
67       */
68     virtual PBoolean IsOpen() const;
69 
70     /**Close the line interface device.
71       */
72     virtual PBoolean Close();
73 
74     /**Get the device type identifier.
75        This is as is used in the factory registration.
76       */
77     virtual PString GetDeviceType() const = 0;
78 
79     /**Get the device name, as used to open the device.
80        Note the format of this name should be as is returned from GetAllName()
81        and must be able to be used in a subsequent Open() call.
82       */
83     virtual PString GetDeviceName() const = 0;
84 
85     /**Get all the possible devices that can be opened.
86       */
87     virtual PStringArray GetAllNames() const = 0;
88 
89     /**Get the description of the line interface device.
90        This is a string indication of the card type for user interface
91        display purposes or device specific control. The device should be
92        as detailed as possible eg "Quicknet LineJACK".
93       */
94     virtual PString GetDescription() const = 0;
95 
96     /**Get the total number of lines supported by this device.
97       */
98     virtual unsigned GetLineCount() const = 0;
99 
100     /**Get the type of the line.
101        A "terminal" line is one where a call may terminate. For example a POTS
102        line with a standard telephone handset on it would be a terminal line.
103        The alternative is a "network" line, that is one connected to switched
104        network eg the standard PSTN.
105       */
106     virtual PBoolean IsLineTerminal(
107       unsigned line   ///<  Number of line
108     ) = 0;
109 
110 
111     /**Determine if a physical line is present on the logical line.
112       */
113     virtual PBoolean IsLinePresent(
114       unsigned line,      ///<  Number of line
115       PBoolean force = false  ///<  Force test, do not optimise
116     );
117 
118 
119     /**Determine if line is currently off hook.
120        This function implies that the state is debounced and that a return
121        value of true indicates that the phone is really off hook. That is
122        hook flashes and winks are masked out.
123       */
124     virtual PBoolean IsLineOffHook(
125       unsigned line   ///<  Number of line
126     ) = 0;
127 
128     /**Set the hook state of the line.
129        Note that not be possible on a given line, for example a POTS line with
130        a standard telephone handset. The hook state is determined by external
131        hardware and cannot be changed by the software.
132       */
133     virtual PBoolean SetLineOffHook(
134       unsigned line,        ///<  Number of line
135       PBoolean newState = true  ///<  New state to set
136     ) = 0;
137 
138     /**Set the hook state of the line.
139        This is the complement of SetLineOffHook().
140       */
SetLineOnHook(unsigned line)141     virtual PBoolean SetLineOnHook(
142       unsigned line        ///<  Number of line
143     ) { return SetLineOffHook(line, false); }
144 
145     /**Set the hook state off then straight back on again.
146        This will only operate if the line is currently off hook.
147       */
148     virtual PBoolean HookFlash(
149       unsigned line,              ///<  Number of line
150       unsigned flashTime = 200    ///<  Time for hook flash in milliseconds
151     );
152 
153     /**Return true if a hook flash has been detected
154       */
155     virtual PBoolean HasHookFlash(unsigned line);
156 
157 
158     /**Determine if line is ringing.
159        This function implies that the state is "debounced" and that a return
160        value of true indicates that the phone is still ringing and it is not
161        simply a pause in the ring cadence.
162 
163        If cadence is not NULL then it is set with the bit pattern for the
164        incoming ringing. Note that in this case the funtion may take a full
165        sequence to return. If it is NULL it can be assumed that the function
166        will return quickly.
167       */
168     virtual PBoolean IsLineRinging(
169       unsigned line,          ///<  Number of line
170       DWORD * cadence = NULL  ///<  Cadence of incoming ring
171     );
172 
173     /**Begin ringing local phone set with specified cadence.
174        If nCadence is zero then stops ringing.
175 
176        Note that this may not be possible on a given line, for example on a
177        PSTN line the ring state is determined by external hardware and cannot
178        be changed by the software.
179 
180        Also note that the cadence may be ignored by particular hardware driver
181        so that only the zero or non-zero values are significant.
182 
183        The ring pattern is an array of millisecond times for on and off parts
184        of the cadence. Thus the Australian ring cadence would be represented
185        by the array   unsigned AusRing[] = { 400, 200, 400, 2000 }
186 
187        If the nCadence in non-zero and the pattern parameter is NULL, then
188        the standard ring pattern for the selected country is used.
189       */
190     virtual PBoolean RingLine(
191       unsigned line,                   ///< Number of line
192       PINDEX nCadence,                 ///< Number of entries in cadence array
193       const unsigned * pattern = NULL, ///< Ring pattern times
194       unsigned frequency = 400         ///< Frequency of ring (if relevant)
195     );
196 
197 
198     /**Indicate to the POTS handset that the call is connected.
199        This uses the hardware (and country) dependent means to indicate to
200        the remote end of a POTS connection that we have answerd. Typically
201        this is a "polarity reversal" but other techniques may be used.
202 
203        The "connected" state remains in force till the remote disconnects
204        the call, though hanging up.
205 
206        Returns true if successful, always returns false for PSTN lines.
207       */
208     virtual PBoolean SetLineConnected(
209       unsigned line   ///<  Number of line
210     );
211 
212     /**Determine if remote has answered call on line.
213        This uses the hardware (and country) dependent means for determining
214        if the remote end of a PSTN connection has answered. Typically this
215        is a "polarity reversal" but other techniques may be used.
216 
217        It should be noted that IsLineConnected() is not exactly the same
218        thing as !IsLineDisconnected().
219 
220        For a POTS port this is equivalent to IsLineOffHook().
221       */
222     virtual PBoolean IsLineConnected(
223       unsigned line   ///<  Number of line
224     );
225 
226 
227     /**Determine if line has been disconnected from a call.
228        This uses the hardware (and country) dependent means for determining
229        if the remote end of a PSTN connection has hung up. For example a
230        "wink" or "K break" which is a short drop in line voltage similar to
231        (though opposite in sense) toa hook flash.
232 
233        It should be noted that IsLineDisconnected() is not exactly the same
234        thing as !IsLineConnected().
235 
236        For a POTS port this is equivalent to !IsLineOffHook().
237       */
238     virtual PBoolean IsLineDisconnected(
239       unsigned line,   ///<  Number of line
240       PBoolean checkForWink = true ///< Flag to check for remote hang up
241     );
242 
243 
244     /**Directly connect the two lines.
245       */
246     virtual PBoolean SetLineToLineDirect(
247       unsigned line1,   ///<  Number of first line
248       unsigned line2,   ///<  Number of second line
249       PBoolean connect      ///<  Flag for connect/disconnect
250     );
251 
252     /**Determine if the two lines are directly connected.
253       */
254     virtual PBoolean IsLineToLineDirect(
255       unsigned line1,   ///<  Number of first line
256       unsigned line2    ///<  Number of second line
257     );
258 
259 
260     /**Get the media formats this device is capable of using.
261       */
262     virtual OpalMediaFormatList GetMediaFormats() const = 0;
263 
264     /**Set the media format (codec) for reading on the specified line.
265       */
266     virtual PBoolean SetReadFormat(
267       unsigned line,    ///<  Number of line
268       const OpalMediaFormat & mediaFormat   ///<  Codec type
269     ) = 0;
270 
271     /**Set the media format (codec) for writing on the specified line.
272       */
273     virtual PBoolean SetWriteFormat(
274       unsigned line,    ///<  Number of line
275       const OpalMediaFormat & mediaFormat   ///<  Codec type
276     ) = 0;
277 
278     /**Get the media format (codec) for reading on the specified line.
279       */
280     virtual OpalMediaFormat GetReadFormat(
281       unsigned line    ///<  Number of line
282     ) = 0;
283 
284     /**Get the media format (codec) for writing on the specified line.
285       */
286     virtual OpalMediaFormat GetWriteFormat(
287       unsigned line    ///<  Number of line
288     ) = 0;
289 
290     /**Stop the read codec.
291       */
292     virtual PBoolean StopReading(
293       unsigned line   ///<  Number of line
294     );
295 
296     /**Stop the write codec.
297       */
298     virtual PBoolean StopWriting(
299       unsigned line   ///<  Number of line
300     );
301 
302     /**Indicate that ReadFrame() & WriteFrame() take whole RTP packets.
303        Note that if this returns true, SetReadFrameSize(), SetWriteFrameSize(),
304        GetReadFrameSize() and GetWriteFrameSize() are no longer relevant.
305       */
306     virtual bool UsesRTP() const;
307 
308     /**Set the read frame size in bytes.
309        Note that a LID may ignore this value so always use GetReadFrameSize()
310        for I/O.
311       */
312     virtual PBoolean SetReadFrameSize(
313       unsigned line,    ///<  Number of line
314       PINDEX frameSize  ///<  New frame size
315     );
316 
317     /**Set the write frame size in bytes.
318        Note that a LID may ignore this value so always use GetReadFrameSize()
319        for I/O.
320       */
321     virtual PBoolean SetWriteFrameSize(
322       unsigned line,    ///<  Number of line
323       PINDEX frameSize  ///<  New frame size
324     );
325 
326     /**Get the read frame size in bytes.
327        All calls to ReadFrame() will return this number of bytes.
328       */
329     virtual PINDEX GetReadFrameSize(
330       unsigned line   ///<  Number of line
331     );
332 
333     /**Get the write frame size in bytes.
334        All calls to WriteFrame() must be this number of bytes.
335       */
336     virtual PINDEX GetWriteFrameSize(
337       unsigned line   ///<  Number of line
338     );
339 
340     /**Low level read of a frame from the device.
341      */
342     virtual PBoolean ReadFrame(
343       unsigned line,    ///<  Number of line
344       void * buf,       ///<  Pointer to a block of memory to receive data.
345       PINDEX & count    ///<  Number of bytes read, <= GetReadFrameSize()
346     ) = 0;
347 
348     /**Low level write frame to the device.
349      */
350     virtual PBoolean WriteFrame(
351       unsigned line,    ///<  Number of line
352       const void * buf, ///<  Pointer to a block of memory to write.
353       PINDEX count,     ///<  Number of bytes to write, <= GetWriteFrameSize()
354       PINDEX & written  ///<  Number of bytes written, <= GetWriteFrameSize()
355     ) = 0;
356 
357     /**High level read of audio data from the device.
358        This version will allow non-integral number of frames to be read.
359      */
360     virtual PBoolean ReadBlock(
361       unsigned line,    ///<  Number of line
362       void * buf,   ///<  Pointer to a block of memory to receive the read bytes.
363       PINDEX count  ///<  Count of bytes to read.
364     );
365 
366     /**High level write audio data to the device.
367      */
368     virtual PBoolean WriteBlock(
369       unsigned line,    ///<  Number of line
370       const void * buf, ///<  Pointer to a block of memory to write.
371       PINDEX count      ///<  Count of bytes to write.
372     );
373 
374 
375     /**Get average signal level in last frame.
376       */
377     virtual unsigned GetAverageSignalLevel(
378       unsigned line,  ///<  Number of line
379       PBoolean playback   ///<  Get average playback or record level.
380     );
381 
382 
383     /**Enable audio for the line.
384       */
385     virtual PBoolean EnableAudio(
386       unsigned line,      ///<  Number of line
387       PBoolean enable = true ///< Enable/disable audio
388     );
389 
390     /**Disable audio for the line.
391       */
DisableAudio(unsigned line)392     PBoolean DisableAudio(
393       unsigned line   ///<  Number of line
394     ) { return EnableAudio(line, false); }
395 
396     /**Determine if audio for the line is enabled.
397       */
398     virtual PBoolean IsAudioEnabled(
399       unsigned line      ///<  Number of line
400     ) const;
401 
402 
403     enum {
404       MaxVolume = 100
405     };
406 
407     /**Set volume level for recording.
408        A value of 100 is the maximum volume possible for the hardware.
409        A value of 0 is the minimum volume possible for the hardware.
410       */
411     virtual PBoolean SetRecordVolume(
412       unsigned line,    ///<  Number of line
413       unsigned volume   ///<  Volume level from 0 to 100%
414     );
415 
416     /**Set volume level for playing.
417        A value of 100 is the maximum volume possible for the hardware.
418        A value of 0 is the minimum volume possible for the hardware.
419       */
420     virtual PBoolean SetPlayVolume(
421       unsigned line,    ///<  Number of line
422       unsigned volume   ///<  Volume level from 0 to 100%
423     );
424 
425     /**Get volume level for recording.
426        A value of 100 is the maximum volume possible for the hardware.
427        A value of 0 is the minimum volume possible for the hardware.
428       */
429     virtual PBoolean GetRecordVolume(
430       unsigned line,      ///<  Number of line
431       unsigned & volume   ///<  Volume level from 0 to 100%
432     );
433 
434     /**Set volume level for playing.
435        A value of 100 is the maximum volume possible for the hardware.
436        A value of 0 is the minimum volume possible for the hardware.
437       */
438     virtual PBoolean GetPlayVolume(
439       unsigned line,      ///<  Number of line
440       unsigned & volume   ///<  Volume level from 0 to 100%
441     );
442 
443 
444     enum AECLevels {
445       AECOff,
446       AECLow,
447       AECMedium,
448       AECHigh,
449       AECAuto,
450       AECAGC,
451       AECError
452     };
453 
454     /**Get acoustic echo cancellation.
455        Note, not all devices may support this function.
456       */
457     virtual AECLevels GetAEC(
458       unsigned line    ///<  Number of line
459     ) const;
460 
461     /**Set acoustic echo cancellation.
462        Note, not all devices may support this function.
463       */
464     virtual PBoolean SetAEC(
465       unsigned line,    ///<  Number of line
466       AECLevels level   ///<  AEC level
467     );
468 
469     /**Get voice activity detection.
470        Note, not all devices, or selected codecs, may support this function.
471       */
472     virtual PBoolean GetVAD(
473       unsigned line    ///<  Number of line
474     ) const;
475 
476     /**Set voice activity detection.
477        Note, not all devices, or selected codecs, may support this function.
478       */
479     virtual PBoolean SetVAD(
480       unsigned line,    ///<  Number of line
481       PBoolean enable       ///<  Flag for enabling VAD
482     );
483 
484 
485     /**Get Caller ID from the last incoming ring.
486        The idString parameter is either simply the "number" field of the caller
487        ID data, or if full is true, all of the fields in the caller ID data.
488 
489        The full data of the caller ID string consists fields separated by tab
490        characters ('\\t'), the first three are always the Calling Line Identity
491        (CLI or calling number), the date and the Calling Line Name field. Other
492        fields may follow and are the of the form name=value. The values are
493        LID dependent.
494 
495        A false is returned if there is no Caller ID information available, e.g.
496        if no ring has occurred.
497       */
498     virtual PBoolean GetCallerID(
499       unsigned line,      ///<  Number of line
500       PString & idString, ///<  ID string returned
501       PBoolean full = false   ///<  Get full information in idString
502     );
503 
504     /**Set Caller ID information.
505        The idString must be as a minimum a number fields for the Calling Line
506        Identity.
507 
508        The full data of the caller ID string consists fields separated by tab
509        characters ('\\t'), the first three are always the Calling Line Identity
510        (CLI or calling number), the date and the Calling Line Name field. Other
511        fields may follow and are the of the form name=value. The values are
512        LID dependent.
513 
514        If the date field is missing (e.g. two consecutive tabs) then the current
515        time and date is used. Using an empty string will clear the caller ID
516        so that no caller ID is sent on the next RingLine() call.
517 
518        if the line is on hook then this information is sent when the next
519        RingLine() function is called to start a ring cycle. Note that if the
520        Ring cycle had already been started then this function may return false.
521 
522        If the line is off hook, then a Caller ID on Message Waiting is sent, if
523        supported by the LID, otherwise false is returned.
524       */
525     virtual PBoolean SetCallerID(
526       unsigned line,            ///<  Number of line
527       const PString & idString  ///<  ID string to use
528     );
529 
530     /**Send a Visual Message Waiting Indicator
531       */
532     virtual PBoolean SendVisualMessageWaitingIndicator(
533       unsigned line,            ///<  Number of line
534       PBoolean on               ///< Flag for VMWI on/off
535     );
536 
537 
538     enum {
539       DefaultDTMFOnTime = 150,
540       DefaultDTMFOffTime = 50
541     };
542 
543     /**Play a DTMF digit.
544        Any characters that are not in the set 0-9, A-D, * or # will be ignored.
545       */
546     virtual PBoolean PlayDTMF(
547       unsigned line,            ///<  Number of line
548       const char * digits,      ///<  DTMF digits to be played
549       DWORD onTime = DefaultDTMFOnTime,  ///<  Number of milliseconds to play each DTMF digit
550       DWORD offTime = DefaultDTMFOffTime ///<  Number of milliseconds between digits
551     );
552 
553     /**Read a DTMF digit detected.
554        This may be characters from the set 0-9, A-D, * or #. A null ('\\0')
555        character indicates that there are no tones in the queue.
556        Characters E through P indicate the following tones:
557 
558          E = 800   F = 1000  G = 1250  H = 950   I = 1100  J = 1400
559          K = 1500  L = 1600  M = 1800  N = 2100  O = 1300  P = 2450
560 
561       */
562     virtual char ReadDTMF(
563       unsigned line   ///<  Number of line
564     );
565 
566     /**Get DTMF removal mode.
567        When set in this mode the DTMF tones detected are removed from the
568        encoded data stream as returned by ReadFrame().
569       */
570     virtual PBoolean GetRemoveDTMF(
571       unsigned line   ///<  Number of line
572     );
573 
574     /**Set DTMF removal mode.
575        When set in this mode the DTMF tones detected are removed from the
576        encoded data stream as returned by ReadFrame().
577       */
578     virtual PBoolean SetRemoveDTMF(
579       unsigned line,     ///<  Number of line
580       PBoolean removeTones   ///<  Flag for removing DTMF tones.
581     );
582 
583 
584     enum CallProgressTones {
585       NoTone = -1, // indicates no tones
586       DialTone,    // Dial tone
587       RingTone,    // Ring indication tone
588       BusyTone,    // Line engaged tone
589       CongestionTone,// aka fast busy tone
590       ClearTone,   // Call failed/disconnected tone (often same as busy tone)
591       MwiTone,     // Message Waiting Tone
592       RoutingTone, // Call is being routed (not normal for PSTN, but VoIP can take a while)
593       CNGTone,     // Fax CNG tone
594       CEDTone,     // Fax CED tone
595       UserDefinedTone,
596       NumTones
597     };
598 
599     /**See if any tone is detected.
600       */
601     virtual CallProgressTones IsToneDetected(
602       unsigned line   ///< Number of line
603     );
604 
605     /**See if any tone is detected.
606       */
607     virtual CallProgressTones WaitForToneDetect(
608       unsigned line,          ///< Number of line
609       unsigned timeout = 3000 ///< Milliseconds to wait for
610     );
611 
612     /**See if a specific tone is detected.
613       */
614     virtual PBoolean WaitForTone(
615       unsigned line,          ///<  Number of line
616       CallProgressTones tone, ///<  Tone to wait for
617       unsigned timeout = 3000 ///<  Milliseconds to wait for
618     );
619 
620     /**Set a calling tones description.
621        This sets the calling tone infromation for both wtah is emitted by PlayTone
622        and what is detected by IsToneDetected().
623 
624        The description string is of the form
625           frequency ':' cadence
626       where frequency is either
627           frequency      play tone, detect +/- 5%
628           low '-' high   play tone halfway, but detect anything in range
629           low '+' high   play both tones, detect anything in range
630           low 'x' high   play tone1 modulated by tone2, detect twice modulation range
631       and cadence is
632           mintime
633           ontime '-' offtime
634           ontime '-' offtime '-' ontime '-' offtime
635       examples:
636           300:0.25      300Hz for minimum 250ms
637           1100:0.4-0.4  1100Hz with cadence 400ms on, 400ms off
638           900-1300:1.5  900Hz to 1300Hz for minimum of 1.5 seconds
639           425:0.4-0.2-0.4-2    425Hz with cadence
640                                 400ms on, 200ms off, 400ms on, 2 seconds off
641       */
642     virtual bool SetToneDescription(
643       unsigned line,              ///<  Number of line
644       CallProgressTones tone,     ///<  Tone filter to change
645       const PString & description ///<  Description of filter parameters
646     );
647 
648     enum ToneMixingModes {
649       SimpleTone,
650       AddedTone,
651       ModulatedTone
652     };
653 
654     /**Set calling tones filter parameters. Note this function is misnamed as it
655        can also set the calling tone to be output by PlayTone().
656       */
657     virtual bool SetToneParameters(
658       unsigned line,            ///<  Number of line
659       CallProgressTones tone,   ///<  Tone filter to change
660       unsigned frequency1,      ///<  Usually low frequency
661       unsigned frequency2,      ///<  Usually high frequency
662       ToneMixingModes mode,     ///<  Mode for how freqencies are mixed, -1 is
663       PINDEX numCadences,       ///<  Number of cadence times
664       const unsigned * onTimes, ///<  Cadence ON times
665       const unsigned * offTimes ///<  Cadence OFF times
666     );
667 
668     /**Play a tone.
669       */
670     virtual PBoolean PlayTone(
671       unsigned line,          ///<  Number of line
672       CallProgressTones tone  ///<  Tone to be played
673     );
674 
675     /**Determine if a tone is still playing
676       */
677     virtual PBoolean IsTonePlaying(
678       unsigned line   ///<  Number of line
679     );
680 
681     /**Stop playing a tone.
682       */
683     virtual PBoolean StopTone(
684       unsigned line   ///<  Number of line
685     );
686 
687 
688     /** Structure for dialling parameters */
689     struct DialParams {
DialParamsDialParams690       DialParams()
691         : m_requireTones(false)
692         , m_dialToneTimeout(2500)
693         , m_dialStartDelay(500)
694         , m_dialDigitTime(DefaultDTMFOnTime)
695         , m_dialInterDigitTime(DefaultDTMFOffTime)
696         , m_progressTimeout(5000)
697         , m_commaDelay(2000)
698       { }
699 
700       bool     m_requireTones;      ///< Require dial/ring tone to be detected
701       unsigned m_dialToneTimeout;   ///< Time in msec to wait for a dial tone to be detected
702       unsigned m_dialStartDelay;    ///< Time in msec to wait between the dial tone detection and dialing the DTMF
703       unsigned m_dialDigitTime;     ///< Time in msec to play DTMF digit
704       unsigned m_dialInterDigitTime;///< Time in msec of silence between each DTMF digit
705       unsigned m_progressTimeout;   ///< Time in msec to wait for a progress tone (ring, busy or connected) to be detected
706       unsigned m_commaDelay;        ///< Time in msec to wait when a comma (',') is found in the dial string
707     };
708 
709     /**Dial a number on network line.
710        The takes the line off hook, waits for dial tone, and transmits the
711        specified number as DTMF tones.
712 
713        If the requireTones flag is true the call is aborted of the call
714        progress tones are not detected. Otherwise the call proceeds with short
715        delays while it tries to detect the call progress tones.
716 
717        The return code indicates the following:
718           DialTone  No dial tone detected
719           RingTone  Dial was successful
720           BusyTone  The remote phone was busy
721           ClearTone Dial failed (usually means rang out)
722           NoTone    There was an internal error making the call
723       */
724     virtual CallProgressTones DialOut(
725       unsigned line,                ///< Number of line
726       const PString & number,       ///< Number to dial
727       const DialParams & params = DialParams() ///< Optional parameters for dial out.
728     );
729 
730 
731     /**Get wink detect minimum duration.
732        This is the signal used by telcos to end PSTN call.
733       */
734     virtual unsigned GetWinkDuration(
735       unsigned line    ///<  Number of line
736     );
737 
738     /**Set wink detect minimum duration.
739        This is the signal used by telcos to end PSTN call.
740       */
741     virtual PBoolean SetWinkDuration(
742       unsigned line,        ///<  Number of line
743       unsigned winkDuration ///<  New minimum duration
744     );
745 
746 
747     enum T35CountryCodes {
748       Japan, Albania, Algeria, AmericanSamoa, Germany, Anguilla, AntiguaAndBarbuda,
749       Argentina, Ascension, Australia, Austria, Bahamas, Bahrain, Bangladesh,
750       Barbados, Belgium, Belize, Benin, Bermudas, Bhutan, Bolivia, Botswana,
751       Brazil, BritishAntarcticTerritory, BritishIndianOceanTerritory,
752       BritishVirginIslands, BruneiDarussalam, Bulgaria, Myanmar, Burundi,
753       Byelorussia, Cameroon, Canada, CapeVerde, CaymanIslands,
754       CentralAfricanRepublic, Chad, Chile, China, Colombia, Comoros, Congo,
755       CookIslands, CostaRica, Cuba, Cyprus, Czechoslovakia, Cambodia,
756       DemocraticPeoplesRepublicOfKorea, Denmark, Djibouti, DominicanRepublic,
757       Dominica, Ecuador, Egypt, ElSalvador, EquatorialGuinea, Ethiopia,
758       FalklandIslands, Fiji, Finland, France, FrenchPolynesia,
759       FrenchSouthernAndAntarcticLands, Gabon, Gambia, Germany2, Angola, Ghana,
760       Gibraltar, Greece, Grenada, Guam, Guatemala, Guernsey, Guinea, GuineaBissau,
761       Guayana, Haiti, Honduras, Hongkong, Hungary, Iceland, India, Indonesia,
762       Iran, Iraq, Ireland, Israel, Italy, CotedIvoire, Jamaica, Afghanistan,
763       Jersey, Jordan, Kenya, Kiribati, KoreaRepublic, Kuwait, Lao, Lebanon,
764       Lesotho, Liberia, Libya, Liechtenstein, Luxemborg, Macao, Madagascar,
765       Malaysia, Malawi, Maldives, Mali, Malta, Mauritania, Mauritius, Mexico,
766       Monaco, Mongolia, Montserrat, Morocco, Mozambique, Nauru, Nepal,
767       Netherlands, NetherlandsAntilles, NewCaledonia, NewZealand, Nicaragua,
768       Niger, Nigeria, Norway, Oman, Pakistan, Panama, PapuaNewGuinea, Paraguay,
769       Peru, Philippines, Poland, Portugal, PuertoRico, Qatar, Romania, Rwanda,
770       SaintKittsAndNevis, SaintCroix, SaintHelenaAndAscension, SaintLucia,
771       SanMarino, SaintThomas, SaoTomeAndPrincipe, SaintVicentAndTheGrenadines,
772       SaudiArabia, Senegal, Seychelles, SierraLeone, Singapore, SolomonIslands,
773       Somalia, SouthAfrica, Spain, SriLanka, Sudan, Suriname, Swaziland, Sweden,
774       Switzerland, Syria, Tanzania, Thailand, Togo, Tonga, TrinidadAndTobago,
775       Tunisia, Turkey, TurksAndCaicosIslands, Tuvalu, Uganda, Ukraine,
776       UnitedArabEmirates, UnitedKingdom, UnitedStates, BurkinaFaso, Uruguay,
777       USSR, Vanuatu, VaticanCityState, Venezuela, VietNam, WallisAndFutuna,
778       WesternSamoa, Yemen, Yemen2, Yugoslavia, Zaire, Zambia, Zimbabwe,
779       NumCountryCodes,
780       UnknownCountry = -1
781     };
782 
783     /**Get the country code set for the device.
784       */
GetCountryCode()785     T35CountryCodes GetCountryCode() const { return countryCode; }
786 
787     /**Get the country code set for the device as a string.
788       */
789     PString GetCountryCodeName() const;
790 
791     /**Get the country code set for the device as a string.
792       */
793     static PString GetCountryCodeName(T35CountryCodes code);
794     static T35CountryCodes GetCountryCode(const PString & name);
795 
796     /**Set the country code set for the device.
797        This may change the line analogue coefficients, ring detect, call
798        disconnect detect and call progress tones to fit the countries
799        telephone network.
800       */
801     virtual PBoolean SetCountryCode(
802       T35CountryCodes country   ///<  COuntry code for device
803     );
804 
805     /**Set the country code set for the device.
806       */
807     virtual PBoolean SetCountryCodeName(
808       const PString & countryName   ///<  COuntry code for device
809     );
810 
811     /**Get the list of countries actually supported by the device
812      */
813     virtual PStringList GetCountryCodeNameList() const;
814 
815 
816     /**Play a wav file
817       */
818     virtual PBoolean PlayAudio(
819       unsigned line,            ///<  Number of line
820       const PString & filename  ///<  File Name
821     );
822 
823     /**Stop playing the Wave File
824       */
825     virtual PBoolean StopAudio(
826       unsigned line   ///Number of line
827     );
828 
829 
830     /**
831       * start recording audio
832       */
833     virtual PBoolean RecordAudioStart(
834       unsigned line,            ///< line
835       const PString & filename  ///< File Name
836     );
837 
838     /**
839      * stop recording audio
840      */
841 
842     virtual PBoolean RecordAudioStop(
843       unsigned line            ///< line
844     );
845 
846 
847     /**Return number for last error.
848       */
GetErrorNumber()849     int GetErrorNumber() const { return osError; }
850 
851     /**Return text for last error.
852       */
853     PString GetErrorText() const;
854 
855     virtual void PrintOn(
856       ostream & strm
857     ) const;
858 
859     /**Create a new device from the registration string
860       */
861     static OpalLineInterfaceDevice * Create(
862       const PString & type,     ///<  Type of device to create
863       void * parameters = NULL  ///<  Arbitrary parameters for the LID
864     );
865 
866     /**Create a new device and open it given the descriptor string.
867        The descriptor consists of the device type, a ':' character and then
868        the specific device name.
869       */
870     static OpalLineInterfaceDevice * CreateAndOpen(
871       const PString & descriptor,     ///<  Type of device to create
872       void * parameters = NULL  ///<  Arbitrary parameters for the LID
873     );
874 
875     /**Return an array of all the LID types registered.
876       */
877     static PStringList GetAllTypes();
878 
879     /**Return an array of all the LID types registered and all of the possible
880        devices each one can open. Each string will be of the form
881           "type: name"  eg "Quicknet: 3211FFFF"
882       */
883     static PStringList GetAllDevices();
884 
885 
886   protected:
887     int               os_handle;
888     mutable int       osError;
889     T35CountryCodes   countryCode;
890     PBYTEArray        m_readDeblockingBuffer, m_writeDeblockingBuffer;
891     PINDEX            m_readDeblockingOffset, m_writeDeblockingOffset;
892     std::vector<bool> m_LineAudioEnabled;
893     PString           m_callProgressTones[NumTones];
894 #if PTRACING
895     friend ostream & operator<<(ostream & o, CallProgressTones t);
896 #endif
897 };
898 
899 
900 PLIST(OpalLIDList, OpalLineInterfaceDevice);
901 
902 
903 
904 /**This class describes the LID based codec capability.
905  */
906 class OpalLine : public PObject
907 {
908     PCLASSINFO(OpalLine, PObject);
909   public:
910   /**@name Construction */
911   //@{
912     /**Create a new telephone line.
913      */
914     OpalLine(
915       OpalLineInterfaceDevice & device, ///<  Device to make connection with
916       unsigned lineNumber,              ///<  number of line on LID
917       const char * userToken = NULL     ///<  Unique token string for line
918     );
919   //@}
920 
921   /**@name Overrides from PObject */
922   //@{
923     /**Standard stream print function.
924        The PObject class has a << operator defined that calls this function
925        polymorphically.
926       */
927     void PrintOn(
928       ostream & strm    ///<  Stream to output text representation
929     ) const;
930   //@}
931 
932   /**@name Basic operations */
933   //@{
934     /**Get the type of the line.
935        A "terminal" line is one where a call may terminate. For example a POTS
936        line with a standard telephone handset on it would be a terminal line.
937        The alternative is a "network" line, that is one connected to switched
938        network eg the standard PSTN.
939       */
IsTerminal()940     virtual PBoolean IsTerminal() { return device.IsLineTerminal(lineNumber); }
941 
942 
943     /**Determine if a physical line is present on the logical line.
944       */
945     virtual PBoolean IsPresent(
946       PBoolean force = false  ///<  Force test, do not optimise
947     ) { return device.IsLinePresent(lineNumber, force); }
948 
949 
950     /**Determine if line is currently off hook.
951        This function implies that the state is debounced and that a return
952        value of true indicates that the phone is really off hook. That is
953        hook flashes and winks are masked out.
954       */
IsOffHook()955     virtual PBoolean IsOffHook() { return device.IsLineOffHook(lineNumber); }
956 
957     /**Set the hook state of the line.
958        Note that not be possible on a given line, for example a POTS line with
959        a standard telephone handset. The hook state is determined by external
960        hardware and cannot be changed by the software.
961       */
SetOffHook()962     virtual PBoolean SetOffHook() { return device.SetLineOffHook(lineNumber, true); }
963 
964     /**Set the hook state of the line.
965        This is the complement of SetLineOffHook().
966       */
SetOnHook()967     virtual PBoolean SetOnHook() { return device.SetLineOffHook(lineNumber, false); }
968 
969     /**Set the hook state off then straight back on again.
970        This will only operate if the line is currently off hook.
971       */
972     virtual PBoolean HookFlash(
973       unsigned flashTime = 200    ///<  Time for hook flash in milliseconds
974     ) { return device.HookFlash(lineNumber, flashTime); }
975 
976     /**Return true if a hook flash has been detected
977       */
HasHookFlash()978     virtual PBoolean HasHookFlash() { return device.HasHookFlash(lineNumber); }
979 
980 
981     /**Determine if line is ringing.
982        This function implies that the state is "debounced" and that a return
983        value of true indicates that the phone is still ringing and it is not
984        simply a pause in the ring cadence.
985 
986        If cadence is not NULL then it is set with the bit pattern for the
987        incoming ringing. Note that in this case the funtion may take a full
988        sequence to return. If it is NULL it can be assumed that the function
989        will return quickly.
990       */
991     virtual PBoolean IsRinging(
992       DWORD * cadence = NULL  ///<  Cadence of incoming ring
993     );
994 
995     /**Get the number of rings.
996        If the line is ringing then
997       */
998     virtual unsigned GetRingCount(
999       DWORD * cadence = NULL  ///<  Cadence of incoming ring
1000     );
1001 
1002     /**Begin ringing local phone set with specified cadence.
1003        If nCadence is zero then stops ringing.
1004 
1005        Note that this may not be possible on a given line, for example on a
1006        PSTN line the ring state is determined by external hardware and cannot
1007        be changed by the software.
1008 
1009        Also note that the cadence may be ignored by particular hardware driver
1010        so that only the zero or non-zero values are significant.
1011 
1012        The ring pattern is an array of millisecond times for on and off parts
1013        of the cadence. Thus the Australian ring cadence would be represented
1014        by the array   unsigned AusRing[] = { 400, 200, 400, 2000 }
1015 
1016        If the nCadence in non-zero and the pattern parameter is NULL, then
1017        the standard ring pattern for the selected country is used.
1018       */
1019     virtual PBoolean Ring(
1020       PINDEX nCadence,                 ///< Number of entries in cadence array
1021       const unsigned * pattern = NULL, ///< Ring pattern times
1022       unsigned frequency = 400         ///< Frequency of ring (if relevant)
1023     ) { return device.RingLine(lineNumber, nCadence, pattern, frequency); }
1024 
1025 
1026     /**Indicate to the POTS handset that the call is connected.
1027        This uses the hardware (and country) dependent means to indicate to
1028        the remote end of a POTS connection that we have answerd. Typically
1029        this is a "polarity reversal" but other techniques may be used.
1030 
1031        The "connected" state remains in force till the remote disconnects
1032        the call, though hanging up.
1033 
1034        Returns true if successful, always returns false for PSTN lines.
1035       */
SetConnected()1036     virtual PBoolean SetConnected() { return device.SetLineConnected(lineNumber); }
1037 
1038     /**Determine if remote has answered call on line.
1039        This uses the hardware (and country) dependent means for determining
1040        if the remote end of a PSTN connection has answered. Typically this
1041        is a "polarity reversal" but other techniques may be used.
1042 
1043        For a POTS port this is equivalent to IsLineOffHook().
1044       */
IsConnected()1045     virtual PBoolean IsConnected() { return device.IsLineConnected(lineNumber); }
1046 
1047 
1048     /**Determine if line has been disconnected from a call.
1049        This uses the hardware (and country) dependent means for determining
1050       */
IsDisconnected()1051     virtual PBoolean IsDisconnected() { return device.IsLineDisconnected(lineNumber); }
1052 
1053     /**Set the media format (codec) for reading on the specified line.
1054       */
SetReadFormat(const OpalMediaFormat & mediaFormat)1055     virtual PBoolean SetReadFormat(
1056       const OpalMediaFormat & mediaFormat   ///<  Codec type
1057     ) { return device.SetReadFormat(lineNumber, mediaFormat); }
1058 
1059     /**Set the media format (codec) for writing on the specified line.
1060       */
SetWriteFormat(const OpalMediaFormat & mediaFormat)1061     virtual PBoolean SetWriteFormat(
1062       const OpalMediaFormat & mediaFormat   ///<  Codec type
1063     ) { return device.SetWriteFormat(lineNumber, mediaFormat); }
1064 
1065     /**Get the media format (codec) for reading on the specified line.
1066       */
GetReadFormat()1067     virtual OpalMediaFormat GetReadFormat() { return device.GetReadFormat(lineNumber); }
1068 
1069     /**Get the media format (codec) for writing on the specified line.
1070       */
GetWriteFormat()1071     virtual OpalMediaFormat GetWriteFormat() { return device.GetWriteFormat(lineNumber); }
1072 
1073     /**Stop the read codec.
1074       */
StopReading()1075     virtual PBoolean StopReading() { return device.StopReading(lineNumber); }
1076 
1077     /**Stop the write codec.
1078       */
StopWriting()1079     virtual PBoolean StopWriting() { return device.StopWriting(lineNumber); }
1080 
1081     /**Set the read frame size in bytes.
1082        Note that a LID may ignore this value so always use GetReadFrameSize()
1083        for I/O.
1084       */
SetReadFrameSize(PINDEX frameSize)1085     virtual PBoolean SetReadFrameSize(
1086       PINDEX frameSize  ///<  New frame size
1087     ) { return device.SetReadFrameSize(lineNumber, frameSize); }
1088 
1089     /**Set the write frame size in bytes.
1090        Note that a LID may ignore this value so always use GetReadFrameSize()
1091        for I/O.
1092       */
SetWriteFrameSize(PINDEX frameSize)1093     virtual PBoolean SetWriteFrameSize(
1094       PINDEX frameSize  ///<  New frame size
1095     ) { return device.SetWriteFrameSize(lineNumber, frameSize); }
1096 
1097     /**Get the read frame size in bytes.
1098        All calls to ReadFrame() will return this number of bytes.
1099       */
GetReadFrameSize()1100     virtual PINDEX GetReadFrameSize() { return device.GetReadFrameSize(lineNumber); }
1101 
1102     /**Get the write frame size in bytes.
1103        All calls to WriteFrame() must be this number of bytes.
1104       */
GetWriteFrameSize()1105     virtual PINDEX GetWriteFrameSize() { return device.GetWriteFrameSize(lineNumber); }
1106 
1107     /**Low level read of a frame from the device.
1108      */
ReadFrame(void * buf,PINDEX & count)1109     virtual PBoolean ReadFrame(
1110       void * buf,       ///<  Pointer to a block of memory to receive data.
1111       PINDEX & count    ///<  Number of bytes read, <= GetReadFrameSize()
1112     ) { return device.ReadFrame(lineNumber, buf, count); }
1113 
1114     /**Low level write frame to the device.
1115      */
WriteFrame(const void * buf,PINDEX count,PINDEX & written)1116     virtual PBoolean WriteFrame(
1117       const void * buf, ///<  Pointer to a block of memory to write.
1118       PINDEX count,     ///<  Number of bytes to write, <= GetWriteFrameSize()
1119       PINDEX & written  ///<  Number of bytes written, <= GetWriteFrameSize()
1120     ) { return device.WriteFrame(lineNumber, buf, count, written); }
1121 
1122     /**High level read of audio data from the device.
1123        This version will allow non-integral number of frames to be read.
1124      */
ReadBlock(void * buf,PINDEX count)1125     virtual PBoolean ReadBlock(
1126       void * buf,   ///<  Pointer to a block of memory to receive the read bytes.
1127       PINDEX count  ///<  Count of bytes to read.
1128     ) { return device.ReadBlock(lineNumber, buf, count); }
1129 
1130     /**High level write audio data to the device.
1131      */
WriteBlock(const void * buf,PINDEX count)1132     virtual PBoolean WriteBlock(
1133       const void * buf, ///<  Pointer to a block of memory to write.
1134       PINDEX count      ///<  Count of bytes to write.
1135     ) { return device.WriteBlock(lineNumber, buf, count); }
1136 
1137 
1138     /**Get average signal level in last frame.
1139       */
GetAverageSignalLevel(PBoolean playback)1140     virtual unsigned GetAverageSignalLevel(
1141       PBoolean playback   ///<  Get average playback or record level.
1142     ) { return device.GetAverageSignalLevel(lineNumber, playback); }
1143 
1144 
1145     /**Enable audio for the line.
1146       */
1147     virtual PBoolean EnableAudio(
1148       PBoolean enable = true
1149     ) { return device.EnableAudio(lineNumber, enable); }
1150 
1151     /**Disable audio for the line.
1152       */
DisableAudio()1153     PBoolean DisableAudio() { return EnableAudio(false); }
1154 
1155     /**Determine if audio is ebabled for the line.
1156       */
IsAudioEnabled()1157     virtual PBoolean IsAudioEnabled() const { return device.IsAudioEnabled(lineNumber); }
1158 
1159 
1160     /**Set volume level for recording.
1161        A value of 100 is the maximum volume possible for the hardware.
1162        A value of 0 is the minimum volume possible for the hardware.
1163       */
SetRecordVolume(unsigned volume)1164     virtual PBoolean SetRecordVolume(
1165       unsigned volume   ///<  Volume level from 0 to 100%
1166     ) { return device.SetRecordVolume(lineNumber, volume); }
1167 
1168     /**Set volume level for playing.
1169        A value of 100 is the maximum volume possible for the hardware.
1170        A value of 0 is the minimum volume possible for the hardware.
1171       */
SetPlayVolume(unsigned volume)1172     virtual PBoolean SetPlayVolume(
1173       unsigned volume   ///<  Volume level from 0 to 100%
1174     ) { return device.SetPlayVolume(lineNumber, volume); }
1175 
1176     /**Get volume level for recording.
1177        A value of 100 is the maximum volume possible for the hardware.
1178        A value of 0 is the minimum volume possible for the hardware.
1179       */
GetRecordVolume(unsigned & volume)1180     virtual PBoolean GetRecordVolume(
1181       unsigned & volume   ///<  Volume level from 0 to 100%
1182     ) { return device.GetRecordVolume(lineNumber, volume); }
1183 
1184     /**Set volume level for playing.
1185        A value of 100 is the maximum volume possible for the hardware.
1186        A value of 0 is the minimum volume possible for the hardware.
1187       */
GetPlayVolume(unsigned & volume)1188     virtual PBoolean GetPlayVolume(
1189       unsigned & volume   ///<  Volume level from 0 to 100%
1190     ) { return device.GetPlayVolume(lineNumber, volume); }
1191 
1192 
1193     /**Get acoustic echo cancellation.
1194        Note, not all devices may support this function.
1195       */
GetAEC()1196     virtual OpalLineInterfaceDevice::AECLevels GetAEC() const { return device.GetAEC(lineNumber); }
1197 
1198     /**Set acoustic echo cancellation.
1199        Note, not all devices may support this function.
1200       */
SetAEC(OpalLineInterfaceDevice::AECLevels level)1201     virtual PBoolean SetAEC(
1202       OpalLineInterfaceDevice::AECLevels level  ///<  AEC level
1203     ) { return device.SetAEC(lineNumber, level); }
1204 
1205 
1206     /**Get voice activity detection.
1207        Note, not all devices, or selected codecs, may support this function.
1208       */
GetVAD()1209     virtual PBoolean GetVAD() const { return device.GetVAD(lineNumber); }
1210 
1211     /**Set voice activity detection.
1212        Note, not all devices, or selected codecs, may support this function.
1213       */
SetVAD(PBoolean enable)1214     virtual PBoolean SetVAD(
1215       PBoolean enable       ///<  Flag for enabling VAD
1216     ) { return device.SetVAD(lineNumber, enable); }
1217 
1218 
1219     /**Get Caller ID from the last incoming ring.
1220        The idString parameter is either simply the "number" field of the caller
1221        ID data, or if full is true, all of the fields in the caller ID data.
1222 
1223        The full data of the caller ID string consists fields separated by tab
1224        characters ('\\t'), the first three are always the Calling Line Identity
1225        (CLI or calling number), the date and the Calling Line Name field. Other
1226        fields may follow and are the of the form name=value. The values are
1227        LID dependent.
1228 
1229        A false is returned if there is no Caller ID information available, e.g.
1230        if no ring has occurred.
1231       */
1232     virtual PBoolean GetCallerID(
1233       PString & idString, ///<  ID string returned
1234       PBoolean full = false   ///<  Get full information in idString
1235     ) { return device.GetCallerID(lineNumber, idString, full); }
1236 
1237     /**Set Caller ID information.
1238        The idString must be as a minimum a number fields for the Calling Line
1239        Identity.
1240 
1241        The full data of the caller ID string consists fields separated by tab
1242        characters ('\\t'), the first three are always the Calling Line Identity
1243        (CLI or calling number), the date and the Calling Line Name field. Other
1244        fields may follow and are the of the form name=value. The values are
1245        LID dependent.
1246 
1247        If the date field is missing (e.g. two consecutive tabs) then the current
1248        time and date is used. Using an empty string will clear the caller ID
1249        so that no caller ID is sent on the next RingLine() call.
1250 
1251        if the line is on hook then this information is sent when the next
1252        RingLine() function is called to start a ring cycle. Note that if the
1253        Ring cycle had already been started then this function may return false.
1254 
1255        If the line is off hook, then a Caller ID on Message Waiting is sent, if
1256        supported by the LID, otherwise false is returned.
1257       */
SetCallerID(const PString & idString)1258     virtual PBoolean SetCallerID(
1259       const PString & idString  ///<  ID string to use
1260     ) { return device.SetCallerID(lineNumber, idString); }
1261 
1262     /**Send a Visual Message Waiting Indicator
1263       */
SendVisualMessageWaitingIndicator(PBoolean on)1264     virtual PBoolean SendVisualMessageWaitingIndicator(
1265       PBoolean on
1266     ) { return device.SendVisualMessageWaitingIndicator(lineNumber, on); }
1267 
1268 
1269     /**Play a DTMF digit.
1270        Any characters that are not in the set 0-9, A-D, * or # will be ignored.
1271       */
1272     virtual PBoolean PlayDTMF(
1273       const char * digits,      ///<  DTMF digits to be played
1274       DWORD onTime = OpalLineInterfaceDevice::DefaultDTMFOnTime,  ///<  Number of milliseconds to play each DTMF digit
1275       DWORD offTime = OpalLineInterfaceDevice::DefaultDTMFOffTime ///<  Number of milliseconds between digits
1276     ) { return device.PlayDTMF(lineNumber, digits, onTime, offTime); }
1277 
1278     /**Read a DTMF digit detected.
1279        This may be characters from the set 0-9, A-D, * or #. A null ('\\0')
1280        character indicates that there are no tones in the queue.
1281        Characters E through P indicate the following tones:
1282 
1283          E = 800   F = 1000  G = 1250  H = 950   I = 1100  J = 1400
1284          K = 1500  L = 1600  M = 1800  N = 2100  O = 1300  P = 2450
1285 
1286       */
ReadDTMF()1287     virtual char ReadDTMF() { return device.ReadDTMF(lineNumber); }
1288 
1289     /**Get DTMF removal mode.
1290        When set in this mode the DTMF tones detected are removed from the
1291        encoded data stream as returned by ReadFrame().
1292       */
GetRemoveDTMF()1293     virtual PBoolean GetRemoveDTMF() { return device.GetRemoveDTMF(lineNumber); }
1294 
1295     /**Set DTMF removal mode.
1296        When set in this mode the DTMF tones detected are removed from the
1297        encoded data stream as returned by ReadFrame().
1298       */
SetRemoveDTMF(PBoolean removeTones)1299     virtual PBoolean SetRemoveDTMF(
1300       PBoolean removeTones   ///<  Flag for removing DTMF tones.
1301     ) { return device.SetRemoveDTMF(lineNumber, removeTones); }
1302 
1303 
1304     /**See if any tone is detected.
1305       */
IsToneDetected()1306     virtual OpalLineInterfaceDevice::CallProgressTones IsToneDetected() { return device.IsToneDetected(lineNumber); }
1307 
1308     /**See if any tone is detected.
1309       */
1310     virtual OpalLineInterfaceDevice::CallProgressTones WaitForToneDetect(
1311       unsigned timeout = 3000 ///< Milliseconds to wait for
1312     ) { return device.WaitForToneDetect(lineNumber, timeout); }
1313 
1314     /**See if a specific tone is detected.
1315       */
1316     virtual PBoolean WaitForTone(
1317       OpalLineInterfaceDevice::CallProgressTones tone, ///<  Tone to wait for
1318       unsigned timeout = 3000 ///<  Milliseconds to wait for
1319     ) { return device.WaitForTone(lineNumber, tone, timeout); }
1320 
1321     /**Play a tone.
1322       */
PlayTone(OpalLineInterfaceDevice::CallProgressTones tone)1323     virtual PBoolean PlayTone(
1324       OpalLineInterfaceDevice::CallProgressTones tone  ///<  Tone to be played
1325     ) { return device.PlayTone(lineNumber, tone); }
1326 
1327     /**Determine if a tone is still playing
1328       */
IsTonePlaying()1329     virtual PBoolean IsTonePlaying() { return device.IsTonePlaying(lineNumber); }
1330 
1331     /**Stop playing a tone.
1332       */
StopTone()1333     virtual PBoolean StopTone() { return device.StopTone(lineNumber); }
1334 
1335 
1336     /**Dial a number on network line.
1337        The takes the line off hook, waits for dial tone, and transmits the
1338        specified number as DTMF tones.
1339 
1340        If the requireTones flag is true the call is aborted of the call
1341        progress tones are not detected. Otherwise the call proceeds with short
1342        delays while it tries to detect the call progress tones.
1343 
1344        The return code indicates the following:
1345           DialTone  No dial tone detected
1346           RingTone  Dial was successful
1347           BusyTone  The remote phone was busy
1348           ClearTone Dial failed (usually means rang out)
1349           NoTone    There was an internal error making the call
1350       */
1351     virtual OpalLineInterfaceDevice::CallProgressTones DialOut(
1352       const PString & number,       ///< Number to dial
1353       const OpalLineInterfaceDevice::DialParams & params = OpalLineInterfaceDevice::DialParams() ///< Optional parameters for dial out.
1354     ) { return device.DialOut(lineNumber, number, params); }
1355   //@}
1356 
1357   /**@name Member variable access */
1358   //@{
1359     /**Get the device this line is on.
1360       */
GetDevice()1361     OpalLineInterfaceDevice & GetDevice() const { return device; }
1362 
1363     /**Get the number of the line on the device.
1364       */
GetLineNumber()1365     unsigned GetLineNumber() const { return lineNumber; }
1366 
1367     /**Get the token to uniquely identify this line.
1368       */
GetToken()1369     PString GetToken() const { return token; }
1370 
1371     /**Set the token to uniquely identify this line.
1372       */
SetToken(const PString & t)1373     void SetToken(const PString & t) { token = t; }
1374   //@}
1375 
1376   protected:
1377     OpalLineInterfaceDevice & device;
1378     unsigned                  lineNumber;
1379     PString                   token;
1380     PTimeInterval             ringStoppedTime;
1381     PTimeInterval             ringInterCadenceTime;
1382 
1383     PTimeInterval             ringTick;
1384     unsigned                  ringCount;
1385     bool                      lastRingState;
1386 };
1387 
1388 
1389 PLIST(OpalLineList, OpalLine);
1390 
1391 
1392 /**This class embodies the description of a Line Interface Device.
1393 
1394    An application may create a descendent off this class and override
1395    the Create() function to make the instance of a class implementing a
1396    transcoder.
1397  */
1398 class OpalLIDRegistration : public PCaselessString
1399 {
1400     PCLASSINFO(OpalLIDRegistration, PCaselessString);
1401   public:
1402   /**@name Construction */
1403   //@{
1404     /**Create a new LID registration.
1405      */
1406     OpalLIDRegistration(
1407       const char * name  ///<  Line Interface Device type name
1408     );
1409 
1410     /**Destroy and remove LID registration.
1411      */
1412     ~OpalLIDRegistration();
1413   //@}
1414 
1415   /**@name Operations */
1416   //@{
1417     /**Create an instance of the transcoder implementation.
1418       */
1419     virtual OpalLineInterfaceDevice * Create(
1420       void * parameters   ///<  Arbitrary parameters for the LID
1421     ) const = 0;
1422   //@}
1423 
1424   protected:
1425     OpalLIDRegistration * link;
1426     bool                  duplicate;
1427 
1428   friend class OpalLineInterfaceDevice;
1429 };
1430 
1431 
1432 #define OPAL_REGISTER_LID_FUNCTION(cls, type, param) \
1433 static class cls##_Registration : public OpalLIDRegistration { \
1434   public: \
1435     cls##_Registration() : OpalLIDRegistration(type) { } \
1436     OpalLineInterfaceDevice * Create(void * param) const; \
1437 } instance_##cls##_Registration; \
1438 OpalLineInterfaceDevice * cls##_Registration::Create(void * param) const
1439 
1440 #ifndef OPAL_NO_PARAM
1441 #define OPAL_NO_PARAM
1442 #endif
1443 
1444 #define OPAL_REGISTER_LID(cls, type) \
1445   OPAL_REGISTER_LID_FUNCTION(cls, type, OPAL_NO_PARAM) \
1446   { return new cls; }
1447 
1448 #define OPAL_REGISTER_LID_PARAM(cls, type) \
1449   OPAL_REGISTER_LID_FUNCTION(cls, type, parameter) \
1450   { return new cls(parameter); }
1451 
1452 
1453 #endif // OPAL_LIDS_LID_H
1454 
1455 
1456 // End of File ///////////////////////////////////////////////////////////////
1457