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


inertial_sense_ros
Author(s):
autogenerated on Sun Feb 28 2021 03:17:57