コード例 #1
0
        protected static ESPPacket makeFromBufferLE(List <Byte> buffer, Devices lastV1Type)
        {
            if (buffer.Count == 0)
            {
                return(null);
            }
            int bufferSize = buffer.Count;

            if (buffer[0] != startOfFrameConstant || buffer[bufferSize - 1] != endOfFrameConstant)
            {
                return(null);
            }

            bool         dataError    = false;
            ProcessState processState = ProcessState.SOF;
            ESPPacket    retPacket    = null;
            byte         espChecksum  = 0;
            byte         tempDest     = 0;
            byte         tempOrigin   = 0;
            int          payloadIdx   = 0;

            for (int i = 0; i < bufferSize; i++)
            {
                byte curByte = buffer[i];
                switch (processState)
                {
                case ProcessState.SOF:
                    if (curByte != startOfFrameConstant)
                    {
                        dataError = true;
                    }
                    espChecksum += curByte;
                    processState = ProcessState.DESTINATION;
                    break;

                case ProcessState.DESTINATION:
                    if ((curByte & destinationIdentifierBaseConstant) != destinationIdentifierBaseConstant)
                    {
                        dataError = true;
                    }

                    tempDest     = curByte;
                    espChecksum += curByte;
                    processState = ProcessState.ORIGINATOR;
                    break;

                case ProcessState.ORIGINATOR:
                    if ((curByte & originationIdentifierBaseConstant) != originationIdentifierBaseConstant)
                    {
                        // This is not a valid originator
                        dataError = true;
                    }
                    tempOrigin   = curByte;
                    espChecksum += curByte;
                    processState = ProcessState.PACKET_ID;
                    break;

                case ProcessState.PACKET_ID:
                    // Make the packet
                    retPacket = PacketFactory.getPacket(PacketIdLookup.getConstant(curByte));
                    if (retPacket == null)
                    {
                        // We couldn't build the packet so stop trying
                        dataError = true;
                    }
                    else
                    {
                        // We have a good packet so fill it up
                        retPacket.headerDelimter = frameDelimitedConstant;                                  //<- We can't get here if this wasn't true
                        // The packet length for LE is equal to the size of the buffer..
                        retPacket.packetLength = (byte)bufferSize;

                        retPacket.startOfFrame          = startOfFrameConstant;                          //<- We can't get here if this wasn't true
                        retPacket.destinationIdentifier = tempDest;
                        // Don't store the upper nibble of the destinations
                        retPacket.m_destination = (byte)(tempDest - destinationIdentifierBaseConstant);
                        // Don't store the upper nibble of the origin
                        retPacket.originatorIdentifier = (byte)(tempOrigin - originationIdentifierBaseConstant);
                        retPacket.packetIdentifier     = curByte;

                        // If the packet is from a V1 set the ESPPacket V1 type to the appropriate Device type.
                        if (IsPacketFromV1(retPacket.originatorIdentifier))
                        {
                            retPacket.m_valentineType = DevicesUtils.DevicesFromByteValue(retPacket.originatorIdentifier);
                        }
                        else
                        {
                            retPacket.m_valentineType = lastV1Type;
                        }
                        // If the last known V1 type is unknown check to see if the ESPPacket is V1connection version response.
                        if (retPacket.m_valentineType == Devices.UNKNOWN)
                        {
                            if (retPacket.packetIdentifier != PacketId.respVersion.ToByteValue() || retPacket.originatorIdentifier != Devices.V1CONNECT.ToByteValue())
                            {
                                // Always allow the V1connection version responses to pass through
                                // Don't process any other data until we know what type of V1 we are working with
                                dataError = true;
                                if (ESPLibraryLogController.LOG_WRITE_ERROR)
                                {
                                    //Log.e(LOG_TAG, "Ignore packet id 0x" + String.Format("%02X ", curByte) + " because the V1 type is unknown");
                                }
                            }
                        }
                    }
                    espChecksum += curByte;
                    processState = ProcessState.PAYLOAD_LENGTH;
                    break;

                case ProcessState.PAYLOAD_LENGTH:
                    if (curByte != 0)
                    {
                        byte tmp;
                        // If this packet is from a V1 that supports checksum, we want to decrement the payload length by 1, to make packet match packets from
                        // Legacy and non-checksum V1's
                        if ((retPacket.m_valentineType == Devices.VALENTINE1_LEGACY) || (retPacket.m_valentineType == Devices.VALENTINE1_WITHOUT_CHECKSUM))
                        {
                            tmp = curByte;
                        }
                        else
                        {
                            // If this packet is from a V1 that supports checksum, we want to decrement the packet length by 1
                            // to make packet match packets from Legacy and non-checksum V1's
                            tmp = (byte)(curByte - 1);
                        }

                        retPacket.payloadLength = tmp;
                        // If payloadLength is zero, then the next byte in the buffer will be the packet checksum. For non-checksum V1 devices
                        // the payloadLength is greater than zero so the next byte will be payload data.
                        if (retPacket.payloadLength == 0)
                        {
                            processState = ProcessState.PACKET_CHEKSUM;
                        }
                        else
                        {
                            retPacket.payloadData = new byte[retPacket.payloadLength];
                            processState          = ProcessState.PAYLOAD;
                        }
                        // Always include the payload length in the packet data.
                        espChecksum += curByte;
                    }
                    else
                    {
                        // There is no payload data so go to the end of frame.
                        processState = ProcessState.EOF;
                    }
                    break;

                case ProcessState.PAYLOAD:
                    retPacket.payloadData[payloadIdx] = curByte;
                    payloadIdx++;
                    // Update the ESP checksum.
                    espChecksum += curByte;
                    // If we have reached the end of the payload data, move on to the next byte in the buffer.
                    if (payloadIdx == retPacket.payloadLength)
                    {
                        if ((retPacket.m_valentineType == Devices.VALENTINE1_LEGACY) || (retPacket.m_valentineType == Devices.VALENTINE1_WITHOUT_CHECKSUM))
                        {
                            // Get the EOF byte next
                            processState = ProcessState.EOF;
                        }
                        else
                        {
                            processState = ProcessState.PACKET_CHEKSUM;
                        }
                    }
                    break;

                case ProcessState.PACKET_CHEKSUM:
                    if (espChecksum != curByte)
                    {
                        // The checksum does not match
                        dataError = true;
                        if (ESPLibraryLogController.LOG_WRITE_ERROR)
                        {
                            //Log.e(LOG_TAG, "Bad ESP checksum. Expected 0x" + String.Format("%02X ", espChecksum) + " but found 0x" + String.Format("%02X ", curByte));
                        }
                    }
                    else
                    {
                        // Store the checksum
                        retPacket.checkSum = curByte;
                    }

                    // Get the EOF byte next
                    processState = ProcessState.EOF;
                    break;

                case ProcessState.EOF:
                    if (curByte != endOfFrameConstant)
                    {
                        // Bad data so let's bail
                        dataError = true;
                        if (ESPLibraryLogController.LOG_WRITE_ERROR)
                        {
                            //Log.e(LOG_TAG, "Unable to find EOF at the expected index: " + i);
                        }
                    }

                    retPacket.endOfFrame = curByte;
                    break;

                case ProcessState.BT_CHECKSUM:
                case ProcessState.END_PACK_BYTE:
                case ProcessState.PACKET_LENGTH:
                case ProcessState.START_PACK_BYTE:
                default:
                    // We should never get here, so something went wrong
                    dataError = true;
                    break;
                }
                if (dataError)
                {
                    break;
                }
            }

            buffer.Clear();
            if (dataError)
            {
                return(null);
            }
            // Force the ESPPacket checksum to zero if the V1 does not support checksums before returning the packet.
            if ((retPacket.m_valentineType == Devices.VALENTINE1_LEGACY) || (retPacket.m_valentineType == Devices.VALENTINE1_WITHOUT_CHECKSUM))
            {
                retPacket.checkSum = 0;
            }

            retPacket.packetChecksum = retPacket.makePacketChecksum();
            return(retPacket);
        }