1 /*
2  * h224handler.h
3  *
4  * H.224 protocol handler implementation for the OpenH323 Project.
5  *
6  * Copyright (c) 2006 Network for Educational Technology, ETH Zurich.
7  * Written by Hannes Friederich.
8  *
9  * The contents of this file are subject to the Mozilla Public License
10  * Version 1.0 (the "License"); you may not use this file except in
11  * compliance with the License. You may obtain a copy of the License at
12  * http://www.mozilla.org/MPL/
13  *
14  * Software distributed under the License is distributed on an "AS IS"
15  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
16  * the License for the specific language governing rights and limitations
17  * under the License.
18  *
19  * Contributor(s): ______________________________________.
20  *
21  * $Revision: 27149 $
22  * $Author: rjongbloed $
23  * $Date: 2012-03-07 18:32:36 -0600 (Wed, 07 Mar 2012) $
24  */
25 
26 #ifndef OPAL_H224_H224HANDLER_H
27 #define OPAL_H224_H224HANDLER_H
28 
29 #ifdef P_USE_PRAGMA
30 #pragma interface
31 #endif
32 
33 #ifndef _PTLIB_H
34 #include <ptlib.h>
35 #endif
36 
37 #include <opal/buildopts.h>
38 
39 #include <opal/connection.h>
40 #include <opal/transports.h>
41 #include <opal/mediastrm.h>
42 #include <rtp/rtp.h>
43 #include <h224/h224.h>
44 
45 class OpalH224Handler;
46 
47 class OpalH224Client : public PObject
48 {
49   PCLASSINFO(OpalH224Client, PObject);
50 
51 public:
52 
53   OpalH224Client();
54   ~OpalH224Client();
55 
56   enum {
57     CMEClientID         = 0x00,
58     H281ClientID        = 0x01,
59     ExtendedClientID    = 0x7e,
60     NonStandardClientID = 0x7f,
61   };
62 
63   /**Return the client ID if this is a standard client.
64      Else, return either ExtendedClientId or NonStandardClientID
65     */
66   virtual BYTE GetClientID() const = 0;
67 
68   /**Return the extended client ID if given. The default returns 0x00
69     */
GetExtendedClientID()70   virtual BYTE GetExtendedClientID() const { return 0x00; }
71 
72   /**Return the T.35 country code octet for the non-standard client.
73      Default returns CountryCodeEscape
74     */
GetCountryCode()75   virtual BYTE GetCountryCode() const { return 0xff; /* CountryCodeEscape */ }
76 
77   /**Return the T.35 extension code octet for the non-standard client.
78      Default returns 0x00
79     */
GetCountryCodeExtension()80   virtual BYTE GetCountryCodeExtension() const { return 0x00; }
81 
82   /**Return the manufacturer code word for the non-standard client.
83      Default returns 0x0000
84     */
GetManufacturerCode()85   virtual WORD GetManufacturerCode() const { return 0x0000; }
86 
87   /**Return the Manufacturer Client ID for the non-standard client.
88      Default returns 0x00;
89     */
GetManufacturerClientID()90   virtual BYTE GetManufacturerClientID() const { return 0x00; }
91 
92   /**Return whether this client has extra capabilities.
93      Default returns FALSE.
94     */
HasExtraCapabilities()95   virtual PBoolean HasExtraCapabilities() const { return false; }
96 
97   /**Called if the CME client received an Extra Capabilities PDU for this client.
98      Default does nothing.
99     */
OnReceivedExtraCapabilities(const BYTE *,PINDEX)100   virtual void OnReceivedExtraCapabilities(const BYTE * /*capabilities*/, PINDEX /*size*/) { }
101 
102   /**Called if a PDU for this client was received.
103      Default does nothing.
104     */
OnReceivedMessage(const H224_Frame &)105   virtual void OnReceivedMessage(const H224_Frame & /*message*/) { }
106 
107   /**Called to indicate that the extra capabilities pdu should be sent.
108      Default does nothing
109     */
SendExtraCapabilities()110   virtual void SendExtraCapabilities() const { }
111 
112   virtual Comparison Compare(const PObject & obj);
113 
114   /**Connection to the H.224 protocol handler */
SetH224Handler(OpalH224Handler * handler)115   void SetH224Handler(OpalH224Handler * handler) { h224Handler = handler; }
116 
117   /**Called by the H.224 handler to indicate if the remote party has such a client or not */
118   void SetRemoteClientAvailable(PBoolean remoteClientAvailable, PBoolean remoteClientHasExtraCapabilities);
119 
GetRemoteClientAvailable()120   PBoolean GetRemoteClientAvailable() const { return remoteClientAvailable; }
GetRemoteClientHasExtraCapabilities()121   PBoolean GetRemoteClientHasExtraCapabilities() const { return remoteClientHasExtraCapabilities; }
122 
123 protected:
124 
125   PBoolean remoteClientAvailable;
126   PBoolean remoteClientHasExtraCapabilities;
127   OpalH224Handler * h224Handler;
128 };
129 
130 PSORTED_LIST(OpalH224ClientList, OpalH224Client);
131 
132 ///////////////////////////////////////////////////////////////////////////////
133 
134 class OpalH224MediaStream;
135 
136 class OpalH224Handler : public PObject
137 {
138   PCLASSINFO(OpalH224Handler, PObject);
139 
140 public:
141 
142   OpalH224Handler();
143   ~OpalH224Handler();
144 
145   enum {
146     Broadcast = 0x0000,
147 
148     CMEClientListCode        = 0x01,
149     CMEExtraCapabilitiesCode = 0x02,
150     CMEMessage               = 0x00,
151     CMECommand               = 0xff,
152 
153     CountryCodeEscape   = 0xff,
154   };
155 
156   /**Adds / removes the client from the client list */
157   PBoolean AddClient(OpalH224Client & client);
158   PBoolean RemoveClient(OpalH224Client & client);
159 
160   /**Sets the transmit / receive media format*/
161   void SetTransmitMediaFormat(const OpalMediaFormat & mediaFormat);
162   void SetReceiveMediaFormat(const OpalMediaFormat & mediaFormat);
163 
164   /**Sets / unsets the transmit H224 media stream*/
165   void SetTransmitMediaStream(OpalH224MediaStream * transmitMediaStream);
166 
167   virtual void StartTransmit();
168   virtual void StopTransmit();
169 
170   /**Sends the complete client list with all clients registered */
171   PBoolean SendClientList();
172 
173   /**Sends the extra capabilities for all clients that indicate to have extra capabilities. */
174   PBoolean SendExtraCapabilities();
175 
176   /**Requests the remote side to send it's client list */
177   PBoolean SendClientListCommand();
178 
179   /**Request the remote side to send the extra capabilities for the given client */
180   PBoolean SendExtraCapabilitiesCommand(const OpalH224Client & client);
181 
182   /**Callback for H.224 clients to send their extra capabilities */
183   PBoolean SendExtraCapabilitiesMessage(const OpalH224Client & client, BYTE *data, PINDEX length);
184 
185   /**Callback for H.224 clients to send a client frame */
186   PBoolean TransmitClientFrame(const OpalH224Client & client, H224_Frame & frame);
187 
188   PBoolean HandleFrame(const RTP_DataFrame & rtpFrame);
189   virtual PBoolean OnReceivedFrame(H224_Frame & frame);
190   virtual PBoolean OnReceivedCMEMessage(H224_Frame & frame);
191   virtual PBoolean OnReceivedClientList(H224_Frame & frame);
192   virtual PBoolean OnReceivedClientListCommand();
193   virtual PBoolean OnReceivedExtraCapabilities(H224_Frame & frame);
194   virtual PBoolean OnReceivedExtraCapabilitiesCommand();
195 
GetTransmitMutex()196   PMutex & GetTransmitMutex() { return transmitMutex; }
197 
198 protected:
199 
200   PMutex transmitMutex;
201   PBoolean canTransmit;
202   RTP_DataFrame transmitFrame;
203   BYTE transmitBitIndex;
204   PTime *transmitStartTime;
205   OpalH224MediaStream * transmitMediaStream;
206 
207   H224_Frame receiveFrame;
208 
209   OpalH224ClientList clients;
210 
211 private:
212   void TransmitFrame(H224_Frame & frame);
213 
214   PBoolean transmitHDLCTunneling;
215   PBoolean receiveHDLCTunneling;
216 };
217 
218 ///////////////////////////////////////////////////////////////////////////////
219 
220 class OpalH224MediaStream : public OpalMediaStream
221 {
222     PCLASSINFO(OpalH224MediaStream, OpalMediaStream);
223 
224   public:
225     OpalH224MediaStream(OpalConnection & connection,
226                         OpalH224Handler & h224Handler,
227                         const OpalMediaFormat & mediaFormat,
228                         unsigned sessionID,
229                         PBoolean isSource);
230     ~OpalH224MediaStream();
231 
232     virtual void OnStartMediaPatch();
233     virtual PBoolean ReadPacket(RTP_DataFrame & packet);
234     virtual PBoolean WritePacket(RTP_DataFrame & packet);
IsSynchronous()235     virtual PBoolean IsSynchronous() const { return false; }
RequiresPatchThread()236     virtual PBoolean RequiresPatchThread() const { return isSource ? false : true; }
237 
238   private:
239     virtual void InternalClose();
240 
241     OpalH224Handler & h224Handler;
242 };
243 
244 #endif // OPAL_H224_H224HANDLER_H
245 
246