Exemple #1
0
            public static Int32 Decode(ReceivedFrame frame, Byte[] buf, Int32 ptr, out String s)
            {
                String r;

                //if (seqNumMode.Equals(SequenceNumberMode.Mod8))
                //{
                frame.numS = (buf[ptr] >> 1) & 0x07;
                frame.numR = (buf[ptr++] >> 5) & 0x07;

                //    NumR = (buf[ptr++] >> 5) & 0x07;
                //}
                //else
                //{
                //    NumS = (buf[ptr++] >> 1) & 0x7f;
                //    PFBit = buf[ptr] & 0x01;
                //    NumR = (buf[ptr++] >> 1) & 0x7f;
                //}
                s = "|ns=" + frame.numS.ToString() + "|nr=" + frame.numR.ToString();

                frame.pidInfo = new PidInfo();
                ptr           = frame.pidInfo.Decode(buf, ptr, out r);

                if (frame.pidInfo.cmdDecode.Equals(PidInfo.CommandDecode.Standard))
                {
                    //
                    // On standard PID fields, pre-load the segmentation chuck data where the PID used to be in the buffer.
                    // Extended info will already have the correct segmentation chunk info there.
                    //
                    buf[ptr] = Segmenter.StartOfSegment;
                }

                frame.iBuf = Support.PackByte(buf, ptr, (buf.Length - ptr));

                s = s + r + "|len:" + frame.iBuf.Length.ToString() + "|txt:(" + Support.GetString(frame.iBuf) + ")";

                return(ptr);
            }
 //
 // Segmenter timeout handler
 //
 void timerSegmenter_Elapsed(object sender, ElapsedEventArgs e)
 {
     Support.DbgPrint("Segmenter timer fired...");
     recvDatagramQ.Wakeup();
     timerSegmenter.Stop();
 }
 //
 // Link Test timeout handler
 //
 void timerTestCommandTimeout_Elapsed(object sender, ElapsedEventArgs e)
 {
     Support.DbgPrint("TestCommandTimeout timer fired...");
     linkTestQ.Wakeup();
     timerTestCommandTimeout.Stop();
 }
        void ProcessDLPackets()
        {
            Frame.Packet packet;
            Connection   con;
            Int32        tmpL = 4;

            Support.DbgPrint(Thread.CurrentThread.Name + " Starting...");

            while (runFlag)
            {
                //
                // This thread get incoming packets from the remote and sends them off for procesing
                //
                try
                {
                    packet = (Frame.Packet)dataLinkProviderQ.Dequeue();
                }
                catch
                {
                    continue;
                }

                if (packet == null)
                {
                    continue;
                }

                if (packet.transmitFrame != null)
                {
                    //
                    // Incoming packets are passed in as transmit frames and are sent out to the TNC Channel
                    //
                    _localTncChannel.Send(packet.transmitFrame);
                }
                else
                {
                    //
                    // Packets arriving from lower layer come in as received frames
                    //
                    if (packet.receivedFrame.decodeOK)
                    {
                        //
                        // Process the parsed frame
                        //

                        Int32 pfBit = packet.receivedFrame.pfBit;

                        //
                        // Unnumbered frame
                        //

                        if (packet.receivedFrame.frameType.Equals(Frame.FrameTypes.UIType))
                        {
                            //
                            // Unnumbered Info Frame received, so pop it into the DLP Recv datagram Q
                            // code falls through and Sends DM resp if PFBit is set
                            //
                            recvDatagramQ.Enqueue(packet.receivedFrame.iBuf);
                            if (pfBit == 0)
                            {
                                continue;
                            }
                        }

                        if (packet.receivedFrame.frameType.Equals(Frame.FrameTypes.TESTType))
                        {
                            //
                            // Test frame
                            //
                            if (packet.receivedFrame.cmdResp.Equals(Frame.PacketType.Command))
                            {
                                Int32 i;
                                Int32 f = tmpR.Length >> 1;

                                //
                                // Send out a response to in incoming test command
                                //
                                Byte[] tBuf = new Byte[f + packet.receivedFrame.iBuf.Length];
                                for (i = 0; i < f; i++)
                                {
                                    tBuf[i] = (Byte)(tmpR[i / tmpL, i % tmpL] ^ tmpR[(i + f) / tmpL, i % tmpL]);
                                }
                                packet.receivedFrame.iBuf.CopyTo(tBuf, i);
                                Frame.Packet tmpP = new Frame.Packet(
                                    Frame.TransmitFrameBuild(packet.receivedFrame.staLink.Rev(),
                                                             Station.CommandResponse.DoResponse,
                                                             pfBit, Frame.FrameTypes.TESTType,
                                                             tBuf));

                                dataLinkProviderQ.Enqueue(tmpP);
                            }
                            else
                            {
                                //
                                // Test resp received. Return buffer to upper layer
                                //
                                linkTestQ.Enqueue(packet.receivedFrame.iBuf);
                            }
                            continue;
                        }
                        //
                        // Other packet types get sent to the upper layer (If one is available)
                        //

                        con = GetConnection(packet.receivedFrame.staLink.GetConnectionPathRev());
                        if (con == null)
                        {
                            //
                            // No existing connection available, so check for any listeners
                            //
                            con = GetAvailableConnection(packet.receivedFrame.staLink.destinationStation.stationIDString);

                            if (con != null)
                            {
                                //
                                // Found a listener, so set up the connection
                                //
                                con.connectedStation.destinationStation.SetCallSign(packet.receivedFrame.staLink.sourceStation.stationIDString);
                                if (packet.receivedFrame.staLink.relayStation2.stationIDString.Length > 0)
                                {
                                    con.connectedStation.relayStation1.SetCallSign(packet.receivedFrame.staLink.relayStation2.stationIDString);
                                    con.connectedStation.relayStation2.SetCallSign(packet.receivedFrame.staLink.relayStation1.stationIDString);
                                }
                                else if (packet.receivedFrame.staLink.relayStation1.stationIDString.Length > 0)
                                {
                                    con.connectedStation.relayStation1.SetCallSign(packet.receivedFrame.staLink.relayStation1.stationIDString);
                                }
                            }
                            else
                            {
                                //
                                // No connection so send DM resp with PF bit set to uframe.pfBit
                                //
                                _localTncChannel.Send(Frame.TransmitFrameBuild(packet.receivedFrame.staLink.Rev(),
                                                                               Station.CommandResponse.DoResponse, pfBit, Frame.FrameTypes.DMType, null).ibuf);
                                continue;
                            }
                        }

                        //
                        // Found a connection, so sent the packet off to it
                        //
                        con.Insert(packet);
                        continue;
                    }

                    //
                    // Arrival here means the frame did not decode correctly, so just drop the packet
                    //
                    Support.DbgPrint(Thread.CurrentThread.Name + " - Frame decode error");
                }
            }
            Support.DbgPrint(Thread.CurrentThread.Name + " exiting...");
        }
        public Byte[] RecvDatagram()
        {
            //
            // Handle returned datagram packets.  Segmented packets are reassembled before returning
            //
            Byte[] tmpB = null;
            Int32  ptr  = 0;
            Int32  j    = 0;

            Byte[] segBuf          = null;
            Int32  chunksRemaining = 0;

            //
            // Start the timeout timer.
            //
            timerSegmenter.Start();

            do
            {
                //
                // If this is our first time through, look at the number of packets remaining
                // to determine how much buffer space we'll need and allocate it.
                //
                segBuf = (Byte[])recvDatagramQ.Dequeue();

                if (segBuf == null)
                {
                    timerSegmenter.Stop();
                    return(null);
                }

                chunksRemaining = segBuf[0] & 0x7f;

                if ((segBuf[0] & Segmenter.StartOfSegment) == Segmenter.StartOfSegment)
                {
                    //
                    // If the start of segment bit is set, look at the number of chunks remaining
                    // to determine how much buffer space we'll need and allocate it.
                    //
                    tmpB = new Byte[MAXUIFRAME * (chunksRemaining + 1)];
                }

                if (tmpB == null)
                {
                    //
                    // No start of segment flag specified.  Return null
                    //
                    timerSegmenter.Stop();
                    return(null);
                }

                //
                // Add this packet to the total
                //
                j = 1;
                while (j < segBuf.Length)
                {
                    tmpB[ptr++] = segBuf[j++];
                }
            } while (chunksRemaining > 0);

            //
            // Stop the timer.
            //
            timerSegmenter.Stop();
            return(Support.PackByte(tmpB, 0, ptr));
        }
