bt_cli.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. #include <furi.h>
  2. #include <furi_hal.h>
  3. #include <cli/cli.h>
  4. #include <lib/toolbox/args.h>
  5. #include <ble/ble.h>
  6. #include "bt_settings.h"
  7. #include "bt_service/bt.h"
  8. static void bt_cli_command_hci_info(Cli* cli, FuriString* args, void* context) {
  9. UNUSED(cli);
  10. UNUSED(args);
  11. UNUSED(context);
  12. FuriString* buffer;
  13. buffer = furi_string_alloc();
  14. furi_hal_bt_dump_state(buffer);
  15. printf("%s", furi_string_get_cstr(buffer));
  16. furi_string_free(buffer);
  17. }
  18. static void bt_cli_command_carrier_tx(Cli* cli, FuriString* args, void* context) {
  19. UNUSED(context);
  20. int channel = 0;
  21. int power = 0;
  22. do {
  23. if(!args_read_int_and_trim(args, &channel) && (channel < 0 || channel > 39)) {
  24. printf("Incorrect or missing channel, expected int 0-39");
  25. break;
  26. }
  27. if(!args_read_int_and_trim(args, &power) && (power < 0 || power > 6)) {
  28. printf("Incorrect or missing power, expected int 0-6");
  29. break;
  30. }
  31. Bt* bt = furi_record_open(RECORD_BT);
  32. bt_disconnect(bt);
  33. furi_hal_bt_reinit();
  34. printf("Transmitting carrier at %d channel at %d dB power\r\n", channel, power);
  35. printf("Press CTRL+C to stop\r\n");
  36. furi_hal_bt_start_tone_tx(channel, 0x19 + power);
  37. while(!cli_cmd_interrupt_received(cli)) {
  38. furi_delay_ms(250);
  39. }
  40. furi_hal_bt_stop_tone_tx();
  41. bt_set_profile(bt, BtProfileSerial);
  42. furi_record_close(RECORD_BT);
  43. } while(false);
  44. }
  45. static void bt_cli_command_carrier_rx(Cli* cli, FuriString* args, void* context) {
  46. UNUSED(context);
  47. int channel = 0;
  48. do {
  49. if(!args_read_int_and_trim(args, &channel) && (channel < 0 || channel > 39)) {
  50. printf("Incorrect or missing channel, expected int 0-39");
  51. break;
  52. }
  53. Bt* bt = furi_record_open(RECORD_BT);
  54. bt_disconnect(bt);
  55. furi_hal_bt_reinit();
  56. printf("Receiving carrier at %d channel\r\n", channel);
  57. printf("Press CTRL+C to stop\r\n");
  58. furi_hal_bt_start_packet_rx(channel, 1);
  59. while(!cli_cmd_interrupt_received(cli)) {
  60. furi_delay_ms(250);
  61. printf("RSSI: %6.1f dB\r", (double)furi_hal_bt_get_rssi());
  62. fflush(stdout);
  63. }
  64. furi_hal_bt_stop_packet_test();
  65. bt_set_profile(bt, BtProfileSerial);
  66. furi_record_close(RECORD_BT);
  67. } while(false);
  68. }
  69. static void bt_cli_command_packet_tx(Cli* cli, FuriString* args, void* context) {
  70. UNUSED(context);
  71. int channel = 0;
  72. int pattern = 0;
  73. int datarate = 1;
  74. do {
  75. if(!args_read_int_and_trim(args, &channel) && (channel < 0 || channel > 39)) {
  76. printf("Incorrect or missing channel, expected int 0-39");
  77. break;
  78. }
  79. if(!args_read_int_and_trim(args, &pattern) && (pattern < 0 || pattern > 5)) {
  80. printf("Incorrect or missing pattern, expected int 0-5 \r\n");
  81. printf("0 - Pseudo-Random bit sequence 9\r\n");
  82. printf("1 - Pattern of alternating bits '11110000'\r\n");
  83. printf("2 - Pattern of alternating bits '10101010'\r\n");
  84. printf("3 - Pseudo-Random bit sequence 15\r\n");
  85. printf("4 - Pattern of All '1' bits\r\n");
  86. printf("5 - Pattern of All '0' bits\r\n");
  87. break;
  88. }
  89. if(!args_read_int_and_trim(args, &datarate) && (datarate < 1 || datarate > 2)) {
  90. printf("Incorrect or missing datarate, expected int 1-2");
  91. break;
  92. }
  93. Bt* bt = furi_record_open(RECORD_BT);
  94. bt_disconnect(bt);
  95. furi_hal_bt_reinit();
  96. printf(
  97. "Transmitting %d pattern packet at %d channel at %d M datarate\r\n",
  98. pattern,
  99. channel,
  100. datarate);
  101. printf("Press CTRL+C to stop\r\n");
  102. furi_hal_bt_start_packet_tx(channel, pattern, datarate);
  103. while(!cli_cmd_interrupt_received(cli)) {
  104. furi_delay_ms(250);
  105. }
  106. furi_hal_bt_stop_packet_test();
  107. printf("Transmitted %lu packets", furi_hal_bt_get_transmitted_packets());
  108. bt_set_profile(bt, BtProfileSerial);
  109. furi_record_close(RECORD_BT);
  110. } while(false);
  111. }
  112. static void bt_cli_command_packet_rx(Cli* cli, FuriString* args, void* context) {
  113. UNUSED(context);
  114. int channel = 0;
  115. int datarate = 1;
  116. do {
  117. if(!args_read_int_and_trim(args, &channel) && (channel < 0 || channel > 39)) {
  118. printf("Incorrect or missing channel, expected int 0-39");
  119. break;
  120. }
  121. if(!args_read_int_and_trim(args, &datarate) && (datarate < 1 || datarate > 2)) {
  122. printf("Incorrect or missing datarate, expected int 1-2");
  123. break;
  124. }
  125. Bt* bt = furi_record_open(RECORD_BT);
  126. bt_disconnect(bt);
  127. furi_hal_bt_reinit();
  128. printf("Receiving packets at %d channel at %d M datarate\r\n", channel, datarate);
  129. printf("Press CTRL+C to stop\r\n");
  130. furi_hal_bt_start_packet_rx(channel, datarate);
  131. while(!cli_cmd_interrupt_received(cli)) {
  132. furi_delay_ms(250);
  133. printf("RSSI: %03.1f dB\r", (double)furi_hal_bt_get_rssi());
  134. fflush(stdout);
  135. }
  136. uint16_t packets_received = furi_hal_bt_stop_packet_test();
  137. printf("Received %hu packets", packets_received);
  138. bt_set_profile(bt, BtProfileSerial);
  139. furi_record_close(RECORD_BT);
  140. } while(false);
  141. }
  142. static void bt_cli_print_usage() {
  143. printf("Usage:\r\n");
  144. printf("bt <cmd> <args>\r\n");
  145. printf("Cmd list:\r\n");
  146. printf("\thci_info\t - HCI info\r\n");
  147. if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug) && furi_hal_bt_is_testing_supported()) {
  148. printf("\ttx_carrier <channel:0-39> <power:0-6>\t - start tx carrier test\r\n");
  149. printf("\trx_carrier <channel:0-39>\t - start rx carrier test\r\n");
  150. printf(
  151. "\ttx_packet <channel:0-39> <pattern:0-5> <datarate:1-2>\t - start tx packet test\r\n");
  152. printf("\trx_packet <channel:0-39> <datarate:1-2>\t - start rx packer test\r\n");
  153. }
  154. }
  155. static void bt_cli(Cli* cli, FuriString* args, void* context) {
  156. UNUSED(context);
  157. furi_record_open(RECORD_BT);
  158. FuriString* cmd;
  159. cmd = furi_string_alloc();
  160. BtSettings bt_settings;
  161. bt_settings_load(&bt_settings);
  162. do {
  163. if(!args_read_string_and_trim(args, cmd)) {
  164. bt_cli_print_usage();
  165. break;
  166. }
  167. if(furi_string_cmp_str(cmd, "hci_info") == 0) {
  168. bt_cli_command_hci_info(cli, args, NULL);
  169. break;
  170. }
  171. if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug) && furi_hal_bt_is_testing_supported()) {
  172. if(furi_string_cmp_str(cmd, "tx_carrier") == 0) {
  173. bt_cli_command_carrier_tx(cli, args, NULL);
  174. break;
  175. }
  176. if(furi_string_cmp_str(cmd, "rx_carrier") == 0) {
  177. bt_cli_command_carrier_rx(cli, args, NULL);
  178. break;
  179. }
  180. if(furi_string_cmp_str(cmd, "tx_packet") == 0) {
  181. bt_cli_command_packet_tx(cli, args, NULL);
  182. break;
  183. }
  184. if(furi_string_cmp_str(cmd, "rx_packet") == 0) {
  185. bt_cli_command_packet_rx(cli, args, NULL);
  186. break;
  187. }
  188. }
  189. bt_cli_print_usage();
  190. } while(false);
  191. if(bt_settings.enabled) {
  192. furi_hal_bt_start_advertising();
  193. }
  194. furi_string_free(cmd);
  195. furi_record_close(RECORD_BT);
  196. }
  197. void bt_on_system_start() {
  198. #ifdef SRV_CLI
  199. Cli* cli = furi_record_open(RECORD_CLI);
  200. cli_add_command(cli, RECORD_BT, CliCommandFlagDefault, bt_cli, NULL);
  201. furi_record_close(RECORD_CLI);
  202. #else
  203. UNUSED(bt_cli);
  204. #endif
  205. }