bool ReadSingleSensor::Response::match(DataBuffer& data)
    {
        const uint16 TOTAL_BYTES = 5;

        //if there aren't enough bytes in the buffer to match the response
        if(data.bytesRemaining() < TOTAL_BYTES)
        {
            //not a good response
            m_success = false;
            return false;
        }

        //create a save point with the data
        ReadBufferSavePoint savePoint(&data);
        
        //verify the command id
        if(data.read_uint8() != 0x03)
        {
            //not a good response
            m_success = false;
            return false;
        }

        uint16 sensorVal = data.read_uint16();

        ChecksumBuilder checksum;
        checksum.append_uint16(sensorVal);    //value of the requested channel

        //verify the checksum (only a checksum on the actual data value)
        if(checksum.simpleChecksum() != data.read_uint16())
        {
            //not a good response
            m_success = false;
            return false;
        }

        //if we made it this far, the bytes match the expected response

        m_success = true;

        m_sensorValue = sensorVal;

        //commit the current read position
        savePoint.commit();

        //we have fully matched the response
        m_fullyMatched = true;

        //notify that the response was matched
        m_matchCondition.notify();

        return true;
    }
Bytes buildBaseReadEepromResponseV2(uint16 valueRead)
{
	ChecksumBuilder checksum;
	checksum.append_uint16(valueRead);

	//build success response
	Bytes bytes;
	bytes.push_back(0x73);	
	bytes.push_back(Utils::msb(valueRead));
	bytes.push_back(Utils::lsb(valueRead));
	bytes.push_back(Utils::msb(checksum.simpleChecksum()));
	bytes.push_back(Utils::lsb(checksum.simpleChecksum()));

	return bytes;
}
Example #3
0
    WirelessParser::ParsePacketResult WirelessParser::parseAsPacket_ASPP_v1(DataBuffer& data, WirelessPacket& packet, WirelessTypes::Frequency freq)
    {
        //Assume we are at the start of the packet, read the packet header
        //byte 1        - Start Of Packet
        //byte 2        - Delivery Stop Flag
        //byte 3        - App Data Type
        //byte 4 - 5    - Node Address (uint16)
        //byte 6        - Payload Length
        //byte 7 to N-4 - Payload
        //byte N-3      - Node RSSI
        //byte N-2      - Base RSSI
        //byte N-1      - Simple Checksum (MSB)
        //byte N        - Simple Checksum (LSB)

        //create a save point for the DataBuffer
        ReadBufferSavePoint savePoint(&data);

        std::size_t totalBytesAvailable = data.bytesRemaining();

        //we need at least 10 bytes for any ASPP v1 packet
        if(totalBytesAvailable < 10)
        {
            //Not Enough Data to tell if valid packet
            return parsePacketResult_notEnoughData;
        }

        //read byte 1
        uint8 startOfPacket = data.read_uint8();                        //Start Of Packet

        //verify that the first byte is the Start Of Packet
        if(startOfPacket != WirelessPacket::ASPP_V1_START_OF_PACKET_BYTE)
        {    
            //Invalid Packet
            return parsePacketResult_invalidPacket;
        }

        //read byte 2
        uint8 deliveryStopFlag = data.read_uint8();                    //Delivery Stop Flag

        //read byte 3
        uint8 appDataType = data.read_uint8();                         //App Data Type

        //read bytes 4 and 5
        uint16 nodeAddress = data.read_uint16();                  //Node Address

        //read byte 6
        uint8 payloadLength = data.read_uint8();                       //Payload Length (max of 255)

        //determine the full packet length 
        uint32 packetLength = payloadLength + WirelessPacket::ASPP_V1_NUM_BYTES_BEFORE_PAYLOAD + WirelessPacket::ASPP_V1_NUM_BYTES_AFTER_PAYLOAD;

        //the DataBuffer must be large enough to hold the rest of the packet
        if(totalBytesAvailable < packetLength)
        {
            //Not Enough Data to tell if valid packet
            return parsePacketResult_notEnoughData;
        }

        //create the Bytes vector to hold the payload bytes
        Bytes payload;
        payload.reserve(payloadLength);

        //loop through the payload
        for(uint8 payloadItr = 0; payloadItr < payloadLength; payloadItr++)
        {
            //store the payload bytes
            payload.push_back(data.read_uint8());                        //Payload Bytes
        }

        //read the node RSSI
        int16 nodeRSSI = data.read_int8();                                //Node RSSI
        
        //read the base station rssi
        int16 baseRSSI = data.read_int8();                                //Base RSSI

        //get the checksum sent in the packet
        uint16 checksum = data.read_uint16();                            //Checksum

        //build the checksum to calculate from all the bytes
        ChecksumBuilder calcChecksum;
        calcChecksum.append_uint8(deliveryStopFlag);
        calcChecksum.append_uint8(appDataType);
        calcChecksum.append_uint16(nodeAddress);
        calcChecksum.append_uint8(payloadLength);
        calcChecksum.appendBytes(payload);

        //verify that the returned checksum is the same as the one we calculated
        if(checksum != calcChecksum.simpleChecksum())
        {
            //Bad Checksum
            return parsePacketResult_badChecksum;
        }

        DeliveryStopFlags flags = DeliveryStopFlags::fromInvertedByte(deliveryStopFlag);

        //add all the info about the packet to the WirelessPacket reference passed in
        packet.deliveryStopFlags(flags);
        packet.type(static_cast<WirelessPacket::PacketType>(appDataType));
        packet.nodeAddress(static_cast<uint32>(nodeAddress));
        packet.payload(payload);
        packet.nodeRSSI(nodeRSSI);
        packet.baseRSSI(baseRSSI);
        packet.frequency(freq);

        //Correct the packet type if it is incorrect
        WirelessPacketUtils::correctPacketType(packet);

        //make sure the packet is valid based on its specific type
        if(!WirelessPacketUtils::packetIntegrityCheck(packet))
        {
            //not a valid packet, failed integrity check
            return parsePacketResult_invalidPacket;
        }

        //check if the packet is a duplicate
        if(isDuplicate(packet))
        {
            //even though it is a duplicate, we still have a complete packet so commit the bytes to skip over them
            savePoint.commit();

            //duplicate packet
            return parsePacketResult_duplicate;
        }

        //we have a complete packet, commit the bytes that we just read (move the read pointer)
        savePoint.commit();

        return parsePacketResult_completePacket;
    }