Exemple #6
0
        //
        // Com port send thread
        //

        void sendToPort()
        {
            KissBuf kBuf = null;

            Byte[] tmpB = new Byte[MAXBUF];
            Byte[] buf;
            Int32  count = 0;

            Support.DbgPrint(Thread.CurrentThread.Name + " starting");

            while (runFlag)      /* 1/22/2015 W4PHS */
            {
                //
                // COM port send process loop
                //
                try
                {
                    kBuf = (KissBuf)sendQ.Dequeue();
                    if (kBuf == null)
                    {
                        continue;
                    }
                }
                catch
                {
                    Support.DbgPrint(Thread.CurrentThread.Name + " sendQ.Dequeue Exception");
                    continue;
                }

                //
                // Add Framing character and channel/command information to the start of the buffer
                //
                count = 0;

                tmpB[count++] = FEND;

                //  If Ackmode specified, send Header           (JNW Jan15)

                if (kBuf.Frame != null)
                {
                    //  Ackmode FOrmat
                    // See if Acxkmode Needed

                    buf = kBuf.Frame.ibuf;

                    if (kBuf.Frame.AckModeID != 0)
                    {
                        tmpB[count++] = (Byte)((kBuf.chan << 4) | 0x0c);
                        tmpB[count++] = (Byte)(kBuf.Frame.AckModeID >> 8);
                        tmpB[count++] = (Byte)(kBuf.Frame.AckModeID & 0xff);
                    }
                    else
                    {
                        tmpB[count++] = (Byte)((kBuf.chan << 4) | kBuf.cmd);
                    }
                }
                else
                {
                    //  Old (Non-AckMode) format

                    buf = kBuf.buf;
                    if (kBuf.cmd == 0x0f)
                    {
                        tmpB[count++] = 0xff;       // Kiss Mode off
                    }
                    else
                    {
                        tmpB[count++] = (Byte)((kBuf.chan << 4) | kBuf.cmd);
                    }
                }

                if (kBuf.cmd != 0x0f)
                {
                    //
                    // PRW change 10/10/2010 - Move the fill buffer code inside the else clause.  Otherwise our kiss exit
                    // sequence ended up being: C0 FF 00 C0 rather than the correct value of: C0 FF C0
                    //
                    foreach (Byte b in buf)
                    {
                        //
                        // In addition to escaping the normal FEND & FESC bytes, we will also
                        // insert a dummy escape sequence for Capital C.  This will break up the string "TC 0 <CR>" that
                        // screws up the D710 TNC while in KISS mode.  Since it is an invalid escape, it should be discarded
                        // at the remote end.
                        //
                        if (Escaped(b))
                        {
                            //
                            // This byte is on the list of characters to escape
                            //
                            tmpB[count++] = FESC;
                        }

                        if ((b == FEND) || (b == FESC))
                        {
                            if (b == FEND)
                            {
                                tmpB[count++] = FESC;
                                tmpB[count++] = TFEND;
                            }
                            if (b == FESC)
                            {
                                tmpB[count++] = FESC;
                                tmpB[count++] = TFESC;
                            }
                        }
                        else
                        {
                            tmpB[count++] = b;
                        }
                    }
                }

                tmpB[count++] = FEND;

                try
                {
                    if (loopBackMode)
                    {
                        // Send data back to receive port
                        if (!receivePortDataQueue.Enqueue((Object)Support.PackByte(tmpB, 0, count)))
                        {
                            // Inbound Queue is full, so just drop the packet... c'est la vie.
                            _inboundQueueErrorCount++;
                        }
                    }
                    else
                    {
                        if (TCPMode)
                        {
                            netStream.Write(tmpB, 0, count);
                        }
                        else
                        {
                            port.Write(tmpB, 0, count);
                        }
                    }
                }
                catch
                {
                }

                // Close if connection lost

                if (TCPMode)
                {
                    runFlag = client.Connected;
                }
                else
                {
                    runFlag = port.IsOpen;          /* 1/22/2015 W4PHS */
                }
            }
            Support.DbgPrint(Thread.CurrentThread.Name + " exit");
        }
