S&B Volcano vaporizer remote control with Pi Pico W
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /*
  2. * ble.c
  3. *
  4. * https://github.com/raspberrypi/pico-examples/blob/master/pico_w/bt/standalone/client.c
  5. *
  6. * Copyright (c) 2023 Thomas Buck (thomas@xythobuz.de)
  7. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * See <http://www.gnu.org/licenses/>.
  19. */
  20. #include "btstack.h"
  21. #include "pico/cyw43_arch.h"
  22. #include "config.h"
  23. #include "log.h"
  24. #include "ble.h"
  25. enum ble_state {
  26. TC_OFF = 0,
  27. TC_IDLE,
  28. TC_W4_SCAN_RESULT,
  29. TC_W4_CONNECT,
  30. TC_W4_SERVICE_RESULT,
  31. TC_W4_CHARACTERISTIC_RESULT,
  32. TC_W4_ENABLE_NOTIFICATIONS_COMPLETE,
  33. TC_W4_READY
  34. };
  35. static btstack_packet_callback_registration_t hci_event_callback_registration;
  36. static enum ble_state state = TC_OFF;
  37. static bd_addr_t server_addr;
  38. static bd_addr_type_t server_addr_type;
  39. static void hci_event_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) {
  40. UNUSED(size);
  41. UNUSED(channel);
  42. if (packet_type != HCI_EVENT_PACKET) {
  43. debug("unexpected packet 0x%02X", packet_type);
  44. return;
  45. }
  46. switch (hci_event_packet_get_type(packet)) {
  47. case BTSTACK_EVENT_STATE:
  48. if (btstack_event_state_get_state(packet) == HCI_STATE_WORKING) {
  49. bd_addr_t local_addr;
  50. gap_local_bd_addr(local_addr);
  51. debug("BTstack up with %s", bd_addr_to_str(local_addr));
  52. state = TC_IDLE;
  53. } else {
  54. debug("BTstack down (%d)", btstack_event_state_get_state(packet));
  55. state = TC_OFF;
  56. }
  57. break;
  58. case HCI_EVENT_COMMAND_COMPLETE:
  59. case HCI_EVENT_TRANSPORT_PACKET_SENT:
  60. break;
  61. case GAP_EVENT_ADVERTISING_REPORT:
  62. if (state != TC_W4_SCAN_RESULT) {
  63. debug("scan result in invalid state %d", state);
  64. return;
  65. }
  66. gap_event_advertising_report_get_address(packet, server_addr);
  67. server_addr_type = gap_event_advertising_report_get_address_type(packet);
  68. debug("Found device with addr %s", bd_addr_to_str(server_addr));
  69. break;
  70. case HCI_EVENT_LE_META:
  71. switch (hci_event_le_meta_get_subevent_code(packet)) {
  72. case HCI_SUBEVENT_LE_ADVERTISING_REPORT:
  73. break;
  74. case HCI_SUBEVENT_LE_CONNECTION_COMPLETE:
  75. debug("connection complete?!");
  76. break;
  77. default:
  78. debug("unexpected LE meta event 0x%02X", hci_event_le_meta_get_subevent_code(packet));
  79. break;
  80. }
  81. break;
  82. default:
  83. debug("unexpected event 0x%02X", hci_event_packet_get_type(packet));
  84. break;
  85. }
  86. }
  87. void ble_init(void) {
  88. l2cap_init();
  89. sm_init();
  90. sm_set_io_capabilities(IO_CAPABILITY_NO_INPUT_NO_OUTPUT);
  91. gatt_client_init();
  92. hci_event_callback_registration.callback = &hci_event_handler;
  93. hci_add_event_handler(&hci_event_callback_registration);
  94. hci_power_control(HCI_POWER_ON);
  95. }
  96. void ble_scan(enum ble_scan_mode mode) {
  97. switch (mode) {
  98. case BLE_SCAN_OFF:
  99. debug("stopping BLE scan");
  100. state = TC_IDLE;
  101. gap_stop_scan();
  102. break;
  103. case BLE_SCAN_ON:
  104. debug("starting BLE scan");
  105. state = TC_W4_SCAN_RESULT;
  106. gap_set_scan_parameters(0,0x0030, 0x0030);
  107. gap_start_scan();
  108. break;
  109. case BLE_SCAN_TOGGLE:
  110. switch (state) {
  111. case TC_W4_SCAN_RESULT:
  112. ble_scan(0);
  113. break;
  114. case TC_IDLE:
  115. ble_scan(1);
  116. break;
  117. default:
  118. debug("invalid state %d", state);
  119. break;
  120. }
  121. break;
  122. default:
  123. debug("invalid mode %d", mode);
  124. break;
  125. }
  126. }