1 /*
2  *
3  * Inter Asterisk Exchange 2
4  *
5  * Open Phone Abstraction Library (OPAL)
6  *
7  * Define the classes that carry information over the ethernet.
8  *
9  * Copyright (c) 2005 Indranet Technologies Ltd.
10  *
11  * The contents of this file are subject to the Mozilla Public License
12  * Version 1.0 (the "License"); you may not use this file except in
13  * compliance with the License. You may obtain a copy of the License at
14  * http://www.mozilla.org/MPL/
15  *
16  * Software distributed under the License is distributed on an "AS IS"
17  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
18  * the License for the specific language governing rights and limitations
19  * under the License.
20  *
21  * The Original Code is Open Phone Abstraction Library.
22  *
23  * The Initial Developer of the Original Code is Indranet Technologies Ltd.
24  *
25  * The author of this code is Derek J Smithies
26  *
27  * $Revision: 24606 $
28  * $Author: dereksmithies $
29  * $Date: 2010-07-28 22:51:05 -0500 (Wed, 28 Jul 2010) $
30  */
31 
32 #ifndef OPAL_IAX2_FRAME_H
33 #define OPAL_IAX2_FRAME_H
34 
35 #ifndef _PTLIB_H
36 #include <ptlib.h>
37 #endif
38 
39 #include <opal/buildopts.h>
40 
41 #if OPAL_IAX2
42 
43 #include <iax2/ies.h>
44 #include <iax2/remote.h>
45 
46 #include <ptlib/sockets.h>
47 
48 #ifdef P_USE_PRAGMA
49 #pragma interface
50 #endif
51 
52 class IAX2Frame;
53 class IAX2FrameList;
54 class IAX2FullFrame;
55 class IAX2FullFrameCng;
56 class IAX2FullFrameDtmf;
57 class IAX2FullFrameHtml;
58 class IAX2FullFrameImage;
59 class IAX2FullFrameNull;
60 class IAX2FullFrameProtocol;
61 class IAX2FullFrameSessionControl;
62 class IAX2FullFrameText;
63 class IAX2FullFrameVideo;
64 class IAX2FullFrameVoice;
65 class IAX2EndPoint;
66 class IAX2Processor;
67 class IAX2CallProcessor;
68 class IAX2IeList;
69 class IAX2MiniFrame;
70 class IAX2Transmitter;
71 
72 
73 
74 /**Base class for holding data to be sent to a remote endpoint*/
75 class IAX2Frame :  public PObject
76 {
77   PCLASSINFO(IAX2Frame, PObject);
78  public:
79   /**construction */
80   IAX2Frame(IAX2EndPoint &_endpoint);
81 
82   /**Destructor - which is empty */
83   virtual ~IAX2Frame();
84 
85   /**Wait on the designated socket for an incoming UDP packet. This
86      method is only called by the receiver. This method does NO interpretation*/
87   PBoolean ReadNetworkPacket(PUDPSocket &sock);
88 
89   /**Interpret the data from the read process*/
90   virtual PBoolean ProcessNetworkPacket();
91 
92   /**True if this is a full frame */
IsFullFrame()93   virtual PBoolean IsFullFrame() { return isFullFrame; }
94 
95   /**True if it is a video frame */
IsVideo()96   PBoolean IsVideo() const { return isVideo; }
97 
98   /**True if is is an audio frame */
IsAudio()99   PBoolean IsAudio() const { return isAudio; }
100 
101   /**Pointer to the beginning of the media (after the header) in this packet.
102      The low level frame has no idea on headers, so just return pointer to beginning
103      of data. */
GetMediaDataPointer()104   virtual BYTE *GetMediaDataPointer() { return data.GetPointer(); }
105 
106   /**Number of bytes in the media section of this packet. The low
107      level frame has no idea on headers, so just return the number of
108      bytes in the packet.*/
GetMediaDataSize()109   virtual PINDEX GetMediaDataSize() { return DataSize();}
110 
111   /**Reporting function, to describe the number of bytes in this packet */
DataSize()112   PINDEX DataSize() { return data.GetSize(); }
113 
114   /**Get the value of the Remote structure */
GetRemoteInfo()115   IAX2Remote & GetRemoteInfo() { return remote; }
116 
117   /**Obtain a pointer to the current position in the incoming data array */
GetDataPointer()118   const BYTE * GetDataPointer() { return data + currentReadIndex; }
119 
120   /** Read the input frame, and create the correct IAX2MiniFrame,
121       FullFrame, and set frame type variables.  If a password is
122       supplied, decrypt the frame with this password
123 
124       This method will never delete the input frame.
125       If the output is null, it failed to derive a result.*/
126   IAX2Frame * BuildAppropriateFrameType(IAX2Encryption &encryptionInfo);
127 
128   /**Same as the preceeding function, except that encryption is off */
129   IAX2Frame * BuildAppropriateFrameType();
130 
131   /** How many bytes are unread in the incoming data array */
GetUnReadBytes()132   PINDEX   GetUnReadBytes() { return data.GetSize() - currentReadIndex; }
133 
134   /**Cause the header bytes for this particular frame type to be written to the internal array */
WriteHeader()135   virtual PBoolean WriteHeader() { return false; }
136 
137   /**Send this packet on the specified socket to the remote host. This method is only
138      called by the transmiter.*/
139   virtual PBoolean TransmitPacket(PUDPSocket &sock);
140 
141   /**Pretty print this frame data to the designated stream*/
142   virtual void PrintOn(ostream & strm) const;
143 
144   /**Calculate the timestamp value, given the call start tick*/
145   static DWORD CalcTimeStamp(const PTimeInterval & callStartTick);
146 
147   /**Write the timestamp value, in preparation for writing the
148      header. When sending a packet, the timestamp is written at packet
149      construction.*/
150   virtual void BuildTimeStamp(const PTimeInterval & callStartTick);
151 
152   /**Return a reference to the endpoint structure */
GetEndpoint()153   IAX2EndPoint & GetEndpoint() { return endpoint; }
154 
155   /**Globally unique ID string for this frame, to help track frames.
156    The value returned is a pretty printed address of this frame instance.*/
157   PString IdString() const;
158 
159   /**Get the timestamp as used by this class*/
GetTimeStamp()160   DWORD  GetTimeStamp() { return timeStamp; }
161 
162   /**Alter the timestamp as used by this class - quite unusual, but ok,.. */
163   void SetTimeStamp(DWORD newValue);
164 
165   /** Report flag stating that this call must be active when this frame is transmitted*/
CallMustBeActive()166   virtual PBoolean CallMustBeActive() { return true; }
167 
168   /**Specify the type of this frame. */
169   enum IAX2FrameType {
170     undefType        = 0,     /*!< full frame type is  Undefined                     */
171     dtmfType         = 1,     /*!< full frame type is  DTMF                          */
172     voiceType        = 2,     /*!< full frame type is  Audio                         */
173     videoType        = 3,     /*!< full frame type is  Video                         */
174     controlType      = 4,     /*!< full frame type is  Session Control               */
175     nullType         = 5,     /*!< full frame type is  NULL - frame ignored.         */
176     iax2ProtocolType = 6,     /*!< full frame type is  IAX protocol specific         */
177     textType         = 7,     /*!< full frame type is  text message                  */
178     imageType        = 8,     /*!< full frame type is  image                         */
179     htmlType         = 9,     /*!< full frame type is  HTML                          */
180     cngType          = 10,    /*!< full frame type is  CNG (comfort noise generation */
181     numFrameTypes    = 11     /*!< the number of defined IAX2 frame types            */
182   };
183 
184   /**Access the current value of the variable controlling frame type,
185      which is used when reading data from the network socket. */
GetFrameType()186   IAX2FrameType GetFrameType() { return frameType; }
187 
188   /**Method supplied here to provide basis for descendant classes.
189 
190    Whenever a frame is transmitted, this method will be called.*/
InitialiseHeader(IAX2Processor *)191   virtual void InitialiseHeader(IAX2Processor * /*processor*/) { }
192 
193   /**Return true if this frame should be retransmitted. Acks are never
194      retransmitted. cmdNew are retransmitted.*/
CanRetransmitFrame()195   PBoolean CanRetransmitFrame() const {return canRetransmitFrame; }
196 
197   /**Get the string which uniquely identifies the IAXConnection that
198      sent this frame */
GetConnectionToken()199   PString GetConnectionToken() const { return connectionToken; }
200 
201   /**Set the string which uniquely identifies the IAXConnection that
202      is responsible for this frame */
SetConnectionToken(PString newToken)203   void SetConnectionToken(PString newToken) { connectionToken = newToken; }
204 
205   /**Create the connection token, which uniquely identifies the
206      connection to process this call */
207   void BuildConnectionToken();
208 
209   /**Write the data in the variables to this frame's data array. If
210      encryption is on, the data will be encrypted */
211   PBoolean EncryptContents(IAX2Encryption &encData);
212 
213   /**Get the offset to the beginning of the encrypted region */
214   virtual PINDEX GetEncryptionOffset();
215 
216  protected:
217 
218   /**Use the supplied encryptionKey, and data in storage, to decrypt this frame.
219 
220   Return False if the decryption fails, true if the decryption works.*/
221   PBoolean DecryptContents(IAX2Encryption & encryption);
222 
223   /**Specification of the location (address, call number etc) of the
224      far endpoint */
225   IAX2Remote  remote;
226 
227   /**Variable specifying the IAX type of frame that this is. Used only
228      in reading from the network */
229   IAX2FrameType frameType;
230 
231   /** Read 1 byte from the internal area, (Internal area is filled
232       when reading the packet in). Big Endian.*/
233   PBoolean          Read1Byte(BYTE & res);
234 
235   /** Read 2 bytes from the internal area, (Internal area is filled
236       when reading the packet in) Big Endian.*/
237   PBoolean          Read2Bytes(PINDEX & res);
238 
239   /** Read 2 bytes from the internal area, (Internal area is filled
240       when reading the packet in) Big Endian.*/
241   PBoolean          Read2Bytes(WORD & res);
242 
243   /** Read 4 bytes from the internal area, (Internal area is filled
244       when reading the packet in) Big Endian.*/
245   PBoolean          Read4Bytes(DWORD & res);
246 
247   /** Write 1 byte to the internal area, as part of writing the header
248       info */
249   void          Write1Byte(BYTE newVal);
250 
251   /** Write 1 byte to the internal area, as part of writing the header
252       info. Send only the lowest 8 bits of source*/
253   void          Write1Byte(PINDEX newVal);
254 
255   /** Write 2 bytes to the internal area, as part of writing the
256       header info Big Endian.*/
257   void          Write2Bytes(PINDEX newVal);
258 
259   /** Write 4 bytes to the internal area, as part of writing the
260       header info Big Endian.*/
261   void          Write4Bytes(unsigned int newVal);
262 
263   /** Initialise all internal storage in this structrue */
264   void          ZeroAllValues();
265 
266   /**Reference to the global variable of this program */
267   IAX2EndPoint      & endpoint;
268 
269   /**Internal storage array, ready for sending to remote node, or
270      ready for receiving from remote node*/
271   PBYTEArray         data;
272 
273   /**Flag to indicate if this is a MiniFrame or FullFrame */
274   PBoolean               isFullFrame;
275 
276   /**Flag to indicate if this is a MiniFrame with video */
277   PBoolean               isVideo;
278 
279   /**Flag to indicate if this is a MiniFrame with audio */
280   PBoolean               isAudio;
281 
282   /**Index of where we are reading from the internal data area */
283   PINDEX               currentReadIndex;
284 
285   /**Index of where we are writing to  the internal data area */
286   PINDEX               currentWriteIndex;
287 
288   /**unsigned 32 bit representaiton of the time of this day */
289   DWORD                timeStamp;
290 
291   /**Indicate if this frame can be retransmitted*/
292   PBoolean               canRetransmitFrame;
293 
294   /**Connection Token, which uniquely identifies the IAX2Connection
295      that sent this frame. The token will (except for the first setup
296      packet) uniquely identify the IAX2Connection that is to receive
297      this incoming frame.  */
298   PString connectionToken;
299 
300   /**The time stamp to use, for those cases when the user demands a
301    * particular timestamp on construction. */
302   DWORD presetTimeStamp;
303 };
304 
305 /////////////////////////////////////////////////////////////////////////////
306 /**Class to manage a mini frame, which is sent unreliable to the remote endpoint*/
307 class IAX2MiniFrame : public IAX2Frame
308 {
309   PCLASSINFO(IAX2MiniFrame, IAX2Frame);
310  public:
311   /**Construction from a supplied dataframe.
312      In this case, this class is filled from an incoming data packet*/
313   IAX2MiniFrame(const IAX2Frame & srcFrame);
314 
315   /** Construction from an endpoint, to create an empty frame. */
316   IAX2MiniFrame(IAX2EndPoint & _endpoint);
317 
318   /**Construction from an encoded audio array (stored in a
319      PBYTEArray), in preparation to sending to remote node.  The
320      constructor will not delete the supplied PBYTEArray structure.
321 
322      TimeStamp will be calculated from time since call started, if the
323      users timestamp is 0.  If the users timeStamp is non zero, the
324      frames timestamp will be this.
325   */
326   IAX2MiniFrame(IAX2Processor * con, PBYTEArray &sound, PBoolean isAudio, DWORD usersTimeStamp = 0);
327 
328   /**Destructor*/
329   virtual ~IAX2MiniFrame();
330 
331   /** Process the incoming frame some more, but process it as this
332       frame type demands*/
333   virtual PBoolean ProcessNetworkPacket();
334 
335   /**Write the header to the internal data area */
336   virtual PBoolean WriteHeader();
337 
338   /**Pretty print this frame data to the designated stream*/
339   virtual void PrintOn(ostream & strm) const;
340 
341   /**Pointer to the beginning of the media (after the header) in this
342      packet */
343   virtual BYTE *GetMediaDataPointer();
344 
345   /**Number of bytes in the media section of this packet. */
346   virtual PINDEX GetMediaDataSize();
347 
348   /**Fix the timestamp in this class, after being shrunk in the MiniFrames */
349   void AlterTimeStamp(PINDEX newValue);
350 
351   /**Given the supplied Connection class, write the first 12 bytes of the frame.
352      This method is called by the frame constructors, in preparation for transmission.
353      This method is never called when processing a received frame.
354 
355      Whenever a frame is transmitted, this method will be called.*/
356   virtual void InitialiseHeader(IAX2Processor *processor);
357 
358   /**Get the offset to the beginning of the encrypted region */
359   virtual PINDEX GetEncryptionOffset();
360 
361  protected:
362   /**Initialise valus in this class to some preset value */
363   void ZeroAllValues();
364 };
365 
366 /////////////////////////////////////////////////////////////////////////////
367 /////////////////////////////////////////////////////////////////////////////
368 /**Class to handle a full frame, which is sent reliably to the remote endpoint */
369 class IAX2FullFrame : public IAX2Frame
370 {
371   PCLASSINFO(IAX2FullFrame, IAX2Frame);
372  public:
373   /**Construction from a supplied dataframe.
374      In this case, this class is filled from an incoming data packet*/
375   IAX2FullFrame(const IAX2Frame & srcFrame);
376 
377   /** Construction from an endpoint, to create an empty frame.
378       In this case, the class is filled with the various methods*/
379   IAX2FullFrame(IAX2EndPoint  &_endpoint);
380 
381   /**Delete this frame now, but first we have to delete every timer on it.
382    */
383   virtual ~IAX2FullFrame();
384 
385   /**Return True if this an ack frame */
IsAckFrame()386   PBoolean IsAckFrame() { return isAckFrame; }
387 
388   /**Return True if this is a PING frame */
389   PBoolean IsPingFrame();
390 
391   /**Return True if this is a NEW frame */
392   PBoolean IsNewFrame();
393 
394   /**Return True if this is a LAGRQ frame */
395   PBoolean IsLagRqFrame();
396 
397   /**Return True if this is a LAGRP frame */
398   PBoolean IsLagRpFrame();
399 
400   /**Return True if this is a PONG frame */
401   PBoolean IsPongFrame();
402 
403   /**Return True if this is a AuthReq frame */
404   PBoolean IsAuthReqFrame();
405 
406   /**Return True if this is a VNAK frame */
407   PBoolean IsVnakFrame();
408 
409   /**Return True if this is a REGREQ frame */
410   PBoolean IsRegReqFrame();
411 
412   /**Return True if this is a REGAUTH frame */
413   PBoolean IsRegAuthFrame();
414 
415   /**Return True if this is a REGACK frame */
416   PBoolean IsRegAckFrame();
417 
418   /**Return True if this is a REGREL frame */
419   PBoolean IsRegRelFrame();
420 
421   /**Return True if this is a REGREJ frame */
422   PBoolean IsRegRejFrame();
423 
424   /**Return True if this is a CALLTOKEN frame */
425   PBoolean IsCallTokenFrame();
426 
427   /**Return True if this FullFrame is of a type that increments the
428      InSeqNo */
429   PBoolean FrameIncrementsInSeqNo();
430 
431   /**True if this is a full frame - always returns true as this is a
432      full frame. */
IsFullFrame()433   virtual PBoolean IsFullFrame() { return true; }
434 
435   /**Report true if this is a hangup frame. We need this information
436      for processing incoming frames, before fully dissection of the
437      frame has completed */
438   PBoolean IsHangupFrame();
439 
440   /** Initialise to zero all the members of this particular class */
441   void ZeroAllValues();
442 
443   /** Process the incoming frame some more, but process it as a full
444       frame */
445   virtual PBoolean ProcessNetworkPacket();
446 
447   /**Send this packet on the specified socket to the remote host. This
448      method is only called by the transmiter.*/
449   virtual PBoolean TransmitPacket(PUDPSocket &sock);
450 
451   /**Get text descrption of this frame type*/
452   PString GetFullFrameName() const;
453 
454   /**Get text description of the subclass contents*/
GetSubClassName()455   virtual PString GetSubClassName() const
456     { return PString(" subclass=") + PString(subClass); }
457 
458   /**Stop the timer, so this packet is not retransmitted. Mark packet
459      as dead. This happens when a packet has been received that
460      matches one of the previously sent packets. */
461   void MarkDeleteNow();
462 
463   /**A Vnak frame has been received. This Vnak frame is demanding that
464      we resend this particular frame. Given it is to be resent by
465      vnak, we reset the countdown variables. E.G. it gets the full
466      amount of retries again. */
467   void MarkVnakSendNow();
468 
469   /**Pointer to the beginning of the media (after the header) in this
470      packet */
471   virtual BYTE *GetMediaDataPointer();
472 
473   /**Number of bytes in the media section of this packet. */
474   virtual PINDEX GetMediaDataSize();
475 
476   /**Determine the current value of the subClass variable */
GetSubClass()477   PINDEX GetSubClass() const { return subClass; }
478 
479   /**Dry the current value of the subClass variable */
SetSubClass(PINDEX newValue)480   void SetSubClass(PINDEX newValue) { subClass = newValue;}
481 
482   /**Write the header for this class to the internal data array. 12
483      bytes of data are writen.  The application developer must write
484      the remaining bytes, before transmiting this frame. */
485   virtual PBoolean WriteHeader();
486 
487   /**Alter the two bytes for in and out sequence values. (in the
488      header)*/
489   void ModifyFrameHeaderSequenceNumbers(PINDEX inNo, PINDEX outNo);
490 
491   /**Alter the four bytes for this frames timestamp. It is required,
492      when transmitting full frames, that there is a 3ms interval to
493      last full frame in the timestamps. This is required by
494      limitations in the handline of time in asterisk. */
495   void ModifyFrameTimeStamp(PINDEX newTimeStamp);
496 
497   /**Mark this frame as having (or not having) information elements*/
InformationElementsPresent()498   virtual PBoolean InformationElementsPresent() { return false; }
499 
500   /**Get flag to see if this frame is ready to be sent (or resent). In
501      other words, has the timer expired?*/
SendFrameNow()502   PBoolean  SendFrameNow() { return sendFrameNow; }
503 
504   /**Get flag to see if this frame is ready for deletion. In other
505      words. Has it been sent too many times? */
DeleteFrameNow()506   PBoolean  DeleteFrameNow() { return deleteFrameNow; }
507 
508   /**Get the sequence number info (inSeqNo and outSeqNo) */
GetSequenceInfo()509   IAX2SequenceNumbers & GetSequenceInfo() { return sequence; }
510 
511   /**Pretty print this frame data to the designated stream*/
512   virtual void PrintOn(ostream & strm) const;
513 
514   /**Mark this frame as having been resent (set bit 7 of data[2])*/
515   void MarkAsResent();
516 
517   /**Compare this FullFrame with another full frame, which is used when determining if we are
518      dealing with a frame we have already processed */
519   PBoolean operator *= (IAX2FullFrame & other);
520 
521   /**enum to define if the call must be active when sending this
522      frame*/
523   enum ConnectionRequired {
524     callActive,      /*!< the call must be active when sending frame*/
525     callIrrelevant   /*!< the call may, or may not be, active when sending frame*/
526   };
527 
528   /**Return the FullFrame type represented here (voice, protocol, session etc*/
GetFullFrameType()529   virtual BYTE GetFullFrameType() { return 0; }
530 
531   /**Get the offset to the beginning of the encrypted region */
GetEncryptionOffset()532   virtual PINDEX GetEncryptionOffset() { return 4; }
533 
534  protected:
535   /** Report flag stating that this call must be active when this frame is transmitted*/
CallMustBeActive()536   virtual PBoolean CallMustBeActive() { return callMustBeActive; }
537 
538   /**Turn the 8 bit subClass value into a 16 bit representation */
539   void UnCompressSubClass(BYTE a);
540 
541   /**Turn the 16 bit subClass value into a 8 bit representation */
542   int  CompressSubClass();
543 
544   /**Mark this frame as not to be sent, and not to be deleted */
545   void ClearListFlags();
546 
547   /**Given the supplied Connection class, write the first 12 bytes of the frame.
548      This method is called by the frame construcors, in preparation for transmission.
549      This method is never called when processing a received frame.
550 
551      Whenever a frame is transmitted, this method will be called.*/
552   virtual void InitialiseHeader(IAX2Processor *processor);
553 
554 #ifdef DOC_PLUS_PLUS
555   /** pwlib constructs to cope with timeout, when transmitting a full frame.  This
556       happens when a full frame has not been acknowledged in the
557       required time period. This frame will be resent.*/
558   void OnTransmissionTimeout(PTimer &, INT);
559 #else
560   PDECLARE_NOTIFIER(PTimer, IAX2FullFrame, OnTransmissionTimeout);
561 #endif
562   /** The timer which is used to test for no reply to this frame (on transmission) */
563   PTimer transmissionTimer;
564 
565   /** integer variable specifying the uncompressed subClass value for this particular frame */
566   PINDEX subClass;
567 
568   /**Time to wait between retries */
569   PTimeInterval retryDelta;
570 
571   /**Time delta between call start and sending (or receiving)*/
572   PTimeInterval timeOffset;
573 
574   /**Number of retries this frame has undergone*/
575   PINDEX       retries;
576 
577   /** Internal variables specifying the retry time periods (in milliseconds) */
578   enum RetryTime {
579     minRetryTime = 1000,   /*!< 1000 milliseconds    */
580     maxRetryTime = 010000, /*!< 10 seconds           */
581     maxRetries   = 3       /*!< number of retries    */
582   };
583 
584   /**Class holding the sequence numbers, which is used by all classes which have a FullFrame ancestor. */
585   IAX2SequenceNumbers sequence;
586 
587   /**List flag, indicating if this frame ready for sending*/
588   PBoolean         sendFrameNow;
589 
590   /**List flag, this frame is ready for deletion (too many retries)*/
591   PBoolean         deleteFrameNow;
592 
593   /**A tracking flag to indicate this fame has been resent*/
594   PBoolean         packetResent;
595 
596   /** Flag stating that this call must be active when this frame is transmitted  */
597   PBoolean callMustBeActive;
598 
599   /** flag to indicate if this is an ack frame */
600   PBoolean isAckFrame;
601 };
602 
603 /////////////////////////////////////////////////////////////////////////////
604 
605 /**Used for transmitting dtmf characters in a reliable fashion. One
606    frame per dtmf character.  No data is carried in the data
607    section */
608 
609 class IAX2FullFrameDtmf : public IAX2FullFrame
610 {
611   PCLASSINFO(IAX2FullFrameDtmf, IAX2FullFrame);
612  public:
613   /**Construction from a supplied dataframe.
614      In this case, this class is filled from an incoming data packet*/
615   IAX2FullFrameDtmf(const IAX2Frame & srcFrame);
616 
617   /**Construction from a supplied dataframe.
618      In this case, this class is filled from an incoming data packet*/
619   IAX2FullFrameDtmf(const IAX2FullFrame & srcFrame);
620 
621   /**Construction from a Connection class.
622      Classes generated from this are then on sent to a remote endpoint. */
623   IAX2FullFrameDtmf(IAX2Processor *processor, /*!< Iax Processor from which this frame originates      */
624 		    char  subClassValue       /*!< IAX protocol command for remote end to process   */
625 		    );
626 
627   /**Construction from a Connection class.
628      Classes generated from this are then on sent to a remote endpoint. */
629   IAX2FullFrameDtmf(IAX2Processor *processor, /*!< Iax Processor from which this frame originates      */
630 		PString  subClassValue    /*!< IAX protocol command for remote end to process   */
631 		);
632 
633 
634   /**Get text description of the subclass contents*/
635   virtual PString GetSubClassName() const;
636 
637   /**enum comtaining the possible subclass value for these dtmf frames */
638   enum DtmfSc {
639     dtmf0 = 48,     /*!< DTMF character 0     */
640     dtmf1 = 49,     /*!< DTMF character 1     */
641     dtmf2 = 50,     /*!< DTMF character 2     */
642     dtmf3 = 51,     /*!< DTMF character 3     */
643     dtmf4 = 52,     /*!< DTMF character 4     */
644     dtmf5 = 53,     /*!< DTMF character 5     */
645     dtmf6 = 54,     /*!< DTMF character 6     */
646     dtmf7 = 55,     /*!< DTMF character 7     */
647     dtmf8 = 56,     /*!< DTMF character 8     */
648     dtmf9 = 57,     /*!< DTMF character 9     */
649     dtmfA = 65,     /*!< DTMF character A     */
650     dtmfB = 66,     /*!< DTMF character B     */
651     dtmfC = 67,     /*!< DTMF character C     */
652     dtmfD = 68,     /*!< DTMF character D     */
653     dtmfStar = 42,  /*!< DTMF character *     */
654     dtmfHash = 35   /*!< DTMF character #     */
655   };
656 
657   /**Return the FullFrame type represented here (voice, protocol, session etc*/
GetFullFrameType()658   virtual BYTE GetFullFrameType() { return dtmfType; }
659 
660  protected:
661 };
662 
663 /////////////////////////////////////////////////////////////////////////////
664 /**Used for transmitting voice packets in a relaible
665    fashion. Typically, one is sent at the start of the call, and then
666    at regular intervals in the call to keep the timestamps in sync.
667 
668    This class has the ability to build audio codecs, and report on available formats.
669 
670    The contents the data section is the compressed audio frame. */
671 class IAX2FullFrameVoice : public IAX2FullFrame
672 {
673   PCLASSINFO(IAX2FullFrameVoice, IAX2FullFrame);
674  public:
675 
676   /**Construction from a supplied dataframe.
677      In this case, this class is filled from an incoming data packet*/
678   IAX2FullFrameVoice(const IAX2Frame & srcFrame);
679 
680   /**Construction from a supplied dataframe.
681      In this case, this class is filled from an incoming data packet*/
682   IAX2FullFrameVoice(const IAX2FullFrame & srcFrame);
683 
684   /**Construction from an encoded audio array (stored in a
685      PBYTEArray), in preparation to sending to remote node.  The
686      constructor will not delete the supplied PBYTEArray structure.
687 
688      The full frame will use the specified timeStamp, if it is > 0.  If the
689      specified timeStamp == 0, the timeStamp will be calculated from when the
690      call started.
691   */
692   IAX2FullFrameVoice(IAX2CallProcessor *processor, PBYTEArray &sound,
693 		 PINDEX usersTimeStamp = 0);
694 
695   /**Declare an empty destructor */
696   virtual ~IAX2FullFrameVoice();
697 
698   /**Get text description of the subclass contents*/
699   virtual PString GetSubClassName() const;
700 
701   /**Get text description of the subclass contents, given the supplied
702      argument*/
GetSubClassName(unsigned short testValue)703   static PString GetSubClassName(unsigned short testValue)
704      { return GetSubClassName((unsigned int) testValue); }
705 
706   /**Get text description of the subclass contents, given the supplied
707      argument*/
708   static PString GetSubClassName(unsigned int testValue);
709 
710   /**Get text description of the subclass contents, given the supplied
711    argument.  The name returned is that recoginised by the OPAL
712    library. */
713   static PString GetOpalNameOfCodec(PINDEX testValue);
714 
715   /**Get text description of the subclass contents, given the supplied argument*/
GetSubClassName(int testValue)716   static PString GetSubClassName(int testValue)
717     { return GetSubClassName((unsigned short) testValue); }
718 
719   /**Turn the OPAL string (which describes the codec) into a AudioSc value. If there is no conversion
720      found, return 0. */
721   static unsigned short OpalNameToIax2Value(const PString opalName);
722 
723   /**enum comtaining the possible (uncompressed) subclass value for these voice frames */
724   enum AudioSc {
725     g7231    = 1,         /*!< G.723.1 audio format in this frame        */
726     gsm      = 2,         /*!< GSM audio format in this frame            */
727     g711ulaw = 4,         /*!< G.711 uLaw audio format in this frame     */
728     g711alaw = 8,         /*!< G.711 ALaw audio format in this frame     */
729     mp3      = 0x10,      /*!< MPeg 3 audio format in this frame         */
730     adpcm    = 0x20,      /*!< ADPCM audio format in this frame          */
731     pcm      = 0x40,      /*!< PCM audio format in this frame            */
732     lpc10    = 0x80,      /*!< LPC10 audio format in this frame          */
733     g729     = 0x100,     /*!< G.729 audio format in this frame          */
734     speex    = 0x200,     /*!< Speex audio format in this frame          */
735     ilbc     = 0x400,     /*!< ILBC audio format in this frame           */
736     supportedCodecs = 11  /*!< The number of codecs defined by this enum */
737   };
738 
739   /**Return the IAX2FullFrame type represented here (voice, protocol, session etc*/
GetFullFrameType()740   virtual BYTE GetFullFrameType() { return voiceType; }
741 };
742 /////////////////////////////////////////////////////////////////////////////
743 /**Used for transmitting video packets in a relaible
744    fashion. Typically, one is sent at the start of the call, and then
745    at regular intervals in the call to keep the timestamps in sync.
746 
747    The contents the data section is compressed video. */
748 class IAX2FullFrameVideo : public IAX2FullFrame
749 {
750   PCLASSINFO(IAX2FullFrameVideo, IAX2FullFrame);
751  public:
752 
753   /**Construction from a supplied dataframe.
754      In this case, this class is filled from an incoming data packet*/
755   IAX2FullFrameVideo(const IAX2Frame & srcFrame);
756 
757   /**Construction from a supplied dataframe.
758      In this case, this class is filled from an incoming data packet*/
759   IAX2FullFrameVideo(const IAX2FullFrame & srcFrame);
760 
761   /**Get text description of the subclass contents*/
762   virtual PString GetSubClassName() const;
763 
764   /**enum comtaining the possible (uncompressed) subclass value for these video frames */
765   enum VideoSc {
766     jpeg  = 0x10000,   /*!< Jpeg video format in this frame     */
767     png   = 0x20000,   /*!< PNG video format in this frame      */
768     h261  = 0x40000,   /*!< H.261 video format in this frame    */
769     h263  = 0x80000    /*!< H.263 video format in this frame    */
770   };
771 
772   /**Return the FullFrame type represented here (voice, protocol, session etc*/
GetFullFrameType()773   virtual BYTE GetFullFrameType() { return videoType; }
774  protected:
775 };
776 
777 /////////////////////////////////////////////////////////////////////////////
778 /**Used for sending  Control Frames. These are used to manipulate the session.
779 
780 Asterisk calls these AST_FRAME_CONTROLs
781 
782 No data is carried in the data section */
783 class IAX2FullFrameSessionControl : public IAX2FullFrame
784 {
785   PCLASSINFO(IAX2FullFrameSessionControl, IAX2FullFrame);
786  public:
787 
788   /**enum comtaining the possible subclass value for these Session Control frames */
789   enum SessionSc {
790     hangup          = 1,     /*!< Other end has hungup    */
791     ring            = 2,     /*!< Local ring    */
792     ringing         = 3,     /*!< Remote end is ringing    */
793     answer          = 4,     /*!< Remote end has answered    */
794     busy            = 5,     /*!< Remote end is busy    */
795     tkoffhk         = 6,     /*!< Make it go off hook    */
796     offhook         = 7,     /*!< Line is off hook    */
797     congestion      = 8,     /*!< Congestion (circuits busy)    */
798     flashhook       = 9,     /*!< Flash hook    */
799     wink            = 10,    /*!< Wink    */
800     option          = 11,    /*!< Set a low-level option    */
801     keyRadio        = 12,    /*!< Key Radio    */
802     unkeyRadio      = 13,    /*!< Un-Key Radio    */
803     callProgress    = 14,    /*!< Indicate PROGRESS    */
804     callProceeding  = 15,    /*!< Indicate CALL PROCEEDING    */
805     callOnHold      = 16,    /*!< Call has been placed on hold    */
806     callHoldRelease = 17,    /*!< Call is no longer on hold    */
807     stopSounds      = 255    /*!< Indicates the transition from ringback to bidirectional audio */
808   };
809 
810 
811 
812   /**Construction from a supplied dataframe.
813      In this case, this class is filled from an incoming data packet*/
814   IAX2FullFrameSessionControl(const IAX2Frame & srcFrame);
815 
816   /**Construction from a supplied dataframe.
817      In this case, this class is filled from an incoming data packet*/
818   IAX2FullFrameSessionControl(const IAX2FullFrame & srcFrame);
819 
820   /**Construction from a Connection class.
821      Classes generated from this are then on sent to a remote endpoint. */
822   IAX2FullFrameSessionControl(IAX2Processor *processor, /*!<Iax Processor from which this frame originates    */
823 			  PINDEX subClassValue/*!<IAX protocol command for remote end to process   */
824 			  );
825 
826   /**Construction from a Connection class.
827      Classes generated from this are then on sent to a remote endpoint. */
828   IAX2FullFrameSessionControl(IAX2Processor *processor,     /*!< Iax Processor from which this frame originates */
829 			  SessionSc subClassValue /*!< IAX protocol command for remote end to process*/
830 			  );
831 
832   /**Declare an empty destructor*/
~IAX2FullFrameSessionControl()833   virtual ~IAX2FullFrameSessionControl() { }
834 
835   /**Get text description of the subclass contents*/
836   virtual PString GetSubClassName() const;
837 
838   /**Return the IAX2FullFrame type represented here (voice, protocol, session etc*/
GetFullFrameType()839   virtual BYTE GetFullFrameType() { return controlType; }
840 
841  protected:
842 };
843 
844 /////////////////////////////////////////////////////////////////////////////
845 /**Class for transfering Nothing. It is essentially a NO Op
846    It is used internally to indicate that the sound card should play a silence frame.
847 
848    These frames are sent reliably.
849    There is no data in the subclass section.
850    There is no data in the data section */
851 class IAX2FullFrameNull : public IAX2FullFrame
852 {
853   PCLASSINFO(IAX2FullFrameNull, IAX2FullFrame);
854  public:
855   /**Construct an empty Full Frame.
856      Classes generated like this are used to handle transmitted information */
IAX2FullFrameNull(IAX2EndPoint & endpoint)857   IAX2FullFrameNull(IAX2EndPoint & endpoint) : IAX2FullFrame(endpoint)   { }
858 
859   /**Construction from a supplied dataframe.
860      In this case, this class is filled from an incoming data packet.
861      Classes generated like this are used to handle received data. */
862   IAX2FullFrameNull(const IAX2Frame & srcFrame);
863 
864   /**Construction from a supplied dataframe.
865      In this case, this class is filled from an incoming data packet.
866      Classes generated like this are used to handle received data. */
867   IAX2FullFrameNull(const IAX2FullFrame & srcFrame);
868 
869   /**Get text description of the subclass contents*/
GetSubClassName()870   virtual PString GetSubClassName() const { return  PString(""); }
871 
872   /**Return the IAX2FullFrame type represented here (voice, protocol, session etc*/
GetFullFrameType()873   virtual BYTE GetFullFrameType() { return nullType; }
874 
875  protected:
876 };
877 
878 /////////////////////////////////////////////////////////////////////////////
879 /**Handle IAX specific protocol issues. Used for initiating a call,
880    closing a call, registration, reject a call etc.. These are used to
881    manipulate the session.
882 
883    The data section contains information elements, or type Ie classes. */
884 
885 class IAX2FullFrameProtocol : public IAX2FullFrame
886 {
887   PCLASSINFO(IAX2FullFrameProtocol, IAX2FullFrame);
888  public:
889 
890   /**enum comtaining the possible subclass value for these IAX protocol control frames */
891   enum ProtocolSc {
892     cmdNew       =  1,       /*!< Create a new call    */
893     cmdPing      =  2,       /*!< Ping request, which is done on an open call. It is "Are you Alive    */
894     cmdPong      =  3,       /*!< reply to a Ping    */
895     cmdAck       =  4,       /*!< Acknowledge a Reliably sent full frame    */
896     cmdHangup    =  5,       /*!< Request to terminate this call    */
897     cmdReject    =  6,       /*!< Refuse to accept this call. May happen if authentication faile    */
898     cmdAccept    =  7,       /*!< Allow this call to procee    */
899     cmdAuthReq   =  8,       /*!< Ask remote end to supply authenticatio    */
900     cmdAuthRep   =  9,       /*!< A reply, that contains authenticatio    */
901     cmdInval     =  10,      /*!< Destroy this call immediatly    */
902     cmdLagRq     =  11,      /*!< Initial message, used to measure the round trip time    */
903     cmdLagRp     =  12,      /*!< Reply to cmdLagrq, which tells us the round trip time    */
904     cmdRegReq    =  13,      /*!< Request for Registration    */
905     cmdRegAuth   =  14,      /*!< Registration requires for authentication    */
906     cmdRegAck    =  15,      /*!< Registration has been accepted    */
907     cmdRegRej    =  16,      /*!< Registration has been rejected    */
908     cmdRegRel    =  17,      /*!< Force the release of the current registration    */
909     cmdVnak      =  18,      /*!< This indicates out of order frames, and can be read as voice not acknowledged */
910     cmdDpReq     =  19,      /*!< Request the status of an entry for dialplan     */
911     cmdDpRep     =  20,      /*!< Request status of an entry for  dialplan     */
912     cmdDial      =  21,      /*!< Request that there is a dial (TBD) on a channel    */
913     cmdTxreq     =  22,      /*!< Request a Transfer    */
914     cmdTxcnt     =  23,      /*!< Connect up a  Transfer     */
915     cmdTxacc     =  24,      /*!< Transfer has been accepted    */
916     cmdTxready   =  25,      /*!< Transfer is ready to happen   */
917     cmdTxrel     =  26,      /*!< Release a Transfer    */
918     cmdTxrej     =  27,      /*!< Reject a Transfer   */
919     cmdQuelch    =  28,      /*!< Stop media transmission    */
920     cmdUnquelch  =  29,      /*!< Resume media transmission    */
921     cmdPoke      =  30,      /*!< Query the remote endpoint (there is no open connection) */
922     cmdPage      =  31,      /*!< Do a Page */
923     cmdMwi       =  32,      /*!< Indicate : message waiting */
924     cmdUnsupport =  33,      /*!< We have received an unsupported message */
925     cmdTransfer  =  34,      /*!< Initiate the remote end to do a transfer */
926     cmdProvision =  35,      /*!< Provision the remote end    */
927     cmdFwDownl   =  36,      /*!< The remote end must download some firmware    */
928     cmdFwData    =  37,      /*!< This message contains firmware.    */
929     cmdTxMedia   =  38,      /*!< undocumented - for now . */
930     cmdRtKey     =  39,      /*!< More undocumented. Apologies */
931     cmdCallToken =  40       /*!< Prevents DOS attack of handling multiple incoming calls. */
932   };
933 
934   /**Construction from a supplied dataframe.
935      In this case, this class is filled from an incoming data packet.
936      Classes generated like this are used to handle received data. */
937   IAX2FullFrameProtocol(const IAX2Frame & srcFrame);
938 
939   /**Construction from a supplied dataframe.
940      In this case, this class is filled from an incoming data packet.
941      Classes generated like this are used to handle received data. */
942   IAX2FullFrameProtocol(const IAX2FullFrame & srcFrame);
943 
944   /**Construction from a Connection class.
945      Classes generated from this are then on sent to a remote endpoint. */
946   IAX2FullFrameProtocol(IAX2Processor *processor,         /*!< Iax Processor from which this frame originates            */
947 		    PINDEX subClassValue,            /*!< IAX protocol command for remote end to process         */
948 		    ConnectionRequired needCon = IAX2FullFrame::callActive
949 		                                     /*!< this frame is only sent if the Connection class exists */
950 		    );
951 
952   /**Construction from an Connection class.
953      Classes generated from this are then on sent to a remote endpoint. */
954   IAX2FullFrameProtocol(IAX2Processor *processor,         /*!< Iax Processor from which this frame originates            */
955 		    ProtocolSc  subClassValue,       /*!< IAX protocol command for remote end to process         */
956 		    ConnectionRequired needCon=IAX2FullFrame::callActive
957 		                                     /*!< this frame is only sent if the Connection class exists */
958 		    );
959 
960   /**Construction from a Connection class.
961      Classes generated from this are then on sent to a remote endpoint.
962 
963      We have received a IAX2FullFrameProtocol, and this constructor is used to create a reply.
964      Use the iseqno and time stamp from the supplied frame to construct the reply */
965   IAX2FullFrameProtocol(IAX2Processor *processor,         /*!< Iax Processor from which this frame originates            */
966 		    ProtocolSc  subClassValue,       /*!< IAX protocol command for remote end to process         */
967 		    IAX2FullFrame *inReplyTo,            /*!< this message was sent in reply to this frame           */
968 		    ConnectionRequired needCon = IAX2FullFrame::callActive
969 		                                     /*!< this frame is only sent if the Connection class exists */
970 		    );
971 
972   /**Destructor, which deletes all current Information Elements */
973   virtual ~IAX2FullFrameProtocol();
974 
975   /**Set internal variable to say that this frame does not need to be retransmitted*/
976   void SetRetransmissionRequired();
977 
978   /**Mark this frame as having (or not having) information elements*/
InformationElementsPresent()979   virtual PBoolean InformationElementsPresent() { return !ieElements.IsEmpty(); }
980 
981   /**Report the current value of the subClass variable */
GetSubClass()982   ProtocolSc GetSubClass() const { return (ProtocolSc) subClass; }
983 
984   /**Get text description of the subclass contents*/
985   virtual PString GetSubClassName() const;
986 
987   /**Get text description of the subclass contents*/
988   static PString GetSubClassName(PINDEX t);
989 
990   /**Return a pointer to the n'th Ie in the internal list. If it is not
991      there, a NULL is returned */
GetIeAt(PINDEX i)992   IAX2Ie *GetIeAt(PINDEX i) {      return ieElements.GetIeAt(i); }
993 
994   /**Add a new Information Element (Ie) to the intenral list */
AppendIe(IAX2Ie * newElement)995   void AppendIe(IAX2Ie *newElement) { ieElements.AppendIe(newElement); }
996 
997   /**Write the contents of the Ie internal list to the frame data array.
998      This is usually done in preparation to transmitting this frame */
999   void WriteIeAsBinaryData();
1000 
1001   /**Transfer the data (stored in the IeList) and place it in into
1002      the IeData class.  This is done when precessing a frame we
1003      have received from an external node, which has to be stored in the IeData class*/
1004   void CopyDataFromIeListTo(IAX2IeData &res);
1005 
1006   /**Look through the list of IEs, and look for remote capabability
1007      and preferred codec */
1008   void GetRemoteCapability(unsigned int & capability,
1009 			   unsigned int & preferred);
1010 
1011   /**Return the IAX2FullFrame type represented here (voice, protocol,
1012      session etc*/
GetFullFrameType()1013   virtual BYTE GetFullFrameType() { return iax2ProtocolType; }
1014 
1015   /**Pretty print this frame data to the designated stream*/
1016   virtual void PrintOn(ostream & strm) const;
1017 
1018   /**Go through the list of IEs read in, and find the CallToken Ie,
1019      and return a copy of it to the caller. If found, return true. */
1020   PBoolean GetCallTokenIe(IAX2IeCallToken & callToken);
1021 
1022  protected:
1023 
1024   /**Read the information elements from the incoming data array
1025      to generate a list of information element classes*/
1026   PBoolean ReadInformationElements();
1027 
1028 
1029   /**A list of the IEs read from/(or written to) the data section of
1030      this frame,*/
1031   IAX2IeList ieElements;
1032 
1033   /**Pretty print the protocol value with an English word. */
1034 #if PTRACING
1035     friend ostream & operator<<(ostream & o, ProtocolSc t);
1036 #endif
1037 };
1038 
1039 /////////////////////////////////////////////////////////////////////////////
1040 /**Class for transfering text. These frames are sent reliably.
1041    There is no data in the subclass section.
1042 
1043    The text is carried in the data section.
1044 */
1045 class IAX2FullFrameText : public IAX2FullFrame
1046 {
1047   PCLASSINFO(IAX2FullFrameText, IAX2FullFrame);
1048  public:
1049 
1050   /**Construction from a Connection class.
1051      Classes generated from this are then on sent to a remote endpoint. */
1052   IAX2FullFrameText(IAX2Processor *processor,       /*!< Iax Processor from which this frame originates      */
1053 		const PString&  textValue/*!< text to send to remote end   */
1054 		);
1055 
1056   /**Construction from a supplied dataframe.
1057      In this case, this class is filled from an incoming data packet*/
1058   IAX2FullFrameText(const IAX2Frame & srcFrame);
1059 
1060   /**Construction from a supplied dataframe.
1061      In this case, this class is filled from an incoming data packet*/
1062   IAX2FullFrameText(const IAX2FullFrame & srcFrame);
1063 
1064   /**Get text description of the subclass contents*/
1065   virtual PString GetSubClassName() const;
1066 
1067   /**Return the IAX2FullFrame type represented here (voice, protocol, session etc*/
GetFullFrameType()1068   virtual BYTE GetFullFrameType() { return textType; }
1069 
1070   /**Return the text data*/
1071   PString GetTextString() const;
1072 
1073  protected:
1074 
1075   /**The text string that will be placed in the body of this message */
1076   PString internalText;
1077 };
1078 /////////////////////////////////////////////////////////////////////////////
1079 
1080 /**Class for transfering images. These frames are sent reliably.
1081    The subclass describes the image compression format.
1082 
1083    The contents of the data section is the raw image data */
1084 class IAX2FullFrameImage : public IAX2FullFrame
1085 {
1086   PCLASSINFO(IAX2FullFrameImage, IAX2FullFrame);
1087  public:
1088 
1089   /**Construction from a supplied dataframe.
1090      In this case, this class is filled from an incoming data packet*/
1091   IAX2FullFrameImage(const IAX2Frame & srcFrame);
1092 
1093   /**Construction from a supplied dataframe.
1094      In this case, this class is filled from an incoming data packet*/
1095   IAX2FullFrameImage(const IAX2FullFrame & srcFrame);
1096 
1097   /**Get text description of the subclass contents*/
1098   virtual PString GetSubClassName() const;
1099 
1100   /**Return the IAX2FullFrame type represented here (voice, protocol, session etc*/
GetFullFrameType()1101   virtual BYTE GetFullFrameType() { return imageType; }
1102  protected:
1103 };
1104 
1105 /////////////////////////////////////////////////////////////////////////////
1106 
1107 /**Class for transfering html. These frames are sent reliably.
1108    The subclass describes the html frame type.
1109 
1110    The contents of the data section is message specific */
1111 class IAX2FullFrameHtml : public IAX2FullFrame
1112 {
1113   PCLASSINFO(IAX2FullFrameHtml, IAX2FullFrame);
1114  public:
1115 
1116   /**Construction from a supplied dataframe.
1117      In this case, this class is filled from an incoming data packet*/
1118   IAX2FullFrameHtml(const IAX2Frame & srcFrame);
1119 
1120   /**Construction from a supplied dataframe.
1121      In this case, this class is filled from an incoming data packet*/
1122   IAX2FullFrameHtml(const IAX2FullFrame & srcFrame);
1123 
1124   /**Get text description of the subclass contents*/
1125   virtual PString GetSubClassName() const;
1126 
1127   /**Return the IAX2FullFrame type represented here (voice, protocol, session etc*/
GetFullFrameType()1128   virtual BYTE GetFullFrameType() { return htmlType; }
1129  protected:
1130 };
1131 
1132 /////////////////////////////////////////////////////////////////////////////
1133 /**Class for transfering Cng (comfort noise generation). These frames are sent reliably.
1134 
1135 
1136 The contents of the data section is message specific */
1137 class IAX2FullFrameCng : public IAX2FullFrame
1138 {
1139   PCLASSINFO(IAX2FullFrameCng, IAX2FullFrame);
1140  public:
1141 
1142   /**Construction from a supplied dataframe.
1143      In this case, this class is filled from an incoming data packet*/
1144   IAX2FullFrameCng(const IAX2Frame & srcFrame);
1145 
1146   /**Construction from a supplied dataframe.
1147      In this case, this class is filled from an incoming data packet*/
1148   IAX2FullFrameCng(const IAX2FullFrame & srcFrame);
1149 
1150   /**Get text description of the subclass contents*/
1151   virtual PString GetSubClassName() const;
1152 
1153   /**Return the IAX2FullFrame type represented here (voice, protocol, session etc*/
GetFullFrameType()1154   virtual BYTE GetFullFrameType() { return cngType; }
1155  protected:
1156 };
1157 
1158 /////////////////////////////////////////////////////////////////////////////
1159 
PDECLARE_LIST(IAX2FrameList,IAX2Frame *)1160 PDECLARE_LIST (IAX2FrameList, IAX2Frame *)
1161 #ifdef DOC_PLUS_PLUS     //This makes emacs bracket matching code happy.
1162 /** A list of all frames waiting for processing
1163 
1164     Note please, this class is thread safe.
1165 
1166    You do not need to protect acces to this class.
1167 */
1168 class IAX2FrameList : public IAX2Frame *
1169 {
1170 #endif
1171  public:
1172   ~IAX2FrameList();
1173 
1174   /**Report the frames queued in this list*/
1175   void ReportList(PString & answer);
1176 
1177   /**Get pointer to last frame in the list. Remove this frame from the list */
1178   IAX2Frame *GetLastFrame();
1179 
1180   /**Removing item from list will not automatically delete it */
1181   void Initialise();
1182 
1183   /**True if this frame list is empty*/
1184   PBoolean Empty() { return GetSize() == 0; }
1185 
1186   /**Copy to this frame the contents of the frameList pointed to by src*/
1187   void GrabContents(IAX2FrameList &src);
1188 
1189   /**Delete the frame that has been sent, which is waiting for this
1190      reply. The reply is the argument. */
1191   void DeleteMatchingSendFrame(IAX2FullFrame *reply);
1192 
1193   /** A Vnak frame has been received (voice not acknowledged) which actually
1194       means, retransmit all those frames you have on this particular call
1195       number from the oseqno specified in the supplied frame */
1196   void SendVnakRequestedFrames(IAX2FullFrameProtocol &src);
1197 
1198   /**Add the frame (supplied as an argument) to the end of this list*/
1199   void AddNewFrame(IAX2Frame *src);
1200 
1201   /**Get a list of frames to send, and delete the timed out frames */
1202   void GetResendFramesDeleteOldFrames(IAX2FrameList & framesToSend);
1203 
1204   /**Thread safe read of the number of elements on this list. */
1205   virtual PINDEX GetSize() { PWaitAndSignal m(mutex); return PAbstractList::GetSize(); }
1206 
1207   /**Mark every frame on this list as having been resent*/
1208   void MarkAllAsResent();
1209 
1210  protected:
1211   /**NON Thread safe read of the number of elements on this list. */
1212   virtual PINDEX GetEntries() { return PAbstractList::GetSize(); }
1213 
1214   /**Local variable which protects access. */
1215   PMutex mutex;
1216 };
1217 
1218 /////////////////////////////////////////////////////////////////////////////
1219 /**The class IAX2ActiveFrameList is essentially the same as
1220    IAX2FrameList, except that it is initialised (by default) and the
1221    user is not required to use the Initialise method. This class will
1222    not ever automatically delete members when they are removed */
1223 class IAX2ActiveFrameList : public IAX2FrameList
1224 {
1225   PCLASSINFO(IAX2ActiveFrameList, IAX2FrameList);
1226  public:
IAX2ActiveFrameList()1227   IAX2ActiveFrameList() { Initialise(); }
1228 };
1229 /////////////////////////////////////////////////////////////////////////////
1230 
1231 
1232 #endif // OPAL_IAX2
1233 
1234 #endif // OPAL_IAX2_FRAME_H
1235 
1236 /* The comment below is magic for those who use emacs to edit this file.
1237  * With the comment below, the tab key does auto indent to 2 spaces.
1238  *
1239  * Local Variables:
1240  * mode:c
1241  * c-basic-offset:2
1242  * End:
1243  */
1244