Exemple #7
0
        //#endregion

        //#region COM port communication thread routines

        //
        // COM port receive thread
        //

        private void recvFromPort()
        {
            Boolean inFrame    = false;
            Boolean doUnescape = false;
            Boolean gotChannel = false;

            Byte[] rcvBuf = new Byte[MAXBUF];
            Byte[] portBuf;
            Int32  count   = 0;
            Int32  channel = 0;
            Int32  command = 0;                       // KISS Command Byte (JNW Jan15)


            Support.DbgPrint(Thread.CurrentThread.Name + " starting");

            while (runFlag)
            {
                //
                // COM port receive process loop
                //
                try
                {
                    portBuf = (Byte[])receivePortDataQueue.Dequeue();
                    if (portBuf == null)
                    {
                        // Loop if null buffer.
                        continue;
                    }
                }
                catch
                {
                    // Loop if we get an exception
                    continue;
                }

                foreach (byte tmp in portBuf)
                {
                    if (inFrame)
                    {
                        //
                        // In a frame
                        //
                        if (doUnescape)
                        {
                            //
                            // Process escaped characters
                            // Characters other than TFEND and TFESC are discarded
                            //
                            if (tmp == TFEND)
                            {
                                rcvBuf[count++] = FEND;
                            }
                            else if (tmp == TFESC)
                            {
                                rcvBuf[count++] = FESC;
                            }
                            else
                            {
                                //
                                // Ignore the FESC character for other characters.
                                //
                                rcvBuf[count++] = tmp;
                            }
                            doUnescape = false;
                            continue;
                        }

                        if (tmp == FESC)
                        {
                            // Process next character as escaped
                            doUnescape = true;
                            continue;
                        }

                        if (tmp == FEND)
                        {
                            if (!gotChannel)
                            {
                                //
                                // looks like back-to-back FEND characters,
                                // so bump the frame error count and keep going
                                //
                                //_KISSFrameErrorCount++;
                                continue;
                            }

                            if (count > 0)
                            {
                                //
                                // End of frame, so send up the packet
                                //
                                if (recvQs[channel] == null)
                                {
                                    // Bad channel received
                                    _KISSFrameErrorCount++;
                                }
                                else
                                {
                                    if (!recvQs[channel].Enqueue((object)Support.PackByte(rcvBuf, 0, count)))
                                    {
                                        // Inbound Queue is full, so just drop the packet... c'est la vie.
                                        _inboundQueueErrorCount++;
                                    }
                                }
                            }

                            count      = 0;    // Reset buffer len
                            inFrame    = true; // Set to True to handle the case where the same FEND byte is used for both end and start
                            gotChannel = false;
                            continue;
                        }

                        if (count >= MAXBUF)
                        {
                            //
                            // Strange happenings on the channel.  Frame should
                            // never get this big.  Reset & continue.
                            //
                            _KISSFrameErrorCount++;
                            count      = 0;
                            inFrame    = false;
                            gotChannel = false;
                            continue;
                        }

                        if (!gotChannel)
                        {
                            //
                            // Get channel # from upper nibble of first byte
                            //

                            command    = tmp & 0x0f;    // Extract Command Byte     (JNW Jan15)
                            channel    = Convert.ToInt32(tmp >> 4);
                            gotChannel = true;
                            continue;
                        }

                        rcvBuf[count++] = tmp;      // Normal character
                    }
                    else
                    {
                        // Not in a frame.  Ignore all but FEND
                        if (tmp == FEND)
                        {
                            //
                            // Start of frame
                            //
                            inFrame = true;
                        }
                    }
                }
            }
            Support.DbgPrint(Thread.CurrentThread.Name + " exit");
        }
