mip_packet.c
Go to the documentation of this file.
1 
2 #include "mip_packet.h"
3 #include "mip_offsets.h"
4 
6 
7 #include <string.h>
8 #include <assert.h>
9 
10 
11 //
12 // Initialization
13 //
14 
36 void mip_packet_from_buffer(mip_packet* packet, uint8_t* buffer, size_t length)
37 {
38  assert(buffer != NULL);
39 
40  // Limit the length in case it's longer than a mip packer (or worse, longer than the buffer size field can hold)
43 
44  packet->_buffer = buffer;
45  packet->_buffer_length = (uint_least16_t)length;
46 }
47 
62 void mip_packet_create(mip_packet* packet, uint8_t* buffer, size_t buffer_size, uint8_t descriptor_set)
63 {
64  mip_packet_from_buffer(packet, buffer, buffer_size);
65 
66  if( buffer_size < MIP_PACKET_LENGTH_MIN )
67  {
68  assert(false); // Buffer too small!
69  return;
70  }
71 
74  packet->_buffer[MIP_INDEX_DESCSET] = descriptor_set;
75  packet->_buffer[MIP_INDEX_LENGTH] = 0;
76 }
77 
78 
79 
80 //
81 // Accessors
82 //
83 
87 uint8_t mip_packet_descriptor_set(const mip_packet* packet)
88 {
89  return packet->_buffer[MIP_INDEX_DESCSET];
90 }
91 
95 uint8_t mip_packet_payload_length(const mip_packet* packet)
96 {
97  return packet->_buffer[MIP_INDEX_LENGTH];
98 }
99 
105 uint_least16_t mip_packet_total_length(const mip_packet* packet)
106 {
108 }
109 
113 uint8_t* mip_packet_buffer(mip_packet* packet)
114 {
115  return packet->_buffer;
116 }
117 
121 const uint8_t* mip_packet_pointer(const mip_packet* packet)
122 {
123  return packet->_buffer;
124 }
125 
129 const uint8_t* mip_packet_payload(const mip_packet* packet)
130 {
131  return packet->_buffer + MIP_INDEX_PAYLOAD;
132 }
133 
140 uint16_t mip_packet_checksum_value(const mip_packet* packet)
141 {
142  const uint_least16_t index = mip_packet_total_length(packet) - MIP_CHECKSUM_LENGTH;
143 
144  return ((uint16_t)(packet->_buffer[index+0]) << 8) | (uint16_t)(packet->_buffer[index+1]);
145 }
146 
153 {
154  uint8_t a = 0;
155  uint8_t b = 0;
156 
157  // mip_packet_total_length always returns at least MIP_PACKET_LENGTH_MIN so this
158  // subtraction is guaranteed to be safe.
159  const uint_least16_t length = mip_packet_total_length(packet) - MIP_CHECKSUM_LENGTH;
160 
161  for(uint_least16_t i=0; i<length; i++)
162  {
163  a += packet->_buffer[i];
164  b += a;
165  }
166 
167  return ((uint16_t)(a) << 8) | (uint16_t)(b);
168 }
169 
170 
179 bool mip_packet_is_sane(const mip_packet* packet)
180 {
181  return packet->_buffer && (packet->_buffer_length >= MIP_PACKET_LENGTH_MIN) && (packet->_buffer_length >= mip_packet_payload_length(packet)+MIP_PACKET_LENGTH_MIN);
182 }
183 
192 bool mip_packet_is_valid(const mip_packet* packet)
193 {
194  if( !mip_packet_is_sane(packet) || (mip_packet_descriptor_set(packet) == 0x00) )
195  return false;
196 
197  const uint16_t listed_checksum = mip_packet_checksum_value(packet);
198  const uint16_t computed_checksum = mip_packet_compute_checksum(packet);
199 
200  return listed_checksum == computed_checksum;
201 }
202 
210 bool mip_packet_is_empty(const mip_packet* packet)
211 {
212  if( !mip_packet_is_sane(packet) )
213  return true;
214 
215  return mip_packet_payload_length(packet) == 0;
216 }
217 
218 
224 uint_least16_t mip_packet_buffer_size(const mip_packet* packet)
225 {
226  return packet->_buffer_length;
227 }
228 
239 {
240  return mip_packet_buffer_size(packet) - mip_packet_total_length(packet);
241 }
242 
251 bool mip_packet_is_data(const mip_packet* packet)
252 {
254 }
255 
256 //
257 // Packet Building
258 //
259 
289 bool mip_packet_add_field(mip_packet* packet, uint8_t field_descriptor, const uint8_t* payload, uint8_t payload_length)
290 {
291  uint8_t* payload_buffer;
292  int remaining = mip_packet_alloc_field(packet, field_descriptor, payload_length, &payload_buffer);
293  if( remaining < 0 )
294  return false;
295 
296  memcpy(payload_buffer, payload, payload_length);
297 
298  return true;
299 }
300 
331 int mip_packet_alloc_field(mip_packet* packet, uint8_t field_descriptor, uint8_t payload_length, uint8_t** const payload_ptr_out)
332 {
333  assert(payload_ptr_out != NULL);
334  assert( payload_length <= MIP_FIELD_PAYLOAD_LENGTH_MAX );
335 
336  const int remaining = mip_packet_remaining_space(packet);
337 
338  const uint8_t field_length = MIP_FIELD_HEADER_LENGTH + payload_length;
339 
340  *payload_ptr_out = NULL;
341 
342  if( field_length <= remaining )
343  {
344  const uint_least16_t field_index = MIP_HEADER_LENGTH + mip_packet_payload_length(packet);
345 
346  packet->_buffer[MIP_INDEX_LENGTH] += field_length;
347 
348  packet->_buffer[field_index+MIP_INDEX_FIELD_LEN] = field_length;
349  packet->_buffer[field_index+MIP_INDEX_FIELD_DESC] = field_descriptor;
350 
351  *payload_ptr_out = &packet->_buffer[field_index + MIP_INDEX_FIELD_PAYLOAD];
352  }
353 
354  return remaining - field_length;
355 }
356 
378 int mip_packet_realloc_last_field(mip_packet* packet, uint8_t* payload_ptr, uint8_t new_payload_length)
379 {
380  assert(payload_ptr != NULL);
381  assert( new_payload_length <= MIP_FIELD_PAYLOAD_LENGTH_MAX );
382 
383  uint8_t* field_ptr = payload_ptr - MIP_INDEX_FIELD_PAYLOAD;
384  const uint8_t old_field_length = field_ptr[MIP_INDEX_FIELD_LEN];
385  const uint8_t new_field_length = new_payload_length + MIP_FIELD_HEADER_LENGTH;
386 
387  const int delta_length = new_field_length - old_field_length;
388 
389  const int remaining = mip_packet_remaining_space(packet) - delta_length;
390 
391  if( remaining >= 0 )
392  {
393  field_ptr[MIP_INDEX_FIELD_LEN] = new_field_length;
394  packet->_buffer[MIP_INDEX_LENGTH] += (int8_t)delta_length;
395  }
396 
397  return remaining;
398 }
399 
414 int mip_packet_cancel_last_field(mip_packet* packet, uint8_t* payload_ptr)
415 {
416  assert(payload_ptr != NULL);
417 
418  uint8_t* field_ptr = payload_ptr - MIP_INDEX_FIELD_PAYLOAD;
419  const uint8_t old_field_length = field_ptr[MIP_INDEX_FIELD_LEN];
420 
421  packet->_buffer[MIP_INDEX_LENGTH] -= old_field_length;
422 
423  return mip_packet_remaining_space(packet);
424 }
425 
444 {
445  uint16_t checksum = mip_packet_compute_checksum(packet);
446  uint_least16_t length = mip_packet_total_length(packet) - MIP_CHECKSUM_LENGTH;
447 
448  packet->_buffer[length+0] = checksum >> 8;
449  packet->_buffer[length+1] = checksum & 0xFF;
450 }
451 
452 
461 void mip_packet_reset(mip_packet* packet, uint8_t descriptor_set)
462 {
463  mip_packet_create(packet, mip_packet_buffer(packet), mip_packet_buffer_size(packet), descriptor_set);
464 }
465 
mip_packet.h
mip_packet::_buffer_length
uint_least16_t _buffer_length
Length of the buffer (NOT the packet length!).
Definition: mip_packet.h:44
mip_packet::_buffer
uint8_t * _buffer
Pointer to the packet data.
Definition: mip_packet.h:43
mip_packet_total_length
uint_least16_t mip_packet_total_length(const mip_packet *packet)
Returns the total length of the packet, in bytes.
Definition: mip_packet.c:105
mip_packet_create
void mip_packet_create(mip_packet *packet, uint8_t *buffer, size_t buffer_size, uint8_t descriptor_set)
Create a brand-new MIP packet in the given buffer.
Definition: mip_packet.c:62
mip_packet_alloc_field
int mip_packet_alloc_field(mip_packet *packet, uint8_t field_descriptor, uint8_t payload_length, uint8_t **const payload_ptr_out)
Allocate a MIP field within the packet and return the payload pointer.
Definition: mip_packet.c:331
mip_packet_is_valid
bool mip_packet_is_valid(const mip_packet *packet)
Returns true if the packet is valid.
Definition: mip_packet.c:192
MIP_SYNC1
@ MIP_SYNC1
Definition: mip_offsets.h:39
MIP_INDEX_LENGTH
@ MIP_INDEX_LENGTH
Definition: mip_offsets.h:12
mip_packet_cancel_last_field
int mip_packet_cancel_last_field(mip_packet *packet, uint8_t *payload_ptr)
Removes the last field from the packet after having allocated it.
Definition: mip_packet.c:414
MIP_INDEX_PAYLOAD
@ MIP_INDEX_PAYLOAD
Definition: mip_offsets.h:13
MIP_PACKET_LENGTH_MIN
@ MIP_PACKET_LENGTH_MIN
Definition: mip_offsets.h:27
MIP_INDEX_SYNC2
@ MIP_INDEX_SYNC2
Definition: mip_offsets.h:10
mip_packet_buffer
uint8_t * mip_packet_buffer(mip_packet *packet)
Returns a writable pointer to the data buffer.
Definition: mip_packet.c:113
MIP_FIELD_PAYLOAD_LENGTH_MAX
@ MIP_FIELD_PAYLOAD_LENGTH_MAX
Definition: mip_offsets.h:35
mip_packet_payload_length
uint8_t mip_packet_payload_length(const mip_packet *packet)
Returns the length of the payload (MIP fields).
Definition: mip_packet.c:95
mip_packet_compute_checksum
uint16_t mip_packet_compute_checksum(const mip_packet *packet)
Computes the checksum of the MIP packet.
Definition: mip_packet.c:152
mip_packet_payload
const uint8_t * mip_packet_payload(const mip_packet *packet)
Returns a pointer to the packet's payload (the first field).
Definition: mip_packet.c:129
MIP_SYNC2
@ MIP_SYNC2
Definition: mip_offsets.h:40
MIP_INDEX_FIELD_DESC
@ MIP_INDEX_FIELD_DESC
Definition: mip_offsets.h:18
mip_packet_reset
void mip_packet_reset(mip_packet *packet, uint8_t descriptor_set)
Reinitialize the packet with the given descriptor set.
Definition: mip_packet.c:461
MIP_INDEX_FIELD_LEN
@ MIP_INDEX_FIELD_LEN
Definition: mip_offsets.h:17
mip_packet_is_empty
bool mip_packet_is_empty(const mip_packet *packet)
Returns true if the mip packet contains no payload.
Definition: mip_packet.c:210
MIP_PACKET_LENGTH_MAX
@ MIP_PACKET_LENGTH_MAX
Definition: mip_offsets.h:28
mip_is_data_descriptor_set
bool mip_is_data_descriptor_set(uint8_t descriptor_set)
Determines if the descriptor set represents some kind of data.
Definition: descriptors.c:31
mip_packet_pointer
const uint8_t * mip_packet_pointer(const mip_packet *packet)
Returns a pointer to the data buffer containing the packet.
Definition: mip_packet.c:121
MIP_CHECKSUM_LENGTH
@ MIP_CHECKSUM_LENGTH
Definition: mip_offsets.h:24
MIP_FIELD_HEADER_LENGTH
@ MIP_FIELD_HEADER_LENGTH
Definition: mip_offsets.h:32
MIP_INDEX_SYNC1
@ MIP_INDEX_SYNC1
Definition: mip_offsets.h:9
MIP_INDEX_DESCSET
@ MIP_INDEX_DESCSET
Definition: mip_offsets.h:11
mip_packet_finalize
void mip_packet_finalize(mip_packet *packet)
Prepares the packet for transmission by adding the checksum.
Definition: mip_packet.c:443
MIP_INDEX_FIELD_PAYLOAD
@ MIP_INDEX_FIELD_PAYLOAD
Definition: mip_offsets.h:19
descriptors.h
mip_packet_add_field
bool mip_packet_add_field(mip_packet *packet, uint8_t field_descriptor, const uint8_t *payload, uint8_t payload_length)
Adds a pre-constructed MIP field to the packet.
Definition: mip_packet.c:289
mip_packet_descriptor_set
uint8_t mip_packet_descriptor_set(const mip_packet *packet)
Returns the MIP descriptor set for this packet.
Definition: mip_packet.c:87
mip_packet_realloc_last_field
int mip_packet_realloc_last_field(mip_packet *packet, uint8_t *payload_ptr, uint8_t new_payload_length)
Changes the size of the last field in the packet.
Definition: mip_packet.c:378
mip_packet_checksum_value
uint16_t mip_packet_checksum_value(const mip_packet *packet)
Returns the value of the checksum as written in the packet.
Definition: mip_packet.c:140
mip_packet_is_data
bool mip_packet_is_data(const mip_packet *packet)
Returns true if the packet is from a data descriptor set.
Definition: mip_packet.c:251
mip_packet
Structure representing a MIP Packet.
Definition: mip_packet.h:41
MIP_HEADER_LENGTH
@ MIP_HEADER_LENGTH
Definition: mip_offsets.h:23
mip_packet_remaining_space
int mip_packet_remaining_space(const mip_packet *packet)
Returns the remaining space available for more payload data.
Definition: mip_packet.c:238
mip_packet_buffer_size
uint_least16_t mip_packet_buffer_size(const mip_packet *packet)
Returns the size of the buffer backing the MIP packet.
Definition: mip_packet.c:224
length
TF2SIMD_FORCE_INLINE tf2Scalar length(const Quaternion &q)
assert.h
mip_packet_is_sane
bool mip_packet_is_sane(const mip_packet *packet)
Returns true if the packet buffer is not NULL and is at least the minimum size (MIP_PACKET_LENGTH_MIN...
Definition: mip_packet.c:179
mip_offsets.h
mip_packet_from_buffer
void mip_packet_from_buffer(mip_packet *packet, uint8_t *buffer, size_t length)
Initializes a MIP packet from an existing buffer.
Definition: mip_packet.c:36


microstrain_inertial_driver
Author(s): Brian Bingham, Parker Hannifin Corp
autogenerated on Fri May 24 2024 06:48:21