com_manager.c
Go to the documentation of this file.
1 /*
2 MIT LICENSE
3 
4 Copyright (c) 2014-2020 Inertial Sense, Inc. - http://inertialsense.com
5 
6 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions :
7 
8 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
9 
10 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
11 */
12 
13 #include "com_manager.h"
14 #include <string.h>
15 #include <stdlib.h>
16 
17 
18 // enable filtering of duplicate packets
19 #define ENABLE_FILTER_DUPLICATE_PACKETS 1
20 
21 // whether the first character or all characters are checked in duplicate packets
22 #define ENABLE_FILTER_DUPLICATE_PACKETS_MATCH_ALL_CHARACTERS 0
23 
24 #define PARSE_DOUBLE(str) strtod(str, 0)
25 #define PARSE_FLOAT(str) strtof(str, 0)
26 
27 #define MIN_REQUEST_PERIOD_MS 1 // (ms) 1 KHz
28 #define MAX_REQUEST_PERIOD_MS 100000 // (ms)
29 #define MSG_PERIOD_SEND_ONCE -1
30 #define MSG_PERIOD_DISABLED 0
31 
33 
35 (
36  com_manager_t* cmInstance,
37  int numHandles,
38  int maxEnsuredPackets,
39  int stepPeriodMilliseconds,
40  int retryCount,
41  pfnComManagerRead readFnc,
42  pfnComManagerSend sendFnc,
44  pfnComManagerPostRead pstRxFnc,
45  pfnComManagerPostAck pstAckFnc,
46  pfnComManagerDisableBroadcasts disableBcastFnc,
47  com_manager_init_t *buffers,
48  com_manager_port_t *cmPorts
49 );
50 // int processAsciiRxPacket(com_manager_t* cmInstance, int pHandle, unsigned char* start, int count);
51 // void parseAsciiPacket(com_manager_t* cmInstance, int pHandle, unsigned char* buf, int count);
52 int processBinaryRxPacket(com_manager_t* cmInstance, int pHandle, packet_t *pkt);
53 void enableBroadcastMsg(com_manager_t* cmInstance, broadcast_msg_t *msg, int periodMultiple);
54 void disableBroadcastMsg(com_manager_t* cmInstance, broadcast_msg_t *msg);
55 void disableDidBroadcast(com_manager_t* cmInstance, int pHandle, p_data_disable_t *disable);
56 int sendPacket(com_manager_t* cmInstance, int pHandle, packet_t *dPkt, uint8_t additionalPktFlags);
57 int sendDataPacket(com_manager_t* cmInstance, int pHandle, pkt_info_t *msg);
58 void sendAck(com_manager_t* cmInstance, int pHandle, packet_t *pkt, unsigned char pid_ack);
59 int findAsciiMessage(const void * a, const void * b);
60 
61 // Packet processing
62 // com manager only...
63 int encodeBinaryPacket(com_manager_t* cmInstance, int pHandle, buffer_t *pkt, packet_t *dPkt, uint8_t additionalPktFlags);
64 // 1 if valid
65 int asciiMessageCompare(const void* elem1, const void* elem2);
66 
67 // Packet Retry
68 void stepPacketRetry(com_manager_t* cmInstance);
69 packet_t* registerPacketRetry(com_manager_t* cmInstance, int pHandle, uint8_t pid, unsigned char data[], unsigned int dataSize);
70 void updatePacketRetryData(com_manager_t* cmInstance, packet_t *pkt);
71 void updatePacketRetryAck(com_manager_t* cmInstance, packet_t *pkt);
72 
75 
76 CMHANDLE comManagerGetGlobal(void) { return &g_cm; }
77 
79 (
80  int numHandles,
81  int maxEnsuredPackets,
82  int stepPeriodMilliseconds,
83  int retryCount,
84  pfnComManagerRead readFnc,
85  pfnComManagerSend sendFnc,
87  pfnComManagerPostRead pstRxFnc,
88  pfnComManagerPostAck pstAckFnc,
89  pfnComManagerDisableBroadcasts disableBcastFnc,
90  com_manager_init_t *buffers,
91  com_manager_port_t *cmPorts
92 )
93 {
95  &g_cm,
96  numHandles,
97  maxEnsuredPackets,
98  stepPeriodMilliseconds,
99  retryCount,
100  readFnc,
101  sendFnc,
102  txFreeFnc,
103  pstRxFnc,
104  pstAckFnc,
105  disableBcastFnc,
106  buffers,
107  cmPorts);
108 }
109 
111 (
112  CMHANDLE cmHandle,
113  int numHandles,
114  int maxEnsuredPackets,
115  int stepPeriodMilliseconds,
116  int retryCount,
117  pfnComManagerRead readFnc,
118  pfnComManagerSend sendFnc,
120  pfnComManagerPostRead pstRxFnc,
121  pfnComManagerPostAck pstAckFnc,
122  pfnComManagerDisableBroadcasts disableBcastFnc,
123  com_manager_init_t *buffers,
124  com_manager_port_t *cmPorts
125 )
126 {
127  int result = 0;
128 
129  com_manager_t* cmInstance = (com_manager_t*)cmHandle;
130  if (cmInstance != 0)
131  {
132  memset(cmInstance, 0, sizeof(com_manager_t));
134  cmInstance,
135  numHandles,
136  maxEnsuredPackets,
137  stepPeriodMilliseconds,
138  retryCount,
139  readFnc,
140  sendFnc,
141  txFreeFnc,
142  pstRxFnc,
143  pstAckFnc,
144  disableBcastFnc,
145  buffers,
146  cmPorts);
147  }
148  return result;
149 }
150 
152 (
153  com_manager_t* cmInstance,
154  int numHandles,
155  int maxEnsuredPackets,
156  int stepPeriodMilliseconds,
157  int retryCount,
158  pfnComManagerRead readFnc,
159  pfnComManagerSend sendFnc,
161  pfnComManagerPostRead pstRxFnc,
162  pfnComManagerPostAck pstAckFnc,
163  pfnComManagerDisableBroadcasts disableBcastFnc,
164  com_manager_init_t *buffers,
165  com_manager_port_t *cmPorts
166 )
167 {
168  int32_t i;
169 
170  if (numHandles <= 0)
171  {
172  return -1;
173  }
174  numHandles = _CLAMP(numHandles, 1, 1024);
175 
176  // assign new variables
177  cmInstance->maxEnsuredPackets = maxEnsuredPackets;
178  cmInstance->readCallback = readFnc;
179  cmInstance->sendPacketCallback = sendFnc;
180  cmInstance->txFreeCallback = txFreeFnc;
181  cmInstance->pstRxFnc = pstRxFnc;
182  cmInstance->pstAckFnc = pstAckFnc;
183  cmInstance->disableBcastFnc = disableBcastFnc;
184  cmInstance->numHandles = numHandles;
185  cmInstance->stepPeriodMilliseconds = stepPeriodMilliseconds;
186  cmInstance->ensureRetryCount = retryCount;
187  cmInstance->cmMsgHandlerAscii = NULL;
188  cmInstance->cmMsgHandlerUblox = NULL;
189  cmInstance->cmMsgHandlerRtcm3 = NULL;
190 
191  if (buffers == NULL)
192  {
193  return -1;
194  }
195 
196  // Buffer: message broadcasts
198  {
199  return -1;
200  }
201  cmInstance->broadcastMessages = (broadcast_msg_t*)buffers->broadcastMsg;
202  memset(cmInstance->broadcastMessages, 0, buffers->broadcastMsgSize);
203 
204  // Port specific info
205  cmInstance->ports = cmPorts;
206  for (i = 0; i < numHandles; i++)
207  { // Initialize IScomm instance, for serial reads / writes
208  com_manager_port_t *port = &(cmInstance->ports[i]);
209  is_comm_init(&(port->comm), port->comm_buffer, MEMBERSIZE(com_manager_port_t, comm_buffer));
210 
211  // Port status
212  memset(&(port->status), 0, MEMBERSIZE(com_manager_port_t,status));
213 
214 #if ENABLE_PACKET_CONTINUATION
215  // Packet data continuation
216  memset(&(port->con), 0, MEMBERSIZE(com_manager_port_t,con));
217 #endif
218  }
219 
220  // Buffer: ensured packets
221  if (cmInstance->maxEnsuredPackets > 0)
222  {
224  {
225  return -1;
226  }
227  cmInstance->ensuredPackets = (ensured_pkt_t*)buffers->ensuredPackets;
228  memset(cmInstance->ensuredPackets, 0, buffers->ensuredPacketsSize);
229  for (i = 0; i < cmInstance->maxEnsuredPackets; i++)
230  {
231  cmInstance->ensuredPackets[i].counter = -2; // indicates no retries are enabled
232  cmInstance->ensuredPackets[i].pkt.body.ptr = cmInstance->ensuredPackets[i].pktBody;
233  }
234  }
235 
236  return 0;
237 }
238 
239 int asciiMessageCompare(const void* elem1, const void* elem2)
240 {
241  asciiMessageMap_t* e1 = (asciiMessageMap_t*)elem1;
242  asciiMessageMap_t* e2 = (asciiMessageMap_t*)elem2;
243 
244  return memcmp(e1->messageId, e2->messageId, 4);
245 }
246 
247 void comManagerRegister(uint32_t dataId, pfnComManagerPreSend txFnc, pfnComManagerPostRead pstRxFnc, const void* txDataPtr, void* rxDataPtr, int dataSize, uint8_t pktFlags)
248 {
249  comManagerRegisterInstance(&g_cm, dataId, txFnc, pstRxFnc, txDataPtr, rxDataPtr, dataSize, pktFlags);
250 }
251 
252 void comManagerRegisterInstance(CMHANDLE cmInstance_, uint32_t dataId, pfnComManagerPreSend txFnc, pfnComManagerPostRead pstRxFnc, const void* txDataPtr, void* rxDataPtr, int dataSize, uint8_t pktFlags)
253 {
254  com_manager_t* cmInstance = (com_manager_t*)cmInstance_;
255 
256  // Validate ID and data pointer
257  if (dataId >= DID_COUNT)
258  {
259  return;
260  }
261 
262  // Function called to update struct before data is sent
263  cmInstance->regData[dataId].preTxFnc = txFnc;
264 
265  // Function called after data is received and struct is updated
266  cmInstance->regData[dataId].pstRxFnc = pstRxFnc;
267 
268  // Pointer to data struct for Tx
269  cmInstance->regData[dataId].dataSet.txPtr = (unsigned char*)txDataPtr;
270 
271  // Pointer to data struct for Rx
272  cmInstance->regData[dataId].dataSet.rxPtr = (unsigned char*)rxDataPtr;
273 
274  // Size of data struct
275  cmInstance->regData[dataId].dataSet.size = dataSize;
276 
277  // Packet flags
278  cmInstance->regData[dataId].pktFlags = pktFlags;
279 }
280 
281 void comManagerStep(void)
282 {
285 }
286 
288 {
289  com_manager_t* cmInstance = (com_manager_t*)cmInstance_;
290  comManagerStepRxInstance(cmInstance);
291  comManagerStepTxInstance(cmInstance);
292 }
293 
294 // pfnISCommRead
295 // static int commRead(int pHandle, uint8_t *buffer, int numberOfBytes)
296 // {
297 //
298 // }
299 
301 {
302  com_manager_t* cmInstance = (com_manager_t*)cmInstance_;
303  int32_t pHandle;
304 
305  if (!cmInstance->readCallback)
306  {
307  return;
308  }
309 
310 
311  for (pHandle = 0; pHandle < cmInstance->numHandles; pHandle++)
312  {
313  com_manager_port_t *port = &(cmInstance->ports[pHandle]);
314  is_comm_instance_t *comm = &(port->comm);
315  protocol_type_t ptype;
316 
317 #if 0 // Read one byte (simple method)
318  uint8_t c;
319 
320  // Read from serial buffer until empty
321  while (cmInstance->readCallback(cmInstance, pHandle, &c, 1))
322  {
323  if ((ptype = is_comm_parse_byte(comm, c)) != _PTYPE_NONE)
324  {
325 
326 #else // Read a set of bytes (fast method)
327 
328  // Get available size of comm buffer
329  int n = is_comm_free(comm);
330 
331  // Read data directly into comm buffer
332  if ((n = cmInstance->readCallback(cmInstance, pHandle, comm->buf.tail, n)))
333  {
334  // Update comm buffer tail pointer
335  comm->buf.tail += n;
336 
337  // Search comm buffer for valid packets
338  while ((ptype = is_comm_parse(comm)) != _PTYPE_NONE)
339  {
340 #endif
341  uint8_t error = 0;
342  uint8_t *dataPtr = comm->dataPtr + comm->dataHdr.offset;
343  uint32_t dataSize = comm->dataHdr.size;
344 
345  switch (ptype)
346  {
347  case _PTYPE_PARSE_ERROR:
348  error = 1;
349  break;
350 
353  error = (uint8_t)processBinaryRxPacket(cmInstance, pHandle, &(comm->pkt));
354  break;
355 
356  case _PTYPE_UBLOX:
357  if (cmInstance->cmMsgHandlerUblox)
358  {
359  error = (uint8_t)cmInstance->cmMsgHandlerUblox(cmInstance, pHandle, dataPtr, dataSize);
360  }
361  break;
362 
363  case _PTYPE_RTCM3:
364  if (cmInstance->cmMsgHandlerRtcm3)
365  {
366  error = (uint8_t)cmInstance->cmMsgHandlerRtcm3(cmInstance, pHandle, dataPtr, dataSize);
367  }
368  break;
369 
370  case _PTYPE_ASCII_NMEA:
371  if (cmInstance->cmMsgHandlerAscii)
372  {
373  error = (uint8_t)cmInstance->cmMsgHandlerAscii(cmInstance, pHandle, dataPtr, dataSize);
374  }
375  break;
376 
377  default:
378  break;
379  }
380 
381  if (error)
382  { // Error parsing packet
383  port->status.readCounter += 32;
384  port->status.rxError = (uint32_t)-1;
386  }
387  }
388  }
389 
390  if ((port->status.flags & CM_PKT_FLAGS_RX_VALID_DATA) && port->status.readCounter > 128)
391  { // communication problem, clear communication received bit
393  }
394  }
395 }
396 
398 {
399  com_manager_t* cmInstance = (com_manager_t*)cmInstance_;
401 }
402 
404 {
406 }
407 
409 {
410  com_manager_t* cmInstance = cmInstance_;
411 
412  // Send data (if necessary)
413  for (broadcast_msg_t* bcPtr = cmInstance->broadcastMessages, *ptrEnd = (cmInstance->broadcastMessages + MAX_NUM_BCAST_MSGS); bcPtr < ptrEnd; bcPtr++)
414  {
415  // If send buffer does not have space, exit out
416  if (cmInstance->txFreeCallback && (bcPtr->pkt.txData.size > (uint32_t)cmInstance->txFreeCallback(cmInstance, bcPtr->pHandle)))
417  {
418  break;
419  }
420  // Send once and remove from message queue
421  else if (bcPtr->period == MSG_PERIOD_SEND_ONCE)
422  {
423  sendDataPacket(cmInstance, bcPtr->pHandle, &(bcPtr->pkt));
424  disableBroadcastMsg(cmInstance, bcPtr);
425  }
426  // Broadcast messages
427  else if (bcPtr->period > 0)
428  {
429  // Check if counter has expired
430  if (++bcPtr->counter >= bcPtr->period)
431  {
432  bcPtr->counter = 0; // reset counter
433 
434  // Prep data if callback exists
435  if (cmInstance->regData[bcPtr->dataHdr.id].preTxFnc)
436  {
437  cmInstance->regData[bcPtr->dataHdr.id].preTxFnc(cmInstance, bcPtr->pHandle);
438  }
439  sendDataPacket(cmInstance, bcPtr->pHandle, &(bcPtr->pkt));
440  }
441  }
442  }
443 
444  // Resend data (if necessary)
445  stepPacketRetry(cmInstance);
446 }
447 
449  pfnComManagerAsapMsg handlerRmc,
450  pfnComManagerGenMsgHandler handlerAscii,
451  pfnComManagerGenMsgHandler handlerUblox,
452  pfnComManagerGenMsgHandler handlerRtcm3)
453 {
454  comManagerSetCallbacksInstance(&g_cm, handlerRmc, handlerAscii, handlerUblox, handlerRtcm3);
455 }
456 
458  pfnComManagerAsapMsg handlerRmc,
459  pfnComManagerGenMsgHandler handlerAscii,
460  pfnComManagerGenMsgHandler handlerUblox,
461  pfnComManagerGenMsgHandler handlerRtcm3)
462 {
463  if (cmInstance != 0)
464  {
465  ((com_manager_t*)cmInstance)->cmMsgHandlerRmc = handlerRmc;
466  ((com_manager_t*)cmInstance)->cmMsgHandlerAscii = handlerAscii;
467  ((com_manager_t*)cmInstance)->cmMsgHandlerUblox = handlerUblox;
468  ((com_manager_t*)cmInstance)->cmMsgHandlerRtcm3 = handlerRtcm3;
469  }
470 }
471 
472 void comManagerAssignUserPointer(CMHANDLE cmInstance, void* userPointer)
473 {
474  ((com_manager_t*)cmInstance)->userPointer = userPointer;
475 }
476 
478 {
479  return ((com_manager_t*)cmInstance)->userPointer;
480 }
481 
483 {
484  return comManagerGetStatusInstance(&g_cm, pHandle);
485 }
486 
488 {
489  com_manager_t *cm = (com_manager_t*)cmInstance;
490 
491  if(cm->numHandles <= 0 || pHandle < 0 || pHandle >= cm->numHandles)
492  {
493  return NULL;
494  }
495 
496  return &(cm->ports[pHandle].status);
497 }
498 
511 void comManagerGetData(int pHandle, uint32_t dataId, int offset, int size, int periodMultiple)
512 {
513  comManagerGetDataInstance(&g_cm, pHandle, dataId, offset, size, periodMultiple);
514 }
515 
516 void comManagerGetDataInstance(CMHANDLE cmInstance, int pHandle, uint32_t dataId, int offset, int size, int periodMultiple)
517 {
518  p_data_get_t request;
519  bufPtr_t data;
520 
521  // Create and Send request packet
522  request.id = dataId;
523  request.offset = offset;
524  request.size = size;
525  request.bc_period_multiple = periodMultiple;
526 
527  data.ptr = (uint8_t*)&request;
528  data.size = sizeof(request);
529  comManagerSendInstance(cmInstance, pHandle, PID_GET_DATA, 0, &data, 0);
530 
531  // comManagerSendEnsured(pHandle, PID_GET_DATA, (unsigned char*)&request, sizeof(request));
532 }
533 
534 void comManagerGetDataRmc(int pHandle, uint64_t rmcBits, uint32_t rmcOptions)
535 {
536  comManagerGetDataRmcInstance(&g_cm, pHandle, rmcBits, rmcOptions);
537 }
538 
539 void comManagerGetDataRmcInstance(CMHANDLE cmInstance, int pHandle, uint64_t rmcBits, uint32_t rmcOptions)
540 {
541  rmc_t rmc;
542  rmc.bits = rmcBits;
543  rmc.options = rmcOptions;
544 
545  comManagerSendDataInstance(cmInstance, pHandle, DID_RMC, &rmc, sizeof(rmc_t), 0);
546 }
547 
548 int comManagerSendData(int pHandle, uint32_t dataId, void *dataPtr, int dataSize, int dataOffset)
549 {
550  return comManagerSendDataInstance(&g_cm, pHandle, dataId, dataPtr, dataSize, dataOffset);
551 }
552 
553 int comManagerSendDataInstance(CMHANDLE cmInstance, int pHandle, uint32_t dataId, void* dataPtr, int dataSize, int dataOffset)
554 {
555  p_data_hdr_t hdr;
556  bufPtr_t bodyHdr, data;
557 
558  // Data Header
559  hdr.id = dataId;
560  hdr.size = dataSize;
561  hdr.offset = dataOffset;
562 
563  // Packet Body
564  bodyHdr.ptr = (uint8_t*)&hdr;
565  bodyHdr.size = sizeof(hdr);
566  data.ptr = (uint8_t*)dataPtr;
567  data.size = dataSize;
568 
569  return comManagerSendInstance(cmInstance, pHandle, PID_SET_DATA, &bodyHdr, &data, 0);
570 }
571 
572 int comManagerSendDataNoAck(int pHandle, uint32_t dataId, void *dataPtr, int dataSize, int dataOffset)
573 {
574  return comManagerSendDataNoAckInstance(&g_cm, pHandle, dataId, dataPtr, dataSize, dataOffset);
575 }
576 
577 int comManagerSendDataNoAckInstance(CMHANDLE cmInstance, int pHandle, uint32_t dataId, void* dataPtr, int dataSize, int dataOffset)
578 {
579  p_data_hdr_t hdr;
580  bufPtr_t bodyHdr, data;
581 
582  // Data Header
583  hdr.id = dataId;
584  hdr.size = dataSize;
585  hdr.offset = dataOffset;
586 
587  // Packet Body
588  bodyHdr.ptr = (uint8_t*)&hdr;
589  bodyHdr.size = sizeof(hdr);
590  data.ptr = (uint8_t*)dataPtr;
591  data.size = dataSize;
592 
593  return comManagerSendInstance((com_manager_t*)cmInstance, pHandle, PID_DATA, &bodyHdr, &data, 0);
594 }
595 
596 int comManagerSendRawData(int pHandle, uint32_t dataId, void *dataPtr, int dataSize, int dataOffset)
597 {
598  return comManagerSendRawDataInstance(&g_cm, pHandle, dataId, dataPtr, dataSize, dataOffset);
599 }
600 
601 int comManagerSendRawDataInstance(CMHANDLE cmInstance, int pHandle, uint32_t dataId, void* dataPtr, int dataSize, int dataOffset)
602 {
603  p_data_hdr_t hdr;
604  bufPtr_t bodyHdr, data;
605 
606  // Data Header
607  hdr.id = dataId;
608  hdr.size = dataSize;
609  hdr.offset = dataOffset;
610 
611  // Packet Body
612  bodyHdr.ptr = (uint8_t*)&hdr;
613  bodyHdr.size = sizeof(hdr);
614  data.ptr = (uint8_t*)dataPtr;
615  data.size = dataSize;
616 
617  return comManagerSendInstance((com_manager_t*)cmInstance, pHandle, PID_SET_DATA, &bodyHdr, &data, CM_PKT_FLAGS_RAW_DATA_NO_SWAP);
618 }
619 
620 int comManagerDisableData(int pHandle, uint32_t dataId)
621 {
622  return comManagerDisableDataInstance(&g_cm, pHandle, dataId);
623 }
624 
625 int comManagerDisableDataInstance(CMHANDLE cmInstance, int pHandle, uint32_t dataId)
626 {
627  bufPtr_t data;
628  data.ptr = (uint8_t*)&dataId;
629  data.size = 4;
630 
631  return comManagerSendInstance(cmInstance, pHandle, PID_STOP_DID_BROADCAST, 0, &data, 0);
632 }
633 
634 int comManagerSend(int pHandle, uint8_t pktInfo, bufPtr_t *bodyHdr, bufPtr_t *txData, uint8_t pFlags)
635 {
636  return comManagerSendInstance(&g_cm, pHandle, pktInfo, bodyHdr, txData, pFlags);
637 }
638 
639 int comManagerSendInstance(CMHANDLE cmInstance, int pHandle, uint8_t pktInfo, bufPtr_t* bodyHdr, bufPtr_t* txData, uint8_t pktFlags)
640 {
641  pkt_info_t pkt = { 0 };
642 
643  // Create Packet String (start to end byte)
645  pkt.hdr.pid = pktInfo;
646  pkt.hdr.flags = pktFlags;
647 
648  if (bodyHdr)
649  {
650  pkt.bodyHdr = *bodyHdr;
651  }
652  if (txData)
653  {
654  pkt.txData = *txData;
655  }
656 
657  return sendDataPacket(cmInstance, pHandle, &pkt);
658 }
659 
660 int comManagerSendEnsured(int pHandle, uint8_t pktInfo, unsigned char* data, unsigned int dataSize)
661 {
662  return comManagerSendEnsuredInstance(&g_cm, pHandle, pktInfo, data, dataSize);
663 }
664 
665 int comManagerSendEnsuredInstance(CMHANDLE cmInstance, int pHandle, uint8_t pktInfo, unsigned char *data, unsigned int dataSize)
666 {
667  packet_t *pkt;
668 
669  // Change retry "Ensured" packets to so that we encode packets first (including pkt counter)
670  // and then ensure they are delivered. Include packet checksum in ACK/NACK to validate delivery.
671  // Then, if all the ensured slots are occupied because of bad comm, either allow
672  // to clear ensured packets or just block until they are delivered. We must
673  // ensure NACKs are used to clear blocking ensured packets.
674 
675  // Create Packet String (start to end byte)
676  if ((pkt = registerPacketRetry((com_manager_t*)cmInstance, pHandle, pktInfo, data, dataSize)) == 0)
677  {
678  return -1;
679  }
680 
681  return sendPacket((com_manager_t*)cmInstance, pHandle, pkt, 0);
682 }
683 
684 int findAsciiMessage(const void * a, const void * b)
685 {
686  unsigned char* a1 = (unsigned char*)a;
688 
689  return memcmp(a1, a2->messageId, 4);
690 }
691 
697 int processBinaryRxPacket(com_manager_t* cmInstance, int pHandle, packet_t *pkt)
698 {
699  p_data_t *data = (p_data_t*)(pkt->body.ptr);
700  p_data_hdr_t *dataHdr;
701  registered_data_t *regd;
702  uint8_t pid = (uint8_t)(pkt->hdr.pid);
703 
704  com_manager_port_t *port = &(cmInstance->ports[pHandle]);
705  port->status.flags |= CM_PKT_FLAGS_RX_VALID_DATA; // communication received
706  port->status.readCounter = 0;
707 
708  // Packet read success
709  port->status.rxPktCount++;
710 
711  switch (pid)
712  {
713  default: // Data ID Unknown
714  return -1;
715 
716  case PID_SET_DATA:
717  case PID_DATA:
718  dataHdr = &(data->hdr);
719 
720  // Validate Data
721  if (dataHdr->id >= DID_COUNT)
722  {
723  return -1;
724  }
725 
726  regd = &(cmInstance->regData[dataHdr->id]);
727 
728  // Validate and constrain Rx data size to fit within local data struct
729  if (regd->dataSet.size && (dataHdr->offset + dataHdr->size) > regd->dataSet.size)
730  {
731  // trim the size down so it fits
732  int size = (int)(regd->dataSet.size - dataHdr->offset);
733  if (size < 4)
734  {
735  // we are completely out of bounds, we cannot process this message at all
736  // the minimum data struct size is 4 bytes
737  return -1;
738  }
739 
740  // Update Rx data size
741  dataHdr->size = _MIN(dataHdr->size, (uint8_t)size);
742  }
743 
744 #if ENABLE_PACKET_CONTINUATION
745 
746  // Consolidate datasets that were broken-up across multiple packets
747  p_data_t* con = &cmInstance->ports[pHandle].con;
748  if (additionalDataAvailable || (con->hdr.size != 0 && con->hdr.id == dataHdr->id))
749  {
750  // New dataset
751  if (con->hdr.id == 0 || con->hdr.size == 0 || con->hdr.id != dataHdr->id || con->hdr.size > dataHdr->offset)
752  {
753  // Reset data consolidation
754  con->hdr.id = dataHdr->id;
755  con->hdr.offset = dataHdr->offset;
756  con->hdr.size = 0;
757  }
758 
759  // Ensure data will fit in buffer
760  if ((con->hdr.size + dataHdr->size) < sizeof(con->buf))
761  {
762  // Add data to buffer
763  memcpy(con->buf + con->hdr.size, data->buf, dataHdr->size);
764  con->hdr.size += dataHdr->size;
765  }
766  else
767  {
768  // buffer overflow
769  }
770 
771  // Wait for end of data
772  if (additionalDataAvailable)
773  {
774  return 0;
775  }
776 
777  // Use consolidated data
778  data = con;
779  }
780 
781 #else
782 
783 // unsigned char additionalDataAvailable // function parameter removed
784 // (void)additionalDataAvailable;
785 
786 #endif
787 
788  // Write to data structure if it was registered
789  if (regd->dataSet.rxPtr)
790  {
791  copyDataPToStructP(regd->dataSet.rxPtr, data, regd->dataSet.size);
792  }
793 
794  // Call data specific callback after data has been written to
795  if (regd->pstRxFnc)
796  {
797  regd->pstRxFnc(cmInstance, pHandle, data);
798  }
799 
800  // Call general/global callback
801  if (cmInstance->pstRxFnc)
802  {
803  cmInstance->pstRxFnc(cmInstance, pHandle, data);
804  }
805 
806  // Remove retry from linked list if necessary
807  updatePacketRetryData(cmInstance, pkt);
808 
809 #if ENABLE_PACKET_CONTINUATION
810 
811  // Clear dataset consolidation
812  con->hdr.id = con->hdr.size = con->hdr.offset = 0;
813 
814 #endif
815 
816  // Reply w/ ACK for PID_SET_DATA
817  if (pid == PID_SET_DATA)
818  {
819  sendAck(cmInstance, pHandle, pkt, PID_ACK);
820  }
821  break;
822 
823  case PID_GET_DATA:
824  if (comManagerGetDataRequestInstance(cmInstance, pHandle, (p_data_get_t *)(data)))
825  {
826  sendAck(cmInstance, pHandle, pkt, PID_NACK);
827  }
828  break;
829 
831  comManagerDisableBroadcastsInstance(cmInstance, -1);
832 
833  // Call disable broadcasts callback if exists
834  if (cmInstance->disableBcastFnc)
835  {
836  cmInstance->disableBcastFnc(cmInstance, -1);
837  }
838  sendAck(cmInstance, pHandle, pkt, PID_ACK);
839  break;
840 
842  comManagerDisableBroadcastsInstance(cmInstance, pHandle);
843 
844  // Call disable broadcasts callback if exists
845  if (cmInstance->disableBcastFnc)
846  {
847  cmInstance->disableBcastFnc(cmInstance, pHandle);
848  }
849  sendAck(cmInstance, pHandle, pkt, PID_ACK);
850  break;
851 
853  disableDidBroadcast(cmInstance, pHandle, (p_data_disable_t *)(data));
854  break;
855 
856  case PID_NACK:
857  case PID_ACK:
858  // Remove retry from linked list if necessary
859  updatePacketRetryAck(cmInstance, pkt);
860 
861  // Call general ack callback
862  if (cmInstance->pstAckFnc)
863  {
864  cmInstance->pstAckFnc(cmInstance, pHandle, (p_ack_t*)(pkt->body.ptr), pid);
865  }
866  break;
867  }
868 
869  return 0;
870 }
871 
873 {
874  return comManagerGetRegisteredDataInfoInstance(&g_cm, dataId);
875 }
876 
878 {
879  if (dataId >= DID_COUNT)
880  {
881  return 0;
882  }
883 
884  com_manager_t* cmInstance = (com_manager_t*)_cmInstance;
885  return &cmInstance->regData[dataId].dataSet;
886 }
887 
888 // 0 on success. -1 on failure.
890 {
891  return comManagerGetDataRequestInstance(&g_cm, pHandle, req);
892 }
893 
894 int comManagerGetDataRequestInstance(CMHANDLE _cmInstance, int pHandle, p_data_get_t* req)
895 {
896  com_manager_t* cmInstance = (com_manager_t*)_cmInstance;
897  broadcast_msg_t* msg = 0;
898 
899  // Validate the request
900  if (req->id >= DID_COUNT)
901  {
902  // invalid data id
903  return -1;
904  }
905  // Call RealtimeMessageController (RMC) handler
906  else if (cmInstance->cmMsgHandlerRmc && (cmInstance->cmMsgHandlerRmc(cmInstance, pHandle, req) == 0))
907  {
908  // Don't allow comManager broadcasts for messages handled by RealtimeMessageController.
909  return 0;
910  }
911  // if size is 0 and offset is 0, set size to full data struct size
912  else if (req->size == 0 && req->offset == 0 && req->id < _ARRAY_ELEMENT_COUNT(cmInstance->regData))
913  {
914  req->size = cmInstance->regData[req->id].dataSet.size;
915  }
916 
917  // Copy reference to source data
918  bufTxRxPtr_t* dataSetPtr = &cmInstance->regData[req->id].dataSet;
919 
920  // Abort if no data pointer is registered or offset + size is out of bounds
921  if (dataSetPtr->txPtr == 0 || dataSetPtr->size == 0)
922  {
923  return -1;
924  }
925  else if (req->offset + req->size > dataSetPtr->size)
926  {
927  req->offset = 0;
928  req->size = dataSetPtr->size;
929  }
930 
931  // Search for matching message (i.e. matches pHandle, id, size, and offset)...
932  for (broadcast_msg_t* bcPtr = cmInstance->broadcastMessages, *ptrEnd = (cmInstance->broadcastMessages + MAX_NUM_BCAST_MSGS); bcPtr < ptrEnd; bcPtr++)
933  {
934  if (bcPtr->pHandle == pHandle && bcPtr->dataHdr.id == req->id && bcPtr->dataHdr.size == req->size && bcPtr->dataHdr.offset == req->offset)
935  {
936  msg = bcPtr;
937  break;
938  }
939  }
940 
941  // otherwise use the first available (period=0) message.
942  if (msg == 0)
943  {
944  for (broadcast_msg_t* bcPtr = cmInstance->broadcastMessages, *ptrEnd = (cmInstance->broadcastMessages + MAX_NUM_BCAST_MSGS); bcPtr < ptrEnd; bcPtr++)
945  {
946  if (bcPtr->period <= MSG_PERIOD_DISABLED)
947  {
948  msg = bcPtr;
949  break;
950  }
951  }
952 
953  if (msg == 0)
954  {
955  // use last slot, force overwrite
956  msg = cmInstance->broadcastMessages + MAX_NUM_BCAST_MSGS - 1;
957  }
958  }
959 
960  // Port handle
961  msg->pHandle = pHandle;
962 
963  // Packet parameters
965  msg->pkt.hdr.pid = PID_DATA;
966 
967  // Data Header
968  msg->dataHdr.id = req->id;
969  msg->dataHdr.size = req->size;
970  msg->dataHdr.offset = req->offset;
971  msg->pkt.hdr.flags = cmInstance->regData[msg->dataHdr.id].pktFlags;
972  msg->pkt.bodyHdr.ptr = (uint8_t *)&msg->dataHdr;
973  msg->pkt.bodyHdr.size = sizeof(msg->dataHdr);
974  msg->pkt.txData.size = req->size;
975  msg->pkt.txData.ptr = cmInstance->regData[req->id].dataSet.txPtr + req->offset;
976 
977  // Prep data if callback exists
978  if (cmInstance->regData[msg->dataHdr.id].preTxFnc)
979  {
980  cmInstance->regData[msg->dataHdr.id].preTxFnc(cmInstance, pHandle);
981  }
982 
983  // Constrain request broadcast period if necessary
984  if (req->bc_period_multiple != 0)
985  {
987  }
988 
989  // Send data
990  if (req->bc_period_multiple > 0)
991  {
992  // *** Request Broadcast ***
993  // Send data immediately if possible
994  if (cmInstance->txFreeCallback == 0 || msg->pkt.txData.size <= (uint32_t)cmInstance->txFreeCallback(cmInstance, pHandle))
995  {
996  sendDataPacket(cmInstance, pHandle, &(msg->pkt));
997  }
998 
999  // Enable broadcast message
1000  enableBroadcastMsg(cmInstance, msg, req->bc_period_multiple);
1001  }
1002  else
1003  {
1004  // *** Request Single ***
1005  // Send data immediately if possible
1006  if (cmInstance->txFreeCallback == 0 || msg->pkt.txData.size <= (uint32_t)cmInstance->txFreeCallback(cmInstance, pHandle))
1007  {
1008  sendDataPacket(cmInstance, pHandle, &(msg->pkt));
1009  disableBroadcastMsg(cmInstance, msg);
1010  }
1011  else
1012  {
1013  // Won't fit in queue, so send it later
1014  enableBroadcastMsg(cmInstance, msg, req->bc_period_multiple);
1015  }
1016  }
1017 
1018  return 0;
1019 }
1020 
1021 void enableBroadcastMsg(com_manager_t* cmInstance, broadcast_msg_t* msg, int periodMultiple)
1022 {
1023  // Update broadcast period
1024  if (periodMultiple > 0)
1025  {
1026  msg->period = periodMultiple / cmInstance->stepPeriodMilliseconds;
1027  }
1028  else
1029  {
1031  }
1032  msg->counter = -1; // Keeps broadcast from sending for at least one period
1033 }
1034 
1036 {
1037  (void)cmInstance;
1038 
1039  // Remove item from linked list
1040  msg->period = MSG_PERIOD_DISABLED;
1041 }
1042 
1044 {
1045  comManagerDisableBroadcastsInstance(&g_cm, pHandle);
1046 }
1047 
1048 void comManagerDisableBroadcastsInstance(CMHANDLE cmInstance_, int pHandle)
1049 {
1050  com_manager_t* cmInstance = (com_manager_t*)cmInstance_;
1051  for (broadcast_msg_t* bcPtr = cmInstance->broadcastMessages, *ptrEnd = (cmInstance->broadcastMessages + MAX_NUM_BCAST_MSGS); bcPtr < ptrEnd; bcPtr++)
1052  {
1053  if (pHandle < 0 || bcPtr->pHandle == pHandle)
1054  {
1055  bcPtr->period = MSG_PERIOD_DISABLED;
1056  }
1057  }
1058 }
1059 
1060 void disableDidBroadcast(com_manager_t* cmInstance, int pHandle, p_data_disable_t* disable)
1061 {
1062  for (broadcast_msg_t* bcPtr = cmInstance->broadcastMessages, *ptrEnd = (cmInstance->broadcastMessages + MAX_NUM_BCAST_MSGS); bcPtr < ptrEnd; bcPtr++)
1063  {
1064  if ((pHandle < 0 || pHandle == bcPtr->pHandle) && bcPtr->dataHdr.id == disable->id)
1065  {
1066  bcPtr->period = MSG_PERIOD_DISABLED;
1067  }
1068  }
1069 
1070  // Call global broadcast handler to disable message control
1071  if (cmInstance->cmMsgHandlerRmc)
1072  {
1073  p_data_get_t req;
1074  req.id = disable->id;
1075  req.size = 0;
1076  req.offset = 0;
1077  req.bc_period_multiple = 0;
1078  cmInstance->cmMsgHandlerRmc(cmInstance, pHandle, &req);
1079  }
1080 }
1081 
1089 int sendPacket(com_manager_t* cmInstance, int pHandle, packet_t *dPkt, uint8_t additionalPktFlags)
1090 {
1091  buffer_t buffer;
1092 
1093  if (encodeBinaryPacket(cmInstance, pHandle, &buffer, dPkt, additionalPktFlags))
1094  {
1095  return -1;
1096  }
1097 
1098  // Send Packet
1099  else if (cmInstance->sendPacketCallback)
1100  {
1101  cmInstance->sendPacketCallback(cmInstance, pHandle, buffer.buf, buffer.size);
1102  }
1103 
1104  return 0;
1105 }
1106 
1107 // Consolidate this with sendPacket() so that we break up packets into multiples that fit our buffer size.
1108 int sendDataPacket(com_manager_t* cmInstance, int pHandle, pkt_info_t* msg)
1109 {
1110  pfnComManagerSend sendCallback = cmInstance->sendPacketCallback;
1111  if (sendCallback == 0)
1112  {
1113  return -1;
1114  }
1115 
1116  buffer_t bufToSend;
1117  packet_t pkt;
1118  pkt.hdr = msg->hdr;
1119 
1120  switch (pkt.hdr.pid)
1121  {
1122  // Large data support - breaks data up into separate packets for Tx
1123  case PID_DATA:
1124  case PID_SET_DATA:
1125  {
1126  // Setup packet and encoding state
1127  buffer_t bufToEncode;
1128  p_data_hdr_t hdr = *(p_data_hdr_t*)msg->bodyHdr.ptr;
1129  p_data_hdr_t* hdrToSend = (p_data_hdr_t*)bufToEncode.buf;
1130  uint32_t size = hdr.size;
1131  uint32_t offset = 0;
1132  uint32_t id = hdr.id;
1133  pkt.body.ptr = bufToEncode.buf;
1134 
1135 #if ENABLE_PACKET_CONTINUATION
1136 
1137  while (size > 0)
1138  {
1139 
1140 #endif
1141 
1142  // Assign data header values
1143  hdrToSend->size = _MIN(size, MAX_P_DATA_BODY_SIZE);
1144  hdrToSend->offset = hdr.offset + offset;
1145  hdrToSend->id = id;
1146 
1147  // copy the data to send to bufToEncode, skipping the data header - since we had to create that data header, we now have to append the actual data
1148  memcpy(bufToEncode.buf + sizeof(p_data_hdr_t), msg->txData.ptr + offset, hdrToSend->size);
1149 
1150  // reduce size by the amount sent - if packet continuation is off, this must become 0 otherwise we fail
1151  size -= hdrToSend->size;
1152 
1153 #if ENABLE_PACKET_CONTINUATION
1154 
1155  // increment offset for the next packet
1156  offset += hdrToSend->size;
1157 
1158 #else
1159 
1160  if (size > 0)
1161  {
1162  // data was too large to fit in one packet, fail
1163  return -1;
1164  }
1165 
1166 #endif
1167 
1168  // Set data body size
1169  pkt.body.size = sizeof(p_data_hdr_t) + hdrToSend->size;
1170 
1171  // Encode the packet, handling special characters, etc.
1172  if (encodeBinaryPacket(cmInstance, pHandle, &bufToSend, &pkt, CM_PKT_FLAGS_MORE_DATA_AVAILABLE * (size != 0)))
1173  {
1174  return -1;
1175  }
1176 
1177  // Send the packet using the specified callback
1178  sendCallback(cmInstance, pHandle, bufToSend.buf, bufToSend.size);
1179 
1180 #if ENABLE_PACKET_CONTINUATION
1181 
1182  }
1183 
1184 #endif
1185 
1186  } break;
1187 
1188  // Single packet commands/data sets. No data header, just body.
1189  default:
1190  {
1191  // Assign packet pointer and encode data as is
1192  pkt.body = msg->txData;
1193  if (encodeBinaryPacket(cmInstance, pHandle, &bufToSend, &pkt, 0))
1194  {
1195  return -1;
1196  }
1197 
1198  // Send the packet using the specified callback
1199  sendCallback(cmInstance, pHandle, bufToSend.buf, bufToSend.size);
1200  } break;
1201  }
1202 
1203  return 0;
1204 }
1205 
1206 void sendAck(com_manager_t* cmInstance, int pHandle, packet_t *pkt, unsigned char pid_ack)
1207 {
1208  int ackSize;
1209  bufPtr_t data;
1210 
1211  // Create and Send request packet
1212  p_ack_t ack = { 0 };
1213  ack.hdr.pktInfo = pkt->hdr.pid;
1214  ack.hdr.pktCounter = pkt->hdr.counter;
1215  ackSize = sizeof(p_ack_hdr_t);
1216 
1217  // Set ack body
1218  switch (pkt->hdr.pid)
1219  {
1220  case PID_SET_DATA:
1221 // memcpy(ack.body.buf, (p_data_hdr_t*)(pkt->body.ptr), sizeof(p_data_hdr_t));
1222  ack.body.dataHdr = *((p_data_hdr_t*)(pkt->body.ptr));
1223  ackSize += sizeof(p_data_hdr_t);
1224  break;
1225  }
1226 
1227  data.ptr = (unsigned char*)&ack;
1228  data.size = ackSize;
1229 
1230  comManagerSendInstance(cmInstance, pHandle, (uint8_t)pid_ack, 0, &data, 0);
1231 }
1232 
1234 // Packet Composition
1236 
1256 int encodeBinaryPacket(com_manager_t* cmInstance, int pHandle, buffer_t *pkt, packet_t *dPkt, uint8_t additionalPktFlags)
1257 {
1258  com_manager_port_t *port = &(cmInstance->ports[pHandle]);
1259 
1260  void* srcBuffer = dPkt->body.ptr;
1261  int srcBufferLength = dPkt->body.size;
1262  void* encodedPacket = pkt->buf;
1263  int encodedPacketLength = PKT_BUF_SIZE - 1;
1264  packet_hdr_t* hdr = &dPkt->hdr;
1265  hdr->counter = (uint8_t)(port->comm.txPktCount++);
1266 
1267  pkt->size = is_encode_binary_packet(srcBuffer, srcBufferLength, hdr, additionalPktFlags | port->status.flags, encodedPacket, encodedPacketLength);
1268  return (-1 * ((int)pkt->size < 8));
1269 }
1270 
1271 
1273 // Packet Retry
1275 
1281 {
1282  int32_t i;
1283  ensured_pkt_t* ePkt;
1284 
1285  for (i = 0; i < cmInstance->maxEnsuredPackets; i++)
1286  {
1287  ePkt = &(cmInstance->ensuredPackets[i]);
1288 
1289  // No more retries in list
1290  if (ePkt->counter == -2)
1291  {
1292  return;
1293  }
1294 
1295  // Check that retry is enabled
1296  if (ePkt->counter >= 0)
1297  {
1298  // Check if counter has expired
1299  if (--(ePkt->counter) == 0)
1300  {
1301  // Reset counter
1302  ePkt->counter = cmInstance->ensureRetryCount;
1303 
1304  // Reset packet
1305  sendPacket(cmInstance, ePkt->pHandle, &(ePkt->pkt), 0);
1306  }
1307  }
1308  }
1309 }
1310 
1322 packet_t* registerPacketRetry(com_manager_t* cmInstance, int pHandle, uint8_t pid, unsigned char data[], unsigned int dataSize)
1323 {
1324  int32_t i;
1325  ensured_pkt_t *ePkt = 0;
1326  unsigned char searching = 1;
1327 
1328  #if ENABLE_FILTER_DUPLICATE_PACKETS
1329 
1330  #if ENABLE_FILTER_DUPLICATE_PACKETS_MATCH_ALL_CHARACTERS
1331 
1332  int32_t j;
1333 
1334  #endif
1335 
1336  // Filter out redundant retries (replace same type packets and pHandle with latest)
1337  p_data_get_t *getData1, *getData2;
1338 
1339  // Validate Data Size
1340  if (dataSize > MAX_P_DATA_BODY_SIZE)
1341  {
1342  return 0;
1343  }
1344 
1345  // Check for existing retry
1346  for (i = 0; searching && i < cmInstance->maxEnsuredPackets; i++)
1347  {
1348  ePkt = &(cmInstance->ensuredPackets[i]);
1349 
1350  // No more retries to search over. Abort and look for first disabled slot.
1351  if (ePkt->counter == -2)
1352  {
1353  break;
1354  }
1355 
1356  // Found enabled retry w/ matching packet ID and data size
1357  if (ePkt->counter >= 0 &&
1358  ePkt->pkt.hdr.pid == pid &&
1359  ePkt->pkt.body.size == dataSize &&
1360  ePkt->pHandle == pHandle)
1361  {
1362  switch (pid)
1363  {
1364  case PID_GET_DATA:
1365  getData1 = (p_data_get_t*)data;
1366  getData2 = (p_data_get_t*)ePkt->pktBody;
1367 
1368  // Match: all Get Data parameters
1369  if (getData1->id == getData2->id &&
1370  getData1->size == getData2->size &&
1371  getData1->offset == getData2->offset)
1372  searching = 0;
1373  break;
1374 
1376  searching = 0;
1377  break;
1378 
1379  default:
1380 
1381 #if !ENABLE_FILTER_DUPLICATE_PACKETS_MATCH_ALL_CHARACTERS
1382 
1383  // Match: first character
1384  if (ePkt->pkt.body.ptr[0] == data[0])
1385  {
1386  searching = 0;
1387  }
1388 
1389 #else
1390 
1391  // Match: All character
1392  for (j = 0; j < dataSize; j++)
1393  {
1394  if (ePkt->pkt.body.ptr[j] == data[j])
1395  {
1396  searching = 0;
1397  break;
1398  }
1399  }
1400 
1401 #endif
1402 
1403  break;
1404  }
1405  }
1406  }
1407 
1408  #endif
1409 
1410  // Find Empty Slot - either first available or tail if all used.
1411  for (i = 0; searching && i < cmInstance->maxEnsuredPackets; i++)
1412  {
1413  ePkt = &(cmInstance->ensuredPackets[i]);
1414 
1415  // Found empty slot
1416  if (ePkt->counter < 0)
1417  {
1418  searching = 0;
1419  break;
1420  }
1421  }
1422 
1423  // All slots enabled, so take the oldest (one after last used)
1424  if (searching && cmInstance->ensuredPackets != 0)
1425  {
1426  if (++cmInstance->lastEnsuredPacketIndex >= cmInstance->maxEnsuredPackets)
1427  {
1428  cmInstance->lastEnsuredPacketIndex = 0;
1429  }
1430  ePkt = &(cmInstance->ensuredPackets[cmInstance->lastEnsuredPacketIndex]);
1431  }
1432  else
1433  {
1434  cmInstance->lastEnsuredPacketIndex = i;
1435  }
1436  if (ePkt == 0)
1437  {
1438  return 0;
1439  }
1440 
1441  // Backup packet contents for retry if not already registered
1442  ePkt->counter = cmInstance->ensureRetryCount;
1443  memcpy(ePkt->pktBody, data, dataSize);
1444 
1445  // Update ePkt pkt header and body info
1446  ePkt->pkt.hdr.startByte = PSC_START_BYTE;
1447  ePkt->pkt.hdr.pid = pid;
1448  ePkt->pkt.body.ptr = ePkt->pktBody; // point to ePkt buffer "pktBody"
1449  ePkt->pkt.body.size = dataSize;
1450  ePkt->pHandle = pHandle;
1451 
1452  return &(ePkt->pkt);
1453 }
1454 
1463 {
1464  int32_t i;
1465  ensured_pkt_t *ePkt;
1466 
1467  // Search for retries that match packet received. If found, removed it from the retry list.
1468  for (i = 0; i < cmInstance->maxEnsuredPackets; i++)
1469  {
1470  ePkt = &(cmInstance->ensuredPackets[i]);
1471 
1472  if (ePkt->counter == -2)
1473  {
1474  // No more retries to search for
1475  return;
1476  }
1477 
1478  if (ePkt->counter < 0)
1479  {
1480  // This retry is disabled. Skip it.
1481  continue;
1482  }
1483 
1484  // Found packet response expected. Remove from retry list.
1485  if (ePkt->pktBody[0] == pkt->body.ptr[0])
1486  {
1487  // Indicate disabled retry
1488  ePkt->counter = -1;
1489  }
1490  }
1491 
1492  // Update last retry indicator
1493  for (i = cmInstance->maxEnsuredPackets - 1; i >= 0; i--)
1494  {
1495  // Current is enabled so stop
1496  if (cmInstance->ensuredPackets[i].counter >= 0)
1497  {
1498  break;
1499  }
1500 
1501  // Indicate no more retries in list
1502  cmInstance->ensuredPackets[i].counter = -2;
1503  }
1504 }
1505 
1507 {
1508  int32_t i;
1509  ensured_pkt_t *ePkt;
1510  p_ack_t *ack;
1511  uint8_t ackInfo;
1512 
1513  ack = (p_ack_t*)(pkt->body.ptr);
1514  ackInfo = (uint8_t)(ack->hdr.pktInfo);
1515 
1516  // Search for retries that match packet received. If found, removed it from the retry list.
1517  for (i = 0; i < cmInstance->maxEnsuredPackets; i++)
1518  {
1519  ePkt = &(cmInstance->ensuredPackets[i]);
1520 
1521  if (ePkt->counter == -2)
1522  {
1523  // No more retries to search for
1524  return;
1525  }
1526 
1527  if (ePkt->counter == -1)
1528  {
1529  // This retry is disabled. Skip it.
1530  continue;
1531  }
1532 
1533  // Check packet info matches
1534  if (ack->hdr.pktInfo == ePkt->pkt.hdr.pid)
1535  {
1536  p_data_hdr_t *dHdr, *eHdr;
1537 
1538  switch (ackInfo)
1539  {
1540  default:
1541  // Custom/Specific Packets
1542  case PID_STOP_BROADCASTS_ALL_PORTS: // No body ID available
1543  ePkt->counter = -1; // indicate disabled retry
1544  break;
1545 
1546  case PID_SET_DATA:
1547  dHdr = &(ack->body.dataHdr);
1548  eHdr = (p_data_hdr_t*)(ePkt->pktBody);
1549 
1550  if (dHdr->id == eHdr->id &&
1551  dHdr->size == eHdr->size &&
1552  dHdr->offset == eHdr->offset)
1553  {
1554  ePkt->counter = -1; // indicate disabled retry
1555  }
1556  break;
1557  }
1558  }
1559  }
1560 
1561  // Update last retry indicator
1562  for (i = cmInstance->maxEnsuredPackets - 1; i >= 0; i--)
1563  {
1564  // Current is enabled so stop
1565  if (cmInstance->ensuredPackets[i].counter >= 0)
1566  {
1567  break;
1568  }
1569  cmInstance->ensuredPackets[i].counter = -2; // Indicate no more retries in list
1570  }
1571 }
1572 
1573 int comManagerValidateBaudRate(unsigned int baudRate)
1574 {
1575  // Valid baudrates for InertialSense hardware
1576  for (size_t i = 0; i < _ARRAY_ELEMENT_COUNT(g_validBaudRates); i++)
1577  {
1578  if (g_validBaudRates[i] == baudRate)
1579  {
1580  return 0;
1581  }
1582  }
1583  return -1;
1584 }
1585 
int comManagerDisableData(int pHandle, uint32_t dataId)
Definition: com_manager.c:620
#define _MIN(a, b)
Definition: ISConstants.h:298
registered_data_t regData[DID_COUNT]
Definition: com_manager.h:212
int comManagerSendDataNoAck(int pHandle, uint32_t dataId, void *dataPtr, int dataSize, int dataOffset)
Definition: com_manager.c:572
bufPtr_t body
Definition: ISComm.h:360
packet_t pkt
Definition: com_manager.h:64
ensured_pkt_t * ensuredPackets
Definition: com_manager.h:218
int comManagerSendDataInstance(CMHANDLE cmInstance, int pHandle, uint32_t dataId, void *dataPtr, int dataSize, int dataOffset)
Definition: com_manager.c:553
uint32_t options
Definition: data_sets.h:1139
int(* pfnComManagerSendBufferAvailableBytes)(CMHANDLE cmHandle, int pHandle)
Definition: com_manager.h:129
int comManagerSendRawData(int pHandle, uint32_t dataId, void *dataPtr, int dataSize, int dataOffset)
Definition: com_manager.c:596
packet_hdr_t hdr
Definition: ISComm.h:366
void comManagerSetCallbacksInstance(CMHANDLE cmInstance, pfnComManagerAsapMsg handlerRmc, pfnComManagerGenMsgHandler handlerAscii, pfnComManagerGenMsgHandler handlerUblox, pfnComManagerGenMsgHandler handlerRtcm3)
Definition: com_manager.c:457
uint8_t startByte
Definition: ISComm.h:319
void comManagerStepRxInstance(CMHANDLE cmInstance_)
Definition: com_manager.c:300
int asciiMessageCompare(const void *elem1, const void *elem2)
Definition: com_manager.c:239
uint8_t * txPtr
Definition: ISComm.h:215
pfnComManagerGenMsgHandler cmMsgHandlerUblox
Definition: com_manager.h:246
int processBinaryRxPacket(com_manager_t *cmInstance, int pHandle, packet_t *pkt)
Process binary packet content:
Definition: com_manager.c:697
pfnComManagerAsapMsg cmMsgHandlerRmc
Definition: com_manager.h:240
broadcast_msg_t * broadcastMessages
Definition: com_manager.h:220
com_manager_status_t * comManagerGetStatus(int pHandle)
Definition: com_manager.c:482
int comManagerValidateBaudRate(unsigned int baudRate)
Definition: com_manager.c:1573
int32_t counter
Definition: com_manager.h:51
#define MSG_PERIOD_DISABLED
Definition: com_manager.c:30
bufTxRxPtr_t * comManagerGetRegisteredDataInfo(uint32_t dataId)
Definition: com_manager.c:872
ensured_pkt_t * ensuredPackets
Definition: com_manager.h:105
void(* pfnComManagerPostRead)(CMHANDLE cmHandle, int pHandle, p_data_t *dataRead)
Definition: com_manager.h:132
#define PID_STOP_BROADCASTS_ALL_PORTS
Definition: ISComm.h:185
pfnComManagerPostRead pstRxFnc
Definition: com_manager.h:203
pfnComManagerSendBufferAvailableBytes txFreeCallback
Definition: com_manager.h:200
uint32_t id
Definition: ISComm.h:375
void comManagerGetDataRmcInstance(CMHANDLE cmInstance, int pHandle, uint64_t rmcBits, uint32_t rmcOptions)
Definition: com_manager.c:539
uint32_t size
Definition: ISComm.h:378
uint8_t buf[PKT_BUF_SIZE]
Definition: ISComm.h:198
bufTxRxPtr_t * comManagerGetRegisteredDataInfoInstance(CMHANDLE _cmInstance, uint32_t dataId)
Definition: com_manager.c:877
void comManagerDisableBroadcasts(int pHandle)
Definition: com_manager.c:1043
pfnComManagerPostRead pstRxFnc
Definition: com_manager.h:165
void updatePacketRetryData(com_manager_t *cmInstance, packet_t *pkt)
Update packet retry. If the specific data requested or acknowledge is received, the retry list is upd...
Definition: com_manager.c:1462
uint32_t communicationErrorCount
Definition: com_manager.h:89
uint8_t comm_buffer[PKT_BUF_SIZE]
Definition: com_manager.h:177
void stepPacketRetry(com_manager_t *cmInstance)
stepPacketRetry - Resend the ensured packets after the ENSURE_RETRY_COUNT period if the expected resp...
Definition: com_manager.c:1280
int(* pfnComManagerAsapMsg)(CMHANDLE cmHandle, int pHandle, p_data_get_t *req)
Definition: com_manager.h:153
uint32_t size
Definition: ISComm.h:208
broadcast_msg_t * broadcastMsg
Definition: com_manager.h:102
uint64_t bits
Definition: data_sets.h:1301
#define MSG_PERIOD_SEND_ONCE
Definition: com_manager.c:29
if(udd_ctrl_interrupt())
Definition: usbhs_device.c:688
void disableDidBroadcast(com_manager_t *cmInstance, int pHandle, p_data_disable_t *disable)
Definition: com_manager.c:1060
void comManagerRegisterInstance(CMHANDLE cmInstance_, uint32_t dataId, pfnComManagerPreSend txFnc, pfnComManagerPostRead pstRxFnc, const void *txDataPtr, void *rxDataPtr, int dataSize, uint8_t pktFlags)
Definition: com_manager.c:252
int32_t pHandle
Definition: com_manager.h:57
int comManagerSendInstance(CMHANDLE cmInstance, int pHandle, uint8_t pktInfo, bufPtr_t *bodyHdr, bufPtr_t *txData, uint8_t pktFlags)
Definition: com_manager.c:639
void sendAck(com_manager_t *cmInstance, int pHandle, packet_t *pkt, unsigned char pid_ack)
Definition: com_manager.c:1206
#define PKT_BUF_SIZE
Definition: ISComm.h:98
#define DID_COUNT
Definition: data_sets.h:138
packet_hdr_t hdr
Definition: ISComm.h:357
uint8_t pktBody[PKT_BUF_SIZE]
Definition: com_manager.h:67
#define DID_RMC
Definition: data_sets.h:43
protocol_type_t is_comm_parse_byte(is_comm_instance_t *instance, uint8_t byte)
Definition: ISComm.c:499
#define NULL
Definition: nm_bsp.h:52
void(* pfnComManagerDisableBroadcasts)(CMHANDLE cmHandle, int pHandle)
Definition: com_manager.h:138
pfnComManagerRead readCallback
Definition: com_manager.h:194
com_manager_status_t * comManagerGetStatusInstance(CMHANDLE cmInstance, int pHandle)
Definition: com_manager.c:487
void comManagerDisableBroadcastsInstance(CMHANDLE cmInstance_, int pHandle)
Definition: com_manager.c:1048
int comManagerGetDataRequestInstance(CMHANDLE _cmInstance, int pHandle, p_data_get_t *req)
Definition: com_manager.c:894
char copyDataPToStructP(void *sptr, const p_data_t *data, const unsigned int maxsize)
Definition: ISComm.c:975
#define MIN_REQUEST_PERIOD_MS
Definition: com_manager.c:27
p_data_hdr_t dataHdr
Definition: com_manager.h:48
void updatePacketRetryAck(com_manager_t *cmInstance, packet_t *pkt)
Definition: com_manager.c:1506
bufPtr_t bodyHdr
Definition: ISComm.h:367
uint32_t pktInfo
Definition: ISComm.h:424
pfnComManagerPreSend preTxFnc
Definition: com_manager.h:162
int comManagerGetDataRequest(int pHandle, p_data_get_t *req)
Definition: com_manager.c:889
#define PID_SET_DATA
Definition: ISComm.h:184
void(* pfnComManagerPreSend)(CMHANDLE cmHandle, int pHandle)
Definition: com_manager.h:141
bufPtr_t txData
Definition: ISComm.h:368
unsigned char messageId[4]
Definition: ISComm.h:300
void comManagerStep(void)
Definition: com_manager.c:281
uint32_t offset
Definition: ISComm.h:404
uint32_t pktCounter
Definition: ISComm.h:427
p_ack_hdr_t hdr
Definition: ISComm.h:434
com_manager_port_t * ports
Definition: com_manager.h:215
int comManagerInitInstance(CMHANDLE cmHandle, int numHandles, int maxEnsuredPackets, int stepPeriodMilliseconds, int retryCount, pfnComManagerRead readFnc, pfnComManagerSend sendFnc, pfnComManagerSendBufferAvailableBytes txFreeFnc, pfnComManagerPostRead pstRxFnc, pfnComManagerPostAck pstAckFnc, pfnComManagerDisableBroadcasts disableBcastFnc, com_manager_init_t *buffers, com_manager_port_t *cmPorts)
Definition: com_manager.c:111
#define COM_MANAGER_BUF_SIZE_BCAST_MSG(max_num_bcast_msgs)
Definition: com_manager.h:115
#define MEMBERSIZE(type, member)
Definition: ISConstants.h:334
#define _LIMIT2(x, xmin, xmax)
Definition: ISConstants.h:314
p_data_hdr_t dataHdr
Definition: ISComm.h:440
is_comm_buffer_t buf
Definition: ISComm.h:488
packet_t * registerPacketRetry(com_manager_t *cmInstance, int pHandle, uint8_t pid, unsigned char data[], unsigned int dataSize)
registerPacketRetry - Saves data and packet header info to a retry list that will be resent if the co...
Definition: com_manager.c:1322
#define PID_STOP_BROADCASTS_CURRENT_PORT
Definition: ISComm.h:187
int sendPacket(com_manager_t *cmInstance, int pHandle, packet_t *dPkt, uint8_t additionalPktFlags)
Encode and send out serial port the referenced packet structure.
Definition: com_manager.c:1089
int is_encode_binary_packet(void *srcBuffer, unsigned int srcBufferLength, packet_hdr_t *hdr, uint8_t additionalPktFlags, void *encodedPacket, int encodedPacketLength)
Definition: ISComm.c:791
#define MAX_P_DATA_BODY_SIZE
Definition: ISComm.h:108
int sendDataPacket(com_manager_t *cmInstance, int pHandle, pkt_info_t *msg)
Definition: com_manager.c:1108
int32_t maxEnsuredPackets
Definition: com_manager.h:228
int comManagerSendEnsured(int pHandle, uint8_t pktInfo, unsigned char *data, unsigned int dataSize)
Definition: com_manager.c:660
int is_comm_free(is_comm_instance_t *instance)
Definition: ISComm.c:462
uint32_t size
Definition: ISComm.h:221
#define MAX_REQUEST_PERIOD_MS
Definition: com_manager.c:28
int comManagerSendRawDataInstance(CMHANDLE cmInstance, int pHandle, uint32_t dataId, void *dataPtr, int dataSize, int dataOffset)
Definition: com_manager.c:601
int initComManagerInstanceInternal(com_manager_t *cmInstance, int numHandles, int maxEnsuredPackets, int stepPeriodMilliseconds, int retryCount, pfnComManagerRead readFnc, pfnComManagerSend sendFnc, pfnComManagerSendBufferAvailableBytes txFreeFnc, pfnComManagerPostRead pstRxFnc, pfnComManagerPostAck pstAckFnc, pfnComManagerDisableBroadcasts disableBcastFnc, com_manager_init_t *buffers, com_manager_port_t *cmPorts)
Definition: com_manager.c:152
#define PID_GET_DATA
Definition: ISComm.h:182
int(* pfnComManagerGenMsgHandler)(CMHANDLE cmHandle, int pHandle, const unsigned char *msg, int msgSize)
Definition: com_manager.h:147
void comManagerGetDataInstance(CMHANDLE cmInstance, int pHandle, uint32_t dataId, int offset, int size, int periodMultiple)
Definition: com_manager.c:516
uint32_t id
Definition: ISComm.h:417
uint8_t * rxPtr
Definition: ISComm.h:218
void * CMHANDLE
Definition: com_manager.h:119
uint32_t broadcastMsgSize
Definition: com_manager.h:103
#define PID_NACK
Definition: ISComm.h:181
#define PID_ACK
Definition: ISComm.h:180
is_comm_instance_t comm
Definition: com_manager.h:174
const unsigned int g_validBaudRates[IS_BAUDRATE_COUNT]
Definition: ISComm.c:84
pfnComManagerSend sendPacketCallback
Definition: com_manager.h:197
int(* pfnComManagerSend)(CMHANDLE cmHandle, int pHandle, unsigned char *buffer, int numberOfBytes)
Definition: com_manager.h:126
int findAsciiMessage(const void *a, const void *b)
Definition: com_manager.c:684
p_data_hdr_t hdr
Definition: ISComm.h:388
uint8_t * tail
Definition: ISComm.h:459
void comManagerStepTxInstance(CMHANDLE cmInstance_)
Definition: com_manager.c:397
#define _CLAMP(v, minV, maxV)
Definition: ISConstants.h:302
uint32_t id
Definition: ISComm.h:398
USBInterfaceDescriptor data
pkt_info_t pkt
Definition: com_manager.h:45
int(* pfnComManagerRead)(CMHANDLE cmHandle, int pHandle, uint8_t *buffer, int numberOfBytes)
Definition: com_manager.h:123
int32_t ensureRetryCount
Definition: com_manager.h:234
com_manager_status_t status
Definition: com_manager.h:180
uint8_t pid
Definition: ISComm.h:322
int comManagerSendDataNoAckInstance(CMHANDLE cmInstance, int pHandle, uint32_t dataId, void *dataPtr, int dataSize, int dataOffset)
Definition: com_manager.c:577
int32_t lastEnsuredPacketIndex
Definition: com_manager.h:222
void comManagerAssignUserPointer(CMHANDLE cmInstance, void *userPointer)
Definition: com_manager.c:472
void is_comm_init(is_comm_instance_t *instance, uint8_t *buffer, int bufferSize)
Definition: ISComm.c:185
uint32_t size
Definition: ISComm.h:195
void stepComManagerSendMessagesInstance(CMHANDLE cmInstance)
Definition: com_manager.c:408
int encodeBinaryPacket(com_manager_t *cmInstance, int pHandle, buffer_t *pkt, packet_t *dPkt, uint8_t additionalPktFlags)
Adds data to a packet: adds start, info, data length, data, checksum, and stop bytes. All data is communicated in the endianess of the sender, each packet has a bit that determines big or little endian. Process for Creating Tx Packet: 1.) Add to packet.
Definition: com_manager.c:1256
pfnComManagerGenMsgHandler cmMsgHandlerAscii
Definition: com_manager.h:243
uint32_t txPktCount
Definition: ISComm.h:494
#define COM_MANAGER_BUF_SIZE_ENSURED_PKTS(max_num_ensured_pkts)
Definition: com_manager.h:116
#define MAX_NUM_BCAST_MSGS
Definition: com_manager.h:112
pfnComManagerGenMsgHandler cmMsgHandlerRtcm3
Definition: com_manager.h:249
union p_ack_t::@41 body
void disableBroadcastMsg(com_manager_t *cmInstance, broadcast_msg_t *msg)
Definition: com_manager.c:1035
p_data_hdr_t dataHdr
Definition: ISComm.h:506
#define PID_DATA
Definition: ISComm.h:183
void comManagerSetCallbacks(pfnComManagerAsapMsg handlerRmc, pfnComManagerGenMsgHandler handlerAscii, pfnComManagerGenMsgHandler handlerUblox, pfnComManagerGenMsgHandler handlerRtcm3)
Definition: com_manager.c:448
void comManagerGetDataRmc(int pHandle, uint64_t rmcBits, uint32_t rmcOptions)
Definition: com_manager.c:534
int comManagerSend(int pHandle, uint8_t pktInfo, bufPtr_t *bodyHdr, bufPtr_t *txData, uint8_t pFlags)
Definition: com_manager.c:634
void stepComManagerSendMessages(void)
Definition: com_manager.c:403
int32_t period
Definition: com_manager.h:54
void * comManagerGetUserPointer(CMHANDLE cmInstance)
Definition: com_manager.c:477
pfnComManagerPostAck pstAckFnc
Definition: com_manager.h:206
int comManagerSendData(int pHandle, uint32_t dataId, void *dataPtr, int dataSize, int dataOffset)
Definition: com_manager.c:548
int comManagerDisableDataInstance(CMHANDLE cmInstance, int pHandle, uint32_t dataId)
Definition: com_manager.c:625
protocol_type_t
Definition: ISComm.h:75
uint8_t * ptr
Definition: ISComm.h:205
void enableBroadcastMsg(com_manager_t *cmInstance, broadcast_msg_t *msg, int periodMultiple)
Definition: com_manager.c:1021
#define PID_STOP_DID_BROADCAST
Definition: ISComm.h:186
protocol_type_t is_comm_parse(is_comm_instance_t *instance)
Definition: ISComm.c:514
void comManagerGetData(int pHandle, uint32_t dataId, int offset, int size, int periodMultiple)
Request data This function requests the specified data w/ offset and length for partial reads...
Definition: com_manager.c:511
uint8_t buf[MAX_DATASET_SIZE]
Definition: ISComm.h:391
int comManagerInit(int numHandles, int maxEnsuredPackets, int stepPeriodMilliseconds, int retryCount, pfnComManagerRead readFnc, pfnComManagerSend sendFnc, pfnComManagerSendBufferAvailableBytes txFreeFnc, pfnComManagerPostRead pstRxFnc, pfnComManagerPostAck pstAckFnc, pfnComManagerDisableBroadcasts disableBcastFnc, com_manager_init_t *buffers, com_manager_port_t *cmPorts)
Definition: com_manager.c:79
packet_t pkt
Definition: ISComm.h:521
#define _ARRAY_ELEMENT_COUNT(a)
Definition: ISConstants.h:326
int32_t stepPeriodMilliseconds
Definition: com_manager.h:231
uint8_t flags
Definition: ISComm.h:334
int32_t numHandles
Definition: com_manager.h:225
uint32_t bc_period_multiple
Definition: ISComm.h:410
bufTxRxPtr_t dataSet
Definition: com_manager.h:159
uint32_t offset
Definition: ISComm.h:381
pfnComManagerDisableBroadcasts disableBcastFnc
Definition: com_manager.h:209
void comManagerRegister(uint32_t dataId, pfnComManagerPreSend txFnc, pfnComManagerPostRead pstRxFnc, const void *txDataPtr, void *rxDataPtr, int dataSize, uint8_t pktFlags)
Definition: com_manager.c:247
uint8_t counter
Definition: ISComm.h:325
uint32_t size
Definition: ISComm.h:401
uint32_t ensuredPacketsSize
Definition: com_manager.h:106
void(* pfnComManagerPostAck)(CMHANDLE cmHandle, int pHandle, p_ack_t *ack, unsigned char packetIdentifier)
Definition: com_manager.h:135
void comManagerStepInstance(CMHANDLE cmInstance_)
Definition: com_manager.c:287
static com_manager_t g_cm
Definition: com_manager.c:32
int comManagerSendEnsuredInstance(CMHANDLE cmInstance, int pHandle, uint8_t pktInfo, unsigned char *data, unsigned int dataSize)
Definition: com_manager.c:665
CMHANDLE comManagerGetGlobal(void)
Definition: com_manager.c:76
uint8_t * dataPtr
Definition: ISComm.h:509


inertial_sense_ros
Author(s):
autogenerated on Sat Sep 19 2020 03:19:04