Exemple #8
0
        //
        // Public methods
        //
        //public void COMPortInit(String comPort, Int32 baud)
        //{
        //    COMPortInit(comPort, baud, false);
        //}

        void COMPortInit(String comPort, Int32 baud, Boolean loopback, String Host, Int32 Port, SerialPort sPort)            // JNW Apr15
        {
            //
            // Initialization
            //
            loopBackMode = loopback;

            receivePortDataQueue = new BlockingQueue(MAXQUEUESIZE); // Port level receive queue
            sendQ = new BlockingQueue(MAXQUEUESIZE);                // packet level send queue for all channels

            if (comPort != null && comPort.Equals("TCP"))
            {
                TCPMode = true;
                TCPPort = Port;             // JNW Apr15
                TCPHost = Host;
            }
            else
            {
                TCPMode = false;
            }

            if (TCPMode)
            {
                try
                {
                    client = new TcpClient(TCPHost, TCPPort);

                    netStream = client.GetStream();

                    // This will run in the background.
                    Task.Run(() =>
                    {
                        var count = netStream.Read(myReadBuffer, 0, myReadBuffer.Length);
                        myReadCallBack(count);
                    });
                }
                catch (Exception ex)
                {
                    Support.DbgPrint("TCP Connect Failed.  Ex: " + ex.Message);
                }
            }
            else
            {
                if (sPort == null)
                {
                    port = new SerialPort(comPort, baud, Parity.None, 8, StopBits.One);

                    // No flow control.  Upper AX.25 layer handles dropped data
                    port.Handshake = Handshake.None;
                    port.RtsEnable = true;
                }
                else
                {
                    // Flow control was initialized already, so no need to do it again.
                    port = sPort;
                }

                if (!loopBackMode) // We don't use the serial port in loopback mode
                {
                    // Add the read event handler
                    //comHandler = new SerialDataReceivedEventHandler(SerialPortRead);
                    //port.DataReceived += comHandler;

                    if (sPort == null)
                    {
                        port.Open();
                    }

                    //port.ReadTimeout = 1;
                    port.DiscardInBuffer();
                    Task.Run(() =>
                    {
                        SerialPortRead();
                    });
                }
            }

            if (client != null || port != null)
            {
                recvThread      = new Thread(recvFromPort); // Threads handle com port I/O
                recvThread.Name = "ComPort Receive Thread for Port: " + comPort;

                sendThread      = new Thread(sendToPort);
                sendThread.Name = "ComPort Transmit Thread for Port: " + comPort;

                recvThread.Start();     // Light 'em up
                sendThread.Start();
            }
        }
