diff -ur openh323-cvs-2001.11.07.vanilla/Makefile openh323-cvs-2001.11.07/Makefile
--- openh323-cvs-2001.11.07.vanilla/Makefile	Fri Sep 14 04:57:39 2001
+++ openh323-cvs-2001.11.07/Makefile	Wed Nov  7 09:57:56 2001
@@ -184,13 +184,20 @@
 # Revision 1.1  1999/01/16 10:32:26  robertj
 # Initial revision
 #
+export INSTALL_DIR=/usr/local
 
 ifndef PWLIBDIR
-PWLIBDIR=$(HOME)/pwlib
+export PWLIBDIR=$(HOME)/tmp/pwlib-cvs
 endif
 
+ifndef OPENH323DIR
+export OPENH323DIR=$(PWD)
+endif
+
+# export NOAUDIOCODECS=true
+# export NOVIDEO=true
 
-SUBDIRS := src samples/simple
+SUBDIRS := src
 
 ifneq (,$(wildcard dump323))
 SUBDIRS += dump323
@@ -236,3 +243,5 @@
 docs: 
 	doc++ --dir html --tables openh323.dxx
 
+install:
+	make -C src install
diff -ur openh323-cvs-2001.11.07.vanilla/include/h323ep.h openh323-cvs-2001.11.07/include/h323ep.h
--- openh323-cvs-2001.11.07.vanilla/include/h323ep.h	Wed Oct 31 19:27:33 2001
+++ openh323-cvs-2001.11.07/include/h323ep.h	Wed Nov  7 09:57:56 2001
@@ -882,6 +882,14 @@
      */
     BOOL CanAutoStartTransmitVideo() const { return autoStartTransmitVideo; }
 
+    /**See if should auto-start receive fax channels on connection.
+     */
+    BOOL CanAutoStartReceiveFax() const { return autoStartReceiveFax; }
+
+    /**See if should auto-start transmit fax channels on connection.
+     */
+    BOOL CanAutoStartTransmitFax() const { return autoStartTransmitFax; }
+
     /**Get the set of listeners (incoming call transports) for this endpoint.
      */
     const H323ListenerList & GetListeners() const { return listeners; }
@@ -1083,6 +1091,8 @@
     PString     videoChannelRecordDevice;
     BOOL        autoStartReceiveVideo;
     BOOL        autoStartTransmitVideo;
+    BOOL        autoStartReceiveFax;
+    BOOL        autoStartTransmitFax;
     BOOL        disableFastStart;
     BOOL        disableH245Tunneling;
     H323AudioCodec::SilenceDetectionMode defaultSilenceDetection;
diff -ur openh323-cvs-2001.11.07.vanilla/include/h323t38.h openh323-cvs-2001.11.07/include/h323t38.h
--- openh323-cvs-2001.11.07.vanilla/include/h323t38.h	Mon Jul 23 22:25:57 2001
+++ openh323-cvs-2001.11.07/include/h323t38.h	Wed Nov  7 09:57:56 2001
@@ -157,6 +157,7 @@
       const H323_T38Capability & capability, /// Capability channel is using
       Directions direction                   /// Direction of channel
     );
+    ~H323_T38Channel();
   //@}
 
   /**@name Overrides from class H323Channel */
@@ -194,6 +195,9 @@
       */
     virtual BOOL CreateTransport();
   //@}
+
+    virtual BOOL OnReceivedPDU(const H245_OpenLogicalChannel &, unsigned &);
+    virtual void OnSendOpenAck(const H245_OpenLogicalChannel &, H245_OpenLogicalChannelAck &) const;
 
   protected:
     BOOL              usesTCP;
diff -ur openh323-cvs-2001.11.07.vanilla/include/rtp.h openh323-cvs-2001.11.07/include/rtp.h
--- openh323-cvs-2001.11.07.vanilla/include/rtp.h	Mon Sep 10 20:21:21 2001
+++ openh323-cvs-2001.11.07/include/rtp.h	Wed Nov  7 09:57:56 2001
@@ -363,7 +363,8 @@
   public:
     enum {
       DefaultAudioSessionID = 1,
-      DefaultVideoSessionID = 2
+      DefaultVideoSessionID = 2,
+      DefaultFaxSessionID = 3
     };
 
   /**@name Construction */
