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.

wifi.c 3.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /*
  2. * wifi.c
  3. *
  4. * https://github.com/raspberrypi/pico-examples/blob/master/adc/read_vsys/power_status.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 "pico/cyw43_arch.h"
  21. #include "lwip/netif.h"
  22. #include "lwip/ip4_addr.h"
  23. #include "config.h"
  24. #include "log.h"
  25. #include "mem.h"
  26. #include "wifi.h"
  27. enum wifi_state {
  28. WS_IDLE = 0,
  29. WS_SCAN,
  30. WS_CONNECT,
  31. WS_READY,
  32. };
  33. static enum wifi_state state = WS_IDLE;
  34. static void wifi_connect(const char *ssid, const char *pw, uint32_t auth) {
  35. debug("connecting to '%s'", ssid);
  36. // https://github.com/raspberrypi/pico-sdk/issues/1413
  37. uint32_t a = 0;
  38. if (auth & 4) {
  39. a = CYW43_AUTH_WPA2_AES_PSK;
  40. } else if (auth & 2) {
  41. a = CYW43_AUTH_WPA_TKIP_PSK;
  42. }
  43. int r = cyw43_arch_wifi_connect_async(ssid, pw, a);
  44. if (r != 0) {
  45. debug("failed to connect %d", r);
  46. } else {
  47. state = WS_CONNECT;
  48. }
  49. }
  50. static int scan_result(void *env, const cyw43_ev_scan_result_t *result) {
  51. (void)env;
  52. cyw43_thread_enter();
  53. if (result && (state == WS_SCAN)) {
  54. for (int i = 0; i < mem_data()->net_count; i++) {
  55. if ((strlen(mem_data()->net[i].name) == result->ssid_len)
  56. && (memcmp(mem_data()->net[i].name, result->ssid, result->ssid_len) == 0)) {
  57. wifi_connect(mem_data()->net[i].name,
  58. mem_data()->net[i].pass,
  59. result->auth_mode);
  60. break;
  61. }
  62. }
  63. }
  64. cyw43_thread_exit();
  65. return 0;
  66. }
  67. static void wifi_scan(void) {
  68. debug("starting scan");
  69. cyw43_wifi_scan_options_t scan_options = {0};
  70. int err = cyw43_wifi_scan(&cyw43_state, &scan_options, NULL, scan_result);
  71. if (err != 0) {
  72. debug("error %d", err);
  73. }
  74. state = WS_SCAN;
  75. }
  76. void wifi_init(void) {
  77. if (state != WS_IDLE) {
  78. debug("invalid state %d", state);
  79. return;
  80. }
  81. cyw43_thread_enter();
  82. cyw43_arch_enable_sta_mode();
  83. wifi_scan();
  84. cyw43_thread_exit();
  85. }
  86. void wifi_deinit(void) {
  87. cyw43_thread_enter();
  88. cyw43_arch_disable_sta_mode();
  89. state = WS_IDLE;
  90. cyw43_thread_exit();
  91. }
  92. bool wifi_initialized(void) {
  93. return (state != WS_IDLE);
  94. }
  95. const char *wifi_state(void) {
  96. switch (state) {
  97. case WS_IDLE:
  98. return "Disabled";
  99. case WS_SCAN:
  100. return "Scanning";
  101. case WS_CONNECT:
  102. return "Connecting";
  103. case WS_READY:
  104. return "Connected";
  105. }
  106. return NULL;
  107. }
  108. void wifi_run(void) {
  109. cyw43_thread_enter();
  110. if (state == WS_SCAN) {
  111. if (!cyw43_wifi_scan_active(&cyw43_state)) {
  112. debug("restarting scan");
  113. wifi_scan();
  114. }
  115. } else if (state == WS_CONNECT) {
  116. if (cyw43_wifi_link_status(&cyw43_state, CYW43_ITF_STA) == CYW43_LINK_JOIN) {
  117. debug("joined network");
  118. state = WS_READY;
  119. }
  120. }
  121. cyw43_thread_exit();
  122. }