Exemple #9
0
        //
        // Procesing thread for incoming packets from the TNC.  The TNC places a buffer
        // containing the incoming data into the channel's receive queue.  This routine pulls
        // these frames from the queue for processing.
        //
        // Processing steps:
        //      - Parse the raw incoming frame into a receive buffer.
        //      - Find the Data Link Provider handling incoming data for the Station ID
        //        specified in the incoming address field of the packet.  If no matching
        //        dlp is registered, then we simply drop the packet.  (Future: we add in support
        //        for multi-cast packets, which will forward to all registered DLPs)
        //      - Place the frame, source, and buffer type into a packet object and place it into the
        //        receive queue of the target DLP.
        //

        void RecvFromPort()
        {
            String parsedFrameString = "";

            Byte[] buf;

            Support.DbgPrint(Thread.CurrentThread.Name + "Starting.");
            while (runFlag && comSerialPort.Enabled)
            {
                try
                {
                    buf = Recv();
                }
                catch
                {
                    continue;
                }

                if (buf == null)
                {
                    continue;
                }

                // check for ACKMODE Response (Need to be at channel level to find DLC)       (JNW Jan15)

                if (buf.Length == 2)            // Only ACK frames are this short
                {
                    Int16      AckID = (Int16)(buf[0] << 8 | buf[1]);
                    Connection con;

                    lock (dataLinkProviderList)

                        foreach (DataLinkProvider dlp in dataLinkProviderList)
                        {
                            con = GetConnectionByACKModeID(dlp, AckID);

                            if (con != null)
                            {
                                // Set Timer back to normal

                                con.timerAck.SetTime(con.smoothedRoundTrip, true);

                                break;
                            }
                        }

                    continue;                   // Donf pass Ack frame up to next level
                }


                //
                // Parse raw buffer
                //
                Frame.ReceivedFrame pFrame = new Frame.ReceivedFrame(buf, out parsedFrameString);

                //
                // Output to monitor queue is enabled
                //
                if (!_packetMonitorEnable.Equals(PacketMonitorType.None))
                {
                    StringBuilder frameString = new StringBuilder("|chan:" + chanNum.ToString() + "|<--", 4096);
                    frameString.Append(parsedFrameString);
                    if (_packetMonitorEnable.Equals(PacketMonitorType.LogFile) || _packetMonitorEnable.Equals(PacketMonitorType.Both))
                    {
                        Support.PktPrint(frameString.ToString() + CRLF, ref packetLogSyncObject);
                    }

                    if (_packetMonitorEnable.Equals(PacketMonitorType.Queue) || _packetMonitorEnable.Equals(PacketMonitorType.Both))
                    {
                        packetMonitorQueue.Enqueue(frameString.ToString());
                    }
                }

                Frame.Packet packet = new Frame.Packet(pFrame);


                DigipeatCheckAndProcess(packet);
                //continue;


                //
                // Send up to the data link provider handling the specified StationID
                //
                //dlp.Send(packet);
            }
            Support.DbgPrint(Thread.CurrentThread.Name + "Exiting.");
        }
