Пример #1
0
        /// <summary>
        /// Function used for packet transmission in xmodem protocol
        /// </summary>
        private static void TransmitPacket(Sym mode)
        {
            if (mode == Sym.NAK)
            {
                PortWriteByte((byte)Sym.SOH);   // Sending StartOfHeader symbol for packet initialization
                                                //Console.WriteLine("SOH")
            }
            else if (mode == Sym.C)
            {
                PortWriteByte((byte)Sym.C);   // Sending C symbol for CRC packet initialization
            }
            else
            {
                throw new Exception("Bad protocol mode passed");
            }

            if (seq == 0)
            {
                seq = 1;
            }
            PortWriteByte(seq);                       // Sending sequence number
            //Console.WriteLine("seq: " + seq);
            PortWriteByte((byte)(255 - (255 & seq))); // Calculating and sending the complement of seq
            //Console.WriteLine("cmpl: " + (byte)(255 -  seq));
            seq++;                                    // Increasing the sequence number

            // Copying 128 bytes of data to transmit
            // If there is any underflow, the following bytes will be left null (0)
            byte[] temp = new byte[128];
            Array.Copy(transmitData, offset, temp, 0, transmitData.Length - offset >= 128 ? 128 : transmitData.Length - offset);
            offset += 128;

            //DisplayData(temp);

            // Sending 128 bytes of data
            port.Write(temp, 0, 128);

            if (mode == Sym.NAK)
            {
                // Calculating and sending checksum
                PortWriteByte(Checksum(temp));
            }
            else if (mode == Sym.C)
            {
                ShiftRegister register = new ShiftRegister(temp, true);
                ushort        crcOut   = register.CalcCRC_16();
                PortWriteByte((byte)(crcOut >> 8));
                PortWriteByte((byte)crcOut);
            }

            // Wait for accept from the receiver
            Sym result = WaitForAny(10);

            if (result == Sym.NAK)
            {
                // If cheksum was incorrect - transmit packet once again
                Console.WriteLine("Bad checksum!");
                offset -= 128;
            }
            else if (result != Sym.ACK)
            {
                throw new InvalidOperationException();
            }
        }
Пример #2
0
        private static Sym ReceivePacket(int timeoutSeconds, Sym protocolMode)
        {
            port.ReadTimeout = timeoutSeconds * 1000;

            byte byteBuffer = 0;

            byte[] dataBuffer = new byte[128];

            byteBuffer = (byte)port.ReadByte();

            //First time (for seq == 1) it shouldn't check for SOH, as the initialization has already read the SOH byte to check if data is coming
            if (!first)
            {
                if (byteBuffer == (byte)Sym.SOH || byteBuffer == (byte)Sym.C)
                {
                    byteBuffer = (byte)port.ReadByte(); // Here the seq number should be read
                    Console.WriteLine("Seq: " + byteBuffer);
                }
                else if (byteBuffer == (byte)Sym.EOT)
                {
                    Console.WriteLine("Received EOT, cleaning up...");
                    return(Sym.EOT);
                }
                else if (byteBuffer == (byte)Sym.CAN)
                {
                    throw new Exception("File transfer cancelled");
                }
            }
            else
            {
                first = false;
            }
            // This isn't the best way to do this, but it works so whatever.

            if (byteBuffer == seq)
            {
                // seq number received succesfully
                byteBuffer = (byte)port.ReadByte(); // Here the cmpl seq should be read

                if (byteBuffer == 255 - (255 & seq))
                {
                    // cmpl seq received succesfully
                    // Increase seq
                    seq++;
                    if (seq == 0)
                    {
                        seq = 1;           //Never let seq be 0, or the whole thing will fall apart
                    }
                    // Reading 128 bytes of data
                    for (int i = 0; i < 128; i++)
                    {
                        dataBuffer[i] = (byte)port.ReadByte();
                    }

                    Console.WriteLine("Received data:");
                    DisplayData(dataBuffer);
                    // Verifying checksum
                    // Warning! Here should be the switch for the checksum/CRC transmission
                    if (protocolMode == Sym.NAK)
                    {
                        byteBuffer = (byte)port.ReadByte();
                        if (byteBuffer != Checksum(dataBuffer))
                        {
                            //Handle wrong checksum
                            return(Sym.NAK);
                        }
                        else
                        {
                            //Handle succesful checksum
                            //Copy all bytes from buffer to receivedData
                            foreach (byte elem in dataBuffer)
                            {
                                receivedData.Enqueue(elem);
                            }
                            return(Sym.ACK);
                        }
                    }
                    else if (protocolMode == Sym.C)
                    {
                        byte[] dataCrc = new byte[130];
                        dataBuffer.CopyTo(dataCrc, 0);
                        dataCrc[128] = (byte)port.ReadByte();
                        dataCrc[129] = (byte)port.ReadByte();

                        ShiftRegister register = new ShiftRegister(dataCrc, false);
                        if (register.CalcCRC_16() == 0)
                        {
                            // Crc ok, proceed
                            foreach (byte elem in dataBuffer)
                            {
                                receivedData.Enqueue(elem);
                            }
                            return(Sym.ACK);
                        }
                        else
                        {
                            // Bad crc, repeat process
                            Console.WriteLine("Bad crc received, requesting retry.");
                            return(Sym.NAK);
                        }
                    }
                }
                else
                {
                    throw new Exception("Bad complement of seq received!");
                }
            }
            else
            {
                throw new Exception("Bad symbol or seq number!");
            }
            throw new InvalidOperationException("Reached unwanted area of ReceivePacket function!");
        }