loragw_debug.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /*
  2. / _____) _ | |
  3. ( (____ _____ ____ _| |_ _____ ____| |__
  4. \____ \| ___ | (_ _) ___ |/ ___) _ \
  5. _____) ) ____| | | || |_| ____( (___| | | |
  6. (______/|_____)_|_|_| \__)_____)\____)_| |_|
  7. (C)2019 Semtech
  8. Description:
  9. LoRa concentrator debug functions
  10. License: Revised BSD License, see LICENSE.TXT file include in the project
  11. */
  12. /* -------------------------------------------------------------------------- */
  13. /* --- DEPENDANCIES --------------------------------------------------------- */
  14. #include <stdint.h> /* C99 types */
  15. #include <stdbool.h> /* bool type */
  16. #include <stdio.h> /* printf fprintf */
  17. #include <string.h> /* memcmp */
  18. #include <time.h>
  19. #include "loragw_aux.h"
  20. #include "loragw_reg.h"
  21. #include "loragw_hal.h"
  22. #include "loragw_debug.h"
  23. #include "tinymt32.h"
  24. /* -------------------------------------------------------------------------- */
  25. /* --- DEBUG CONSTANTS ------------------------------------------------------ */
  26. /* -------------------------------------------------------------------------- */
  27. /* --- PRIVATE MACROS ------------------------------------------------------- */
  28. /* -------------------------------------------------------------------------- */
  29. /* --- PRIVATE CONSTANTS & TYPES -------------------------------------------- */
  30. /* -------------------------------------------------------------------------- */
  31. /* --- PRIVATE VARIABLES ---------------------------------------------------- */
  32. static tinymt32_t tinymt;
  33. /* -------------------------------------------------------------------------- */
  34. /* --- PRIVATE FUNCTIONS DECLARATION ---------------------------------------- */
  35. /* -------------------------------------------------------------------------- */
  36. /* --- PRIVATE FUNCTIONS DEFINITION ----------------------------------------- */
  37. /* -------------------------------------------------------------------------- */
  38. /* --- PUBLIC FUNCTIONS DEFINITION ------------------------------------------ */
  39. void dbg_init_random(void) {
  40. tinymt.mat1 = 0x8f7011ee;
  41. tinymt.mat2 = 0xfc78ff1f;
  42. tinymt.tmat = 0x3793fdff;
  43. }
  44. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  45. void dbg_log_buffer_to_file(FILE * file, uint8_t * buffer, uint16_t size) {
  46. int i;
  47. char stat_timestamp[24];
  48. time_t t;
  49. t = time(NULL);
  50. strftime(stat_timestamp, sizeof stat_timestamp, "%F %T %Z", gmtime(&t));
  51. fprintf(file, "---------(%s)------------\n", stat_timestamp);
  52. for (i = 0; i < size; i++) {
  53. fprintf(file, "%02X ", buffer[i]);
  54. }
  55. fprintf(file, "\n");
  56. fflush(file);
  57. }
  58. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  59. void dbg_log_payload_diff_to_file(FILE * file, uint8_t * buffer1, uint8_t * buffer2, uint16_t size) {
  60. int i, j;
  61. uint16_t nb_bits_diff = 0;
  62. uint8_t debug_payload_diff[255];
  63. fprintf(file, "Diff: ");
  64. /* bit comparison of payloads */
  65. for (j = 0; j < size; j++) {
  66. debug_payload_diff[j] = buffer1[j] ^ buffer2[j];
  67. fprintf(file, "%02X ", debug_payload_diff[j]);
  68. }
  69. fprintf(file, "\n");
  70. /* count number of bits flipped, and display bit by bit */
  71. for (j = 0; j < size; j++) {
  72. for (i = 7; i >= 0; i--) {
  73. fprintf(file, "%u", TAKE_N_BITS_FROM(debug_payload_diff[j], i, 1));
  74. if (TAKE_N_BITS_FROM(debug_payload_diff[j], i, 1) == 1) {
  75. nb_bits_diff += 1;
  76. }
  77. }
  78. fprintf(file, " ");
  79. }
  80. fprintf(file, "\n");
  81. fprintf(file, "%u bits flipped\n", nb_bits_diff);
  82. fflush(file);
  83. }
  84. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  85. void dbg_generate_random_payload(uint32_t pkt_cnt, uint8_t * buffer_expected, uint8_t size) {
  86. int k;
  87. /* construct payload we should get for this packet counter */
  88. tinymt32_init(&tinymt, (int)pkt_cnt);
  89. buffer_expected[4] = (uint8_t)(pkt_cnt >> 24);
  90. buffer_expected[5] = (uint8_t)(pkt_cnt >> 16);
  91. buffer_expected[6] = (uint8_t)(pkt_cnt >> 8);
  92. buffer_expected[7] = (uint8_t)(pkt_cnt >> 0);
  93. tinymt32_generate_uint32(&tinymt); /* dummy: for sync with random size generation */
  94. for (k = 8; k < (int)size; k++) {
  95. buffer_expected[k] = (uint8_t)tinymt32_generate_uint32(&tinymt);
  96. }
  97. }
  98. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  99. int dbg_check_payload(struct lgw_conf_debug_s * context, FILE * file, uint8_t * payload_received, uint8_t size, uint8_t ref_payload_idx, uint8_t sf) {
  100. int k;
  101. uint32_t debug_payload_cnt;
  102. /* If the 4 first bytes of received payload match with the expected ones, go on with comparison */
  103. if (memcmp((void*)payload_received, (void*)(context->ref_payload[ref_payload_idx].payload), 4) == 0) {
  104. /* get counter to initialize random seed */
  105. debug_payload_cnt = (unsigned int)(payload_received[4] << 24) | (unsigned int)(payload_received[5] << 16) | (unsigned int)(payload_received[6] << 8) | (unsigned int)(payload_received[7] << 0);
  106. /* check if we missed some packets */
  107. if (debug_payload_cnt > (context->ref_payload[ref_payload_idx].prev_cnt + 1)) {
  108. printf("ERROR: 0x%08X missed %u pkt before %u (SF%u, size:%u)\n", context->ref_payload[ref_payload_idx].id, debug_payload_cnt - context->ref_payload[ref_payload_idx].prev_cnt - 1, debug_payload_cnt, sf, size);
  109. if (file != NULL) {
  110. fprintf(file, "ERROR: 0x%08X missed %u pkt before %u (SF%u, size:%u)\n", context->ref_payload[ref_payload_idx].id, debug_payload_cnt - context->ref_payload[ref_payload_idx].prev_cnt - 1, debug_payload_cnt, sf, size);
  111. fflush(file);
  112. }
  113. } else if (debug_payload_cnt < context->ref_payload[ref_payload_idx].prev_cnt) {
  114. if (file != NULL) {
  115. fprintf(file, "INFO: 0x%08X got missing pkt %u (SF%u, size:%u) ?\n", context->ref_payload[ref_payload_idx].id, debug_payload_cnt, sf, size);
  116. fflush(file);
  117. }
  118. } else {
  119. #if 0
  120. if (file != NULL) {
  121. fprintf(file, "0x%08X %u (SF%u, size:%u)\n", context.ref_payload[ref_payload_idx].id, debug_payload_cnt, sf, size);
  122. }
  123. #endif
  124. }
  125. context->ref_payload[ref_payload_idx].prev_cnt = debug_payload_cnt;
  126. /* generate the random payload which is expected for this packet count */
  127. dbg_generate_random_payload(debug_payload_cnt, context->ref_payload[ref_payload_idx].payload, size);
  128. /* compare expected with received */
  129. if (memcmp((void *)payload_received, (void *)(context->ref_payload[ref_payload_idx].payload), size) != 0) {
  130. if (file != NULL) {
  131. fprintf(file, "RECEIVED:");
  132. for (k = 0; k < (int)size; k++) {
  133. fprintf(file, "%02X ", payload_received[k]);
  134. }
  135. fprintf(file, "\n");
  136. fprintf(file, "EXPECTED:");
  137. for (k = 0; k < (int)size; k++) {
  138. fprintf(file, "%02X ", context->ref_payload[ref_payload_idx].payload[k]);
  139. }
  140. fprintf(file, "\n");
  141. }
  142. return -1;
  143. } else {
  144. return 1; /* matches */
  145. }
  146. }
  147. return 0; /* ignored */
  148. }