Exemplo n.º 1
0
        //==========================================================================
        // Last stop before transmitting information
        private void EncodeAndSendPacket(byte[] messageBytes, int messageOffset, int messageSize)
        {
            try
            {
                // For testing calculate the crc including the sequence number
                _packetCrc32 = CrcTools.Crc32part(messageBytes, messageSize, 0, _packetCrc32);

                byte[] encodedBytes  = new byte[MeadowDeviceManager.MaxSizeOfXmitPacket];
                int    encodedToSend = CobsTools.CobsEncoding(messageBytes, messageOffset, messageSize, ref encodedBytes);

                // Verify COBS - any delimiters left?
                for (int i = 0; i < encodedToSend; i++)
                {
                    if (encodedBytes[i] == 0x00)
                    {
                        throw new InvalidProgramException("All zeros should have been removed. " +
                                                          $"There's one at {i}");
                    }
                }

                // Terminate packet with delimiter so packet boundaries can be found
                encodedBytes[encodedToSend] = 0;
                encodedToSend++;

                try
                {
                    if (_device.Socket != null)
                    {
                        _device.Socket.Send(encodedBytes, encodedToSend,
                                            System.Net.Sockets.SocketFlags.None);
                    }
                    else
                    {
                        if (_device.SerialPort == null)
                        {
                            throw new ArgumentException("SerialPort cannot be null");
                        }

                        _device.SerialPort.Write(encodedBytes, 0, encodedToSend);
                    }
                }
                catch (InvalidOperationException ioe)  // Port not opened
                {
                    Console.WriteLine("Write but port not opened. Exception: {0}", ioe);
                    throw;
                }
                catch (ArgumentOutOfRangeException aore)  // offset or count don't match buffer
                {
                    Console.WriteLine("Write buffer, offset and count don't line up. Exception: {0}", aore);
                    throw;
                }
                catch (ArgumentException ae)  // offset plus count > buffer length
                {
                    Console.WriteLine("Write offset plus count > buffer length. Exception: {0}", ae);
                    throw;
                }
                catch (TimeoutException te) // Took too long to send
                {
                    Console.WriteLine("Write took too long to send. Exception: {0}", te);
                    throw;
                }
            }
            catch (Exception except)
            {
                Debug.WriteLine($"EncodeAndSendPacket threw: {except}");
                throw;
            }
        }
        HcomBufferReturn PullAndProcessAllPackets()
        {
            byte[]           packetBuffer  = new byte[MeadowDeviceManager.MaxSizeOfPacketBuffer];
            byte[]           decodedBuffer = new byte[MeadowDeviceManager.MaxAllowableDataBlock];
            int              packetLength;
            HcomBufferReturn result;

            while (true)
            {
                result = _hostCommBuffer.GetNextPacket(packetBuffer, MeadowDeviceManager.MaxAllowableDataBlock, out packetLength);
                if (result == HcomBufferReturn.HCOM_CIR_BUF_GET_NONE_FOUND)
                {
                    break;      // We've emptied buffer of all messages
                }
                if (result == HcomBufferReturn.HCOM_CIR_BUF_GET_BUF_NO_ROOM)
                {
                    // The buffer to receive the message is too small! Perhaps
                    // corrupted data in buffer.
                    // I don't know why but without the following 2 lines the Debug.Assert will
                    // assert eventhough the following line is not executed?
                    Console.WriteLine($"Need a buffer with {packetLength} bytes, not {MeadowDeviceManager.MaxSizeOfPacketBuffer}");
                    Thread.Sleep(1);
                    Debug.Assert(false);
                }

                // Only other possible outcome is success
                Debug.Assert(result == HcomBufferReturn.HCOM_CIR_BUF_GET_FOUND_MSG);

                // It's possible that we may find a series of 0x00 values in the buffer.
                // This is because when the sender is blocked (because this code isn't
                // running) it will attempt to send a single 0x00 before the full message.
                // This allows it to test for a connection. When the connection is
                // unblocked this 0x00 is sent and gets put into the buffer along with
                // any others that were queued along the usb serial pipe line.
                if (packetLength == 1)
                {
                    //ConsoleOut("Throwing out 0x00 from buffer");
                    continue;
                }

                int decodedSize = CobsTools.CobsDecoding(packetBuffer, --packetLength, ref decodedBuffer);

                // If a message is too short it is ignored
                if (decodedSize < MeadowDeviceManager.ProtocolHeaderSize)
                {
                    continue;
                }

                Debug.Assert(decodedSize <= MeadowDeviceManager.MaxAllowableDataBlock);

                // Process the received packet
                if (decodedSize > 0)
                {
                    bool procResult = ParseAndProcessReceivedPacket(decodedBuffer, decodedSize);
                    if (procResult)
                    {
                        continue;   // See if there's another packet ready
                    }
                }
                break;   // processing errors exit
            }
            return(result);
        }