InertialSense.cpp
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 "InertialSense.h"
14 
15 using namespace std;
16 
17 typedef struct
18 {
20  bool result;
22  void* thread;
24 
25 static void bootloaderThread(void* state)
26 {
30  {
32  s->result = false;
33  return;
34  }
35  s->result = (bootloadFileEx(&s->param) != 0);
37 }
38 
39 static void bootloaderUpdateBootloaderThread(void* state)
40 {
43  s->result = (bootloadUpdateBootloaderEx(&s->param) != 0);
45 }
46 
47 static int staticSendPacket(CMHANDLE cmHandle, int pHandle, unsigned char* buf, int len)
48 {
49  // Suppress compiler warnings
50  (void)pHandle;
51  (void)cmHandle;
52 
54  if ((size_t)pHandle >= s->devices.size())
55  {
56  return 0;
57  }
58  return serialPortWrite(&s->devices[pHandle].serialPort, buf, len);
59 }
60 
61 static int staticReadPacket(CMHANDLE cmHandle, int pHandle, unsigned char* buf, int len)
62 {
63  // Suppress compiler warnings
64  (void)pHandle;
65  (void)cmHandle;
66 
68  if ((size_t)pHandle >= s->devices.size())
69  {
70  return 0;
71  }
72  return serialPortReadTimeout(&s->devices[pHandle].serialPort, buf, len, 1);
73 }
74 
75 static void staticProcessRxData(CMHANDLE cmHandle, int pHandle, p_data_t* data)
76 {
77  (void)cmHandle;
78 
79  if (data->hdr.id >= DID_COUNT)
80  {
81  return;
82  }
83 
85  pfnHandleBinaryData handler = s->binaryCallback[data->hdr.id];
86  s->stepLogFunction(s->inertialSenseInterface, data, pHandle);
87 
88  if ((size_t)pHandle > s->devices.size())
89  {
90  return;
91  }
92 
93  if (handler != NULLPTR)
94  {
95  handler(s->inertialSenseInterface, data, pHandle);
96  }
97 
98  pfnHandleBinaryData handlerGlobal = s->binaryCallbackGlobal;
99  if (handlerGlobal != NULLPTR)
100  {
101  // Called for all DID's
102  handlerGlobal(s->inertialSenseInterface, data, pHandle);
103  }
104 
105  // if we got dev info, sysCmd or flash config, set it
106  switch (data->hdr.id)
107  {
108  case DID_DEV_INFO: s->devices[pHandle].devInfo = *(dev_info_t*)data->buf; break;
109  case DID_SYS_CMD: s->devices[pHandle].sysCmd = *(system_command_t*)data->buf; break;
110  case DID_FLASH_CONFIG: s->devices[pHandle].flashConfig = *(nvm_flash_cfg_t*)data->buf; break;
111  case DID_GPS1_POS:
112  // every 5 seconds, put in a new gps position message
113  static time_t nextGpsMessageTime;
114  time_t currentTime = time(NULLPTR);
115  if (currentTime > nextGpsMessageTime)
116  {
117  nextGpsMessageTime = currentTime + 5;
119  }
120  }
121 }
122 
124 {
126  m_lastLogReInit = time(0);
139  memset(&m_cmInit, 0, sizeof(m_cmInit));
140  m_cmPorts = NULLPTR;
142 }
143 
145 {
147  Close();
148 }
149 
150 bool InertialSense::EnableLogging(const string& path, cISLogger::eLogType logType, float maxDiskSpacePercent, uint32_t maxFileSize, const string& subFolder)
151 {
152  cMutexLocker logMutexLocker(&m_logMutex);
153  if (!m_logger.InitSaveTimestamp(subFolder, path, cISLogger::g_emptyString, (int)m_comManagerState.devices.size(), logType, maxDiskSpacePercent, maxFileSize, subFolder.length() != 0))
154  {
155  return false;
156  }
157  m_logger.EnableLogging(true);
158  for (size_t i = 0; i < m_comManagerState.devices.size(); i++)
159  {
161  }
162  if (m_logThread == NULLPTR)
163  {
165  }
166  return true;
167 }
168 
170 {
171  // just sets a bool no need to lock
172  m_logger.EnableLogging(false);
176 }
177 
179 {
180  if (index >= m_comManagerState.devices.size())
181  {
182  return false;
183  }
184 
185  return (m_comManagerState.devices[index].flashConfig.size != 0 &&
186  m_comManagerState.devices[index].devInfo.serialNumber != 0 &&
187  m_comManagerState.devices[index].devInfo.manufacturer[0] != 0);
188 }
189 
191 {
192  if (m_comManagerState.devices.size() == 0)
193  {
194  return false;
195  }
196 
197  for (size_t i = 0; i < m_comManagerState.devices.size(); i++)
198  {
200  {
201  return false;
202  }
203  }
204  return true;
205 }
206 
207 void InertialSense::RemoveDevice(size_t index)
208 {
209  if (index >= m_comManagerState.devices.size())
210  {
211  return;
212  }
213 
214  serialPortClose(&m_comManagerState.devices[index].serialPort);
215  m_comManagerState.devices.erase(m_comManagerState.devices.begin() + index);
216 }
217 
219 {
220  bool running = true;
221  InertialSense* inertialSense = (InertialSense*)info;
222 
223  // gather up packets in memory
224  map<int, vector<p_data_t>> packets;
225 
226  while (running)
227  {
228  SLEEP_MS(20);
229  {
230  // lock so we can read and clear m_logPackets
231  cMutexLocker logMutexLocker(&inertialSense->m_logMutex);
232  for (map<int, vector<p_data_t>>::iterator i = inertialSense->m_logPackets.begin(); i != inertialSense->m_logPackets.end(); i++)
233  {
234  packets[i->first] = i->second;
235  }
236 
237  // clear shared memory
238  inertialSense->m_logPackets.clear();
239 
240  // update running state
241  running = inertialSense->m_logger.Enabled();
242  }
243 
244  if (running)
245  {
246  // log the packets
247  for (map<int, vector<p_data_t>>::iterator i = packets.begin(); i != packets.end(); i++)
248  {
249  for (size_t j = 0; j < i->second.size(); j++)
250  {
251  if (!inertialSense->m_logger.LogData(i->first, &i->second[j].hdr, i->second[j].buf))
252  {
253  // Failed to write to log
254  SLEEP_MS(20);
255  }
256  }
257 
258  // clear all log data for this pHandle
259  i->second.clear();
260  }
261  }
262 
263  inertialSense->m_logger.Update();
264  }
265 
266  printf("\n...Logger thread terminated...\n");
267 }
268 
270 {
271  cMutexLocker logMutexLocker(&i->m_logMutex);
272  if (i->m_logger.Enabled())
273  {
274  vector<p_data_t>& vec = i->m_logPackets[pHandle];
275  vec.push_back(*data);
276  }
277 }
278 
279 bool InertialSense::Open(const char* port, int baudRate, bool disableBroadcastsOnClose)
280 {
281  // null com port, just use other features of the interface like ntrip
282  if (port[0] == '0' && port[1] == '\0')
283  {
284  return true;
285  }
286 
288  if (OpenSerialPorts(port, baudRate))
289  {
290  m_disableBroadcastsOnClose = disableBroadcastsOnClose;
291  return true;
292  }
293  return false;
294 }
295 
297  bool enable,
298  const string& path,
299  cISLogger::eLogType logType,
300  uint64_t rmcPreset,
301  float maxDiskSpacePercent,
302  uint32_t maxFileSize,
303  const string& subFolder)
304 {
305  if (enable)
306  {
307  if (m_logThread != NULLPTR)
308  {
309  // already logging
310  return true;
311  }
312 
313  if(rmcPreset)
314  {
315  BroadcastBinaryDataRmcPreset(rmcPreset);
316  }
317  return EnableLogging(path, logType, maxDiskSpacePercent, maxFileSize, subFolder);
318  }
319 
320  // !enable, shutdown logger gracefully
321  DisableLogging();
322  return true;
323 }
324 
325 bool InertialSense::OpenServerConnection(const string& connectionString)
326 {
327  bool opened = false;
328 
330  vector<string> pieces;
331  splitString(connectionString, ":", pieces);
332  if (pieces.size() < 3)
333  {
334  return opened;
335  }
336 
337  if (pieces[1] == "SERIAL")
338  {
339  if (pieces.size() < 4)
340  {
341  return opened;
342  }
343  else if ((opened = (m_serialServer.Open(pieces[2].c_str(), atoi(pieces[3].c_str())))))
344  {
346  }
347  }
348  else
349  {
350  opened = (m_tcpClient.Open(pieces[1], atoi(pieces[2].c_str())) == 0);
351  string url = (pieces.size() > 3 ? pieces[3] : "");
352  string userAgent = "NTRIP Inertial Sense"; // NTRIP standard requires "NTRIP" to be at the start of the User-Agent string.
353  string username = (pieces.size() > 4 ? pieces[4] : "");
354  string password = (pieces.size() > 5 ? pieces[5] : "");
355  if (url.size() != 0)
356  {
357  m_tcpClient.HttpGet(url, userAgent, username, password);
358  }
359  }
360  if (opened)
361  {
362 #if 0
363  // configure as RTK rover
364  uint32_t cfgBits = RTK_CFG_BITS_ROVER_MODE_RTK_POSITIONING;
365  for (size_t i = 0; i < m_comManagerState.devices.size(); i++)
366  {
367  comManagerSendData((int)i, DID_FLASH_CONFIG, &cfgBits, sizeof(cfgBits), offsetof(nvm_flash_cfg_t, RTKCfgBits));
368  }
369 #endif
370  if (m_clientStream == NULLPTR)
371  {
373  }
374  }
375 
376  return opened;
377 }
378 
380 {
381  m_tcpClient.Close();
382  m_tcpServer.Close();
385 }
386 
387 bool InertialSense::CreateHost(const string& ipAndPort)
388 {
389  // if no serial connection, fail
390  if (!IsOpen())
391  {
392  return false;
393  }
394 
396  size_t colon = ipAndPort.find(':', 0);
397  if (colon == string::npos)
398  {
399  return false;
400  }
401  StopBroadcasts();
402  string host = ipAndPort.substr(0, colon);
403  string portString = ipAndPort.substr(colon + 1);
404  int port = (int)strtol(portString.c_str(), NULLPTR, 10);
405  return (m_tcpServer.Open(host, port) == 0);
406 }
407 
409 {
410  return (m_comManagerState.devices.size() != 0 && serialPortIsOpen(&m_comManagerState.devices[0].serialPort));
411 }
412 
414 {
415  return m_comManagerState.devices.size();
416 }
417 
419 {
420  uint8_t buffer[PKT_BUF_SIZE];
421  if (m_tcpServer.IsOpen() && m_comManagerState.devices.size() != 0)
422  {
423  // as a tcp server, only the first serial port is read from
424  int count = serialPortReadTimeout(&m_comManagerState.devices[0].serialPort, buffer, sizeof(buffer), 0);
425  if (count > 0)
426  {
427  // forward data on to connected clients
429  if (m_tcpServer.Write(buffer, count) != count)
430  {
431  cout << endl << "Failed to write bytes to tcp server!" << endl;
432  }
433  }
435  }
436  else
437  {
438  if (m_clientStream != NULLPTR)
439  {
440  // Forward only valid uBlox and RTCM3 packets
441 
442  is_comm_instance_t *comm = &(m_gpComm);
444  static int error = 0;
445 // static int ubxRtcmCnt = 0;
446 // printf("Rx data: %d\n", count);
447 
448 #if 0 // Read one byte (simple method)
449  uint8_t c;
450 
451  // Read from serial buffer until empty
452  while (m_clientStream->Read(&c, 1))
453  {
454  if ((ptype = is_comm_parse_byte(comm, c)) != _PTYPE_NONE)
455  {
456 
457 #else // Read a set of bytes (fast method)
458 
459  // Get available size of comm buffer
460  int n = is_comm_free(comm);
461 
462  // Read data directly into comm buffer
463  if ((n = m_clientStream->Read(comm->buf.tail, n)))
464  {
465  // Update comm buffer tail pointer
466  comm->buf.tail += n;
467 
468  // Search comm buffer for valid packets
469  while ((ptype = is_comm_parse(comm)) != _PTYPE_NONE)
470  {
471 #endif
472  switch (ptype)
473  {
474  case _PTYPE_UBLOX:
475  case _PTYPE_RTCM3:
476 // if (comm->externalDataIdentifier == EXTERNAL_DATA_ID_UBLOX)
477 // {
478 // printf("Receive uBlox: %d\n", ubxRtcmCnt++);
479 // }
480 // else
481 // {
482 // printf("Receive RTCM3: %d\n", ubxRtcmCnt++);
483 // }
485  OnPacketReceived(comm->dataPtr, comm->dataHdr.size);
486  break;
487 
488  case _PTYPE_PARSE_ERROR:
489  printf("PARSE ERROR: %d\n", error++);
490  break;
492 // printf("Receive DID: %d\n", did);
493  break;
494  case _PTYPE_ASCII_NMEA:
495 // printf("Receive ASCII\n");
496  break;
497 
498  default:
499  break;
500  }
501  }
502  }
503 
504  // send data to client if available, i.e. nmea gga pos
505  if (m_clientServerByteCount > 0)
506  {
507  int bytes = m_clientBufferBytesToSend;
508  if (bytes != 0)
509  {
512  }
513  }
514  }
515 
516  // [C COMM INSTRUCTION] 2.) Update Com Manager at regular interval to send and receive data.
517  // Normally called within a while loop. Include a thread "sleep" if running on a multi-thread/
518  // task system with serial port read function that does NOT incorporate a timeout.
519  if (m_comManagerState.devices.size() != 0)
520  {
521  comManagerStep();
522  }
523  }
524 
525  // if any serial ports have closed, shutdown
526  for (size_t i = 0; i < m_comManagerState.devices.size(); i++)
527  {
528  if (!serialPortIsOpen(&m_comManagerState.devices[i].serialPort))
529  {
530  Close();
531  return false;
532  }
533  }
534 
535  return true;
536 }
537 
539 {
540  SetLoggerEnabled(false);
542  {
543  StopBroadcasts();
544  SLEEP_MS(100);
545  }
546  for (size_t i = 0; i < m_comManagerState.devices.size(); i++)
547  {
548  serialPortClose(&m_comManagerState.devices[i].serialPort);
549  }
550  m_comManagerState.devices.clear();
552 }
553 
554 vector<string> InertialSense::GetPorts()
555 {
556  vector<string> ports;
557  for (size_t i = 0; i < m_comManagerState.devices.size(); i++)
558  {
559  ports.push_back(m_comManagerState.devices[i].serialPort.port);
560  }
561  return ports;
562 }
563 
564 void InertialSense::StopBroadcasts(bool allPorts)
565 {
567 
568  // Stop all broadcasts
569  for (size_t i = 0; i < m_comManagerState.devices.size(); i++)
570  {
571  // [C COMM INSTRUCTION] Turns off (disable) all broadcasting and streaming on all ports from the uINS.
572  comManagerSend((int)i, pid, 0, 0, 0);
573  }
574 }
575 
576 void InertialSense::SendData(eDataIDs dataId, uint8_t* data, uint32_t length, uint32_t offset)
577 {
578  for (size_t i = 0; i < m_comManagerState.devices.size(); i++)
579  {
580  // [C COMM INSTRUCTION] 4.) Send data to the uINS.
581  comManagerSendData((int)i, dataId, data, length, offset);
582  }
583 }
584 
585 void InertialSense::SendRawData(eDataIDs dataId, uint8_t* data, uint32_t length, uint32_t offset)
586 {
587  for (size_t i = 0; i < m_comManagerState.devices.size(); i++)
588  {
589  comManagerSendRawData((int)i, dataId, data, length, offset);
590  }
591 }
592 
593 void InertialSense::SetSysCmd(const system_command_t& sysCmd, int pHandle)
594 {
595  if ((size_t)pHandle >= m_comManagerState.devices.size())
596  {
597  return;
598  }
599 
600  m_comManagerState.devices[pHandle].sysCmd = sysCmd;
601  // [C COMM INSTRUCTION] Update the entire DID_SYS_CMD data set in the uINS.
602  comManagerSendData(pHandle, DID_SYS_CMD, &m_comManagerState.devices[pHandle].sysCmd, sizeof(sysCmd), 0);
603 }
604 
605 void InertialSense::SetFlashConfig(const nvm_flash_cfg_t& flashConfig, int pHandle)
606 {
607  if ((size_t)pHandle >= m_comManagerState.devices.size())
608  {
609  return;
610  }
611 
612  m_comManagerState.devices[pHandle].flashConfig = flashConfig;
613  // [C COMM INSTRUCTION] Update the entire DID_FLASH_CONFIG data set in the uINS.
614  comManagerSendData(pHandle, DID_FLASH_CONFIG, &m_comManagerState.devices[pHandle].flashConfig, sizeof(nvm_flash_cfg_t), 0);
615  Update();
616 }
617 
618 bool InertialSense::BroadcastBinaryData(uint32_t dataId, int periodMultiple, pfnHandleBinaryData callback)
619 {
620  if (m_comManagerState.devices.size() == 0 || dataId >= DID_COUNT)
621  {
622  return false;
623  }
624  else
625  {
626  m_comManagerState.binaryCallback[dataId] = callback;
627  }
628  if (periodMultiple < 0)
629  {
630  for (int i = 0; i < (int)m_comManagerState.devices.size(); i++)
631  {
632  // [C COMM INSTRUCTION] Stop broadcasting of one specific DID message from the uINS.
633  comManagerDisableData(i, dataId);
634  }
635  }
636  else
637  {
638  for (int i = 0; i < (int)m_comManagerState.devices.size(); i++)
639  {
640  // [C COMM INSTRUCTION] 3.) Request a specific data set from the uINS. "periodMultiple" specifies the interval
641  // between broadcasts and "periodMultiple=0" will disable broadcasts and transmit one single message.
642  comManagerGetData(i, dataId, 0, 0, periodMultiple);
643  }
644  }
645  return true;
646 }
647 
648 void InertialSense::BroadcastBinaryDataRmcPreset(uint64_t rmcPreset, uint32_t rmcOptions)
649 {
650  for (size_t i = 0; i < m_comManagerState.devices.size(); i++)
651  {
652  // [C COMM INSTRUCTION] Use a preset to enable a predefined set of messages. R
653  comManagerGetDataRmc((int)i, rmcPreset, rmcOptions);
654  }
655 }
656 
657 vector<InertialSense::bootloader_result_t> InertialSense::BootloadFile(const string& comPort, const string& fileName, int baudRate, pfnBootloadProgress uploadProgress, pfnBootloadProgress verifyProgress, bool updateBootloader)
658 {
659  return BootloadFile(comPort, fileName, "", baudRate, uploadProgress, verifyProgress, NULLPTR, updateBootloader);
660 }
661 
662 vector<InertialSense::bootloader_result_t> InertialSense::BootloadFile(const string& comPort, const string& fileName, const string& bootloaderFileName, int baudRate, pfnBootloadProgress uploadProgress, pfnBootloadProgress verifyProgress, pfnBootloadStatus infoProgress, bool updateBootloader)
663 {
664  vector<bootloader_result_t> results;
665  vector<string> portStrings;
666  vector<bootloader_state_t> state;
667 
668  if (comPort == "*")
669  {
670  cISSerialPort::GetComPorts(portStrings);
671  }
672  else
673  {
674  splitString(comPort, ",", portStrings);
675  }
676  sort(portStrings.begin(), portStrings.end());
677  state.resize(portStrings.size());
678 
679  // test file exists
680  {
681  ifstream tmpStream(fileName);
682  if (!tmpStream.good())
683  {
684  for (size_t i = 0; i < state.size(); i++)
685  {
686  results.push_back({ state[i].serial.port, "File does not exist" });
687  }
688  }
689  }
690 
691  if (results.size() == 0)
692  {
693  // for each port requested, setup a thread to do the bootloader for that port
694  for (size_t i = 0; i < state.size(); i++)
695  {
696  memset(state[i].param.error, 0, BOOTLOADER_ERROR_LENGTH);
697  serialPortPlatformInit(&state[i].serial);
698  serialPortSetPort(&state[i].serial, portStrings[i].c_str());
699  state[i].param.uploadProgress = uploadProgress;
700  state[i].param.verifyProgress = verifyProgress;
701  state[i].param.statusText = infoProgress;
702  state[i].param.fileName = fileName.c_str();
703  state[i].param.bootName = bootloaderFileName.c_str();
704  state[i].param.port = &state[i].serial;
705  state[i].param.verifyFileName = NULLPTR;
706  state[i].param.flags.bitFields.enableVerify = (verifyProgress != NULLPTR);
707  state[i].param.numberOfDevices = (int)state.size();
708  state[i].param.baudRate = baudRate;
709  strncpy(state[i].param.bootloadEnableCmd, "BLEN", 4);
710  if (updateBootloader)
711  { // Update bootloader firmware
712  state[i].thread = threadCreateAndStart(bootloaderUpdateBootloaderThread, &state[i]);
713  }
714  else
715  { // Update application firmware
716  state[i].thread = threadCreateAndStart(bootloaderThread, &state[i]);
717  }
718  }
719 
720  // wait for all threads to finish
721  for (size_t i = 0; i < state.size(); i++)
722  {
723  threadJoinAndFree(state[i].thread);
724  }
725 
726  // if any thread failed, we return failure
727  for (size_t i = 0; i < state.size(); i++)
728  {
729  results.push_back({ state[i].serial.port, state[i].param.error });
730  }
731  }
732 
733  return results;
734 }
735 
736 bool InertialSense::OnPacketReceived(const uint8_t* data, uint32_t dataLength)
737 {
738  for (size_t i = 0; i < m_comManagerState.devices.size(); i++)
739  {
740  // sleep in between to allow test bed to send the serial data
741  // TODO: This was 10ms, but that was to long for the CI test.
742 // SLEEP_MS(1); // This is commented out because it causes problems when using testbad with CLTool on single board computer.
743  serialPortWrite(&m_comManagerState.devices[i].serialPort, data, dataLength);
744  }
745  return false; // do not parse, since we are just forwarding it on
746 }
747 
749 {
750  (void)server;
751  cout << endl << "Client connecting..." << endl;
752 }
753 
755 {
756  cout << endl << "Client connected: " << (int)socket << endl;
757 }
758 
760 {
761  cout << endl << "Client connection failed!" << endl;
762 }
763 
765 {
766  cout << endl << "Client disconnected: " << (int)socket << endl;
767 }
768 
769 bool InertialSense::OpenSerialPorts(const char* port, int baudRate)
770 {
771  Close();
772 
773  if (port == NULLPTR || comManagerValidateBaudRate(baudRate) != 0)
774  {
775  return false;
776  }
777 
778  // split port on comma in case we need to open multiple serial ports
779  vector<string> ports;
780  size_t maxCount = UINT32_MAX;
781 
782  // handle wildcard, auto-detect serial ports
783  if (port[0] == '*')
784  {
786  if (port[1] != '\0')
787  {
788  maxCount = atoi(port + 1);
789  maxCount = (maxCount == 0 ? UINT32_MAX : maxCount);
790  }
791  }
792  else
793  {
794  // comma separated list of serial ports
795  splitString(port, ",", ports);
796  }
797 
798  // open serial ports
799  for (size_t i = 0; i < ports.size(); i++)
800  {
801  serial_port_t serial;
802  serialPortPlatformInit(&serial);
803  if (serialPortOpen(&serial, ports[i].c_str(), baudRate, 0) == 0)
804  {
805  // failed to open
806  serialPortClose(&serial);
807  }
808  else
809  {
810  is_device_t device = {};
811  device.serialPort = serial;
812  m_comManagerState.devices.push_back(device);
813  }
814  }
815 
816  // [C COMM INSTRUCTION] 1.) Setup com manager. Specify number of serial ports and register callback functions for
817  // serial port read and write and for successfully parsed data. Ensure appropriate buffer memory allocation.
818  if (m_cmPorts) { delete [] m_cmPorts; }
820 
821  if (m_cmInit.broadcastMsg) { delete [] m_cmInit.broadcastMsg; }
824 #define NUM_ENSURED_PKTS 10
825  if (m_cmInit.ensuredPackets) { delete [] m_cmInit.ensuredPackets; }
829  { // Error
830  return false;
831  }
832 
833  // negotiate baud rate by querying device info - don't return out until it negotiates or times out
834  // if the baud rate is already correct, the request for the message should succeed very quickly
835  time_t startTime = time(0);
836 
837  // try to auto-baud for up to 10 seconds, then abort if we didn't get a valid packet
838  // we wait until we get a valid serial number and manufacturer
839  while (!HasReceivedResponseFromAllDevices() && time(0) - startTime < 10)
840  {
841  for (size_t i = 0; i < m_comManagerState.devices.size(); i++)
842  {
843  comManagerGetData((int)i, DID_SYS_CMD, 0, 0, 0);
844  comManagerGetData((int)i, DID_DEV_INFO, 0, 0, 0);
845  comManagerGetData((int)i, DID_FLASH_CONFIG, 0, 0, 0);
846  }
847 
848  SLEEP_MS(13);
849  comManagerStep();
850  }
851 
852  bool removedSerials = false;
853 
854  // remove each failed device where communications were not received
855  for (int i = ((int)m_comManagerState.devices.size() - 1); i >= 0; i--)
856  {
858  {
859  RemoveDevice(i);
860  removedSerials = true;
861  }
862  }
863 
864  // if no devices left, all failed, we return failure
865  if (m_comManagerState.devices.size() == 0)
866  {
867  Close();
868  return false;
869  }
870 
871  // remove ports if we are over max count
872  while (m_comManagerState.devices.size() > maxCount)
873  {
875  removedSerials = true;
876  }
877 
878  // setup com manager again if serial ports dropped out with new count of serial ports
879  if (removedSerials)
880  {
882  }
883 
884  return m_comManagerState.devices.size() != 0;
885 }
int comManagerDisableData(int pHandle, uint32_t dataId)
Definition: com_manager.c:620
static void LoggerThread(void *info)
void CloseAllFiles()
Definition: ISLogger.cpp:439
void RemoveDevice(size_t index)
bool OnPacketReceived(const uint8_t *data, uint32_t dataLength)
void StopBroadcasts(bool allPorts=true)
vector< string > GetPorts()
static vector< bootloader_result_t > BootloadFile(const string &comPort, const string &fileName, const string &bootloaderFileName, int baudRate=IS_BAUD_RATE_BOOTLOADER, pfnBootloadProgress uploadProgress=NULLPTR, pfnBootloadProgress verifyProgress=NULLPTR, pfnBootloadStatus infoProgress=NULLPTR, bool updateBootloader=false)
int comManagerSendRawData(int pHandle, uint32_t dataId, void *dataPtr, int dataSize, int dataOffset)
Definition: com_manager.c:596
static void StepLogger(InertialSense *i, const p_data_t *data, int pHandle)
bool param(const std::string &param_name, T &param_val, const T &default_val)
is_comm_instance_t m_gpComm
NMI_API SOCKET socket(uint16 u16Domain, uint8 u8Type, uint8 u8Flags)
Definition: socket.c:477
void threadJoinAndFree(void *handle)
bootload_params_t param
char port[MAX_SERIAL_PORT_NAME_LENGTH+1]
int comManagerValidateBaudRate(unsigned int baudRate)
Definition: com_manager.c:1573
bool HasReceivedResponseFromDevice(size_t index)
std::function< void(InertialSense *i, p_data_t *data, int pHandle)> pfnHandleBinaryData
Definition: InertialSense.h:54
ensured_pkt_t * ensuredPackets
Definition: com_manager.h:105
#define PID_STOP_BROADCASTS_ALL_PORTS
Definition: ISComm.h:185
InertialSense(pfnHandleBinaryData callback=NULL)
uint64_t m_clientServerByteCount
static int running
void * threadCreateAndStart(void(*function)(void *info), void *info)
uint32_t id
Definition: ISComm.h:375
uint32_t size
Definition: ISComm.h:378
int serialPortReadTimeout(serial_port_t *serialPort, unsigned char *buffer, int readCount, int timeoutMilliseconds)
uint8_t m_gpCommBuffer[PKT_BUF_SIZE]
int serialPortOpen(serial_port_t *serialPort, const char *port, int baudRate, int blocking)
#define printf(...)
broadcast_msg_t * broadcastMsg
Definition: com_manager.h:102
XmlRpcServer s
bool OpenServerConnection(const string &connectionString)
#define NUM_ENSURED_PKTS
bool IsOpen()
Definition: ISTcpServer.h:131
size_t splitString(const string &s, const string &delimiter, vector< string > &result)
size_t count(InputIterator first, InputIterator last, T const &item)
Definition: catch.hpp:3206
void serialPortSetPort(serial_port_t *serialPort, const char *port)
#define PKT_BUF_SIZE
Definition: ISComm.h:98
pfnHandleBinaryData binaryCallbackGlobal
Definition: InertialSense.h:82
#define DID_COUNT
Definition: data_sets.h:138
#define DID_DEV_INFO
Definition: data_sets.h:35
static void GetComPorts(vector< string > &ports)
protocol_type_t is_comm_parse_byte(is_comm_instance_t *instance, uint8_t byte)
Definition: ISComm.c:499
int Close() OVERRIDE
uint32_t eDataIDs
Definition: data_sets.h:32
int Open(const string &ipAddress, int port)
Definition: ISTcpServer.cpp:45
int m_clientBufferBytesToSend
void CloseServerConnection()
static void staticProcessRxData(CMHANDLE cmHandle, int pHandle, p_data_t *data)
#define SLEEP_MS(timeMs)
Definition: ISUtilities.h:134
void OnClientConnecting(cISTcpServer *server) OVERRIDE
void comManagerStep(void)
Definition: com_manager.c:281
#define NULLPTR
Definition: ISConstants.h:426
bool CreateHost(const string &ipAndPort)
#define COM_MANAGER_BUF_SIZE_BCAST_MSG(max_num_bcast_msgs)
Definition: com_manager.h:115
static int staticReadPacket(CMHANDLE cmHandle, int pHandle, unsigned char *buf, int len)
void EnableLogging(bool enabled)
Definition: ISLogger.h:76
bool LogData(unsigned int device, p_data_hdr_t *dataHdr, const uint8_t *dataBuf)
Definition: ISLogger.cpp:348
is_comm_buffer_t buf
Definition: ISComm.h:488
std::ostream & cout()
int Open(const string &host, int port, int timeoutMilliseconds=IS_SOCKET_DEFAULT_TIMEOUT_MS)
void SendData(eDataIDs dataId, uint8_t *data, uint32_t length, uint32_t offset)
#define PID_STOP_BROADCASTS_CURRENT_PORT
Definition: ISComm.h:187
bool SetLoggerEnabled(bool enable, const string &path=cISLogger::g_emptyString, cISLogger::eLogType logType=cISLogger::eLogType::LOGTYPE_DAT, uint64_t rmcPreset=RMC_PRESET_PPD_BITS, float maxDiskSpacePercent=0.5f, uint32_t maxFileSize=1024 *1024 *5, const string &subFolder=cISLogger::g_emptyString)
void SendRawData(eDataIDs dataId, uint8_t *data, uint32_t length=0, uint32_t offset=0)
size_t GetDeviceCount()
cISTcpServer m_tcpServer
void * m_logThread
#define DID_SYS_CMD
Definition: data_sets.h:41
bool InitSaveTimestamp(const string &timeStamp, const string &directory=g_emptyString, const string &subDirectory=g_emptyString, int numDevices=1, eLogType logType=LOGTYPE_DAT, float maxDiskSpacePercent=0.5f, uint32_t maxFileSize=1024 *1024 *5, bool useSubFolderTimestamp=true)
Definition: ISLogger.cpp:213
int is_comm_free(is_comm_instance_t *instance)
Definition: ISComm.c:462
int Write(const uint8_t *data, int dataLength)
void SetFlashConfig(const nvm_flash_cfg_t &flashConfig, int pHandle=0)
com_manager_port_t * m_cmPorts
int enableBootloader(serial_port_t *port, int baudRate, char *error, int errorLength, const char *bootloadEnableCmd)
void Update()
Definition: ISLogger.cpp:107
bool EnableLogging(const string &path, cISLogger::eLogType logType, float maxDiskSpacePercent, uint32_t maxFileSize, const string &subFolder)
void * CMHANDLE
Definition: com_manager.h:119
#define DID_FLASH_CONFIG
Definition: data_sets.h:46
uint32_t broadcastMsgSize
Definition: com_manager.h:103
static int staticSendPacket(CMHANDLE cmHandle, int pHandle, unsigned char *buf, int len)
int(* pfnBootloadProgress)(const void *obj, float percent)
int serialPortWrite(serial_port_t *serialPort, const unsigned char *buffer, int writeCount)
p_data_hdr_t hdr
Definition: ISComm.h:388
bool m_disableBroadcastsOnClose
void OnClientDisconnected(cISTcpServer *server, socket_t socket) OVERRIDE
uint8_t * tail
Definition: ISComm.h:459
int serialPortClose(serial_port_t *serialPort)
int gpsToNmeaGGA(const gps_pos_t *gps, char *buffer, int bufferLength)
Definition: data_sets.c:745
USBInterfaceDescriptor data
bool BroadcastBinaryData(uint32_t dataId, int periodMultiple, pfnHandleBinaryData callback=NULL)
bool OpenSerialPorts(const char *port, int baudRate)
int bootloadFileEx(bootload_params_t *params)
static void bootloaderUpdateBootloaderThread(void *state)
static void bootloaderThread(void *state)
void comManagerAssignUserPointer(CMHANDLE cmInstance, void *userPointer)
Definition: com_manager.c:472
void SetSysCmd(const system_command_t &sysCmd, int pHandle=0)
void is_comm_init(is_comm_instance_t *instance, uint8_t *buffer, int bufferSize)
Definition: ISComm.c:185
char error[BOOTLOADER_ERROR_LENGTH]
int Close() OVERRIDE
#define DID_GPS1_POS
Definition: data_sets.h:47
pfnHandleBinaryData binaryCallback[DID_COUNT]
Definition: InertialSense.h:83
int serialPortPlatformInit(serial_port_t *serialPort)
#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
time_t m_lastLogReInit
serial_port_t serial
bool Open(const char *port, int baudRate=IS_COM_BAUDRATE_DEFAULT, bool disableBroadcastsOnClose=false)
cISStream * m_clientStream
int serialPortIsOpen(serial_port_t *serialPort)
p_data_hdr_t dataHdr
Definition: ISComm.h:506
cISLogger m_logger
InertialSense::com_manager_cpp_state_t m_comManagerState
int bootloadUpdateBootloaderEx(bootload_params_t *p)
GeneratorWrapper< T > map(Func &&function, GeneratorWrapper< U > &&generator)
Definition: catch.hpp:3853
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 * comManagerGetUserPointer(CMHANDLE cmInstance)
Definition: com_manager.c:477
static const string g_emptyString
Definition: ISLogger.h:59
bool SetDeviceInfo(const dev_info_t *info, unsigned int device=0)
Definition: ISLogger.cpp:520
virtual int Read(void *buffer, int count)
Definition: ISStream.h:45
int comManagerSendData(int pHandle, uint32_t dataId, void *dataPtr, int dataSize, int dataOffset)
Definition: com_manager.c:548
bool Enabled()
Definition: ISLogger.h:77
void(* pfnBootloadStatus)(const void *obj, const char *infoString)
protocol_type_t
Definition: ISComm.h:75
bool HasReceivedResponseFromAllDevices()
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
virtual ~InertialSense()
com_manager_init_t m_cmInit
bool Open(const std::string &portName, int baudRate=BAUDRATE_921600, int timeout=0, bool blocking=false)
#define BOOTLOADER_ERROR_LENGTH
virtual int Write(const void *buffer, int count)
Definition: ISStream.h:53
char m_clientBuffer[512]
map< int, vector< p_data_t > > m_logPackets
cISSerialPort m_serialServer
uint32_t ensuredPacketsSize
Definition: com_manager.h:106
void HttpGet(const string &subUrl, const string &userAgent, const string &userName, const string &password)
void OnClientConnectFailed(cISTcpServer *server) OVERRIDE
void OnClientConnected(cISTcpServer *server, socket_t socket) OVERRIDE
cISTcpClient m_tcpClient
CMHANDLE comManagerGetGlobal(void)
Definition: com_manager.c:76
void BroadcastBinaryDataRmcPreset(uint64_t rmcPreset=RMC_PRESET_INS_BITS, uint32_t rmcOptions=0)
uint8_t * dataPtr
Definition: ISComm.h:509


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