gps_protocol.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. //
  2. // The MIT License (MIT)
  3. //
  4. // Copyright (c) 2019 Livox. All rights reserved.
  5. //
  6. // Permission is hereby granted, free of charge, to any person obtaining a copy
  7. // of this software and associated documentation files (the "Software"), to deal
  8. // in the Software without restriction, including without limitation the rights
  9. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. // copies of the Software, and to permit persons to whom the Software is
  11. // furnished to do so, subject to the following conditions:
  12. //
  13. // The above copyright notice and this permission notice shall be included in
  14. // all copies or substantial portions of the Software.
  15. //
  16. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  22. // SOFTWARE.
  23. //
  24. #include "gps_protocol.h"
  25. #include <ctype.h>
  26. #include <stdio.h>
  27. #include <string.h>
  28. namespace livox_ros {
  29. const uint8_t kGpsProtocolSof = '$';
  30. const uint8_t kGpsProtocolEof = '*';
  31. const uint32_t kPacketLengthLmit = 200;
  32. const uint32_t kPreambleLen = 1;
  33. const uint32_t kWrapperLen = 4; /** '$' + '*' + '2 checksum byte' */
  34. GpsProtocol::GpsProtocol() { found_length_ = 0; }
  35. int32_t GpsProtocol::Pack(uint8_t *o_buf, uint32_t o_buf_size, uint32_t *o_len,
  36. const CommPacket &i_packet) {
  37. // GpsPacket* gps_packet = (GpsPacket*)o_buf;
  38. return 0;
  39. }
  40. int32_t GpsProtocol::ParsePacket(const uint8_t *i_buf, uint32_t i_len,
  41. CommPacket *o_packet) {
  42. // GpsPacket *gps_packet = (GpsPacket *)i_buf;
  43. if (i_len < GetPacketWrapperLen()) {
  44. return -1; // packet length error
  45. }
  46. memset((void *)o_packet, 0, sizeof(CommPacket));
  47. o_packet->protocol = kGps;
  48. o_packet->data = (uint8_t *)i_buf;
  49. o_packet->data_len = i_len;
  50. return 0;
  51. }
  52. uint32_t GpsProtocol::GetPreambleLen() { return kPreambleLen; /** '$' */ }
  53. uint32_t GpsProtocol::GetPacketWrapperLen() {
  54. return kWrapperLen; /** '$' + '*' + '2 checksum bytes' */
  55. }
  56. uint32_t GpsProtocol::FindPacketLen(const uint8_t *buf, uint32_t buf_length) {
  57. uint32_t i = 0;
  58. for (; (i < buf_length) && (i < kPacketLengthLmit); i++) {
  59. if ((buf[i] == kGpsProtocolEof) && (buf[0] == kGpsProtocolSof)) {
  60. found_length_ = i + 1 + 2; /* num = index + 1 + two bytes checksum */
  61. return kFindLengthSuccess;
  62. }
  63. }
  64. if (i < kPacketLengthLmit) {
  65. return kFindLengthContinue;
  66. } else {
  67. return kFindLengthError;
  68. }
  69. }
  70. uint32_t GpsProtocol::GetPacketLen(const uint8_t *buf) { return found_length_; }
  71. int32_t GpsProtocol::CheckPreamble(const uint8_t *buf) {
  72. GpsPreamble *preamble = (GpsPreamble *)buf;
  73. if (preamble->sof == kGpsProtocolSof) {
  74. return 0;
  75. } else {
  76. return -1;
  77. }
  78. }
  79. int32_t GpsProtocol::CheckPacket(const uint8_t *buf) {
  80. uint8_t checksum =
  81. CalcGpsPacketChecksum(&buf[1], found_length_ - kWrapperLen);
  82. uint8_t raw_checksum = AscciiToHex(&buf[found_length_ - 2]);
  83. if (checksum == raw_checksum) {
  84. return 0;
  85. } else {
  86. return -1;
  87. }
  88. }
  89. uint8_t GpsProtocol::CalcGpsPacketChecksum(const uint8_t *buf,
  90. uint32_t length) {
  91. uint8_t result = buf[0];
  92. for (uint32_t i = 1; i < length; i++) {
  93. result ^= buf[i];
  94. }
  95. return result;
  96. }
  97. uint8_t AscciiToHex(const uint8_t *TwoChar) {
  98. uint8_t h = toupper(TwoChar[0]) - 0x30;
  99. if (h > 9) h -= 7;
  100. uint8_t l = toupper(TwoChar[1]) - 0x30;
  101. if (l > 9) l -= 7;
  102. return h * 16 + l;
  103. }
  104. } // namespace livox_ros