wifi_ap.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /*
  2. * Copyright 2016 Dius Computing Pty Ltd. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * - Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * - Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the
  13. * distribution.
  14. * - Neither the name of the copyright holders nor the names of
  15. * its contributors may be used to endorse or promote products derived
  16. * from this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  21. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
  22. * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  23. * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  24. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  25. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  26. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  27. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  28. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  29. * OF THE POSSIBILITY OF SUCH DAMAGE.
  30. *
  31. * @author Johny Mattsson <jmattsson@dius.com.au>
  32. */
  33. #include "module.h"
  34. #include "lauxlib.h"
  35. #include "lextra.h"
  36. #include "wifi_common.h"
  37. #include "ip_fmt.h"
  38. #include "nodemcu_esp_event.h"
  39. #include <string.h>
  40. // Note: these are documented in wifi.md, update there too if changed here!
  41. #define DEFAULT_AP_CHANNEL 11
  42. #define DEFAULT_AP_MAXCONNS 4
  43. #define DEFAULT_AP_BEACON 100
  44. // --- Event handling ----------------------------------------------------
  45. static void ap_staconn (lua_State *L, const system_event_t *evt);
  46. static void ap_stadisconn (lua_State *L, const system_event_t *evt);
  47. static void ap_probe_req (lua_State *L, const system_event_t *evt);
  48. static void empty_arg (lua_State *L, const system_event_t *evt) {}
  49. static const event_desc_t events[] =
  50. {
  51. { "start", SYSTEM_EVENT_AP_START, empty_arg },
  52. { "stop", SYSTEM_EVENT_AP_STOP, empty_arg },
  53. { "sta_connected", SYSTEM_EVENT_AP_STACONNECTED, ap_staconn },
  54. { "sta_disconnected", SYSTEM_EVENT_AP_STADISCONNECTED, ap_stadisconn },
  55. { "probe_req", SYSTEM_EVENT_AP_PROBEREQRECVED, ap_probe_req }
  56. };
  57. static int event_cb[ARRAY_LEN(events)];
  58. static void ap_staconn (lua_State *L, const system_event_t *evt)
  59. {
  60. char mac[MAC_STR_SZ];
  61. macstr (mac, evt->event_info.sta_connected.mac);
  62. lua_pushstring (L, mac);
  63. lua_setfield (L, -2, "mac");
  64. lua_pushinteger (L, evt->event_info.sta_connected.aid);
  65. lua_setfield (L, -2, "id");
  66. }
  67. static void ap_stadisconn (lua_State *L, const system_event_t *evt)
  68. {
  69. char mac[MAC_STR_SZ];
  70. macstr (mac, evt->event_info.sta_disconnected.mac);
  71. lua_pushstring (L, mac);
  72. lua_setfield (L, -2, "mac");
  73. lua_pushinteger (L, evt->event_info.sta_disconnected.aid);
  74. lua_setfield (L, -2, "id");
  75. }
  76. static void ap_probe_req (lua_State *L, const system_event_t *evt)
  77. {
  78. char str[MAC_STR_SZ];
  79. macstr (str, evt->event_info.ap_probereqrecved.mac);
  80. lua_pushstring (L, str);
  81. lua_setfield (L, -2, "from");
  82. lua_pushinteger (L, evt->event_info.ap_probereqrecved.rssi);
  83. lua_setfield (L, -2, "rssi");
  84. }
  85. static void on_event (const system_event_t *evt)
  86. {
  87. int idx = wifi_event_idx_by_id (events, ARRAY_LEN(events), evt->event_id);
  88. if (idx < 0 || event_cb[idx] == LUA_NOREF)
  89. return;
  90. lua_State *L = lua_getstate ();
  91. lua_rawgeti (L, LUA_REGISTRYINDEX, event_cb[idx]);
  92. lua_pushstring (L, events[idx].name);
  93. lua_createtable (L, 0, 5);
  94. events[idx].fill_cb_arg (L, evt);
  95. lua_call (L, 2, 0);
  96. }
  97. NODEMCU_ESP_EVENT(SYSTEM_EVENT_AP_START, on_event);
  98. NODEMCU_ESP_EVENT(SYSTEM_EVENT_AP_STOP, on_event);
  99. NODEMCU_ESP_EVENT(SYSTEM_EVENT_AP_STACONNECTED, on_event);
  100. NODEMCU_ESP_EVENT(SYSTEM_EVENT_AP_STADISCONNECTED, on_event);
  101. NODEMCU_ESP_EVENT(SYSTEM_EVENT_AP_PROBEREQRECVED, on_event);
  102. void wifi_ap_init (void)
  103. {
  104. for (unsigned i = 0; i < ARRAY_LEN(event_cb); ++i)
  105. event_cb[i] = LUA_NOREF;
  106. }
  107. // --- Lua API funcs -----------------------------------------------------
  108. static int wifi_ap_config (lua_State *L)
  109. {
  110. luaL_checkanytable (L, 1);
  111. bool save = luaL_optbool (L, 2, DEFAULT_SAVE);
  112. wifi_config_t cfg;
  113. memset (&cfg, 0, sizeof (cfg));
  114. lua_getfield (L, 1, "ssid");
  115. size_t len;
  116. const char *str = luaL_checklstring (L, -1, &len);
  117. if (len > sizeof (cfg.ap.ssid))
  118. len = sizeof (cfg.ap.ssid);
  119. strncpy ((char *)cfg.ap.ssid, str, len);
  120. cfg.ap.ssid_len = len;
  121. lua_getfield (L, 1, "pwd");
  122. str = luaL_optlstring (L, -1, "", &len);
  123. if (len > sizeof (cfg.ap.password))
  124. len = sizeof (cfg.ap.password);
  125. strncpy ((char *)cfg.ap.password, str, len);
  126. lua_getfield (L, 1, "auth");
  127. int authmode = luaL_optint (L, -1, WIFI_AUTH_WPA2_PSK);
  128. if (authmode < 0 || authmode >= WIFI_AUTH_MAX)
  129. return luaL_error (L, "unknown auth mode %d", authmode);
  130. cfg.ap.authmode = authmode;
  131. lua_getfield (L, 1, "channel");
  132. cfg.ap.channel = luaL_optint (L, -1, DEFAULT_AP_CHANNEL);
  133. lua_getfield (L, 1, "hidden");
  134. cfg.ap.ssid_hidden = luaL_optbool (L, -1, false);
  135. lua_getfield (L, 1, "max");
  136. cfg.ap.max_connection = luaL_optint (L, -1, DEFAULT_AP_MAXCONNS);
  137. lua_getfield (L, 1, "beacon");
  138. cfg.ap.beacon_interval = luaL_optint (L, -1, DEFAULT_AP_BEACON);
  139. SET_SAVE_MODE(save);
  140. esp_err_t err = esp_wifi_set_config (WIFI_IF_AP, &cfg);
  141. return (err == ESP_OK) ?
  142. 0 : luaL_error (L, "failed to set wifi config, code %d", err);
  143. }
  144. static int wifi_ap_getmac (lua_State *L)
  145. {
  146. return wifi_getmac(WIFI_IF_AP, L);
  147. }
  148. static int wifi_ap_on (lua_State *L)
  149. {
  150. return wifi_on (L, events, ARRAY_LEN(events), event_cb);
  151. }
  152. const LUA_REG_TYPE wifi_ap_map[] =
  153. {
  154. { LSTRKEY( "config" ), LFUNCVAL( wifi_ap_config ) },
  155. { LSTRKEY( "on" ), LFUNCVAL( wifi_ap_on ) },
  156. { LSTRKEY( "getmac" ), LFUNCVAL( wifi_ap_getmac ) },
  157. { LNILKEY, LNILVAL }
  158. };