diff -ur openh323-cvs-2001.11.07.vanilla/include/t38proto.h openh323-cvs-2001.11.07/include/t38proto.h
--- openh323-cvs-2001.11.07.vanilla/include/t38proto.h	Tue Jul 17 00:44:29 2001
+++ openh323-cvs-2001.11.07/include/t38proto.h	Wed Nov  7 10:27:07 2001
@@ -42,7 +42,7 @@
 
 
 ///////////////////////////////////////////////////////////////////////////////
-
+#if 0
 /**This class describes the T.38 protocol handler.
  */
 class OpalT38Protocol : public PObject
@@ -79,9 +79,61 @@
     );
   //@}
 };
+#endif
+/////////////////////////////////////////////////////////////////////////////
 
+class OpalT38Protocol : public PObject
+{
+    PCLASSINFO(OpalT38Protocol, PObject);
+  public:
+  /**@name Construction */
+  //@{
+    /**Create a new protocol handler.
+     */
+    OpalT38Protocol();
+    ~OpalT38Protocol();
+  //@}
 
-#endif // __T38PROTO_H
+  /**@name Operations */
+  //@{
 
+    /**Handle the origination of a T.38 connection.
+      */
+    virtual BOOL Originate(
+      H323Transport & transport
+    );
+
+    /**Handle the origination of a T.38 connection.
+      */
+    virtual BOOL Answer(
+      H323Transport & transport
+    );
+
+    /**Prepare outgoing T.38 packet.
+
+       If returns FALSE, then the writing loop should be terminated.
+      */
+    virtual BOOL PreparePacket(
+      T38_IFPPacket & pdu
+    );
+
+    /**Handle incoming T.38 packet.
+
+       If returns FALSE, then the reading loop should be terminated.
+      */
+    virtual BOOL HandlePacket(
+      const T38_IFPPacket & pdu
+    );
+
+    /**Handle lost T.38 packets.
+
+       If returns FALSE, then the reading loop should be terminated.
+      */
+    virtual BOOL HandlePacketLost(
+      unsigned nLost
+    );
+  //@}
+};
+
+#endif // __T38PROTO_H
 
