/*
* 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_