1
+ /*
2
+ ESP8266WiFiMesh.cpp - Mesh network node
3
+ Sets up a Mesh Node which acts as a router, creating a Mesh Network with other nodes. All information
4
+ is passed in both directions, but it is up to the user what the data sent is and how it is dealt with.
5
+
6
+ Copyright (c) 2015 Julian Fell. All rights reserved.
7
+
8
+ This library is free software; you can redistribute it and/or
9
+ modify it under the terms of the GNU Lesser General Public
10
+ License as published by the Free Software Foundation; either
11
+ version 2.1 of the License, or (at your option) any later version.
12
+ This library is distributed in the hope that it will be useful,
13
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
+ Lesser General Public License for more details.
16
+ You should have received a copy of the GNU Lesser General Public
17
+ License along with this library; if not, write to the Free Software
18
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19
+ */
20
+
21
+ #include < Arduino.h>
22
+ #include < ESP8266WiFi.h>
23
+ #include < WiFiClient.h>
24
+ #include < WiFiServer.h>
25
+
26
+ #include " ESP8266WiFiMesh.h"
27
+
28
+ #define SSID_PREFIX " Mesh_Node"
29
+ #define SERVER_IP_ADDR " 192.168.4.1"
30
+ #define SERVER_PORT 4011
31
+
32
+ ESP8266WiFiMesh::ESP8266WiFiMesh (uint32_t chip_id, std::function<String(String)> handler)
33
+ : _server(SERVER_PORT)
34
+ {
35
+ _chip_id = chip_id;
36
+ _ssid = String ( String ( SSID_PREFIX ) + String ( _chip_id ) );
37
+ _ssid_prefix = String ( SSID_PREFIX );
38
+ _handler = handler;
39
+ }
40
+
41
+ void ESP8266WiFiMesh::begin ()
42
+ {
43
+ WiFi.mode (WIFI_AP_STA);
44
+ WiFi.softAP ( _ssid.c_str () );
45
+ _server.begin ();
46
+ }
47
+
48
+ /* *
49
+ * Wait for a WiFiClient to connect
50
+ *
51
+ * @returns: True if the client is ready, false otherwise.
52
+ *
53
+ */
54
+ bool ESP8266WiFiMesh::waitForClient (WiFiClient curr_client, int max_wait)
55
+ {
56
+ int wait = max_wait;
57
+ while (curr_client.connected () && !curr_client.available () && wait --)
58
+ delay (3 );
59
+
60
+ /* Return false if the client isn't ready to communicate */
61
+ if (WiFi.status () == WL_DISCONNECTED || !curr_client.connected ())
62
+ return false ;
63
+
64
+ return true ;
65
+ }
66
+
67
+ /* *
68
+ * Send the supplied message then read back the other node's response
69
+ * and pass that to the user-supplied handler.
70
+ *
71
+ * @target_ssid The name of the AP the other node has set up.
72
+ * @message The string to send to the node.
73
+ * @returns: True if the exchange was a succes, false otherwise.
74
+ *
75
+ */
76
+ bool ESP8266WiFiMesh::exchangeInfo (String message, WiFiClient curr_client)
77
+ {
78
+ curr_client.println ( message.c_str () );
79
+
80
+ if (!waitForClient (curr_client, 1000 ))
81
+ return false ;
82
+
83
+ String response = curr_client.readStringUntil (' \r ' );
84
+ curr_client.readStringUntil (' \n ' );
85
+
86
+ if (response.length () <= 2 )
87
+ return false ;
88
+
89
+ /* Pass data to user callback */
90
+ _handler (response);
91
+ return true ;
92
+ }
93
+
94
+ /* *
95
+ * Connect to the AP at ssid, send them a message then disconnect.
96
+ *
97
+ * @target_ssid The name of the AP the other node has set up.
98
+ * @message The string to send to the node.
99
+ *
100
+ */
101
+ void WiFiMesh::connectToNode (String target_ssid, String message)
102
+ {
103
+ WiFiClient curr_client;
104
+ WiFi.begin ( target_ssid.c_str () );
105
+
106
+ int wait = 1500 ;
107
+ while ((WiFi.status () == WL_DISCONNECTED) && wait --)
108
+ delay (3 );
109
+
110
+ /* If the connection timed out */
111
+ if (WiFi.status () != 3 )
112
+ return ;
113
+
114
+ /* Connect to the node's server */
115
+ if (!curr_client.connect (SERVER_IP_ADDR, SERVER_PORT))
116
+ return ;
117
+
118
+ if (!exchangeInfo (message, curr_client))
119
+ return ;
120
+
121
+ curr_client.stop ();
122
+ WiFi.disconnect ();
123
+ }
124
+
125
+ void ESP8266WiFiMesh::attemptScan (String message)
126
+ {
127
+ /* Scan for APs */
128
+ int n = WiFi.scanNetworks ();
129
+
130
+ for (int i = 0 ; i < n; ++i) {
131
+ String current_ssid = WiFi.SSID (i);
132
+ int index = current_ssid.indexOf ( _ssid_prefix );
133
+ uint32_t target_chip_id = (current_ssid.substring (index + _ssid_prefix.length ())).toInt ();
134
+
135
+ /* Connect to any _suitable_ APs which contain _ssid_prefix */
136
+ if (index >= 0 && (target_chip_id < _chip_id)) {
137
+
138
+ WiFi.mode (WIFI_STA);
139
+ delay (100 );
140
+ connectToNode (current_ssid, message);
141
+ WiFi.mode (WIFI_AP_STA);
142
+ delay (100 );
143
+ }
144
+ }
145
+ }
146
+
147
+ void ESP8266WiFiMesh::acceptRequest ()
148
+ {
149
+ while (true ) {
150
+ _client = _server.available ();
151
+ if (!_client)
152
+ break ;
153
+
154
+ if (!waitForClient (_client, 1500 )) {
155
+ continue ;
156
+ }
157
+
158
+ /* Read in request and pass it to the supplied handler */
159
+ String request = _client.readStringUntil (' \r ' );
160
+ _client.readStringUntil (' \n ' );
161
+
162
+ String response = _handler (request);
163
+
164
+ /* Send the response back to the client */
165
+ if (_client.connected ())
166
+ _client.println (response);
167
+ }
168
+ }
0 commit comments