-/////////////////////////////////////////////////////////////////////////////
diff -ur openh323-cvs-2001.11.07.vanilla/src/channels.cxx openh323-cvs-2001.11.07/src/channels.cxx
--- openh323-cvs-2001.11.07.vanilla/src/channels.cxx	Tue Oct 23 20:55:49 2001
+++ openh323-cvs-2001.11.07/src/channels.cxx	Wed Nov  7 15:45:22 2001
@@ -1356,6 +1356,7 @@
   const H245_TransportAddress * address;
 
   if (separateReverseChannel) {
+      PTRACE(3, "LogChan\tseparateReverseChannels");
     if (!ack.HasOptionalField(H245_OpenLogicalChannelAck::e_forwardMultiplexAckParameters)) {
       PTRACE(1, "LogChan\tNo forwardMultiplexAckParameters");
       return FALSE;
@@ -1376,8 +1377,10 @@
 
     address = &param.m_mediaChannel;
 
-    if (ack.HasOptionalField(H245_OpenLogicalChannelAck::e_reverseLogicalChannelParameters))
+    if (ack.HasOptionalField(H245_OpenLogicalChannelAck::e_reverseLogicalChannelParameters)) {
+      PTRACE(3, "LogChan\treverseLogicalChannelParameters set");
       reverseChannel = H323ChannelNumber(ack.m_reverseLogicalChannelParameters.m_reverseLogicalChannelNumber, TRUE);
+    }
   }
   else {
     if (!ack.HasOptionalField(H245_OpenLogicalChannelAck::e_reverseLogicalChannelParameters)) {
diff -ur openh323-cvs-2001.11.07.vanilla/src/h323.cxx openh323-cvs-2001.11.07/src/h323.cxx
--- openh323-cvs-2001.11.07.vanilla/src/h323.cxx	Tue Nov  6 17:57:23 2001
+++ openh323-cvs-2001.11.07/src/h323.cxx	Thu Nov  8 14:58:20 2001
@@ -2913,6 +2913,8 @@
       SelectDefaultLogicalChannel(RTP_Session::DefaultAudioSessionID);
       if (endpoint.CanAutoStartTransmitVideo())
         SelectDefaultLogicalChannel(RTP_Session::DefaultVideoSessionID);
+      if (endpoint.CanAutoStartTransmitFax())
+        SelectDefaultLogicalChannel(RTP_Session::DefaultFaxSessionID);
       break;
 
     case FastStartInitiate :
@@ -2920,6 +2922,8 @@
       SelectFastStartChannels(RTP_Session::DefaultVideoSessionID,
                               endpoint.CanAutoStartTransmitVideo(),
                               endpoint.CanAutoStartReceiveVideo());
+      SelectFastStartChannels(RTP_Session::DefaultFaxSessionID, endpoint.CanAutoStartTransmitFax(),
+                              endpoint.CanAutoStartReceiveFax());
       break;
 
     case FastStartResponse :
@@ -2929,6 +2933,10 @@
         StartFastStartChannel(fastStartChannels, RTP_Session::DefaultVideoSessionID, H323Channel::IsTransmitter);
       if (endpoint.CanAutoStartReceiveVideo())
         StartFastStartChannel(fastStartChannels, RTP_Session::DefaultVideoSessionID, H323Channel::IsReceiver);
+      if (endpoint.CanAutoStartTransmitFax())
+        StartFastStartChannel(fastStartChannels, RTP_Session::DefaultFaxSessionID, H323Channel::IsTransmitter);
+      if (endpoint.CanAutoStartReceiveFax())
+        StartFastStartChannel(fastStartChannels, RTP_Session::DefaultFaxSessionID, H323Channel::IsReceiver);
       break;
   }
 }
@@ -3427,16 +3435,19 @@
                                          const H245_TransportAddress & taddr)
 {
   // We only support unicast IP at this time.
-  if (taddr.GetTag() != H245_TransportAddress::e_unicastAddress)
+  if (taddr.GetTag() != H245_TransportAddress::e_unicastAddress) {
     return NULL;
+  }
 
   const H245_UnicastAddress & uaddr = taddr;
-  if (uaddr.GetTag() != H245_UnicastAddress::e_iPAddress)
+  if (uaddr.GetTag() != H245_UnicastAddress::e_iPAddress) {
     return NULL;
+  }
 
   RTP_Session * session = rtpSessions.UseSession(sessionID);
-  if (session != NULL)
+  if (session != NULL) {
     return session;
+  }
 
   RTP_UDP * udp_session = new RTP_UDP(sessionID);
   udp_session->SetUserData(new H323_RTP_UDP(*this, *udp_session));
diff -ur openh323-cvs-2001.11.07.vanilla/src/h323neg.cxx openh323-cvs-2001.11.07/src/h323neg.cxx
--- openh323-cvs-2001.11.07.vanilla/src/h323neg.cxx	Thu Sep 13 00:18:57 2001
+++ openh323-cvs-2001.11.07/src/h323neg.cxx	Thu Nov  8 15:00:05 2001
@@ -722,6 +722,7 @@
 
   replyTimer = endpoint.GetLogicalChannelTimeout();
 
+  PTRACE(3, "end of OpenWhileLocked");
   return connection.WriteControlPDU(pdu);
 }
 
