50 assert(0 == p_map->count(payload_id));
51 (*p_map)[payload_id] = fn;
56 const std::string& what,
int num_bytes_needed = 0)
58 if (p_num_bytes_needed != NULL) *p_num_bytes_needed = num_bytes_needed;
59 if (p_what != NULL) *p_what = what;
64 const Buffer::const_iterator& end,
65 int* num_bytes_needed, std::string* what)
68 if (num_bytes_needed != NULL) *num_bytes_needed = 0;
69 if (what != NULL) what->clear();
72 int buffer_size(std::distance(begin, end));
74 return createFailed(num_bytes_needed, what,
"Buffer does not contain a complete frame",
80 return createFailed(num_bytes_needed, what,
"Buffer must begin with start-of-frame character");
87 view_payload.first = begin + 2;
88 view_payload.second = view_payload.first + *(begin + 1);
94 view_payload.first = begin + 3;
95 view_payload.second = view_payload.first + (*(begin + 1) << 8) + *(begin + 2);
100 return createFailed(num_bytes_needed, what,
"Invalid payload length");
103 Buffer::const_iterator iter_crc(view_payload.second);
104 Buffer::const_iterator iter_eof(iter_crc + 2);
108 int frame_size = std::distance(view_frame.first, view_frame.second);
109 if (buffer_size < frame_size)
110 return createFailed(num_bytes_needed, what,
"Buffer does not contain a complete frame",
111 frame_size - buffer_size);
115 return createFailed(num_bytes_needed, what,
"Invalid end-of-frame character");
118 uint16_t crc = (
static_cast<uint16_t
>(*iter_crc) << 8) + *(iter_crc + 1);
120 &(*view_payload.first), std::distance(view_payload.first, view_payload.second),
VescFrame::CRC_TYPE))
121 return createFailed(num_bytes_needed, what,
"Invalid checksum");
124 std::shared_ptr<VescFrame> raw_frame(
new VescFrame(view_frame, view_payload));
127 if (std::distance(view_payload.first, view_payload.second) > 0)
131 FactoryMap::const_iterator
search(p_map->find(*view_payload.first));
132 if (
search != p_map->end())
134 return search->second(raw_frame);
139 return createFailed(num_bytes_needed, what,
"Unkown payload type.");
145 return createFailed(num_bytes_needed, what,
"Frame does not have a payload");
static constexpr CRC::Parameters< crcpp_uint16, 16 > CRC_TYPE
std::pair< Buffer::const_iterator, Buffer::const_iterator > BufferRangeConst
static VescPacketPtr createPacket(const Buffer::const_iterator &begin, const Buffer::const_iterator &end, int *num_bytes_needed, std::string *what)
static const int VESC_MIN_FRAME_SIZE
Smallest VESC frame size, in bytes.
VescPacketPtr createFailed(int *p_num_bytes_needed, std::string *p_what, const std::string &what, int num_bytes_needed=0)
std::map< int, CreateFn > FactoryMap
static const int VESC_MAX_PAYLOAD_SIZE
Maximum VESC payload size, in bytes.
static const unsigned int VESC_EOF_VAL
VESC end-of-frame value.
static CRCType Calculate(const void *data, crcpp_size size, const Parameters< CRCType, CRCWidth > ¶meters)
Computes a CRC.
std::shared_ptr< VescPacket > VescPacketPtr
static void registerPacketType(int payload_id, CreateFn fn)
std::function< VescPacketPtr(std::shared_ptr< VescFrame >)> CreateFn
static const unsigned int VESC_SOF_VAL_LARGE_FRAME
VESC start of "large" frame value.
static const unsigned int VESC_SOF_VAL_SMALL_FRAME
VESC start of "small" frame value.
ROSCPP_DECL bool search(const std::string &ns, const std::string &key, std::string &result)
static FactoryMap * getMap()