/* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef NANOPACKET_H_ #define NANOPACKET_H_ #include <cstddef> #include <cstdint> #include <vector> #include "noncopyable.h" namespace android { /* * The various reasons for a NanoPacket to be sent. */ enum class PacketReason : uint32_t { Acknowledge = 0x00000000, NAcknowledge = 0x00000001, NAcknowledgeBusy = 0x00000002, GetHardwareVersion = 0x00001000, ReadEventRequest = 0x00001090, WriteEventRequest = 0x00001091, }; /* * A NanoPacket parsing engine. Used to take a stream of bytes and convert them * into an object that can more easily be worked with. */ class NanoPacket : public NonCopyable { public: /* * The result of parsing a buffer into the packet. */ enum class ParseResult { Success, Incomplete, CrcMismatch, }; // Formats data into NanoPacket format in the provided buffer. NanoPacket(uint32_t sequence_number, PacketReason reason, const std::vector<uint8_t> *data = nullptr); // Creates an empty NanoPacket for data to be parsed into. NanoPacket(); // Resets the parsing engine to the idle state and clears parsed content. void Reset(); // Parses content from a buffer. Returns true if a packet has been entirely // parsed. ParseResult Parse(uint8_t *buffer, size_t length, size_t *bytes_parsed); // Indicated that parsing of the packet has completed. bool ParsingIsComplete() const; // The entire content of the message. const std::vector<uint8_t>& packet_buffer() const; // Obtains the reason for the packet. uint32_t reason() const; // Obtains the reason as a PacketReason. PacketReason TypedReason() const; // Obtains the data content of the packet. const std::vector<uint8_t>& packet_content() const; private: /* * The current state of the parser. */ enum class ParsingState { Idle, ParsingSequenceNumber, ParsingReason, ParsingLength, ParsingContent, ParsingCrc, Complete, }; // Parsing engine state. std::vector<uint8_t> packet_buffer_; ParsingState parsing_state_; uint32_t parsing_progress_; // Parsed protocol fields. uint32_t sequence_number_; uint32_t reason_; std::vector<uint8_t> packet_content_; uint32_t crc_; // Validates that the received packet has a CRC that matches a generated // CRC. bool ValidateCrc(); // Deserializes a little-endian word using the parsing_progress_ member to // maintain state. template<typename T> bool DeserializeWord(T *destination, uint8_t byte); }; } // namespace android #include "nanopacket_impl.h" #endif // NANOPACKET_H_