@@ -1095,6 +1096,7 @@
 
 void H245NegLogicalChannels::Add(H323Channel & channel)
 {
+  PTRACE(1, "H245NegLogicalChannels::Add");
   mutex.Wait();
   channels.SetAt(channel.GetNumber(), new H245NegLogicalChannel(endpoint, connection, channel));
   mutex.Signal();
@@ -1105,6 +1107,7 @@
 {
   mutex.Wait();
 
+  lastChannelNumber++;
   lastChannelNumber++;
 
   H245NegLogicalChannel * negChan = new H245NegLogicalChannel(endpoint, connection, lastChannelNumber);
diff -ur openh323-cvs-2001.11.07.vanilla/src/h323t38.cxx openh323-cvs-2001.11.07/src/h323t38.cxx
--- openh323-cvs-2001.11.07.vanilla/src/h323t38.cxx	Wed Sep 12 03:48:05 2001
+++ openh323-cvs-2001.11.07/src/h323t38.cxx	Thu Nov  8 15:15:48 2001
@@ -92,6 +92,7 @@
 
 unsigned H323_T38Capability::GetSubType() const
 {
+  PTRACE(1, "H323_T38Capability::GetSubType()");
   return H245_DataApplicationCapability_application::e_t38fax;
 }
 
@@ -107,43 +108,84 @@
 
 H323Channel * H323_T38Capability::CreateChannel(H323Connection & connection,
                                                 H323Channel::Directions direction,
-                                                unsigned,
-                               const H245_H2250LogicalChannelParameters *) const
+                                                unsigned int SessionID,
+                               const H245_H2250LogicalChannelParameters *params) const
 {
-  return new H323_T38Channel(connection, *this, direction);
-}
+    H323Channel *channel;
+    PTRACE(1, "H323_T38Capability::CreateChannel()\tSessionID=" << SessionID << " direction=" << direction);
+
+    RTP_Session * session;
+    if (params != NULL) {
+        PTRACE(2, "H323_T38Capability::CreateChannel()\tparams != NULL SessionID=" << params->m_sessionID );
+        // XXX this breaks things
+        // session = connection.UseSession(params->m_sessionID, params->m_mediaControlChannel);
+    } else {
+        PTRACE(2, "H323_T38Capability::CreateChannel()\tparams = NULL");
+        /* Make a fake transport address from the connection so things get
+         * initialized with the transport type (IP, IPx, multicast, etc) */
+        H245_TransportAddress addr;
+        connection.GetControlChannel().SetUpTransportPDU(addr, 0);
+        PTRACE(1, "H323_T38Capability::CreateChannel()\tSessionID=" << SessionID <<" addr = "<< addr);
+        session = connection.UseSession(SessionID, addr);
+    }
 
+    channel = new H323_T38Channel(connection, *this, direction);
+#if 0
+    if (direction == H323Channel::IsReceiver) {
+        channel = new H323_T38Channel(connection, *this, direction);
+    } else {
+        channel = connection.FindChannel(SessionID, TRUE);
+        if (channel == NULL)
+            PTRACE(1, "H323_T38Capability::CreateChannel()\tERROR: Incoming channel not found!");
+    }
+#endif
+    return channel;
+}
 
 BOOL H323_T38Capability::OnSendingPDU(H245_DataApplicationCapability & cap) const
 {
-  cap.m_maxBitRate = 144; // 14.4kbps
-  cap.m_application.SetTag(H245_DataApplicationCapability_application::e_t38fax);
-  H245_DataApplicationCapability_application_t38fax & fax = cap.m_application;
+    PTRACE(1, "H323_T38Capability::OnSendingPDU");
+    cap.m_maxBitRate = 144; // 14.4kbps
+    cap.m_application.SetTag(H245_DataApplicationCapability_application::e_t38fax);
+    H245_DataApplicationCapability_application_t38fax & fax = cap.m_application;
     H245_DataProtocolCapability & proto = fax.m_t38FaxProtocol;
-  H245_T38FaxProfile & profile = fax.m_t38FaxProfile;
-  if (mode == e_UDP) {
-    proto.SetTag(H245_DataProtocolCapability::e_udp);
-    profile.IncludeOptionalField(H245_T38FaxProfile::e_t38FaxUdpOptions);
-    profile.m_t38FaxUdpOptions.m_t38FaxMaxBuffer = 200;
-    profile.m_t38FaxUdpOptions.m_t38FaxMaxDatagram = 72;
-    profile.m_t38FaxUdpOptions.m_t38FaxUdpEC.SetTag(H245_T38FaxUdpOptions_t38FaxUdpEC::e_t38UDPRedundancy);
-  }
-  else {
-    proto.SetTag(H245_DataProtocolCapability::e_tcp);
-    profile.IncludeOptionalField(H245_T38FaxProfile::e_t38FaxTcpOptions);
-    profile.m_t38FaxTcpOptions.m_t38TCPBidirectionalMode = mode == e_SingleTCP;
-  }
-  return TRUE;
+    H245_T38FaxProfile & profile = fax.m_t38FaxProfile;
+
+    if (mode == e_UDP) {
+        proto.SetTag(H245_DataProtocolCapability::e_udp);
+        profile.IncludeOptionalField(H245_T38FaxProfile::e_t38FaxUdpOptions);
+        profile.m_t38FaxUdpOptions.m_t38FaxMaxBuffer = 200;
+        profile.m_t38FaxUdpOptions.m_t38FaxMaxDatagram = 72;
+        profile.m_t38FaxUdpOptions.m_t38FaxUdpEC.SetTag(H245_T38FaxUdpOptions_t38FaxUdpEC::e_t38UDPRedundancy);
+    } else {
+        proto.SetTag(H245_DataProtocolCapability::e_tcp);
+        profile.IncludeOptionalField(H245_T38FaxProfile::e_t38FaxTcpOptions);
+        profile.m_t38FaxTcpOptions.m_t38TCPBidirectionalMode = mode == e_SingleTCP;
+    }
+    return TRUE;
 }
