mip_dispatch.c
Go to the documentation of this file.
1 
2 #include "mip_dispatch.h"
3 
4 #include "mip_packet.h"
5 #include "mip_field.h"
6 
7 #include <assert.h>
8 
9 
10 #ifdef __cplusplus
11 namespace mip {
12 namespace C {
13 #endif
14 
21 {
26 };
27 
28 
49 void mip_dispatch_handler_init_packet_handler(mip_dispatch_handler* handler, uint8_t descriptor_set, bool post_callback, mip_dispatch_packet_callback callback, void* user_data)
50 {
51  handler->_next = NULL;
52  handler->_packet_callback = callback;
53  handler->_user_data = user_data;
55  handler->_descriptor_set = descriptor_set;
57  handler->_enabled = true;
58 }
59 
60 
84 void mip_dispatch_handler_init_field_handler(mip_dispatch_handler* handler, uint8_t descriptor_set, uint8_t field_descriptor, mip_dispatch_field_callback callback, void* user_data)
85 {
86  handler->_next = NULL;
87  handler->_field_callback = callback;
88  handler->_user_data = user_data;
89  handler->_type = MIP_DISPATCH_TYPE_FIELD;
90 
91  handler->_descriptor_set = descriptor_set;
92  handler->_field_descriptor = field_descriptor;
93  handler->_enabled = true;
94 }
95 
129 void mip_dispatch_handler_init_extractor(mip_dispatch_handler* handler, uint8_t descriptor_set, uint8_t field_descriptor, mip_dispatch_extractor extractor, void* field_ptr)
130 {
131  // The only wildcard allowed is MIP_DISPATCH_ANY_DATA_SET when field_descriptor is from the shared data set.
132  assert(descriptor_set != MIP_DISPATCH_ANY_DESCRIPTOR);
133  assert(field_descriptor != MIP_DISPATCH_ANY_DESCRIPTOR && field_descriptor != MIP_DISPATCH_ANY_DATA_SET);
134  assert(!mip_is_data_descriptor_set(descriptor_set) || (descriptor_set != MIP_DISPATCH_ANY_DATA_SET) || mip_is_shared_data_field_descriptor(field_descriptor));
135  assert(field_ptr);
136 
137  handler->_next = NULL;
138  handler->_extract_callback = extractor;
139  handler->_user_data = field_ptr;
140 
141  handler->_type = MIP_DISPATCH_TYPE_EXTRACT;
142  handler->_descriptor_set = descriptor_set;
143  handler->_field_descriptor = field_descriptor;
144  handler->_enabled = true;
145 }
146 
147 
155 {
156  handler->_enabled = enable;
157 }
158 
165 {
166  return handler->_enabled;
167 }
168 
170 
171 
172 
177 {
178  self->_first_handler = NULL;
179 }
180 
181 
188 {
189  if( self->_first_handler == NULL )
190  self->_first_handler = handler;
191  else
192  {
193  mip_dispatch_handler* last = self->_first_handler;
194 
195  while(last->_next != NULL)
196  last = last->_next;
197 
198  last->_next = handler;
199  }
200 }
201 
202 
209 {
210  if( self->_first_handler == NULL )
211  return;
212 
213  mip_dispatch_handler* query = self->_first_handler;
214 
215  if( query == handler )
216  {
217  self->_first_handler = handler->_next;
218  handler->_next = NULL;
219  return;
220  }
221 
222  while(query->_next != NULL)
223  {
224  if( query->_next == handler )
225  {
226  query->_next = handler->_next;
227  handler->_next = NULL;
228  return;
229  }
230  }
231 }
232 
233 
238 {
239  mip_dispatch_handler* query = self->_first_handler;
240 
241  self->_first_handler = NULL;
242 
243  // Break the chain (technically not necessary, but aids debugging)
244  while(query)
245  {
246  mip_dispatch_handler* next = query->_next;
247  query->_next = NULL;
248  query = next;
249  }
250 }
251 
252 static bool mip_dispatch_is_descriptor_set_match(uint8_t desc_set, uint8_t handler_desc_set)
253 {
254  return (
255  (handler_desc_set == desc_set) ||
256  (handler_desc_set == MIP_DISPATCH_ANY_DESCRIPTOR) ||
257  ((handler_desc_set == MIP_DISPATCH_ANY_DATA_SET) && mip_is_data_descriptor_set(desc_set))
258  );
259 }
260 
270 static void mip_dispatcher_call_packet_callbacks(mip_dispatcher* self, const mip_packet* packet, mip_timestamp timestamp, bool post)
271 {
272  const uint8_t descriptor_set = mip_packet_descriptor_set(packet);
273 
274  // Iterate all packet handlers for this packet.
275  for(mip_dispatch_handler* handler = self->_first_handler; handler != NULL; handler = handler->_next)
276  {
277  switch(handler->_type)
278  {
279  case MIP_DISPATCH_TYPE_PACKET_POST: if(!post) continue; else break;
280  case MIP_DISPATCH_TYPE_PACKET_PRE: if( post) continue; else break;
281  default: continue;
282  }
283 
284  if( mip_dispatch_is_descriptor_set_match(descriptor_set, handler->_descriptor_set) )
285  handler->_packet_callback(handler->_user_data, packet, timestamp);
286  }
287 }
288 
299 static bool mip_dispatch_is_descriptor_match(uint8_t desc_set, uint8_t field_desc, uint8_t handler_desc_set, uint8_t handler_field_desc)
300 {
301  return mip_dispatch_is_descriptor_set_match(desc_set, handler_desc_set) && (
302  (handler_field_desc == field_desc) ||
303  (handler_field_desc == MIP_DISPATCH_ANY_DESCRIPTOR)
304  );
305 }
306 
316 {
317  const uint8_t descriptor_set = mip_field_descriptor_set(field);
318  const uint8_t field_descriptor = mip_field_field_descriptor(field);
319 
320  // Iterate all field handlers for this field.
321  for(mip_dispatch_handler* handler = self->_first_handler; handler != NULL; handler = handler->_next)
322  {
323  if(handler->_type == MIP_DISPATCH_TYPE_FIELD)
324  {
325  if( mip_dispatch_is_descriptor_match(descriptor_set, field_descriptor, handler->_descriptor_set, handler->_field_descriptor) )
326  {
327  handler->_field_callback(handler->_user_data, field, timestamp);
328  }
329  }
330  else if(handler->_type == MIP_DISPATCH_TYPE_EXTRACT)
331  {
332  if( handler->_descriptor_set == descriptor_set && handler->_field_descriptor == field_descriptor )
333  {
334  handler->_extract_callback(field, handler->_user_data);
335  }
336  }
337  };
338 }
339 
352 {
353  mip_dispatcher_call_packet_callbacks(self, packet, timestamp, false);
354 
355  mip_field field;
356  mip_field_init_empty(&field);
357  while( mip_field_next_in_packet(&field, packet) )
358  {
359  mip_dispatcher_call_field_callbacks(self, &field, timestamp);
360  }
361 
362  mip_dispatcher_call_packet_callbacks(self, packet, timestamp, true);
363 }
364 
365 #ifdef __cplusplus
366 } // namespace C
367 } // namespace mip
368 #endif
mip_packet.h
mip_dispatch_handler::_extract_callback
mip_dispatch_extractor _extract_callback
User callback for data fields. Valid if _type is MIP_DISPATCH_TYPE_EXTRACT.
Definition: mip_dispatch.h:94
mip
Definition: ping.cpp:12
mip_dispatch_handler_init_packet_handler
void mip_dispatch_handler_init_packet_handler(mip_dispatch_handler *handler, uint8_t descriptor_set, bool post_callback, mip_dispatch_packet_callback callback, void *user_data)
Initialize the dispatch handler with a packet callback.
Definition: mip_dispatch.c:49
MIP_DISPATCH_TYPE_FIELD
@ MIP_DISPATCH_TYPE_FIELD
Field callback. Use handler._field_callback.
Definition: mip_dispatch.c:24
mip_dispatch_packet_callback
void(* mip_dispatch_packet_callback)(void *context, const mip_packet *packet, mip_timestamp timestamp)
Signature for packet-level callbacks.
Definition: mip_dispatch.h:38
mip_dispatch.h
mip_dispatch_handler::_user_data
void * _user_data
User-provided pointer which is passed directly to the callback.
Definition: mip_dispatch.h:96
mip_dispatcher_call_field_callbacks
static void mip_dispatcher_call_field_callbacks(mip_dispatcher *self, const mip_field *field, mip_timestamp timestamp)
Called to dispatch packet callback before and after field iteration.
Definition: mip_dispatch.c:315
mip_dispatch_handler::_field_descriptor
uint8_t _field_descriptor
MIP field descriptor for this callback. If 0x00, the callback is a packet callback.
Definition: mip_dispatch.h:99
mip_dispatch_handler_init_field_handler
void mip_dispatch_handler_init_field_handler(mip_dispatch_handler *handler, uint8_t descriptor_set, uint8_t field_descriptor, mip_dispatch_field_callback callback, void *user_data)
Initialize the dispatch handler with a field callback.
Definition: mip_dispatch.c:84
mip_field_next_in_packet
bool mip_field_next_in_packet(mip_field *field, const mip_packet *packet)
Iterates over all fields in a packet.
Definition: mip_field.c:227
mip_dispatcher_dispatch_packet
void mip_dispatcher_dispatch_packet(mip_dispatcher *self, const mip_packet *packet, mip_timestamp timestamp)
Called to dispatch the callbacks for a given packet.
Definition: mip_dispatch.c:351
mip_dispatch_extractor
bool(* mip_dispatch_extractor)(const mip_field *field, void *ptr)
Signature for extraction callbacks.
Definition: mip_dispatch.h:55
MIP_DISPATCH_ANY_DATA_SET
@ MIP_DISPATCH_ANY_DATA_SET
Wildcard descriptor set which only includes data packets.
Definition: mip_dispatch.h:63
mip_dispatch_handler::_packet_callback
mip_dispatch_packet_callback _packet_callback
User function for packets. Valid if type is MIP_DISPATCH_TYPE_PACKET*.
Definition: mip_dispatch.h:92
MIP_DISPATCH_ANY_DESCRIPTOR
@ MIP_DISPATCH_ANY_DESCRIPTOR
Any descriptor set or field descriptor.
Definition: mip_dispatch.h:67
mip_dispatch_handler::_field_callback
mip_dispatch_field_callback _field_callback
User callback for data fields. Valid if _type is MIP_DISPATCH_TYPE_FIELD.
Definition: mip_dispatch.h:93
mip_dispatcher_add_handler
void mip_dispatcher_add_handler(mip_dispatcher *self, mip_dispatch_handler *handler)
Registers a handler in the dispatch system.
Definition: mip_dispatch.c:187
mip_dispatcher_remove_handler
void mip_dispatcher_remove_handler(mip_dispatcher *self, mip_dispatch_handler *handler)
Removes a handler from the dispatch system.
Definition: mip_dispatch.c:208
mip_dispatch_handler::_descriptor_set
uint8_t _descriptor_set
MIP descriptor set for this callback.
Definition: mip_dispatch.h:98
mip_dispatch_handler_is_enabled
bool mip_dispatch_handler_is_enabled(mip_dispatch_handler *handler)
Determines if the handler is currently enabled.
Definition: mip_dispatch.c:164
mip_field
A structure representing a MIP field.
Definition: mip_field.h:52
mip_field_field_descriptor
uint8_t mip_field_field_descriptor(const mip_field *field)
Returns the field descriptor.
Definition: mip_field.c:52
mip_timestamp
uint64_t mip_timestamp
Type used for packet timestamps and timeouts.
Definition: mip_types.h:32
mip_dispatch_handler::_next
struct mip_dispatch_handler * _next
Pointer to the next handler in the list.
Definition: mip_dispatch.h:89
mip_dispatcher_call_packet_callbacks
static void mip_dispatcher_call_packet_callbacks(mip_dispatcher *self, const mip_packet *packet, mip_timestamp timestamp, bool post)
Called to dispatch packet callback before and after field iteration.
Definition: mip_dispatch.c:270
mip_dispatch_is_descriptor_set_match
static bool mip_dispatch_is_descriptor_set_match(uint8_t desc_set, uint8_t handler_desc_set)
Definition: mip_dispatch.c:252
MIP_DISPATCH_TYPE_EXTRACT
@ MIP_DISPATCH_TYPE_EXTRACT
Extraction callback. Use handler._extract_callback.
Definition: mip_dispatch.c:25
mip_dispatch_handler_set_enabled
void mip_dispatch_handler_set_enabled(mip_dispatch_handler *handler, bool enable)
Enables or disables the handler.
Definition: mip_dispatch.c:154
mip_field_descriptor_set
uint8_t mip_field_descriptor_set(const mip_field *field)
Returns the descriptor set of the packet containing this field._.
Definition: mip_field.c:44
mip_dispatch_type
mip_dispatch_type
Type of dispatch callback.
Definition: mip_dispatch.c:20
mip_field.h
mip_dispatch_handler_init_extractor
void mip_dispatch_handler_init_extractor(mip_dispatch_handler *handler, uint8_t descriptor_set, uint8_t field_descriptor, mip_dispatch_extractor extractor, void *field_ptr)
Initialize the dispatch handler with an extraction callback.
Definition: mip_dispatch.c:129
mip_dispatch_handler
Handler information for MIP Packet or Field callbacks.
Definition: mip_dispatch.h:87
mip_dispatch_is_descriptor_match
static bool mip_dispatch_is_descriptor_match(uint8_t desc_set, uint8_t field_desc, uint8_t handler_desc_set, uint8_t handler_field_desc)
Determines if the field matches the dispatcher.
Definition: mip_dispatch.c:299
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_dispatch_handler::_enabled
uint8_t _enabled
If false, the handler will be ignored. (Using u8 for better struct packing.)
Definition: mip_dispatch.h:100
mip_dispatcher_remove_all_handlers
void mip_dispatcher_remove_all_handlers(mip_dispatcher *self)
Removes all handlers from the dispatcher.
Definition: mip_dispatch.c:237
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
Structure representing a MIP Packet.
Definition: mip_packet.h:41
mip_dispatch_field_callback
void(* mip_dispatch_field_callback)(void *context, const mip_field *field, mip_timestamp timestamp)
Signature for field-level callbacks.
Definition: mip_dispatch.h:47
mip_is_shared_data_field_descriptor
bool mip_is_shared_data_field_descriptor(uint8_t field_descriptor)
Determines if the field descriptor is from the shared data set.
Definition: descriptors.c:148
MIP_INVALID_FIELD_DESCRIPTOR
@ MIP_INVALID_FIELD_DESCRIPTOR
Definition: descriptors.h:25
assert.h
MIP_DISPATCH_TYPE_PACKET_PRE
@ MIP_DISPATCH_TYPE_PACKET_PRE
Packet callback, before field callbacks. Use handler._packet_callback.
Definition: mip_dispatch.c:22
mip_dispatcher_init
void mip_dispatcher_init(mip_dispatcher *self)
Initializes the mip_dispatcher object.
Definition: mip_dispatch.c:176
mip_dispatch_handler::_type
uint8_t _type
Type of the callback. (Using u8 for better struct packing.)
Definition: mip_dispatch.h:97
mip_dispatcher
Holds the state of the MIP dispatch system.
Definition: mip_dispatch.h:121
mip_field_init_empty
void mip_field_init_empty(mip_field *field)
Initialize a mip_field struct to an invalid/empty state.
Definition: mip_field.c:93
MIP_DISPATCH_TYPE_PACKET_POST
@ MIP_DISPATCH_TYPE_PACKET_POST
Packet callback, after field callbacks. Use handler._packet_callback.
Definition: mip_dispatch.c:23


microstrain_inertial_driver
Author(s): Brian Bingham, Parker Hannifin Corp
autogenerated on Mon Jun 24 2024 02:51:40