_WiFi.ino 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. // 1-channel LoRa Gateway for ESP8266
  2. // Copyright (c) 2016, 2017, 2018, 2019 Maarten Westenberg version for ESP8266
  3. // Version 6.1.0
  4. // Date: 2019-10-20
  5. //
  6. // based on work done by Thomas Telkamp for Raspberry PI 1ch gateway
  7. // and many others.
  8. //
  9. // All rights reserved. This program and the accompanying materials
  10. // are made available under the terms of the MIT License
  11. // which accompanies this distribution, and is available at
  12. // https://opensource.org/licenses/mit-license.php
  13. //
  14. // NO WARRANTY OF ANY KIND IS PROVIDED
  15. //
  16. // Author: Maarten Westenberg (mw12554@hotmail.com)
  17. //
  18. // This file contains the LoRa filesystem specific code
  19. // ----------------------------------------------------------------------------
  20. // WLANSTATUS prints the status of the Wlan.
  21. // The status of the Wlan "connection" can change if we have no relation
  22. // with the well known router anymore. Normally this relation is preserved
  23. // but sometimes we have to reconfirm to the router again and we get the same
  24. // address too.
  25. // So, if the router is still in range we can "survive" with the same address
  26. // and we may have to renew the "connection" from time to time.
  27. // But when we loose the SSID connection, we may have to look for another router.
  28. //
  29. // Parameters: <none>
  30. // Return value: Returns 1 when still WL_CONNETED, otherwise returns 0
  31. // ----------------------------------------------------------------------------
  32. int WlanStatus() {
  33. switch (WiFi.status()) {
  34. case WL_CONNECTED:
  35. #if DUSB>=1
  36. if ( debug>=0 ) {
  37. Serial.print(F("A WlanStatus:: CONNECTED to ")); // 3
  38. Serial.println(WiFi.SSID());
  39. }
  40. #endif
  41. WiFi.setAutoReconnect(true); // Reconenct to this AP if DISCONNECTED
  42. return(1);
  43. break;
  44. // In case we get disconnected from the AP we loose the IP address.
  45. // The ESP is configured to reconnect to the last router in memory.
  46. case WL_DISCONNECTED:
  47. #if DUSB>=1
  48. if ( debug>=0 ) {
  49. Serial.print(F("A WlanStatus:: DISCONNECTED, IP=")); // 6
  50. Serial.println(WiFi.localIP());
  51. }
  52. #endif
  53. //while (! WiFi.isConnected() ) {
  54. // Wait
  55. delay(1);
  56. //}
  57. return(0);
  58. break;
  59. // When still pocessing
  60. case WL_IDLE_STATUS:
  61. #if DUSB>=1
  62. if ( debug>=0 ) {
  63. Serial.println(F("A WlanStatus:: IDLE")); // 0
  64. }
  65. #endif
  66. break;
  67. // This code is generated as soonas the AP is out of range
  68. // Whene detected, the program will search for a better AP in range
  69. case WL_NO_SSID_AVAIL:
  70. #if DUSB>=1
  71. if ( debug>=0 )
  72. Serial.println(F("WlanStatus:: NO SSID")); // 1
  73. #endif
  74. break;
  75. case WL_CONNECT_FAILED:
  76. #if DUSB>=1
  77. if ( debug>=0 )
  78. Serial.println(F("A WlanStatus:: FAILED")); // 4
  79. #endif
  80. break;
  81. // Never seen this code
  82. case WL_SCAN_COMPLETED:
  83. #if DUSB>=1
  84. if ( debug>=0 )
  85. Serial.println(F("A WlanStatus:: SCAN COMPLETE")); // 2
  86. #endif
  87. break;
  88. // Never seen this code
  89. case WL_CONNECTION_LOST:
  90. #if DUSB>=1
  91. if ( debug>=0 )
  92. Serial.println(F("A WlanStatus:: LOST")); // 5
  93. #endif
  94. break;
  95. // This code is generated for example when WiFi.begin() has not been called
  96. // before accessing WiFi functions
  97. case WL_NO_SHIELD:
  98. #if DUSB>=1
  99. if ( debug>=0 )
  100. Serial.println(F("A WlanStatus:: WL_NO_SHIELD")); //
  101. #endif
  102. break;
  103. default:
  104. #if DUSB>=1
  105. if ( debug>=0 ) {
  106. Serial.print(F("A WlanStatus Error:: code="));
  107. Serial.println(WiFi.status()); // 255 means ERROR
  108. }
  109. #endif
  110. break;
  111. }
  112. return(-1);
  113. } // WlanStatus
  114. // ----------------------------------------------------------------------------
  115. // config.txt is a text file that contains lines(!) with WPA configuration items
  116. // Each line contains an KEY vaue pair describing the gateway configuration
  117. //
  118. // ----------------------------------------------------------------------------
  119. int WlanReadWpa() {
  120. readConfig( CONFIGFILE, &gwayConfig);
  121. if (gwayConfig.sf != (uint8_t) 0) sf = (sf_t) gwayConfig.sf;
  122. ifreq = gwayConfig.ch;
  123. debug = gwayConfig.debug;
  124. pdebug = gwayConfig.pdebug;
  125. _cad = gwayConfig.cad;
  126. _hop = gwayConfig.hop;
  127. gwayConfig.boots++; // Every boot of the system we increase the reset
  128. #if GATEWAYNODE==1
  129. if (gwayConfig.fcnt != (uint8_t) 0) frameCount = gwayConfig.fcnt+10;
  130. #endif
  131. #if WIFIMANAGER==1
  132. String ssid=gwayConfig.ssid;
  133. String pass=gwayConfig.pass;
  134. char ssidBuf[ssid.length()+1];
  135. ssid.toCharArray(ssidBuf,ssid.length()+1);
  136. char passBuf[pass.length()+1];
  137. pass.toCharArray(passBuf,pass.length()+1);
  138. Serial.print(F("WlanReadWpa: ")); Serial.print(ssidBuf); Serial.print(F(", ")); Serial.println(passBuf);
  139. strcpy(wpa[0].login, ssidBuf); // XXX changed from wpa[0][0] = ssidBuf
  140. strcpy(wpa[0].passw, passBuf);
  141. Serial.print(F("WlanReadWpa: <"));
  142. Serial.print(wpa[0].login); // XXX
  143. Serial.print(F(">, <"));
  144. Serial.print(wpa[0].passw);
  145. Serial.println(F(">"));
  146. #endif
  147. }
  148. // ----------------------------------------------------------------------------
  149. // Print the WPA data of last WiFiManager to the config file
  150. // ----------------------------------------------------------------------------
  151. #if WIFIMANAGER==1
  152. int WlanWriteWpa( char* ssid, char *pass) {
  153. #if DUSB>=1
  154. if (( debug >=0 ) && ( pdebug & P_MAIN )) {
  155. Serial.print(F("M WlanWriteWpa:: ssid="));
  156. Serial.print(ssid);
  157. Serial.print(F(", pass="));
  158. Serial.print(pass);
  159. Serial.println();
  160. }
  161. #endif
  162. // Version 3.3 use of config file
  163. String s((char *) ssid);
  164. gwayConfig.ssid = s;
  165. String p((char *) pass);
  166. gwayConfig.pass = p;
  167. #if GATEWAYNODE==1
  168. gwayConfig.fcnt = frameCount;
  169. #endif
  170. gwayConfig.ch = ifreq;
  171. gwayConfig.sf = sf;
  172. gwayConfig.cad = _cad;
  173. gwayConfig.hop = _hop;
  174. writeConfig( CONFIGFILE, &gwayConfig);
  175. return 1;
  176. }
  177. #endif
  178. // ----------------------------------------------------------------------------
  179. // Function to join the Wifi Network
  180. // It is a matter of returning to the main loop() asap and make sure in next loop
  181. // the reconnect is done first thing. By default the system will reconnect to the
  182. // samen SSID as it was connected to before.
  183. // Parameters:
  184. // int maxTry: Number of retries we do:
  185. // 0: Used during Setup first CONNECT
  186. // 1: Try once and if unsuccessful return(1);
  187. // x: Try x times
  188. //
  189. // Returns:
  190. // On failure: Return -1
  191. // On connect: return 1
  192. // On Disconnect state: return 0
  193. //
  194. // XXX After a few retries, the ESP8266 should be reset. Note: Switching between
  195. // two SSID's does the trick. Rettrying the same SSID does not.
  196. // Workaround is found below: Let the ESP8266 forget the SSID
  197. //
  198. // NOTE: The Serial works only on debug setting and not on pdebug. This is
  199. // because WiFi problems would make webserver (which works on WiFi) useless.
  200. // ----------------------------------------------------------------------------
  201. int WlanConnect(int maxTry) {
  202. #if WIFIMANAGER==1
  203. WiFiManager wifiManager;
  204. #endif
  205. unsigned char agains = 0;
  206. unsigned char wpa_index = (WIFIMANAGER >0 ? 0 : 1); // Skip over first record for WiFiManager
  207. // The initial setup() call is done with parameter 0
  208. // We clear the WiFi memory and start with previous AP.
  209. //
  210. if (maxTry==0) {
  211. Serial.println(F("WlanConnect:: Init para 0"));
  212. WiFi.persistent(false);
  213. WiFi.mode(WIFI_OFF); // this is a temporary line, to be removed after SDK update to 1.5.4
  214. if (gwayConfig.ssid.length() >0) {
  215. WiFi.begin(gwayConfig.ssid.c_str(), gwayConfig.pass.c_str());
  216. delay(100);
  217. }
  218. }
  219. // So try to connect to WLAN as long as we are not connected.
  220. // The try parameters tells us how many times we try before giving up
  221. // Value 0 is reserved for setup() first time connect
  222. int i=0;
  223. while ( (WiFi.status() != WL_CONNECTED) && ( i<= maxTry ) )
  224. {
  225. // We try every SSID in wpa array until success
  226. for (int j=wpa_index; (j< (sizeof(wpa)/sizeof(wpa[0]))) && (WiFi.status() != WL_CONNECTED ); j++)
  227. {
  228. // Start with well-known access points in the list
  229. char *ssid = wpa[j].login;
  230. char *password = wpa[j].passw;
  231. #if DUSB>=1
  232. if (debug>=0) {
  233. Serial.print(i);
  234. Serial.print(':');
  235. Serial.print(j);
  236. Serial.print(':');
  237. Serial.print(sizeof(wpa)/sizeof(wpa[0]));
  238. Serial.print(F(". WiFi connect SSID="));
  239. Serial.print(ssid);
  240. if ( debug>=1 ) {
  241. Serial.print(F(", pass="));
  242. Serial.print(password);
  243. }
  244. Serial.println();
  245. }
  246. #endif
  247. // Count the number of times we call WiFi.begin
  248. gwayConfig.wifis++;
  249. WiFi.mode(WIFI_STA);
  250. delay(1000);
  251. WiFi.begin(ssid, password);
  252. delay(8000);
  253. // Check the connection status again, return values
  254. // 1 = CONNECTED
  255. // 0 = DISCONNECTED (will reconnect)
  256. // -1 = No SSID or other cause
  257. int stat = WlanStatus();
  258. if ( stat == 1) {
  259. writeGwayCfg(CONFIGFILE); // XXX Write configuration to SPIFFS
  260. return(1);
  261. }
  262. // We increase the time for connect but try the same SSID
  263. // We try for 10 times
  264. agains=1;
  265. while (((WiFi.status()) != WL_CONNECTED) && (agains < 10)) {
  266. agains++;
  267. delay(agains*500);
  268. #if DUSB>=1
  269. if ( debug>=0 ) {
  270. Serial.print(".");
  271. }
  272. #endif
  273. }
  274. #if DUSB>=1
  275. Serial.println();
  276. #endif
  277. //if ( WiFi.status() == WL_DISCONNECTED) return(0); // XXX 180811 removed
  278. // Make sure that we can connect to different AP's than 1
  279. // this is a patch. Normally we connect to previous one.
  280. WiFi.persistent(false);
  281. WiFi.mode(WIFI_OFF); // this is a temporary line, to be removed after SDK update to 1.5.4
  282. } //for next WPA defined AP
  283. i++; // Number of times we try to connect
  284. } //while
  285. // If we are not connected to a well known AP
  286. // we can invoike WIFIMANAGER or else return unsuccessful.
  287. if (WiFi.status() != WL_CONNECTED) {
  288. #if WIFIMANAGER==1
  289. #if DUSB>=1
  290. Serial.println(F("Starting Access Point Mode"));
  291. Serial.print(F("Connect Wifi to accesspoint: "));
  292. Serial.print(AP_NAME);
  293. Serial.print(F(" and connect to IP: 192.168.4.1"));
  294. Serial.println();
  295. #endif
  296. wifiManager.autoConnect(AP_NAME, AP_PASSWD );
  297. //wifiManager.startConfigPortal(AP_NAME, AP_PASSWD );
  298. // At this point, there IS a Wifi Access Point found and connected
  299. // We must connect to the local SPIFFS storage to store the access point
  300. //String s = WiFi.SSID();
  301. //char ssidBuf[s.length()+1];
  302. //s.toCharArray(ssidBuf,s.length()+1);
  303. // Now look for the password
  304. struct station_config sta_conf;
  305. wifi_station_get_config(&sta_conf);
  306. //WlanWriteWpa(ssidBuf, (char *)sta_conf.password);
  307. WlanWriteWpa((char *)sta_conf.ssid, (char *)sta_conf.password);
  308. #else
  309. #if DUSB>=1
  310. if (debug>=0) {
  311. Serial.println(F("WlanConnect:: Not connected after all"));
  312. Serial.print(F("WLAN retry="));
  313. Serial.print(i);
  314. Serial.print(F(" , stat="));
  315. Serial.print(WiFi.status() ); // Status. 3 is WL_CONNECTED
  316. Serial.println();
  317. }
  318. #endif// DUSB
  319. return(-1);
  320. #endif
  321. }
  322. yield();
  323. return(1);
  324. }