+#if 0
+    H245_NonStandardParameter &param = cap.m_application;
+    param.m_data = "T38FaxUDP";
+    param.m_nonStandardIdentifier.SetTag(H245_CapabilityIdentifier::e_h221NonStandard);
+    H245_NonStandardIdentifier_h221NonStandard &h221id = param.m_nonStandardIdentifier;
+    h221id.m_t35CountryCode =  181;
+    h221id.m_t35Extension = 0;
+    h221id.m_manufacturerCode = 18;
 
+    return TRUE;
+}
+#endif
 
 BOOL H323_T38Capability::OnReceivedPDU(const H245_DataApplicationCapability & cap)
 {
+  PTRACE(1, "H323_T38Capability::OnRecievedPDU");
   if (cap.m_application.GetTag() != H245_DataApplicationCapability_application::e_t38fax)
     return FALSE;
 
   const H245_DataApplicationCapability_application_t38fax & fax = cap.m_application;
   const H245_DataProtocolCapability & proto = fax.m_t38FaxProtocol;
+
   if (proto.GetTag() == H245_DataProtocolCapability::e_udp)
     mode = e_UDP;
   else {
@@ -158,8 +200,168 @@
 }
 
 
-/////////////////////////////////////////////////////////////////////////////
+////H323_T38Channel//////////////////////////////////////////////////////////
+
+H323_T38Channel::H323_T38Channel(H323Connection & connection,
+                        const H323_T38Capability & capability,
+                        H323Channel::Directions dir)
+        : H323DataChannel(connection, capability, dir)
+{
+    PTRACE(1, "H323_T38Channel::H323_T38Channel()");
+
+    H323TransportAddress addr;
+    PIPSocket::Address ip;
+    WORD port;
+
+    addr = connection.GetControlChannel().GetLocalAddress();
+    addr.GetIpAndPort(ip, port);
+
+    separateReverseChannel = capability.GetTransportMode() != H323_T38Capability::e_SingleTCP;
+    usesTCP = capability.GetTransportMode() != H323_T38Capability::e_UDP;
+
+    if (!usesTCP) {
+        transport =  new H323TransportUDP(connection.GetEndPoint(), ip, port - 1);
+        t38handler = new OpalT38Protocol();
+    } else {
+        PTRACE(1, "T.38 " << capability << " not supported!");
+    }
+}
+
+H323_T38Channel::~H323_T38Channel()
+{
+    delete t38handler;
+}
+
+void H323_T38Channel::Receive()
+{
+    if (terminating)
+        return;
+    PTRACE(1, "H323_T38Channel::Receive()\tstarting");
+
+    if (t38handler == NULL) {
+        PTRACE(1, "H323_T38Channel::Receive()\tNo proto handler");
+    } else {
+        t38handler->Answer(*transport);
+//      connection.CloseLogicalChannelNumber(number);
+    }
+    PTRACE(1, "H323_T38Channel::Receive()\tterminated");
+}
+
+void H323_T38Channel::Transmit()
+{
+    if (terminating)
+        return;
+    PTRACE(1, "H323_T38Channel::Transmit()\tstarting");
+    if (t38handler == NULL) 
+        PTRACE(1, "H323_T38Channel::Transmit()\tNo proto handler");
+    else
+        t38handler->Originate(*transport);
+//      connection.CloseLogicalChannelNumber(number);
+    PTRACE(1, "H323_T38Channel::Transmit()\tterminating");
+}
+
+BOOL H323_T38Channel::OnReceivedPDU(const H245_OpenLogicalChannel & open, unsigned & errorCode)
+{
+    PTRACE(1, "H323_T38Channel::OnReceivedPDU()");
+
+    PTRACE(4, open);
+    number = H323ChannelNumber(open.m_forwardLogicalChannelNumber, TRUE);
 
+    if (open.m_forwardLogicalChannelParameters.m_multiplexParameters.GetTag() !=
+        H245_OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters::e_h2250LogicalChannelParameters) {
+        PTRACE(1, "ERROR: Received PDU has no network info!!");
+        return FALSE;
+    }
+    const H245_H2250LogicalChannelParameters & param = open.m_forwardLogicalChannelParameters.m_multiplexParameters;
+    if (param.HasOptionalField(H245_H2250LogicalChannelParameters::e_mediaControlChannel)) {
+        PIPSocket::Address ip;
+        WORD port;
+        H323TransportAddress addr = param.m_mediaControlChannel;
+
+        addr.GetIpAndPort(ip, port, "udp");
+        port--;
+
+        H323TransportAddress addr2(ip,port);
+        if (transport->SetRemoteAddress(addr2) == FALSE) {
+            PTRACE(1, "Setting remote address failed!!");
+        }
+        PTRACE(4, "Remote address set to " << ip << ":" << port);
+    }
+    return TRUE;
+}
+
+void H323_T38Channel::OnSendOpenAck(const H245_OpenLogicalChannel & open, H245_OpenLogicalChannelAck & ack) const
+{
+    PTRACE(1, "H323_T38Channel::OnSendOpenAck()");
+
+    ack.IncludeOptionalField(H245_OpenLogicalChannelAck::e_forwardMultiplexAckParameters);
+    ack.m_forwardMultiplexAckParameters.SetTag(
+                    H245_OpenLogicalChannelAck_forwardMultiplexAckParameters::e_h2250LogicalChannelAckParameters);
+
+    H245_H2250LogicalChannelAckParameters &param = ack.m_forwardMultiplexAckParameters;
+
+    param.IncludeOptionalField(H245_H2250LogicalChannelAckParameters::e_mediaChannel);
+    param.IncludeOptionalField(H245_H2250LogicalChannelAckParameters::e_mediaControlChannel);
+    param.IncludeOptionalField(H245_H2250LogicalChannelAckParameters::e_sessionID);
+
+    H323TransportAddress addr = transport->GetLocalAddress();
+    PIPSocket::Address ip;
+    WORD port;
+
+    addr.GetIpAndPort(ip, port, "udp");
+    transport->SetUpTransportPDU(param.m_mediaChannel, port);
+
+    addr = connection.GetControlChannel().GetLocalAddress();
+    addr.GetIpAndPort(ip, port);
+    connection.GetControlChannel().SetUpTransportPDU(param.m_mediaControlChannel, port);
+
+    /* test to see if we're supposed to have a separate rev channel */
+    if (separateReverseChannel) {
+        /* if we are, then test to see if there already is one open */
+        if (!connection.FindChannel(GetSessionID(), FALSE)) {
+            /* and if there isn't... try to open one */
+            PTRACE(1,"H323_T38Channel::OnSendOpenAck()\tOpenLogicalChannel SessionId=" << (unsigned) param.m_sessionID);
+            if (connection.OpenLogicalChannel(GetCapability(), (unsigned) param.m_sessionID, H323Channel::IsTransmitter) == FALSE) {
+                PTRACE(1, "H323_T38Channel::OnSendOpenAck()\tERROR: Opening outgoing channel failed!!!");
+            }
+        } else {
+            PTRACE(1, "H323_T38Channel::OnSendOpenAck()\treverse channel already open, not trying to open a new one");
+        }
+    }
+#if 0
+    if () {
+        H323Capability *cap = connection.GetEndPoint().FindCapability(H323Capability::e_Data,
+                                    H245_DataApplicationCapability_application::e_t38fax );
+
+        if (connection.OpenLogicalChannel(*cap, (unsigned) param.m_sessionID, H323Channel::IsTransmitter) == FALSE)
+            PTRACE(1, "ERROR: Opening outgoing channel failed!!!");
+    }
+#endif
+    PTRACE(3, ack);
+}
+
+BOOL H323_T38Channel::CreateTransport()
+{
+  PTRACE(1, "H323_T38Channel::CreateTransport()");
+  if (transport == NULL) {
+      transport = connection.GetControlChannel().GetLocalAddress().CreateTransport(connection.GetEndPoint());
+  }
+  return transport != NULL;
+}
+
+BOOL H323_T38Channel::CreateListener()
+{
+  PTRACE(1, "H323_T38Channel::CreateListener()");
+  if (listener != NULL)
+    return TRUE;
+
+  if (usesTCP)
+    return H323DataChannel::CreateListener();
+
+  return CreateTransport();
+}
+
+#if 0
 H323_T38Channel::H323_T38Channel(H323Connection & conn,
                                    const H323_T38Capability & cap,
                                    Directions dir)
@@ -181,7 +383,7 @@
     if (transport != NULL)
       t38handler->Answer(*transport);
     else {
-      PTRACE(1, "H323T38\tNo transport, aborting thread.");
+      PTRACE(0, "H323T38\tNo transport, aborting thread.");
     }
   }
   else {
@@ -244,6 +446,6 @@
   transport = new H323TransportUDP(connection.GetEndPoint(), ip);
   return TRUE;
 }