Exemple #10
0
 public void Restart()
 {
     Support.DbgPrint("Timer " + tName + " Restarted");
     Stop();
     Start();
 }
Exemple #11
0
 public void Start()
 {
     Support.DbgPrint("Timer " + tName + " Started");
     timerT.Start();
 }
Exemple #12
0
 public void Stop()
 {
     timerT.Stop();
     Support.DbgPrint("Timer " + tName + " Stopped");
 }
Exemple #13
0
            public static TransmitFrame Encode(Station stl, Connection.ConnectionParameterBuf cBuf, Station.CommandResponse cmdResp, Int32 pfBit)
            {
                //
                // Build the XID frame to send
                //

                TransmitFrame commandFrame = new TransmitFrame();

                Byte[] stlB = stl.GetStationAddresBuffer(cmdResp);
                Int32  ptr  = stlB.Length;
                Int32  t;
                Int32  c;
                Int32  paramPtr = 0;

                Byte[] tmpP = new Byte[30];

                commandFrame.ibuf        = new Byte[tmpP.Length + stlB.Length]; // overallocate buffer space to handle worst case.  We'll trim later
                commandFrame.frameType   = FrameTypes.XIDType;
                commandFrame.seqNumMode  = SequenceNumberMode.Mod8;
                commandFrame.cmdOctetPtr = stlB.Length;

                stlB.CopyTo(commandFrame.ibuf, 0);     // Load station address fields

                commandFrame.ibuf[ptr++] = (Byte)(((Int32)FrameTypes.XIDType) | (pfBit << 4));
                commandFrame.ibuf[ptr++] = (Byte)(FormatIdentifier.GeneralPurposeXIDInfo);
                commandFrame.ibuf[ptr++] = (Byte)(GroupIdentifier.ParameterNegotiation);
                //
                // Load parameters to negotiate
                //

                t = (Int32)ClassOfProcedures.BalancedABMHalfDup;
                tmpP[paramPtr++] = (Byte)(ParameterIndicator.ClassOfProcedures);
                tmpP[paramPtr++] = (Byte)2;
                tmpP[paramPtr++] = (Byte)((t >> 8) & 0xff);
                tmpP[paramPtr++] = (Byte)(t & 0x7f);

                tmpP[paramPtr++] = (Byte)(ParameterIndicator.HDLCOptionalParams);
                tmpP[paramPtr++] = (Byte)3;
                tmpP[paramPtr++] = (Byte)(cBuf.optionalFuncByte0);
                tmpP[paramPtr++] = (Byte)(cBuf.optionalFuncByte1);
                tmpP[paramPtr++] = (Byte)(cBuf.optionalFuncByte2);

                //
                // The IFrame size specified here is in bits.  Check to see how many bytes we'll need to specify
                //
                tmpP[paramPtr++] = (Byte)(ParameterIndicator.RXIFieldLen);
                c = cBuf.maxIFrame * 8;
                if (c >= 65536)
                {
                    //
                    // Need 4 bytes to specify the window size
                    //
                    tmpP[paramPtr++] = (Byte)4;
                    tmpP[paramPtr++] = (Byte)((c >> 24) & 0xff);
                    tmpP[paramPtr++] = (Byte)((c >> 16) & 0xff);
                }
                else
                {
                    //
                    // Need only 2 bytes
                    //
                    tmpP[paramPtr++] = (Byte)2;
                }
                tmpP[paramPtr++] = (Byte)((c >> 8) & 0xff);
                tmpP[paramPtr++] = (Byte)(c & 0xff);

                tmpP[paramPtr++] = (Byte)(ParameterIndicator.RXWindowSize);
                tmpP[paramPtr++] = (Byte)1;
                tmpP[paramPtr++] = (Byte)(cBuf.maxWindowSize & 0xff);

                //
                // The Ack timer is specified in mSec.  Check to see how many bytes we'll need
                //
                tmpP[paramPtr++] = (Byte)(ParameterIndicator.AckTimer);
                if (cBuf.ackTimer >= 65536)
                {
                    //
                    // Need 4 bytes to specify ack timer
                    //
                    tmpP[paramPtr++] = (Byte)4;
                    tmpP[paramPtr++] = (Byte)((cBuf.ackTimer >> 24) & 0xff);
                    tmpP[paramPtr++] = (Byte)((cBuf.ackTimer >> 16) & 0xff);
                }
                else
                {
                    //
                    // Need only 2 bytes
                    //
                    tmpP[paramPtr++] = (Byte)2;
                }
                tmpP[paramPtr++] = (Byte)((cBuf.ackTimer >> 8) & 0xff);
                tmpP[paramPtr++] = (Byte)(cBuf.ackTimer & 0xff);

                tmpP[paramPtr++] = (Byte)(ParameterIndicator.NumRetries);
                tmpP[paramPtr++] = (Byte)1;
                tmpP[paramPtr++] = (Byte)(cBuf.maxRetry & 0xff);

                tmpP = Support.PackByte(tmpP, 0, paramPtr);     // Pack it down

                //
                // Add parameter length field to buffer
                //

                commandFrame.ibuf[ptr++] = (Byte)((tmpP.Length >> 8) & 0xff);
                commandFrame.ibuf[ptr++] = (Byte)(tmpP.Length & 0xff);

                //
                // Add the parameters to the buffer
                //
                tmpP.CopyTo(commandFrame.ibuf, ptr);
                ptr += tmpP.Length;

                commandFrame.ibuf = Support.PackByte(commandFrame.ibuf, 0, ptr);  //Pack it down

                return(commandFrame);
            }
