00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 #ifndef OPAL_H46018_H225
00045 #define OPAL_H46018_NAT
00046
00047 #if _MSC_VER > 1000
00048 #pragma once
00049 #endif // _MSC_VER > 1000
00050
00051 #if OPAL_H460_NAT
00052
00053 #include <h323/h323pdu.h>
00054
00055
00056 class H46018SignalPDU : public H323SignalPDU
00057 {
00058 public:
00066 H46018SignalPDU(const OpalGloballyUniqueID & callIdentifier);
00068 };
00069
00070
00071 class H323EndPoint;
00072 class H46018Handler;
00073
00074 class H46018Transport : public OpalTransportTCP
00075 {
00076 PCLASSINFO(H46018Transport, OpalTransportTCP);
00077
00078 public:
00079 enum PDUType {
00080 e_raw,
00081 };
00082
00087 H46018Transport(
00088 H323EndPoint & endpoint
00089 );
00090
00091 ~H46018Transport();
00093
00101 virtual PBoolean WritePDU(
00102 const PBYTEArray & pdu
00103 );
00104
00110 virtual PBoolean ReadPDU(
00111 PBYTEArray & pdu
00112 );
00114
00120 PBoolean HandleH46018SignallingChannelPDU();
00121
00125 PBoolean HandleH46018SignallingSocket(H323SignalPDU & pdu);
00126
00130 PBoolean InitialPDU(const OpalGloballyUniqueID & callIdentifier);
00131
00135 PBoolean isCall() { return isConnected; };
00136
00140 void ConnectionLost(PBoolean established);
00141
00145 PBoolean IsConnectionLost();
00147
00148
00151 virtual PBoolean Connect(const OpalGloballyUniqueID & callIdentifier);
00152
00155 virtual PBoolean Close();
00156
00157 virtual PBoolean IsListening() const;
00158
00159 virtual PBoolean IsOpen () const;
00160
00161 PBoolean CloseTransport() { return closeTransport; };
00162
00163 protected:
00164 PMutex connectionsMutex;
00165 PMutex WriteMutex;
00166 PMutex IntMutex;
00167 PTimeInterval ReadTimeOut;
00168 PSyncPoint ReadMutex;
00169
00170 H46018Handler * Feature;
00171
00172 PBoolean isConnected;
00173 PBoolean remoteShutDown;
00174 PBoolean closeTransport;
00175 };
00176
00177
00178 class H323EndPoint;
00179 class PNatMethod_H46019;
00180
00181 class H46018Handler : public PObject
00182 {
00183 PCLASSINFO(H46018Handler, PObject);
00184
00185 public:
00186 H46018Handler(H323EndPoint * ep);
00187 ~H46018Handler();
00188
00189 void Enable();
00190 PBoolean IsEnabled();
00191
00192 H323EndPoint * GetEndPoint();
00193
00194 PBoolean CreateH225Transport(const PASN_OctetString & information);
00195
00196 void H46024ADirect(bool reply, const PString & token);
00197
00198 protected:
00199 H323EndPoint * EP;
00200 PNatMethod_H46019 * nat;
00201 PString lastCallIdentifer;
00202
00203 PMutex m_h46024aMutex;
00204 bool m_h46024a;
00205
00206 private:
00207 H323TransportAddress m_address;
00208 OpalGloballyUniqueID m_callId;
00209 PThread * SocketCreateThread;
00210 PDECLARE_NOTIFIER(PThread, H46018Handler, SocketThread);
00211 PBoolean m_h46018inOperation;
00212 };
00213
00214
00215 class PNatMethod_H46019 : public PNatMethod
00216 {
00217 PCLASSINFO(PNatMethod_H46019,PNatMethod);
00218
00219 public:
00224 PNatMethod_H46019();
00225
00228 ~PNatMethod_H46019();
00230
00236 static PString GetNatMethodName();
00237 virtual PString GetName() const;
00238
00241 virtual PString GetServer() const;
00242
00246 virtual PBoolean CreateSocketPair(
00247 PUDPSocket * & socket1,
00248 PUDPSocket * & socket2,
00249 const PIPSocket::Address & binding,
00250 void * userData
00251 );
00252
00261 virtual bool IsAvailable(const PIPSocket::Address & address);
00262
00263
00264
00265
00266
00267 void SetAvailable();
00268
00272 virtual void Activate(bool act) { active = act; }
00273
00277 PBoolean OpenSocket(PUDPSocket & socket, PortInfo & portInfo, const PIPSocket::Address & binding) const;
00279
00285 void AttachHandler(H46018Handler * _handler);
00286
00287 protected:
00288 virtual NatTypes InternalGetNatType(bool forced, const PTimeInterval & maxAge);
00289
00290 #if OPAL_H460_NAT
00291
00298 void SetConnectionSockets(
00299 PUDPSocket * data,
00300 PUDPSocket * control,
00301 H323Connection::SessionInformation * info
00302 );
00303 #endif
00304
00305 PBoolean available;
00306 PBoolean active;
00307 H46018Handler * handler;
00308 };
00309
00310 #ifndef _WIN32_WCE
00311 PPLUGIN_STATIC_LOAD(H46019,PNatMethod);
00312 #endif
00313
00314
00315 class H46019UDPSocket : public PUDPSocket
00316 {
00317 PCLASSINFO(H46019UDPSocket, PUDPSocket);
00318 public:
00324 H46019UDPSocket(
00325 H46018Handler & _handler,
00326 H323Connection::SessionInformation * info,
00327 bool _rtpSocket
00328 );
00329
00333 ~H46019UDPSocket();
00335
00336 PBoolean GetLocalAddress(Address & addr, WORD & port);
00337
00340
00343 void Allocate(
00344 const H323TransportAddress & keepalive,
00345 unsigned _payload,
00346 unsigned _ttl,
00347 unsigned _muxId
00348 );
00349
00352 void Activate();
00353
00356 void Activate(const H323TransportAddress & keepalive,
00357 unsigned _payload,
00358 unsigned _ttl,
00359 unsigned _muxId
00360 );
00361
00364 unsigned GetPingPayload();
00365
00368 void SetPingPayLoad(unsigned val);
00369
00372 unsigned GetTTL();
00373
00376 void SetTTL(unsigned val);
00377
00381 virtual PBoolean ReadFrom(
00382 void * buf,
00383 PINDEX len,
00384 Address & addr,
00385 WORD & port
00386 );
00387
00391 virtual PBoolean WriteTo(
00392 const void * buf,
00393 PINDEX len,
00394 const Address & addr,
00395 WORD port
00396 );
00397
00398 enum probe_state {
00399 e_notRequired,
00400 e_initialising,
00401 e_idle,
00402 e_probing,
00403 e_verify_receiver,
00404 e_verify_sender,
00405 e_wait,
00406 e_direct
00407 };
00408
00409 struct probe_packet {
00410 PUInt16b Length;
00411 PUInt32b SSRC;
00412 BYTE name[4];
00413 BYTE cui[20];
00414 };
00415
00418 virtual void SetAlternateAddresses(const H323TransportAddress & address, const PString & cui);
00419
00422 virtual void GetAlternateAddresses(H323TransportAddress & address, PString & cui);
00423
00426 virtual PBoolean IsAlternateAddress(
00427 const Address & address,
00428 WORD port
00429 );
00432 void H46024Adirect(bool starter);
00433
00436 void H46024Bdirect(const H323TransportAddress & address);
00438
00439 protected:
00440
00441
00442 void InitialiseKeepAlive();
00443 void SendRTPPing(const PIPSocket::Address & ip, const WORD & port);
00444 void SendRTCPPing();
00445 PBoolean SendRTCPFrame(RTP_ControlFrame & report, const PIPSocket::Address & ip, WORD port);
00446 PMutex PingMutex;
00447
00448
00449 PBoolean ReceivedProbePacket(const RTP_ControlFrame & frame, bool & probe, bool & success);
00450 void BuildProbe(RTP_ControlFrame & report, bool reply);
00451 void StartProbe();
00452 void ProbeReceived(bool probe, const PIPSocket::Address & addr, WORD & port);
00453 void SetProbeState(probe_state newstate);
00454 int GetProbeState() const;
00455 probe_state m_state;
00456 PMutex probeMutex;
00457
00461 virtual PBoolean Internal_WriteTo(
00462 const Slice * slices,
00463 size_t nSlices,
00464 const Address & addr,
00465 WORD port
00466 );
00467
00471 virtual PBoolean Internal_WriteTo(
00472 const void * buf,
00473 PINDEX len,
00474 const Address & addr,
00475 WORD port
00476 );
00477
00478 private:
00479 H46018Handler & m_Handler;
00480 unsigned m_Session;
00481 PString m_Token;
00482 OpalGloballyUniqueID m_CallId;
00483 PString m_CUI;
00484
00485
00486 PIPSocket::Address keepip;
00487 WORD keepport;
00488 unsigned keeppayload;
00489 unsigned keepTTL;
00490 PUInt32b muxId;
00491 WORD keepseqno;
00492 PTime * keepStartTime;
00493
00494 PDECLARE_NOTIFIER(PTimer, H46019UDPSocket, Ping);
00495 PTimer Keep;
00496
00497
00498 PString m_CUIrem;
00499 PIPSocket::Address m_locAddr; WORD m_locPort;
00500 PIPSocket::Address m_remAddr; WORD m_remPort;
00501 PIPSocket::Address m_detAddr; WORD m_detPort;
00502 PIPSocket::Address m_pendAddr; WORD m_pendPort;
00503 PDECLARE_NOTIFIER(PTimer, H46019UDPSocket, Probe);
00504 PTimer m_Probe;
00505 PINDEX m_probes;
00506 DWORD SSRC;
00507 PIPSocket::Address m_altAddr; WORD m_altPort;
00508
00509 PBoolean m_h46024b;
00510
00511 bool rtpSocket;
00512 };
00513
00514 #endif // OPAL_H460_NAT
00515
00516 #endif // OPAL_H46018_H225