-
+#endif
 
 /////////////////////////////////////////////////////////////////////////////
diff -ur openh323-cvs-2001.11.07.vanilla/src/t38proto.cxx openh323-cvs-2001.11.07/src/t38proto.cxx
--- openh323-cvs-2001.11.07.vanilla/src/t38proto.cxx	Tue Jul 17 00:44:32 2001
+++ openh323-cvs-2001.11.07/src/t38proto.cxx	Thu Nov  8 12:48:21 2001
@@ -45,6 +45,7 @@
 
 /////////////////////////////////////////////////////////////////////////////
 
+#if 0
 OpalT38Protocol::OpalT38Protocol()
 {
 }
@@ -78,6 +79,125 @@
 {
   return FALSE;
 }
-
+#endif
 
 /////////////////////////////////////////////////////////////////////////////
+
+OpalT38Protocol::OpalT38Protocol()
+{
+  /* pEngine = NULL; */
+}
+
+OpalT38Protocol::~OpalT38Protocol()
+{
+}
+
+BOOL OpalT38Protocol::Originate(H323Transport & transport)
+{
+  PTRACE(1, "Originate LocalAddress: " << transport.GetLocalAddress()
+          << " --> RemoteAddress: " << transport.GetRemoteAddress());
+
+  sleep(1);
+  WORD seq = 0;	// 16 bit
+  T38_IFPPacket pdu;
+
+  while( PreparePacket(pdu) ) {
+    PTRACE(1, "<-- IFPPacket (" << seq << ") " << setprecision(2) << pdu);
+
+    T38_UDPTLPacket udptl;
+
+    udptl.m_seq_number = seq;
+    udptl.m_primary_ifp_packet.EncodeSubType(pdu);
+
+    PTRACE(1, "UDPTLPacket " << setprecision(2) << udptl);
+
+    PPER_Stream rawData;
+
+    udptl.Encode(rawData);
+    PTRACE(1, "raw " << setprecision(2) << rawData);
+
+    if(!transport.WritePDU(rawData) ) {
+        PTRACE(1, "<-- OpalT38Protocol::Originate - WritePDU ERROR: " << transport.GetErrorText());
+        break;
+    }
+
+    seq++;      // 16 bit
+    sleep(1);
+  }
+
+  PTRACE(2, "Originate end");
+  return FALSE;
+}
+
+BOOL OpalT38Protocol::Answer(H323Transport & transport)
+{
+  PTRACE(1, "Answer LocalAddress: " << transport.GetLocalAddress()
+          <<" <-- RemoteAddress: " << transport.GetRemoteAddress());
+
+  /* HACK HACK HACK -- need to figure out how to get the remote address
+   * properly here */
+  transport.SetPromiscuous(TRUE);
+
+  PPER_Stream rawData;
+  int nBad = 0;
+  WORD seq = 0;	// 16 bit
+
+  while (transport.ReadPDU(rawData)) {
+    PTRACE(1, "--> RemoteAddress: " << transport.GetRemoteAddress());
+    rawData.ResetDecoder();
+
+    T38_UDPTLPacket udptl;
+    if( !udptl.Decode(rawData) ) {
+      PTRACE(1, "--> raw  bad !!!" << setprecision(2) << rawData);
+      if( ++nBad > 5 ) break;
+      continue;
+    }
+
+    T38_IFPPacket pdu;
+    if( !udptl.m_primary_ifp_packet.DecodeSubType(pdu) ) {
+      PTRACE(1, "--> UDPTLPacket bad !!! " << setprecision(2) << udptl);
+      continue;
+    }
+    WORD rseq = udptl.m_seq_number;	// 16 bit
+
+    PTRACE(1, "--> IFPPacket (" << rseq << ") " << setprecision(2) << pdu);
+
+    if( seq != rseq ) {
+      // recovery should be here
+      PInt32 diff = PInt32(rseq) - PInt32(seq);
+      if( diff < 0 ) diff += 0x10000;	// ???
+      if( ! HandlePacketLost((unsigned)diff) ) break;
+    }
+
+    seq++;	// 16 bit
+
+    if( !HandlePacket(pdu) ) break;
+  }
+  PTRACE(2, "Answer end");
+  return FALSE;
+}
+
+
+BOOL OpalT38Protocol::HandlePacket(const T38_IFPPacket & pdu)
+{
+    PTRACE(1, "OpalT38Protocol::HandlePacket()");
+    PTRACE(1, pdu);
+    return TRUE;
+}
+
+BOOL OpalT38Protocol::PreparePacket(T38_IFPPacket & pdu)
+{
+    PTRACE(1, "OpalT38Protocol::PreparePacket()");
+    pdu.m_type_of_msg = T38_Type_of_msg::e_t30_indicator;
+    pdu.m_type_of_msg = T38_Type_of_msg_t30_indicator::e_cng;
+    // pdu.m_data_field = new T38_Data_Field();
+    return TRUE;
+}
+
+BOOL OpalT38Protocol::HandlePacketLost(unsigned nLost)
+{
+    PTRACE(1, "OpalT38Protocol::HandlePacketLost()");
+    /* don't handle lost packets yet */
+    return FALSE;
+}
+