Exemple #14
0
            //
            // Decode the received frame
            //
            Boolean Decode(out String packetFrame)
            {
                Int32         ptr    = 0;
                Boolean       retVal = false;
                StringBuilder s      = new StringBuilder("|", 4096);

                try
                {
                    //
                    //  Catch any exceptions during decode
                    //
                    ptr = staLink.destinationStation.Decode(inBuf, ptr);
                    ptr = staLink.sourceStation.Decode(inBuf, ptr);

                    s.Append("|" + staLink.sourceStation.stationIDString + "|ch=" + staLink.sourceStation.chBit.ToString());
                    s.Append("|" + staLink.destinationStation.stationIDString + "|ch=" + staLink.destinationStation.chBit.ToString());

                    if (staLink.sourceStation.extBit == 0)
                    {
                        ptr = staLink.relayStation1.Decode(inBuf, ptr);
                        s.Append("|" + staLink.relayStation1.stationIDString + "|ch=" + staLink.relayStation1.chBit.ToString());
                        if (staLink.relayStation1.extBit == 0)
                        {
                            ptr = staLink.relayStation2.Decode(inBuf, ptr);
                            s.Append("|" + staLink.relayStation2.stationIDString + "|ch=" + staLink.relayStation2.chBit.ToString());
                            if (staLink.relayStation2.extBit == 0)
                            {
                                StationAddress tmpR = new StationAddress();
                                s.Append("|r??:(");

                                do
                                {
                                    ptr = tmpR.Decode(inBuf, ptr);
                                    s.Append("\\" + tmpR.stationIDString + ":ch=" + tmpR.chBit.ToString());
                                } while (tmpR.extBit == 0);
                                s.Append(")");
                                //throw new Exception("Too many relay addresses");
                            }
                            else
                            {
                                s.Append("|");
                            }
                        }
                        else
                        {
                            s.Append("||");
                        }
                    }
                    else
                    {
                        s.Append("|||");
                    }
                    cmdOctetPtr = ptr;

                    if ((staLink.destinationStation.chBit == staLink.sourceStation.chBit))
                    {
                        //
                        // Old protocol version
                        //
                        version = ProtocolVersion.V20;
                    }
                    else
                    {
                        //
                        // New protocol version
                        //
                        version = ProtocolVersion.V22;
                    }

                    if (staLink.destinationStation.chBit == 0)
                    {
                        //
                        // Response type
                        //
                        cmdResp = PacketType.Response;
                    }
                    else
                    {
                        //
                        // Command type
                        //
                        cmdResp = PacketType.Command;
                    }

                    //
                    // Get frame type.  I and S frame must be decoded later after we know whether we
                    // are using mod8 or mod128 sequence numbers.
                    //
                    Byte   tmp = inBuf[ptr];
                    String t   = "";

                    pfBit = (tmp >> 4) & 0x01;      //ToDo  change needed to support SABME

                    seqNumMode = SequenceNumberMode.Mod8;

                    //Frame.InformationFrame.Decode(this, rawBuf, ptr, out t);

                    if ((tmp & 0x01) == I)
                    {
                        //
                        // I frame
                        //
                        frameClass = FrameClasses.IClass;
                        frameType  = FrameTypes.IType;
                        ptr        = InformationFrame.Decode(this, inBuf, ptr, out t);
                    }

                    if ((tmp & 0x03) == S)
                    {
                        //
                        // S frame
                        //
                        frameClass = FrameClasses.SClass;
                        frameType  = (FrameTypes)(tmp & 0x0f);
                        ptr        = SupervisoryFrame.Decode(this, inBuf, ptr, out t);
                    }

                    if ((tmp & 0x03) == U)
                    {
                        //
                        // U frame.  We can decode uFrames right away
                        //
                        frameClass = FrameClasses.UClass;
                        frameType  = (FrameTypes)(tmp & 0xef);
                        ptr        = UnnumberedFrame.Decode(this, inBuf, ptr, out t);
                    }
                    s.Append("|" + version.ToString() + "|" + frameType.ToString() + "|" + cmdResp.ToString() + "|pf=" + pfBit.ToString());

                    if (t.Length > 0)
                    {
                        s.Append(t);
                    }
                    s.Append(Support.DumpRawFrame(rawBuf));

                    retVal = true;
                }
                catch (Exception ex)
                {
                    s.Append(ex.Message + CRLF);
                    Support.DbgPrint("Exception during frame decode:" + ex.Message + CRLF);
                    retVal = false;
                }
                finally
                {
                    s.Append("]");
                    packetFrame = s.ToString();
                }

                return(retVal);
            }