ublox_device.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. // This is a personal academic project. Dear PVS-Studio, please check it.
  2. // PVS-Studio Static Code Analyzer for C, C++, C#, and Java: https://pvs-studio.com
  3. #include "ublox_device.h"
  4. #define TAG "ublox_device"
  5. UbloxMessage* ublox_frame_to_bytes(UbloxFrame* frame) {
  6. uint32_t message_size = 8 + frame->len;
  7. // Found the issue! frame_bytes isn't being freed. This function
  8. // should always have returned a pointer.
  9. uint8_t* frame_bytes = malloc(message_size);
  10. frame->sync1 = 0xb5;
  11. frame->sync2 = 0x62;
  12. frame_bytes[0] = frame->sync1;
  13. frame_bytes[1] = frame->sync2;
  14. frame_bytes[2] = frame->class;
  15. frame_bytes[3] = frame->id;
  16. frame_bytes[4] = frame->len & 0xff;
  17. frame_bytes[5] = (frame->len & 0xff) >> 8;
  18. if(frame->len != 0) {
  19. for(int i = 0; i < frame->len; i++) {
  20. frame_bytes[6 + i] = frame->payload[i];
  21. }
  22. }
  23. frame->ck_a = 0;
  24. frame->ck_b = 0;
  25. // checksum is calculated over class, id, length, and payload
  26. for(int i = 2; i < 2 + (frame->len + 4); i++) {
  27. frame->ck_a = frame->ck_a + frame_bytes[i];
  28. frame->ck_b = frame->ck_b + frame->ck_a;
  29. }
  30. frame_bytes[message_size - 2] = frame->ck_a;
  31. frame_bytes[message_size - 1] = frame->ck_b;
  32. UbloxMessage* m = malloc(sizeof(UbloxMessage));
  33. m->message = frame_bytes;
  34. m->length = message_size;
  35. return m;
  36. }
  37. void ublox_message_free(UbloxMessage* message) {
  38. if(message != NULL) {
  39. if(message->message != NULL) {
  40. free(message->message);
  41. } /*else {
  42. FURI_LOG_I(TAG, "message free: message->message == NULL");
  43. }*/
  44. free(message);
  45. } /*else {
  46. FURI_LOG_I(TAG, "message free: message == NULL");
  47. }*/
  48. }
  49. // Pointer, because we are assigning a pointer in the returned frame.
  50. UbloxFrame* ublox_bytes_to_frame(UbloxMessage* message) {
  51. if(message->length < 8) {
  52. FURI_LOG_I(TAG, "message length in bytes_to_frame < 8, = 0x%x", message->length);
  53. // minimum 8 bytes in a message (message with no payload)
  54. return NULL;
  55. }
  56. UbloxFrame* frame = malloc(sizeof(UbloxFrame));
  57. if(message->message[0] != 0xb5) {
  58. FURI_LOG_E(TAG, "message[0] != 0xb5, = 0x%x", message->message[0]);
  59. free(frame);
  60. return NULL;
  61. }
  62. frame->sync1 = message->message[0];
  63. if(message->message[1] != 0x62) {
  64. FURI_LOG_E(TAG, "Message[1] != 0x62, = 0x%x", message->message[1]);
  65. free(frame);
  66. return NULL;
  67. }
  68. frame->sync2 = message->message[1];
  69. frame->class = message->message[2];
  70. frame->id = message->message[3];
  71. // little-endian
  72. frame->len = (message->message[5] << 8) | (message->message[4]);
  73. // frame->len must be initialized before malloc (duh, but I made that mistake...)
  74. frame->payload = malloc(frame->len);
  75. //FURI_LOG_I(TAG, "frame->len: %d", frame->len);
  76. for(int i = 6; i < 6 + frame->len; i++) {
  77. frame->payload[i - 6] = message->message[i];
  78. }
  79. frame->ck_a = message->message[6 + frame->len];
  80. frame->ck_b = message->message[6 + frame->len + 1];
  81. // Test checksum
  82. uint8_t ck_a = 0, ck_b = 0;
  83. for(int i = 2; i < 2 + (frame->len + 4); i++) {
  84. ck_a = ck_a + message->message[i];
  85. ck_b = ck_b + ck_a;
  86. }
  87. if(ck_a != frame->ck_a) {
  88. FURI_LOG_E(TAG, "checksum A doesn't match! expected 0x%x, got 0x%x", ck_a, frame->ck_a);
  89. free(frame);
  90. free(frame->payload);
  91. return NULL;
  92. }
  93. if(ck_b != frame->ck_b) {
  94. FURI_LOG_E(TAG, "checksum B doesn't match! expected 0x%x, got 0x%x", ck_b, frame->ck_b);
  95. free(frame);
  96. free(frame->payload);
  97. return NULL;
  98. }
  99. return frame;
  100. }
  101. void ublox_frame_free(UbloxFrame* frame) {
  102. if(frame != NULL) {
  103. if(frame->payload != NULL) {
  104. free(frame->payload);
  105. } /* else {
  106. FURI_LOG_I(TAG, "frame free: frame->payload == NULL");
  107. }*/
  108. free(frame);
  109. } /* else {
  110. FURI_LOG_I(TAG, "frame free: frame == NULL");
  111. }*/
  112. }