├── .travis.yml
├── CHANGES.txt
├── LICENSE
├── README.md
├── examples
├── ConnectWithWPA
│ └── ConnectWithWPA.ino
├── MQTT_Publish
│ └── MQTT_Publish.ino
├── UDP_Multicast_Receiver
│ └── UDP_Multicast_Receiver.ino
├── UDP_Multicast_Transmitter
│ └── UDP_Multicast_Transmitter.ino
├── UdpNTPClient
│ └── UdpNTPClient.ino
├── WiFiWebClient
│ └── WiFiWebClient.ino
└── WiFiWebClientSSL
│ └── WiFiWebClientSSL.ino
├── keywords.txt
├── library.properties
└── src
├── WiFiSpi.cpp
├── WiFiSpi.h
├── WiFiSpiClient.cpp
├── WiFiSpiClient.h
├── WiFiSpiServer.cpp
├── WiFiSpiServer.h
├── WiFiSpiUdp.cpp
├── WiFiSpiUdp.h
├── config.h
└── utility
├── debug.cpp
├── debug.h
├── espspi_drv.cpp
├── espspi_drv.h
├── espspi_proxy.cpp
├── espspi_proxy.h
├── srvspi_drv.cpp
├── srvspi_drv.h
├── wifi_spi.h
├── wifispi_drv.cpp
├── wifispi_drv.h
├── wl_definitions.h
└── wl_types.h
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: c
2 |
3 | before_install:
4 | - "/sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_1.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :1 -ac -screen 0 1280x1024x16"
5 | - sleep 3
6 | - export DISPLAY=:1.0
7 | - wget http://downloads.arduino.cc/arduino-1.8.5-linux64.tar.xz
8 | - tar xf arduino-1.8.5-linux64.tar.xz
9 | - sudo mv arduino-1.8.5 /usr/local/share/arduino
10 | - sudo ln -s /usr/local/share/arduino/arduino /usr/local/bin/arduino
11 |
12 | install:
13 | - ln -s $PWD /usr/local/share/arduino/libraries/WiFiSpi
14 |
15 | script:
16 | - arduino --verify --board ${BOARD} $PWD/examples/ConnectWithWPA/ConnectWithWPA.ino
17 |
18 | notifications:
19 | email:
20 | on_success: change
21 | on_failure: change
22 |
23 | env:
24 | - BOARD=arduino:avr:uno
25 | # - BOARD=arduino:avr:yun
26 | # - BOARD=arduino:avr:diecimila:cpu=atmega168
27 | # - BOARD=arduino:avr:diecimila:cpu=atmega328
28 | # - BOARD=arduino:avr:nano:cpu=atmega168
29 | # - BOARD=arduino:avr:nano:cpu=atmega328
30 | # - BOARD=arduino:avr:mega:cpu=atmega1280
31 | # - BOARD=arduino:avr:mega:cpu=atmega2560
32 | # - BOARD=arduino:avr:megaADK
33 | # - BOARD=arduino:avr:leonardo
34 | # - BOARD=arduino:avr:micro
35 | # - BOARD=arduino:avr:esplora
36 | # - BOARD=arduino:avr:mini:cpu=atmega168
37 | # - BOARD=arduino:avr:mini:cpu=atmega328
38 | # - BOARD=arduino:avr:ethernet
39 | # - BOARD=arduino:avr:bt:cpu=atmega168
40 | # - BOARD=arduino:avr:bt:cpu=atmega328
41 | # - BOARD=arduino:avr:lilypad:cpu=atmega168
42 | # - BOARD=arduino:avr:lilypad:cpu=atmega328
43 | # - BOARD=arduino:avr:pro:cpu=atmega168
44 | # - BOARD=arduino:avr:pro:cpu=atmega328
45 | # - BOARD=arduino:sam:arduino_due_x
--------------------------------------------------------------------------------
/CHANGES.txt:
--------------------------------------------------------------------------------
1 | 0.3.0 (2021-13-05)
2 | * BearSSL engine, protocol 0.3.0
3 | * UDP Multicast support
4 | 0.2.3 (2019-02-18)
5 | * SSL Client connection, verifySSL function, protocol 0.2.3
6 | 0.2.0 (2019-01-27)
7 | * Protocol changed. Status shortened to 2 bytes, added XOR check. Data messages checked by a CRC8.
8 | * Developed mechanism of confirming and repeating messages.
9 | * Added hardware reset support (hardReset command)
10 | * Added support for external 8266 circuit guarding the GPIO15 (SS pin) on reset
11 | 0.1.4 (2019-01-24)
12 | * Fixed delays in SPI protocol
13 | * Added softReset and protocolVersion commands (might be added earlier)
14 | 0.1.1 (2018-07-03)
15 | * Added parameter to init function (SPI max speed)
16 | * Enabled STM32F1 architecture although there will be a lot of work yet
17 | 0.1.0 (2017-03-14)
18 | * First version for testing
19 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
166 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | WiFiSpi
2 | =======
3 |
4 | This library connects Arduino to ESP8266 module and uses it as a dedicated WiFi device. The SPI interface is used because of its strictly master/slave nature.
5 |
6 | The library allows Arduino to be client or server on the WiFi network.
7 |
8 | ## News
9 |
10 | #### 2021-01-25
11 |
12 | Added UDP Multicast support
13 |
14 | #### 2021-01-02
15 |
16 | Fixed a bug with closing server connection when closing asynchronously opened another client.
17 | Changed deprecated boolean type to bool.
18 |
19 | #### 2019-02-18
20 |
21 | Added SSL connection to WiFiClient class. Added verifySSL function.
22 |
23 | #### 2019-01-27
24 |
25 | Enhanced communications protocol (added CRC-8 and confirmation of message reception). Shortened the status message from 4 bytes to 2 bytes and added XOR check. The protocol version is now 0.2.0 and is incompatible with the former one.
26 |
27 | Added support for hardware circuit removing the problems with ESP8266 reset by pulling GPIO15 (SS) pin to GND on reset.
28 |
29 | ## Requirements
30 |
31 | ### ESP8266 device
32 |
33 | The ESP8266 has two SPI interfaces. The first is connected to the flash memory, the second (named HSPI) can be used by user. The HSPI signals are multiplexed with GPIO12-15. Suitable device for the slave is ESP-12. On the ESP device must be run a custom firmware - see WifiESPSPI project.
34 |
35 | ### Wiring
36 |
37 | The library uses hardware SPI on Arduino so most of the signals are fixed to certain pins.
38 |
39 | The wiring is as follows:
40 |
41 | Name | Uno | STM32F103C8 | ESP8266
42 | | | SPI1 SPI2 | GPIO NodeMCU
43 | -------+---------+---------------------------------
44 | SS | D10 | PA4 PB12 | 15 D8
45 | MOSI | D11 | PA7 PB15 | 13 D7
46 | MISO | D12 | PA6 PB14 | 12 D6
47 | SCK | D13 | PA5 PB13 | 14 D5
48 |
49 | The SS pin is the only pin the user can change. Changing SS to another pin enables more devices on one SPI interface.
50 |
51 | Please be careful, the ESP8266 chip ports are **NOT** 5V tolerant, if you're connecting to a 5V device you have to use a level converter.
52 |
53 | ## Library Reference
54 |
55 | The library implements almost the same functions as the [Arduino WiFi library](https://www.arduino.cc/en/Reference/WiFi).
56 |
57 | ### Setup
58 |
59 | All the important defines are in file **config.h**. The user can comment and/or uncomment them and modify the behaviour of the library.
60 |
61 | ### WiFiSpiClass
62 |
63 | After including *WiFiSpi.h* header the *WiFiSpi* variable is automatically instantiated. Use the variable to perform the following calls.
64 |
65 | - **void init(int8_t pin, uint32_t max_speed = 0, SPIClass \*in_spi = &SPI, int8_t hwResetPin = -1)**
66 | Initializes the library and the Arduino SPI interface. Must be called on beginning of the communication. The parameter *max_speed* limits the SPI speed. Tests on STM32F1 show that speeds as high as 9 Mhz are usable. The parameter *in_spi* allows to use another SPI port (if there are more present in the MCU). Refer to a particular implementation of SPIClass. The optional parameter *hwResetPin* defines the pin which is connected to reset pin on ESP8266 for hardware reset. Then this parameter is present, master resets the ESP8266 on start.
67 |
68 | - **char\* firmwareVersion()**
69 | Returns version of custom firmware loaded into ESP8266.
70 |
71 | - **char\* protocolVersion()**
72 | Returns version of protocol the ESP8266 firmware operates with.
73 |
74 | - **char\* masterProtocolVersion()**
75 | Returns version of protocol the master runs.
76 |
77 | - **uint8_t checkProtocolVersion()**
78 | Checks master and ESP protocol version. If they match, returns 1, otherwise 0.
79 |
80 | - **uint8_t begin(const char\* ssid)**
81 | Connects to an open (unencrypted) wifi. Returns a value from *wl_status_t* enum(when connected returns WL_CONNECTED). Establishing of the connection may last several seconds.
82 |
83 | - **uint8_t begin(const char\* ssid, const char \*passphrase)**
84 | Connects to a WPA/WPA2 encrypted wifi. Returns status from *wl_status_t* type (when connected returns WL_CONNECTED). Establishing of the connection may last several seconds.
85 |
86 | - **int disconnect(void)**
87 | Disconnects from the WiFi network. Returns a value from *wl_status_t* enum(when disconnected returns WL_DISCONNECTED).
88 |
89 | - **uint8_t status()**
90 | Returns the connection status of the WiFi interface. The returned value is one of the enum *wl_status_t*.
91 |
92 | - **int8_t hostByName(const char\* aHostname, IPAddress& aResult)**
93 | Resolves the given hostname to an IP address. Returns 1 for Ok else error code.
94 |
95 | - **void softReset(void)**
96 | Sends reset command to ESP8266. The ESP8266 then resets itself. The command is performed only if the connection between the host and ESP8266 is not broken.
97 |
98 | - **void hardReset(void)**
99 | Resets the ESP8266. One pin on master unit must be wired to reset pin on ESP8266. The pin is defined in **init** function.
100 |
101 | ----------
102 |
103 |
104 | - **bool config(IPAddress local_ip)**
105 | Changes IP configuration, sets local IP address and disables DHCP client.
106 |
107 | - **bool config(IPAddress local_ip, IPAddress dns_server)**
108 | Changes IP configuration, sets local IP address, primary DNS server and disables DHCP client.
109 |
110 | - **bool config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway)**
111 | Changes IP configuration, sets local IP address, primary DNS server, static gateway address and disables DHCP client.
112 |
113 | - **bool config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway, IPAddress subnet)**
114 | Changes IP configuration, sets local IP address, primary DNS server, static gateway address, subnet mask and disables DHCP client.
115 |
116 | - **bool setDNS(IPAddress dns_server1)**
117 | Changes IP configuration, sets primary DNS server IP address.
118 |
119 | - **bool setDNS(IPAddress dns_server1, IPAddress dns_server2)**
120 | Changes IP configuration, sets primary and secondary DNS server IP addresses.
121 |
122 | - **uint8_t\* macAddress(uint8_t\* mac)**
123 | Returns MAC address value of the WiFi interface. The MAC address is copiend to the array *mac* and also returned as a pointer to this array. The array size must be at least 6 bytes.
124 |
125 | - **IPAddress localIP()**
126 | Returns local IP address value.
127 |
128 | - **IPAddress subnetMask()**
129 | Returns interface subnet mask value.
130 |
131 | - **IPAddress gatewayIP()**
132 | Returns interface gateway address value.
133 |
134 | - **char\* SSID()**
135 | Returns the current SSID associated with the network.
136 |
137 | - **uint8_t\* BSSID()**
138 | Returns the current BSSID associated with the network. It is in fact the MAC address of the Access Point. Returns a pointer to byte array of 6 byte length.
139 |
140 | - **int32_t RSSI()**
141 | Returns the currect RSSI (signal strength in dBm) as a signed value.
142 |
143 |
144 | ----------
145 |
146 |
147 | - **int8_t scanNetworks()**
148 | Scans the WiFi network. Returns the number of networks found or error value (WL_FAILURE). The call may last several seconds.
149 |
150 | - **char\* SSID(uint8_t networkItem)**
151 | Returns the current SSID associated with the discovered network during the network scan. Parameter *networkItem* is the index into a discovered networks array.
152 |
153 | - **uint8_t encryptionType(uint8_t networkItem)**
154 | Returns the encryption type of the discovered network during the network scan. The returned value is one of the enum *wl_enc_type*. Parameter *networkItem* is the index into a discovered networks array.
155 |
156 | - **int32_t RSSI(uint8_t networkItem)**
157 | Returns the signal strength in dBm of the discovered network during the network scan. The returned value is signed 32 bit integer. Parameter *networkItem* is the index into a discovered networks array.
158 |
159 | ----------
160 |
161 | - **uint8_t setSSLFingerprint(uint8_t\* fingerprint)**
162 | Loads server certificate SHA-1 fingerprint into BearSSL engine. Subsequent connections are checked against
163 | this fingerprint. The fingerprint is an array of type *uint8_t[20]*.
164 | Note that without checking the fingerprint the TLS connection is insecure and prone to MITM attacks.
165 |
166 |
167 | ### WiFiSpiClient
168 |
169 | The WiFiSpiClient class performs data communication between your program and the remote site. It is used not only with client connections (where Arduino acts as a client) but also in server connections (sending responses to a web request) and udp connections.
170 | The library has a pool of 4 sockets and after exhausting all the sockets no more connection is available. Therefore it is important to close the socket (i. e. stop the client) when it is no longer used.
171 |
172 | - **WiFiSpiClient()**
173 | Default constructor, creates a closed connection. Use it for client side of communication.
174 |
175 | - **WiFiSpiClient(uint8_t sock)**
176 | Creates client for open server connection. Called by the library in when server connection has data.
177 |
178 | - **int connect(IPAddress ip, uint16_t port)**
179 | Connects to the specified IP address and port. Returns a value from enum *wl_tcp_state* (for open connection returns ESTABLISHED).
180 |
181 | - **int connect(const char \*host, uint16_t port)**
182 | Connects to the specified host and port. Returns a value from enum *wl_tcp_state* (for open connection returns ESTABLISHED).
183 |
184 | - **int connectSSL(IPAddress ip, uint16_t port)**
185 | Connects using SSL to the specified IP address and port. Returns a value from enum *wl_tcp_state* (for open connection returns ESTABLISHED). If there is a previously loaded certificate fingerprint, the server certificate is checked against the fingerprint, otherwise the connection is insecure (prone to MITM attacks).
186 |
187 | - **int connectSSL(const char \*host, uint16_t port)**
188 | Connects using SSL to the specified host and port. Returns a value from enum *wl_tcp_state* (for open connection returns ESTABLISHED). If there is a previously loaded certificate fingerprint, the server certificate is checked against the fingerprint, otherwise the connection is insecure (prone to MITM attacks).
189 |
190 | - **uint8_t connected()**
191 | Returns connection state as a logic value: 1 = connected, 0 = error. Note that the connection could be closed by a server when ESP8266 reads all data in its internal buffer although the master haven't read it yet.
192 |
193 | - **uint8_t status()**
194 | Returns connection state as a value from enum *wl_tcp_state* (for open connection returns ESTABLISHED).
195 |
196 | - **void stop()**
197 | Stops the client (disconnects from the remote server if still connected) and frees the socket used for the client.
198 |
199 | - **operator bool()**
200 | Returns true when the client is associated with a socket.
201 |
202 | ----------
203 |
204 | - **int available()**
205 | Returns available bytes in the input queue (data received from the network) for reading.
206 |
207 | - **int read()**
208 | Reads one byte from the input queue. Returns -1 for an error.
209 |
210 | - **int read(uint8_t \*buf, size_t size)**
211 | Reads *size* bytes into an input buffer *buf*. Returns 0 on success, -1 on error or insufficient data in the input queue.
212 |
213 | - **int peek()**
214 | Peeks into the input queue and returns the first byte in the queue. On error returns -1.
215 |
216 | - **size_t write(uint8_t)**
217 | Sends one byte to the network. Returns 1 on success, 0 on error.
218 |
219 | - **size_t write(const void \*buf, size_t size)**
220 | Sends the buffer to the network. Returns number of bytes transmitted.
221 |
222 | - **size_t write(const char \*str)**
223 | Sends the character string to the network. Returns number of bytes transmitted.
224 |
225 | - **IPAddress remoteIP()**
226 | Returns the IP address of the host who sent the current incoming packet. When there is no incoming connection returns 0.0.0.0.
227 |
228 | - **uint16_t remotePort()**
229 | Returns the port of the host who sent the current incoming packet. When there is no incoming connection returns 0.
230 |
231 | ### WiFiSpiServer
232 |
233 | The library has a pool of 4 sockets and after exhausting all the sockets no more connection is available. Therefore it is important to close the socket (i. e. stop the server) when it is no longer used. This version of the library is further constrained to one client connection per server.
234 |
235 | - **WiFiSpiServer(uint16_t port)**
236 | Constructor. Does not open a connection.
237 |
238 | - **void begin()**
239 | Creates and starts the server listener on specified *port*.
240 |
241 | - **uint8_t status()**
242 | Returns the server's status. Return 1 for opened connection, 0 for closed or error.
243 |
244 | - **void stop()**
245 | Stops the listener, stops the associated client (if any) and frees the socket.
246 |
247 | - **WiFiSpiClient available(uint8_t\* status = NULL)**
248 | Returns WiFiSpiClient instance for communication with remote client. Returns opened WiFiSpiClient instance when there is a remote client connected. When there is no connection the function returns closed client. Use the WiFiSpiClient's bool operator on the return value to test it.
249 | When pointer *status* is not null, loads it with the remote client's status.
250 |
251 | - **size_t write(uint8_t)**
252 | Writes a byte to the output queue. Returns 1 on success, 0 on error.
253 |
254 | - **size_t write(const uint8_t \*buf, size_t size)**
255 | Writes a buffer to the output queue. Returns number of bytes written.
256 | Note: transmitting data can be also achieved using a WiFiSpiClient object returned by the *WiFiSpiServer::available()* function.
257 |
258 | ### WiFiSpiUDP
259 |
260 | - **WiFiSpiUdp()**
261 | Default constuctor.
262 |
263 | - **uint8_t begin(uint16_t port)**
264 | Initializes the instance, starts listening on specified *port*. Returns 1 if successful, 0 on error.
265 |
266 | - **uint8_t begin(uint16_t multicastIP, uint16_t port)**
267 | Initializes the instance, starts listening on specified *port* for multicast messages from *multicastIP* address. Returns 1 if successful, 0 on error.
268 |
269 | - **void stop()**
270 | Stops listening on the UDP port, frees the UDP socket used.
271 |
272 | - **int beginPacket(IPAddress ip, uint16_t port)**
273 | Starts building up a packet to send to the remote host specific in *ip* and *port*. Returns 1 if successful, 0 if there was a problem with the connection. This function works for both unicast and multicast communication.
274 |
275 | - **int endPacket()**
276 | Finishes the packet and sends it. Returns 1 if the packet was sent successfully, 0 if there was an error.
277 |
278 | - **size_t write(uint8_t)**
279 | Writes a single byte into the packet. Returns 1 on sucesss, 0 on error.
280 |
281 | - **size_t write(const uint8_t \*buffer, size_t size)**
282 | Writes *size* bytes from buffer into the packet. Returns number of bytes written, on error returns 0.
283 |
284 | - **int parsePacket();**
285 | Starts processing the next available incoming packet. Returns the size of the packet in bytes, or 0 if no packets are available.
286 |
287 | - **int available()**
288 | Returns the number of bytes remaining in the current packet.
289 |
290 | - **int read()**
291 | Reads a single byte from the current packet.
292 |
293 | - **int read(unsigned char\* buffer, size_t len)**
294 | - **int read(char\* buffer, size_t len)**
295 | Reads up to *len* bytes from the current packet and places them into *buffer*. Returns the number of bytes read, or 0 if none are available or an error occurred.
296 |
297 | - **int peek()**
298 | Returns the next byte from the current packet without moving on to the next byte.
299 |
300 | - **IPAddress remoteIP()**
301 | Returns the IP address of the host who sent the current incoming packet. When there is no incoming connection returns 0.0.0.0.
302 |
303 | - **uint16_t remotePort()**
304 | Returns the port of the host who sent the current incoming packet. When there is no incoming connection returns 0.
305 |
306 | ## Examples
307 |
308 | - **ConnectWithWPA**
309 | Connects to the network and prints out some information.
310 |
311 | - **WiFiWebClient**
312 | Connects to the google.com site and transmits the http response.
313 |
314 | - **MQTT_Publish**
315 | Simple mqtt messaging.
316 |
317 | - **UdpNTPClient**
318 | Reads current time and date from a NTP server.
319 |
320 | - **UDP_Multicast_Transmitter**
321 | Peridically transmits a short messaage via UDP multicast.
322 |
323 | - **UDP_Multicast_Receiver**
324 | Listens for multicast messages, reads them and prints them out.
325 |
326 | More examples to come soon. But you can easily use the ones from WiFi library. Don't forget to add a line *WiFiSpi.init();* before using other library functions.
327 |
328 | ## Debugging
329 |
330 | For some debugging information on Serial output uncomment line 23 (#define _DEBUG) in file espspi_srv.cpp.
331 |
332 | ## ToDo and Wish Lists
333 |
334 | - more SPI protocol optimization
335 | - TLS: loading and checking server certificate chain instead of the fingerprint
336 |
337 | ## Credits
338 |
339 | The protocol running on SPI interface was inspired by protocol used in Arduino WiFi library. The code structure and some code is taken from this library, too.
340 |
341 | The SPI master code was inspired and parts were taken from the [ESPSlave example](https://github.com/esp8266/Arduino/tree/master/libraries/SPISlave) of the ESP8266 Arduino project.
342 |
343 |
344 |
--------------------------------------------------------------------------------
/examples/ConnectWithWPA/ConnectWithWPA.ino:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | This example connects to an unencrypted Wifi network.
4 | Then it prints the MAC address of the Wifi module,
5 | the IP address obtained, and other network details.
6 |
7 | Circuit:
8 | 1. On ESP8266 must be running (flashed) WiFiSPIESP application.
9 |
10 | 2. Connect the master (Arduino or STM32F103) to the following pins on the esp8266:
11 |
12 | ESP8266 | |
13 | GPIO NodeMCU Name | Uno | STM32F103
14 | ===============================================
15 | 15 D8 SS | D10 | PA4
16 | 13 D7 MOSI | D11 | PA7
17 | 12 D6 MISO | D12 | PA6
18 | 14 D5 SCK | D13 | PA5
19 |
20 | Note: If the ESP is booting at a moment when the SPI Master (i.e. Arduino) has the Select line HIGH (deselected)
21 | the ESP8266 WILL FAIL to boot!
22 |
23 | original sketch for WiFi library created 13 July 2010
24 | by dlf (Metodo2 srl)
25 | modified 31 May 2012
26 | by Tom Igoe
27 |
28 | modified for WiFiSpi library 14 Mar 2017
29 | by Jiri Bilek
30 | */
31 |
32 | #include
33 |
34 | // WiFi credentials
35 | char ssid[] = "yourNetwork"; // your network SSID (name)
36 | char pass[] = "secretPassword"; // your network password
37 |
38 | void setup() {
39 | //Initialize serial and wait for port to open:
40 | Serial.begin(9600);
41 | while (!Serial) {
42 | ; // wait for serial port to connect. Needed for native USB port only
43 | }
44 |
45 | // Initialize the WifiSpi library
46 | WiFiSpi.init();
47 |
48 | // check for the presence of the ESP module:
49 | if (WiFiSpi.status() == WL_NO_SHIELD) {
50 | Serial.println("WiFi module not present");
51 | // don't continue:
52 | while (true);
53 | }
54 |
55 | if (!WiFiSpi.checkProtocolVersion()) {
56 | Serial.println("Protocol version mismatch. Please upgrade the firmware");
57 | // don't continue:
58 | while (true);
59 | }
60 |
61 | // attempt to connect to Wifi network:
62 | int status; // the Wifi radio's status
63 |
64 | do {
65 | Serial.print("Attempting to connect to WPA SSID: ");
66 | Serial.println(ssid);
67 | // Connect to WPA/WPA2 network:
68 | status = WiFiSpi.begin(ssid, pass);
69 | } while (status != WL_CONNECTED);
70 |
71 | // you're connected now, so print out the data:
72 | Serial.println("You're connected to the network");
73 | printCurrentNet();
74 | printWifiData();
75 | }
76 |
77 | void loop() {
78 | // check the network connection once every 10 seconds:
79 | delay(10000);
80 | printCurrentNet();
81 | }
82 |
83 | void printWifiData() {
84 | // print your WiFi module's IP address:
85 | IPAddress ip = WiFiSpi.localIP();
86 | Serial.print("IP Address: ");
87 | Serial.println(ip);
88 |
89 | // print your MAC address:
90 | byte mac[6];
91 | WiFiSpi.macAddress(mac);
92 | Serial.print("MAC address: ");
93 | Serial.print(mac[5], HEX);
94 | Serial.print(":");
95 | Serial.print(mac[4], HEX);
96 | Serial.print(":");
97 | Serial.print(mac[3], HEX);
98 | Serial.print(":");
99 | Serial.print(mac[2], HEX);
100 | Serial.print(":");
101 | Serial.print(mac[1], HEX);
102 | Serial.print(":");
103 | Serial.println(mac[0], HEX);
104 | }
105 |
106 | void printCurrentNet() {
107 | // print the SSID of the network you're attached to:
108 | Serial.print("SSID: ");
109 | Serial.println(WiFiSpi.SSID());
110 |
111 | // print the MAC address of the router you're attached to:
112 | byte *bssid = WiFiSpi.BSSID();
113 | Serial.print("BSSID: ");
114 | Serial.print(bssid[5], HEX);
115 | Serial.print(":");
116 | Serial.print(bssid[4], HEX);
117 | Serial.print(":");
118 | Serial.print(bssid[3], HEX);
119 | Serial.print(":");
120 | Serial.print(bssid[2], HEX);
121 | Serial.print(":");
122 | Serial.print(bssid[1], HEX);
123 | Serial.print(":");
124 | Serial.println(bssid[0], HEX);
125 |
126 | // print the received signal strength:
127 | long rssi = WiFiSpi.RSSI();
128 | Serial.print("signal strength (RSSI):");
129 | Serial.println(rssi);
130 | }
131 |
--------------------------------------------------------------------------------
/examples/MQTT_Publish/MQTT_Publish.ino:
--------------------------------------------------------------------------------
1 | /*
2 | Publishing in the callback
3 |
4 | Uses the PubSubClient library
5 |
6 | - connects to an MQTT server (broker.hivemq.com)
7 | - subscribes to the topic "EspSpi/inTopic"
8 | - when a message is received, republishes it to "EspSpi/outTopic"
9 | - every 5 seconds writes number in sequence from 1 to "EspSpi/outTopic/msg"
10 |
11 | This example shows how to publish messages within the
12 | callback function. The callback function header needs to
13 | be declared before the PubSubClient constructor and the
14 | actual callback defined afterwards.
15 | This ensures the client reference in the callback function
16 | is valid.
17 |
18 | The result could be viewed online on http://www.hivemq.com/demos/websocket-client/
19 |
20 | Circuit:
21 | 1. On ESP8266 must be running (flashed) WiFiSPIESP application.
22 |
23 | 2. Connect the master (Arduino or STM32F103) to the following pins on the esp8266:
24 |
25 | ESP8266 | |
26 | GPIO NodeMCU Name | Uno | STM32F103
27 | ===============================================
28 | 15 D8 SS | D10 | PA4
29 | 13 D7 MOSI | D11 | PA7
30 | 12 D6 MISO | D12 | PA6
31 | 14 D5 SCK | D13 | PA5
32 |
33 | Note: If the ESP is booting at the moment when the SPI Master (i.e. Arduino) has the Select line HIGH (deselected)
34 | the ESP8266 WILL FAIL to boot!
35 | */
36 |
37 | #include
38 | #include
39 |
40 | // WiFi credentials
41 | char ssid[] = "yourNetwork"; // your network SSID (name)
42 | char pass[] = "secretPassword"; // your network password (use for WPA)
43 |
44 | // MQTT Broker Address
45 | //IPAddress server(18, 185, 232, 233); // broker.hivemq.com (check it if the client does not connect, the IP address may change)
46 | const char *server = "broker.hivemq.com";
47 |
48 | // Callback function header
49 | void callback(char* topic, byte* payload, unsigned int length);
50 |
51 | WiFiSpiClient wifiClient;
52 | PubSubClient client(server, 1883, callback, wifiClient);
53 |
54 | // Callback function
55 | void callback(char* topic, byte* payload, unsigned int length) {
56 | // In order to republish this payload, a copy must be made
57 | // as the orignal payload buffer will be overwritten whilst
58 | // constructing the PUBLISH packet.
59 |
60 | // Allocate the correct amount of memory for the payload copy
61 | byte* p = (byte*)malloc(length);
62 | // Copy the payload to the new buffer
63 | memcpy(p, payload, length);
64 | client.publish("EspSpi/outTopic", p, length);
65 | // Free the memory
66 | free(p);
67 | }
68 |
69 | void setup() {
70 | //Initialize serial and wait for port to open:
71 | Serial.begin(9600);
72 | while (!Serial) {
73 | ; // wait for serial port to connect. Needed for native USB port only
74 | }
75 |
76 | // Initialize the WifiSpi library
77 | WiFiSpi.init();
78 |
79 | // check for the presence of the shield:
80 | if (WiFiSpi.status() == WL_NO_SHIELD) {
81 | Serial.println("WiFi shield not present");
82 | // don't continue:
83 | while (true);
84 | }
85 |
86 | if (!WiFiSpi.checkProtocolVersion()) {
87 | Serial.println("Protocol version mismatch. Please upgrade the firmware");
88 | // don't continue:
89 | while (true);
90 | }
91 |
92 | // attempt to connect to Wifi network
93 | int status; // the Wifi radio's status
94 |
95 | do {
96 | Serial.print("Attempting to connect to SSID: ");
97 | Serial.println(ssid);
98 | // Connect to WPA/WPA2 network
99 | status = WiFiSpi.begin(ssid, pass);
100 | } while (status != WL_CONNECTED);
101 |
102 | Serial.println("Connected to wifi");
103 |
104 | // Connect to mqtt broker
105 | if (client.connect("arduinoTest")) {
106 | client.publish("EspSpi/outTopic","hello world");
107 | client.subscribe("EspSpi/inTopic");
108 | }
109 | }
110 |
111 | void reconnect() {
112 | // Loop until we're reconnected
113 | while (!client.connected()) {
114 | Serial.print(F("Attempting MQTT connection..."));
115 |
116 | // Attempt to connect
117 | if (client.connect("arduinoTest")) {
118 | Serial.println(F("reconnected"));
119 |
120 | // Once connected, publish an announcement...
121 | client.publish("EspSpi/outTopic", "reconnected");
122 |
123 | // ... and resubscribe
124 | client.subscribe("EspSpi/inTopic");
125 | } else {
126 | Serial.print(F("failed, rc="));
127 | Serial.println(client.state());
128 | }
129 | }
130 | }
131 |
132 | unsigned long lastMillis = millis();
133 | unsigned int number = 1;
134 |
135 | void loop() {
136 | client.loop();
137 |
138 | // Sending every 5 seconds
139 | if (lastMillis < millis()) {
140 | if (!client.connected())
141 | reconnect();
142 |
143 | char payload[10];
144 | sprintf(payload, "%u", number);
145 | client.publish("EspSpi/outTopic/msg", payload);
146 | ++number;
147 |
148 | lastMillis = millis() + 5000;
149 | }
150 | }
151 |
--------------------------------------------------------------------------------
/examples/UDP_Multicast_Receiver/UDP_Multicast_Receiver.ino:
--------------------------------------------------------------------------------
1 | /*
2 | Receive multicast UDP packets
3 |
4 | This sketch receives multicast UDP packets from address 239.1.74.74, port 7474
5 | Uses WiFi ESP8266 module.
6 |
7 | This example is written for a network using WPA encryption.
8 |
9 | Circuit:
10 | 1. On ESP8266 must be running (flashed) WiFiSPIESP application.
11 |
12 | 2. Connect the Arduino to the following pins on the esp8266:
13 |
14 | ESP8266 |
15 | GPIO NodeMCU Name | STM32F103
16 | ===================================
17 | 15 D8 SS | PA4
18 | 13 D7 MOSI | PA7
19 | 12 D6 MISO | PA6
20 | 14 D5 SCK | PA5
21 | RESET | PB12
22 |
23 | Note: If the ESP is booting at the moment when the SPI Master (i.e. Arduino) has the Select line HIGH (deselected)
24 | the ESP8266 WILL FAIL to boot!
25 |
26 | */
27 |
28 | #include
29 |
30 | char ssid[] = "your ssid here"; // your network SSID (name)
31 | char pass[] = "your password here"; // your network password
32 |
33 | #if defined(MCU_STM32F103C8)
34 | const uint8_t RESET_PIN = PB12; // For STM32F103
35 | #endif
36 |
37 | // Note: remoteIP is a multicast address, it should begin with 239.x.x.x or some other
38 | // appropriate multicast address.
39 | // It's not the same as your local IP address (192.168.x.x, for example)!
40 | IPAddress remoteIP(239, 1, 74, 74);
41 |
42 | // The remote port must be otherwise unused on any machine that is receiving these packets
43 | int remotePort = 7474;
44 |
45 | // Create the UDP object
46 | WiFiSpiUdp udp;
47 |
48 | void setup() {
49 | #if defined(MCU_STM32F103C8)
50 | // Reset PIN
51 | pinMode(RESET_PIN, OUTPUT);
52 | digitalWrite(RESET_PIN, HIGH);
53 | #endif
54 |
55 | //Initialize serial and wait for port to open:
56 | Serial.begin(115200);
57 | while (!Serial.available()) {
58 | ; // wait for serial port to connect. Needed for native USB port only
59 | }
60 |
61 | Serial.println("Reset ESP8266");
62 |
63 | #if defined(MCU_STM32F103C8)
64 | // Reset the ESP
65 | digitalWrite(RESET_PIN, LOW);
66 | delay(100);
67 | digitalWrite(RESET_PIN, HIGH);
68 | delay(500);
69 | #endif
70 |
71 | // Initialize the library
72 | WiFiSpi.init(SS, 100000);
73 |
74 | // check for the presence of the shield:
75 | if (WiFiSpi.status() == WL_NO_SHIELD) {
76 | Serial.println("Error in communication with the ESP board, halted");
77 | WiFiSpi.status();
78 | // don't continue:
79 | while (true);
80 | }
81 |
82 | if (! WiFiSpi.checkProtocolVersion())
83 | Serial.println("Please upgrade the firmware");
84 |
85 | // attempt to connect to Wifi network:
86 | uint8_t status;
87 | do {
88 | Serial.print("Attempting to connect to SSID: ");
89 | Serial.println(ssid);
90 | // Connect to WPA/WPA2 network.
91 | status = WiFiSpi.begin(ssid, pass);
92 | } while (status != WL_CONNECTED);
93 |
94 | Serial.println("Connected to wifi");
95 |
96 | // Start listening for multicast messages
97 | udp.beginMulticast(remoteIP, remotePort);
98 | }
99 |
100 | void loop() {
101 | // If there's data available, read a packet
102 | int packetSize = udp.parsePacket();
103 |
104 | // If there's data, read them and print them
105 | if (packetSize > 0) {
106 | Serial.print("Incoming packet, size="); Serial.println(packetSize);
107 | while (udp.available()) {
108 | int inp = udp.read();
109 | if (inp >= ' ' && inp <= 0x7f)
110 | Serial.print(char(inp));
111 | else {
112 | Serial.print(inp); Serial.print(' ');
113 | }
114 | }
115 | Serial.println();
116 | }
117 |
118 | delay(100);
119 | }
120 |
121 |
122 | void printWifiStatus() {
123 | // print the SSID of the network you're attached to:
124 | Serial.print("SSID: ");
125 | Serial.println(WiFiSpi.SSID());
126 |
127 | // print your WiFi shield's IP address:
128 | IPAddress ip = WiFiSpi.localIP();
129 | Serial.print("IP Address: ");
130 | Serial.println(ip);
131 |
132 | // print the received signal strength:
133 | long rssi = WiFiSpi.RSSI();
134 | Serial.print("signal strength (RSSI): ");
135 | Serial.print(rssi);
136 | Serial.println(" dBm");
137 | }
138 |
--------------------------------------------------------------------------------
/examples/UDP_Multicast_Transmitter/UDP_Multicast_Transmitter.ino:
--------------------------------------------------------------------------------
1 | /*
2 | Transmit multicast UDP packets
3 |
4 | This sketch transmits multicast UDP packets to address 239.1.74.74, port 7474
5 | Uses WiFi ESP8266 module.
6 |
7 | This example is written for a network using WPA encryption.
8 |
9 | Circuit:
10 | 1. On ESP8266 must be running (flashed) WiFiSPIESP application.
11 |
12 | 2. Connect the Arduino to the following pins on the esp8266:
13 |
14 | ESP8266 |
15 | GPIO NodeMCU Name | STM32F103
16 | ===================================
17 | 15 D8 SS | PA4
18 | 13 D7 MOSI | PA7
19 | 12 D6 MISO | PA6
20 | 14 D5 SCK | PA5
21 | RESET | PB12
22 |
23 | Note: If the ESP is booting at the moment when the SPI Master (i.e. Arduino) has the Select line HIGH (deselected)
24 | the ESP8266 WILL FAIL to boot!
25 |
26 | */
27 |
28 | #include
29 |
30 | char ssid[] = "your ssid here"; // your network SSID (name)
31 | char pass[] = "your password here"; // your network password
32 |
33 | #if defined(MCU_STM32F103C8)
34 | const uint8_t RESET_PIN = PB12;
35 | #endif
36 |
37 | // Note: remoteIP is a multicast address, it should begin with 239.x.x.x or some other
38 | // appropriate multicast address.
39 | // It's not the same as your local IP address (192.168.x.x, for example)!
40 | IPAddress remoteIP(239, 1, 74, 74);
41 |
42 | // The remote port must be otherwise unused on any machine that is receiving these packets
43 | int remotePort = 7474;
44 |
45 | // Create the UDP object
46 | WiFiSpiUdp udp;
47 |
48 | void setup() {
49 | #if defined(MCU_STM32F103C8)
50 | // Reset PIN
51 | pinMode(RESET_PIN, OUTPUT);
52 | digitalWrite(RESET_PIN, HIGH);
53 | #endif
54 |
55 | //Initialize serial and wait for port to open:
56 | Serial.begin(115200);
57 | while (!Serial.available()) {
58 | ; // wait for serial port to connect. Needed for native USB port only
59 | }
60 |
61 | Serial.println("Reset ESP8266");
62 |
63 | #if defined(MCU_STM32F103C8)
64 | // Reset the ESP
65 | digitalWrite(RESET_PIN, LOW);
66 | delay(100);
67 | digitalWrite(RESET_PIN, HIGH);
68 | delay(500);
69 | #endif
70 |
71 | // Initialize the library
72 | WiFiSpi.init(SS, 100000);
73 |
74 | // check for the presence of the shield:
75 | if (WiFiSpi.status() == WL_NO_SHIELD) {
76 | Serial.println("Error in communication with the ESP board, halted");
77 | WiFiSpi.status();
78 | // don't continue:
79 | while (true);
80 | }
81 |
82 | if (! WiFiSpi.checkProtocolVersion())
83 | Serial.println("Please upgrade the firmware");
84 |
85 | // attempt to connect to Wifi network:
86 | uint8_t status;
87 | do {
88 | Serial.print("Attempting to connect to SSID: ");
89 | Serial.println(ssid);
90 | // Connect to WPA/WPA2 network.
91 | status = WiFiSpi.begin(ssid, pass);
92 | } while (status != WL_CONNECTED);
93 |
94 | Serial.println("Connected to wifi");
95 |
96 | // Start UDP communication. No IP needed, because we are transmitting data
97 | udp.begin(0);
98 | }
99 |
100 | void loop() {
101 | static uint16_t counter = 0; // The payload is only a simple counter
102 |
103 | // via multicast we send the counter as the UDP message
104 | if (udp.beginPacket(remoteIP, remotePort) == 1) {
105 | uint8_t buffer[2];
106 |
107 | ++counter;
108 | buffer[0] = counter >> 8;
109 | buffer[1] = (counter && 0xff);
110 |
111 | // Write the payload
112 | udp.write(buffer, sizeof(buffer));
113 |
114 | // Send the packet
115 | if (udp.endPacket() == 1) {
116 | // Success
117 | Serial.println(counter);
118 | }
119 | else {
120 | Serial.println("send failed");
121 | }
122 | }
123 | else {
124 | Serial.println("open failed");
125 | }
126 |
127 | delay(1000);
128 | }
129 |
130 |
131 | void printWifiStatus() {
132 | // print the SSID of the network you're attached to:
133 | Serial.print("SSID: ");
134 | Serial.println(WiFiSpi.SSID());
135 |
136 | // print your WiFi shield's IP address:
137 | IPAddress ip = WiFiSpi.localIP();
138 | Serial.print("IP Address: ");
139 | Serial.println(ip);
140 |
141 | // print the received signal strength:
142 | long rssi = WiFiSpi.RSSI();
143 | Serial.print("signal strength (RSSI):");
144 | Serial.print(rssi);
145 | Serial.println(" dBm");
146 | }
147 |
--------------------------------------------------------------------------------
/examples/UdpNTPClient/UdpNTPClient.ino:
--------------------------------------------------------------------------------
1 | /*
2 | WiFiSPI example: UdpNTPClient
3 |
4 | Gets the time from a Network Time Protocol (NTP) time server.
5 | Demonstrates the use of UDP to send and receive data packets
6 | For more on NTP time servers and the messages needed to communicate with them,
7 | see http://en.wikipedia.org/wiki/Network_Time_Protocol
8 |
9 | This example is written for a network using WPA encryption.
10 |
11 | Circuit:
12 | 1. On ESP8266 must be running (flashed) WiFiSPIESP application.
13 |
14 | 2. Connect the master (Arduino or STM32F103) to the following pins on the esp8266:
15 |
16 | ESP8266 | |
17 | GPIO NodeMCU Name | Uno | STM32F103
18 | ===============================================
19 | 15 D8 SS | D10 | PA4
20 | 13 D7 MOSI | D11 | PA7
21 | 12 D6 MISO | D12 | PA6
22 | 14 D5 SCK | D13 | PA5
23 |
24 | Note: If the ESP is booting at the moment when the SPI Master (i.e. Arduino) has the Select line HIGH (deselected)
25 | the ESP8266 WILL FAIL to boot!
26 |
27 | modified for WiFiSpi library 25 Nov 2017
28 | by Jiri Bilek
29 | */
30 |
31 | #include "WiFiSpi.h"
32 | #include "WiFiSpiUdp.h"
33 |
34 | // WiFi credentials
35 | char ssid[] = "yourNetwork"; // your network SSID (name)
36 | char pass[] = "secretPassword"; // your network password (use for WPA)
37 |
38 | int status = WL_IDLE_STATUS; // the Wifi radio's status
39 |
40 | char timeServer[] = "time.nist.gov"; // NTP server
41 | unsigned int localPort = 2390; // local port to listen for UDP packets
42 |
43 | const int NTP_PACKET_SIZE = 48; // NTP timestamp is in the first 48 bytes of the message
44 | const int UDP_TIMEOUT = 2000; // timeout in miliseconds to wait for an UDP packet to arrive
45 |
46 | byte packetBuffer[NTP_PACKET_SIZE]; // buffer to hold incoming and outgoing packets
47 |
48 | // A UDP instance to let us send and receive packets over UDP
49 | WiFiSpiUdp Udp;
50 |
51 | void setup()
52 | {
53 | // initialize serial for debugging
54 | Serial.begin(115200);
55 | while (!Serial) {
56 | ; // wait for serial port to connect. Needed for native USB port only
57 | }
58 |
59 | // initialize the ESP module
60 | WiFiSpi.init();
61 |
62 | // check for the presence of the shield
63 | if (WiFiSpi.status() == WL_NO_SHIELD) {
64 | Serial.println("WiFi shield not present");
65 | // don't continue
66 | while (true);
67 | }
68 |
69 | if (!WiFiSpi.checkProtocolVersion()) {
70 | Serial.println("Protocol version mismatch. Please upgrade the firmware");
71 | // don't continue:
72 | while (true);
73 | }
74 |
75 | // attempt to connect to WiFi network
76 | while (status != WL_CONNECTED) {
77 | Serial.print("Attempting to connect to WPA SSID: ");
78 | Serial.println(ssid);
79 | // Connect to WPA/WPA2 network
80 | status = WiFiSpi.begin(ssid, pass);
81 | }
82 |
83 | // you're connected now, so print out the data
84 | Serial.println("You're connected to the network");
85 |
86 | Udp.begin(localPort);
87 | }
88 |
89 | void loop()
90 | {
91 | sendNTPpacket(timeServer); // send an NTP packet to a time server
92 |
93 | // wait for a reply for UDP_TIMEOUT miliseconds
94 | unsigned long startMs = millis();
95 | while (!Udp.parsePacket() && (millis() - startMs) < UDP_TIMEOUT) {}
96 |
97 | // when there should be a packet do not call parsePacket() once more, call available() instead
98 | if (Udp.available()) {
99 | Serial.println("packet received");
100 | // We've received a packet, read the data from it into the buffer
101 | Udp.read(packetBuffer, NTP_PACKET_SIZE);
102 |
103 | // the timestamp starts at byte 40 of the received packet and is four bytes,
104 | // or two words, long. First, extract the two words:
105 |
106 | unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
107 | unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
108 | // combine the four bytes (two words) into a long integer
109 | // this is NTP time (seconds since Jan 1 1900):
110 | unsigned long secsSince1900 = highWord << 16 | lowWord;
111 | Serial.print("Seconds since Jan 1 1900 = ");
112 | Serial.println(secsSince1900);
113 |
114 | // now convert NTP time into everyday time:
115 | Serial.print("Unix time = ");
116 | // Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
117 | const unsigned long seventyYears = 2208988800UL;
118 | // subtract seventy years:
119 | unsigned long epoch = secsSince1900 - seventyYears;
120 | // print Unix time:
121 | Serial.println(epoch);
122 |
123 |
124 | // print the hour, minute and second:
125 | Serial.print("The UTC time is "); // UTC is the time at Greenwich Meridian (GMT)
126 | Serial.print((epoch % 86400L) / 3600); // print the hour (86400 equals secs per day)
127 | Serial.print(':');
128 | if (((epoch % 3600) / 60) < 10) {
129 | // In the first 10 minutes of each hour, we'll want a leading '0'
130 | Serial.print('0');
131 | }
132 | Serial.print((epoch % 3600) / 60); // print the minute (3600 equals secs per minute)
133 | Serial.print(':');
134 | if ((epoch % 60) < 10) {
135 | // In the first 10 seconds of each minute, we'll want a leading '0'
136 | Serial.print('0');
137 | }
138 | Serial.println(epoch % 60); // print the second
139 | }
140 |
141 | // wait ten seconds before asking for the time again
142 | delay(10000);
143 | }
144 |
145 | // send an NTP request to the time server at the given address
146 | void sendNTPpacket(char *ntpSrv)
147 | {
148 | // set all bytes in the buffer to 0
149 | memset(packetBuffer, 0, NTP_PACKET_SIZE);
150 | // Initialize values needed to form NTP request
151 | // (see URL above for details on the packets)
152 |
153 | packetBuffer[0] = 0b11100011; // LI, Version, Mode
154 | packetBuffer[1] = 0; // Stratum, or type of clock
155 | packetBuffer[2] = 6; // Polling Interval
156 | packetBuffer[3] = 0xEC; // Peer Clock Precision
157 | // 8 bytes of zero for Root Delay & Root Dispersion
158 | packetBuffer[12] = 49;
159 | packetBuffer[13] = 0x4E;
160 | packetBuffer[14] = 49;
161 | packetBuffer[15] = 52;
162 |
163 | // all NTP fields have been given values, now
164 | // you can send a packet requesting a timestamp:
165 | Udp.beginPacket(ntpSrv, 123); //NTP requests are to port 123
166 |
167 | Udp.write(packetBuffer, NTP_PACKET_SIZE);
168 |
169 | Udp.endPacket();
170 | }
171 |
--------------------------------------------------------------------------------
/examples/WiFiWebClient/WiFiWebClient.ino:
--------------------------------------------------------------------------------
1 | /*
2 | Web client
3 |
4 | This sketch connects to a website (http://www.example.com)
5 | using a WiFi ESP8266 module.
6 |
7 | This example is written for a network using WPA encryption.
8 |
9 | Circuit:
10 | 1. On ESP8266 must be running (flashed) WiFiSPIESP application.
11 |
12 | 2. Connect the master (Arduino or STM32F103) to the following pins on the esp8266:
13 |
14 | ESP8266 | |
15 | GPIO NodeMCU Name | Uno | STM32F103
16 | ===============================================
17 | 15 D8 SS | D10 | PA4
18 | 13 D7 MOSI | D11 | PA7
19 | 12 D6 MISO | D12 | PA6
20 | 14 D5 SCK | D13 | PA5
21 |
22 | Note: If the ESP is booting at the moment when the SPI Master (i.e. Arduino) has the Select line HIGH (deselected)
23 | the ESP8266 WILL FAIL to boot!
24 |
25 | original sketch for WiFi library created 13 July 2010
26 | by dlf (Metodo2 srl)
27 | modified 31 May 2012
28 | by Tom Igoe
29 |
30 | modified for WiFiSpi library 14 Mar 2017
31 | by Jiri Bilek
32 | */
33 |
34 |
35 | #include
36 |
37 | // WiFi credentials
38 | char ssid[] = "yourNetwork"; // your network SSID (name)
39 | char pass[] = "secretPassword"; // your network password (use for WPA)
40 |
41 | // if you don't want to use DNS (and reduce your sketch size)
42 | // use the numeric IP instead of the name for the server:
43 | //IPAddress server(93,184,216,34); // numeric IP for www.example.com (no DNS)
44 | char server[] = "www.example.com"; // name address using DNS
45 |
46 | // Initialize the Ethernet client library
47 | // with the IP address and port of the server
48 | // that you want to connect to (port 80 is default for HTTP):
49 | WiFiSpiClient client;
50 |
51 | void setup() {
52 | //Initialize serial and wait for port to open:
53 | Serial.begin(9600);
54 | while (!Serial) {
55 | ; // wait for serial port to connect. Needed for native USB port only
56 | }
57 |
58 | // Initialize the WifiSpi library
59 | WiFiSpi.init();
60 |
61 | // check for the presence of the shield:
62 | if (WiFiSpi.status() == WL_NO_SHIELD) {
63 | Serial.println("WiFi shield not present");
64 | // don't continue:
65 | while (true);
66 | }
67 |
68 | if (!WiFiSpi.checkProtocolVersion()) {
69 | Serial.println("Protocol version mismatch. Please upgrade the firmware");
70 | // don't continue:
71 | while (true);
72 | }
73 |
74 | // attempt to connect to Wifi network:
75 | Serial.print("Attempting to connect to SSID: ");
76 | Serial.println(ssid);
77 | // Connect to WPA/WPA2 network. Change this line if using open network:
78 | int status = WiFiSpi.begin(ssid, pass);
79 |
80 | if (status != WL_CONNECTED) {
81 | Serial.println("Cannot connect to AP. Stop.");
82 | // don't continue if connection failed
83 | while (true);
84 | }
85 |
86 | Serial.println("Connected to wifi");
87 | printWifiStatus();
88 |
89 | Serial.println("\nStarting connection to server...");
90 | // if you get a connection, report back via serial:
91 | if (client.connect(server, 80)) {
92 | Serial.println("connected to server");
93 | // Make a HTTP request:
94 | // Note: client.print() is transmitting one char per a message that is awfully wasting the SPI bus bandwidth
95 | // client.write(char*) is optimized and has minimum overhead
96 | client.write("GET / HTTP/1.1\r\n"
97 | "Host: www.example.com\r\n"
98 | "Connection: close\r\n\r\n");
99 | }
100 | }
101 |
102 | void loop() {
103 | // if there are incoming bytes available
104 | // from the server, read them and print them:
105 | while (client.available()) {
106 | char c = client.read();
107 | Serial.write(c);
108 | }
109 |
110 | // if the server's disconnected, stop the client:
111 | if (!client.connected()) {
112 | Serial.println();
113 | Serial.println("disconnecting from server.");
114 | client.stop();
115 |
116 | // do nothing forevermore:
117 | while (true);
118 | }
119 | }
120 |
121 |
122 | void printWifiStatus() {
123 | // print the SSID of the network you're attached to:
124 | Serial.print("SSID: ");
125 | Serial.println(WiFiSpi.SSID());
126 |
127 | // print your WiFi shield's IP address:
128 | IPAddress ip = WiFiSpi.localIP();
129 | Serial.print("IP Address: ");
130 | Serial.println(ip);
131 |
132 | // print the received signal strength:
133 | long rssi = WiFiSpi.RSSI();
134 | Serial.print("signal strength (RSSI):");
135 | Serial.print(rssi);
136 | Serial.println(" dBm");
137 | }
138 |
--------------------------------------------------------------------------------
/examples/WiFiWebClientSSL/WiFiWebClientSSL.ino:
--------------------------------------------------------------------------------
1 | /*
2 | SSL Web client
3 |
4 | This sketch connects to a website (https://www.example.com)
5 | using a WiFi ESP8266 module and checks the validity of the server certificate.
6 |
7 | This example is written for a network using WPA encryption.
8 |
9 | Circuit:
10 | 1. On ESP8266 must be running (flashed) WiFiSPIESP application.
11 |
12 | 2. Connect the master (Arduino or STM32F103) to the following pins on the esp8266:
13 |
14 | ESP8266 | |
15 | GPIO NodeMCU Name | Uno | STM32F103
16 | ===============================================
17 | 15 D8 SS | D10 | PA4
18 | 13 D7 MOSI | D11 | PA7
19 | 12 D6 MISO | D12 | PA6
20 | 14 D5 SCK | D13 | PA5
21 |
22 | Note: If the ESP is booting at the moment when the SPI Master (i.e. Arduino) has the Select line HIGH (deselected)
23 | the ESP8266 WILL FAIL to boot!
24 |
25 | original sketch for WiFi library created 13 July 2010
26 | by dlf (Metodo2 srl)
27 | modified 31 May 2012
28 | by Tom Igoe
29 |
30 | modified for WiFiSpi library 14 Mar 2017
31 | by Jiri Bilek
32 | */
33 |
34 |
35 | #include
36 |
37 | // WiFi credentials
38 | char ssid[] = "yourNetwork"; // your network SSID (name)
39 | char pass[] = "secretPassword"; // your network password (use for WPA)
40 |
41 | // if you don't want to use DNS (and reduce your sketch size)
42 | // use the numeric IP instead of the name for the server:
43 | //IPAddress server(93,184,216,34); // numeric IP for www.example.com (no DNS)
44 | char server[] = "www.example.com"; // name address using DNS
45 |
46 | // Initialize the Ethernet client library
47 | // with the IP address and port of the server
48 | // that you want to connect to (port 80 is default for HTTP):
49 | WiFiSpiClient client;
50 |
51 | void setup() {
52 | //Initialize serial and wait for port to open:
53 | Serial.begin(9600);
54 | while (!Serial) {
55 | ; // wait for serial port to connect. Needed for native USB port only
56 | }
57 |
58 | // Initialize the WifiSpi library
59 | WiFiSpi.init();
60 |
61 | // check for the presence of the shield:
62 | if (WiFiSpi.status() == WL_NO_SHIELD) {
63 | Serial.println("WiFi shield not present");
64 | // don't continue:
65 | while (true);
66 | }
67 |
68 | if (!WiFiSpi.checkProtocolVersion()) {
69 | Serial.println("Protocol version mismatch. Please upgrade the firmware");
70 | // don't continue:
71 | while (true);
72 | }
73 |
74 | // attempt to connect to Wifi network:
75 | int status;
76 |
77 | do {
78 | Serial.print("Attempting to connect to SSID: ");
79 | Serial.println(ssid);
80 | // Connect to WPA/WPA2 network. Change this line if using open network:
81 | status = WiFiSpi.begin(ssid, pass);
82 | } while (status != WL_CONNECTED);
83 |
84 | Serial.println("Connected to wifi");
85 | printWifiStatus();
86 |
87 | // Set the server certificate SHA-1 fingerprint
88 | // Please check the correctness of the fingerprint - this certificate expires on 12-26-2021
89 | uint8_t fingerprint[] = {0x0A,0x28,0xA6,0xEB,0x17,0x6E,0xA9,0xCC,0x59,0x6F,
90 | 0x4C,0x73,0xFD,0x89,0x7E,0xFB,0xD3,0x2D,0xCA,0x2A};
91 | WiFiSpi.setSSLFingerprint(fingerprint);
92 |
93 | Serial.println("\nStarting connection to server...");
94 | // if you get a connection, report back via serial:
95 | if (client.connectSSL(server, 443)) {
96 | Serial.println("connected to server");
97 |
98 | // Make a HTTP request:
99 | // Note: client.print() is transmitting one char per a message that is awfully wasting the SPI bus bandwidth
100 | // client.write(char*) is optimized and has minimum overhead
101 | client.write("GET / HTTP/1.1\r\n"
102 | "Host: www.example.com\r\n"
103 | "Connection: close\r\n\r\n");
104 | }
105 | }
106 |
107 | void loop() {
108 | // if there are incoming bytes available
109 | // from the server, read them and print them:
110 | while (client.available()) {
111 | char c = client.read();
112 | Serial.write(c);
113 | }
114 |
115 | // if the server's disconnected, stop the client:
116 | if (!client.connected()) {
117 | Serial.println();
118 | Serial.println("disconnecting from server.");
119 | client.stop();
120 |
121 | // do nothing forevermore:
122 | while (true);
123 | }
124 | }
125 |
126 |
127 | void printWifiStatus() {
128 | // print the SSID of the network you're attached to:
129 | Serial.print("SSID: ");
130 | Serial.println(WiFiSpi.SSID());
131 |
132 | // print your WiFi shield's IP address:
133 | IPAddress ip = WiFiSpi.localIP();
134 | Serial.print("IP Address: ");
135 | Serial.println(ip);
136 |
137 | // print the received signal strength:
138 | long rssi = WiFiSpi.RSSI();
139 | Serial.print("signal strength (RSSI):");
140 | Serial.print(rssi);
141 | Serial.println(" dBm");
142 | }
143 |
--------------------------------------------------------------------------------
/keywords.txt:
--------------------------------------------------------------------------------
1 | #######################################
2 | # Syntax Coloring Map For WiFiSpi
3 | #######################################
4 |
5 | #######################################
6 | # Library (KEYWORD3)
7 | #######################################
8 |
9 |
10 | #######################################
11 | # Datatypes (KEYWORD1)
12 | #######################################
13 |
14 | WiFiSpi KEYWORD1
15 | WiFiSpiClient KEYWORD1
16 | WiFiSpiServer KEYWORD1
17 | WiFiSpiUDP KEYWORD1
18 |
19 | #######################################
20 | # Methods and Functions (KEYWORD2)
21 | #######################################
22 |
23 | firmwareVersion KEYWORD2
24 | status KEYWORD2
25 | connect KEYWORD2
26 | write KEYWORD2
27 | available KEYWORD2
28 | config KEYWORD2
29 | setDNS KEYWORD2
30 | read KEYWORD2
31 | flush KEYWORD2
32 | stop KEYWORD2
33 | connected KEYWORD2
34 | begin KEYWORD2
35 | disconnect KEYWORD2
36 | macAddress KEYWORD2
37 | localIP KEYWORD2
38 | subnetMask KEYWORD2
39 | gatewayIP KEYWORD2
40 | scanNetworks KEYWORD2
41 | SSID KEYWORD2
42 | BSSID KEYWORD2
43 | RSSI KEYWORD2
44 | encryptionType KEYWORD2
45 | getResult KEYWORD2
46 | getSocket KEYWORD2
47 | beginPacket KEYWORD2
48 | endPacket KEYWORD2
49 | parsePacket KEYWORD2
50 | remoteIP KEYWORD2
51 | remotePort KEYWORD2
52 | softReset KEYWORD2
53 | hardReset KEYWORD2
54 | protocolVersion KEYWORD2
55 | masterProtocolVersion KEYWORD2
56 | checkProtocolVersion KEYWORD2
57 |
58 |
59 | #######################################
60 | # Constants (LITERAL1)
61 | #######################################
62 |
63 |
--------------------------------------------------------------------------------
/library.properties:
--------------------------------------------------------------------------------
1 | name=WiFiSpi
2 | version=0.3.0
3 | author=JiriBilek
4 | maintainer=Jiri Bilek
5 | sentence=Arduino WiFi library connecting ESP8266 via SPI protocol
6 | paragraph=Arduino WiFi library for connecting with ESP8266. Uses SPI protocol for communication.
7 | category=Communication
8 | url=https://github.com/JiriBilek/WiFiSpi
9 | architectures=avr,STM32F1,stm32
--------------------------------------------------------------------------------
/src/WiFiSpi.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | WiFiSPI.cpp - Library for Arduino SPI connection to ESP8266
3 | Copyright (c) 2017 Jiri Bilek. All rights reserved.
4 |
5 | -----
6 |
7 | Based on WiFi.cpp - Library for Arduino Wifi shield.
8 | Copyright (c) 2011-2014 Arduino LLC. All right reserved.
9 |
10 | This library is free software; you can redistribute it and/or
11 | modify it under the terms of the GNU Lesser General Public
12 | License as published by the Free Software Foundation; either
13 | version 2.1 of the License, or (at your option) any later version.
14 |
15 | This library is distributed in the hope that it will be useful,
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 | Lesser General Public License for more details.
19 |
20 | You should have received a copy of the GNU Lesser General Public
21 | License along with this library; if not, write to the Free Software
22 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 | */
24 |
25 | #include "WiFiSpi.h"
26 | #include "utility/wifispi_drv.h"
27 | #include "utility/espspi_proxy.h"
28 |
29 | extern "C" {
30 | #include "utility/wl_definitions.h"
31 | #include "utility/wl_types.h"
32 | /// #include "utility/debug.h"
33 | }
34 |
35 | // Protocol version
36 | const char *WiFiSpiClass::protocolVer = "0.3.0";
37 |
38 | // Hardware reset pin
39 | int8_t WiFiSpiClass::hwResetPin = -1;
40 |
41 | // No assumptions about the value of MAX_SOCK_NUM
42 | int16_t WiFiSpiClass::_state[MAX_SOCK_NUM];
43 | uint16_t WiFiSpiClass::_server_port[MAX_SOCK_NUM];
44 |
45 | WiFiSpiClass::WiFiSpiClass()
46 | {
47 | }
48 |
49 | void WiFiSpiClass::init(int8_t pin, uint32_t max_speed, SPIClass *in_spi, int8_t hwResetPin)
50 | {
51 | // Initialize the connection arrays
52 | for (uint8_t i = 0; i < MAX_SOCK_NUM; ++i)
53 | {
54 | _state[i] = NA_STATE;
55 | _server_port[i] = 0;
56 | }
57 |
58 | if (pin < 0)
59 | pin = SS;
60 |
61 | WiFiSpiDrv::wifiDriverInit(pin, max_speed, in_spi);
62 |
63 | WiFiSpiClass::hwResetPin = hwResetPin;
64 | hardReset();
65 | }
66 |
67 | uint8_t WiFiSpiClass::getSocket()
68 | {
69 | for (uint8_t i = 0; i < MAX_SOCK_NUM; ++i)
70 | {
71 | if (WiFiSpiClass::_state[i] == NA_STATE) // _state is for both server and client
72 | return i;
73 | }
74 | return SOCK_NOT_AVAIL;
75 | }
76 |
77 | /*
78 | *
79 | */
80 | const char* WiFiSpiClass::firmwareVersion()
81 | {
82 | return WiFiSpiDrv::getFwVersion();
83 | }
84 |
85 | /*
86 | *
87 | */
88 | uint8_t WiFiSpiClass::begin(const char* ssid)
89 | {
90 | uint8_t status = WL_IDLE_STATUS;
91 | uint8_t attempts = WL_MAX_ATTEMPT_CONNECTION;
92 |
93 | if (WiFiSpiDrv::wifiSetNetwork(ssid, strlen(ssid)) != WL_FAILURE)
94 | {
95 | do
96 | {
97 | delay(WL_DELAY_START_CONNECTION);
98 | status = WiFiSpiDrv::getConnectionStatus();
99 | }
100 | while (((status == WL_IDLE_STATUS) || (status == WL_SCAN_COMPLETED) || (status == WL_DISCONNECTED)) && (--attempts > 0));
101 | } else
102 | status = WL_CONNECT_FAILED;
103 |
104 | return status;
105 | }
106 |
107 | /*
108 | *
109 | */
110 | uint8_t WiFiSpiClass::begin(const char* ssid, const char *passphrase)
111 | {
112 | uint8_t status = WL_IDLE_STATUS;
113 | uint8_t attempts = WL_MAX_ATTEMPT_CONNECTION;
114 |
115 | // SSID and passphrase for WPA connection
116 | if (WiFiSpiDrv::wifiSetPassphrase(ssid, strlen(ssid), passphrase, strlen(passphrase)) != WL_FAILURE)
117 | {
118 | do
119 | {
120 | delay(WL_DELAY_START_CONNECTION);
121 | status = WiFiSpiDrv::getConnectionStatus();
122 | }
123 | while (((status == WL_IDLE_STATUS) || (status == WL_SCAN_COMPLETED) || (status == WL_DISCONNECTED)) && (--attempts > 0));
124 | } else
125 | status = WL_CONNECT_FAILED;
126 |
127 | return status;
128 | }
129 |
130 | /*
131 | *
132 | */
133 | bool WiFiSpiClass::config(IPAddress local_ip)
134 | {
135 | return WiFiSpiDrv::config((uint32_t)local_ip, 0, 0, 0, 0);
136 | }
137 |
138 | /*
139 | *
140 | */
141 | bool WiFiSpiClass::config(IPAddress local_ip, IPAddress dns_server)
142 | {
143 | return WiFiSpiDrv::config((uint32_t)local_ip, 0, 0, (uint32_t)dns_server, 0);
144 | }
145 |
146 | /*
147 | *
148 | */
149 | bool WiFiSpiClass::config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway)
150 | {
151 | return WiFiSpiDrv::config((uint32_t)local_ip, (uint32_t)gateway, 0, (uint32_t)dns_server, 0);
152 | }
153 |
154 | /*
155 | *
156 | */
157 | bool WiFiSpiClass::config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway, IPAddress subnet)
158 | {
159 | return WiFiSpiDrv::config((uint32_t)local_ip, (uint32_t)gateway, (uint32_t)subnet, (uint32_t)dns_server, 0);
160 | }
161 |
162 | /*
163 | *
164 | */
165 | bool WiFiSpiClass::setDNS(IPAddress dns_server1)
166 | {
167 | return WiFiSpiDrv::config(0, 0, 0, (uint32_t)dns_server1, 0);
168 | }
169 |
170 | /*
171 | *
172 | */
173 | bool WiFiSpiClass::setDNS(IPAddress dns_server1, IPAddress dns_server2)
174 | {
175 | return WiFiSpiDrv::config(0, 0, 0, (uint32_t)dns_server1, (uint32_t)dns_server2);
176 | }
177 |
178 | /*
179 | *
180 | */
181 | int WiFiSpiClass::disconnect()
182 | {
183 | return WiFiSpiDrv::disconnect();
184 | }
185 |
186 | /*
187 | *
188 | */
189 | uint8_t* WiFiSpiClass::macAddress(uint8_t* mac)
190 | {
191 | uint8_t* _mac = WiFiSpiDrv::getMacAddress();
192 | memcpy(mac, _mac, WL_MAC_ADDR_LENGTH);
193 | return mac;
194 | }
195 |
196 | /*
197 | *
198 | */
199 | IPAddress WiFiSpiClass::localIP()
200 | {
201 | IPAddress ret;
202 | WiFiSpiDrv::getIpAddress(ret);
203 | return ret;
204 | }
205 |
206 | /*
207 | *
208 | */
209 | IPAddress WiFiSpiClass::subnetMask()
210 | {
211 | IPAddress ret;
212 | WiFiSpiDrv::getSubnetMask(ret);
213 | return ret;
214 | }
215 |
216 | /*
217 | *
218 | */
219 | IPAddress WiFiSpiClass::gatewayIP()
220 | {
221 | IPAddress ret;
222 | WiFiSpiDrv::getGatewayIP(ret);
223 | return ret;
224 | }
225 |
226 | /*
227 | *
228 | */
229 | char* WiFiSpiClass::SSID()
230 | {
231 | return WiFiSpiDrv::getCurrentSSID();
232 | }
233 |
234 | /*
235 | *
236 | */
237 | uint8_t* WiFiSpiClass::BSSID()
238 | {
239 | return WiFiSpiDrv::getCurrentBSSID();
240 | }
241 |
242 | /*
243 | *
244 | */
245 | int32_t WiFiSpiClass::RSSI()
246 | {
247 | return WiFiSpiDrv::getCurrentRSSI();
248 | }
249 |
250 | /*///uint8_t WiFiSpiClass::encryptionType()
251 | {
252 | return WiFiSpiDrv::getCurrentEncryptionType();
253 | }*/
254 |
255 | /*
256 | *
257 | */
258 | int8_t WiFiSpiClass::scanNetworks()
259 | {
260 | #define WIFI_SCAN_RUNNING (-1)
261 | #define WIFI_SCAN_FAILED (-2)
262 |
263 | uint8_t attempts = 10;
264 | int8_t numOfNetworks = 0;
265 |
266 | if (WiFiSpiDrv::startScanNetworks() == WIFI_SCAN_FAILED)
267 | return WL_FAILURE;
268 |
269 | do
270 | {
271 | delay(2000);
272 | numOfNetworks = WiFiSpiDrv::getScanNetworks();
273 |
274 | if (numOfNetworks == WIFI_SCAN_FAILED)
275 | return WL_FAILURE;
276 | }
277 | while ((numOfNetworks == WIFI_SCAN_RUNNING) && (--attempts > 0));
278 |
279 | return numOfNetworks;
280 | }
281 |
282 | /*
283 | *
284 | */
285 | char* WiFiSpiClass::SSID(uint8_t networkItem)
286 | {
287 | return WiFiSpiDrv::getSSIDNetworks(networkItem);
288 | }
289 |
290 | /*
291 | *
292 | */
293 | int32_t WiFiSpiClass::RSSI(uint8_t networkItem)
294 | {
295 | return WiFiSpiDrv::getRSSINetworks(networkItem);
296 | }
297 |
298 | /*
299 | *
300 | */
301 | uint8_t WiFiSpiClass::encryptionType(uint8_t networkItem)
302 | {
303 | return WiFiSpiDrv::getEncTypeNetworks(networkItem);
304 | }
305 |
306 | /*
307 | *
308 | */
309 | uint8_t WiFiSpiClass::status()
310 | {
311 | return WiFiSpiDrv::getConnectionStatus();
312 | }
313 |
314 | /*
315 | *
316 | */
317 | int8_t WiFiSpiClass::hostByName(const char* aHostname, IPAddress& aResult)
318 | {
319 | return WiFiSpiDrv::getHostByName(aHostname, aResult);
320 | }
321 |
322 | /*
323 | * Perform remote software reset of the ESP8266 module.
324 | * The reset succeedes only if the SPI communication is not broken.
325 | * The function does not wait for the ESP8266.
326 | */
327 | void WiFiSpiClass::softReset(void) {
328 | WiFiSpiDrv::softReset();
329 | }
330 |
331 | /*
332 | *
333 | */
334 | const char* WiFiSpiClass::protocolVersion()
335 | {
336 | return WiFiSpiDrv::getProtocolVersion();
337 | }
338 |
339 | /*
340 | *
341 | */
342 | const char* WiFiSpiClass::masterProtocolVersion()
343 | {
344 | return protocolVer;
345 | }
346 |
347 | /*
348 | *
349 | */
350 | uint8_t WiFiSpiClass::checkProtocolVersion()
351 | {
352 | const char* s = WiFiSpiDrv::getProtocolVersion();
353 | for (const char* p = protocolVer; *p; ++p, ++s)
354 | if (*p != *s)
355 | return 0;
356 |
357 | return (*s == 0);
358 | }
359 |
360 | /*
361 | *
362 | */
363 | void WiFiSpiClass::hardReset(void)
364 | {
365 | if (hwResetPin <= 0)
366 | return; // no reset pin
367 |
368 | pinMode(hwResetPin, OUTPUT);
369 |
370 | espSpiProxy.hardReset(hwResetPin);
371 | }
372 |
373 | /*
374 | *
375 | */
376 |
377 | uint8_t WiFiSpiClass::setSSLFingerprint(uint8_t* fingerprint)
378 | {
379 | return WiFiSpiDrv::setSSLFingerprint(fingerprint);
380 | }
381 |
382 |
383 | WiFiSpiClass WiFiSpi;
384 |
--------------------------------------------------------------------------------
/src/WiFiSpi.h:
--------------------------------------------------------------------------------
1 | /*
2 | WiFiSPI.h - Library for Arduino SPI connection to ESP8266
3 | Copyright (c) 2017 Jiri Bilek. All rights reserved.
4 |
5 | Circuit:
6 | 1. On ESP8266 must be running (flashed) WiFiSPIESP application.
7 |
8 | 2. Connect the Arduino to the following pins on the esp8266:
9 |
10 | ESP8266 |
11 | GPIO NodeMCU Name | Uno
12 | ===================================
13 | 15 D8 SS | D10
14 | 13 D7 MOSI | D11
15 | 12 D6 MISO | D12
16 | 14 D5 SCK | D13
17 |
18 | Note: If the ESP is booting at a moment when the SPI Master (i.e. Arduino) has the Select line HIGH (deselected)
19 | the ESP8266 WILL FAIL to boot!
20 |
21 | -----
22 |
23 | Based on WiFi.h - Library for Arduino Wifi shield.
24 | Copyright (c) 2011-2014 Arduino LLC. All right reserved.
25 |
26 | This library is free software; you can redistribute it and/or
27 | modify it under the terms of the GNU Lesser General Public
28 | License as published by the Free Software Foundation; either
29 | version 2.1 of the License, or (at your option) any later version.
30 |
31 | This library is distributed in the hope that it will be useful,
32 | but WITHOUT ANY WARRANTY; without even the implied warranty of
33 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
34 | Lesser General Public License for more details.
35 |
36 | You should have received a copy of the GNU Lesser General Public
37 | License along with this library; if not, write to the Free Software
38 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
39 | */
40 |
41 | #ifndef _WIFISPI_H_INCLUDED
42 | #define _WIFISPI_H_INCLUDED
43 |
44 | #include
45 | #include
46 |
47 | extern "C" {
48 | #include "utility/wl_definitions.h"
49 | #include "utility/wl_types.h"
50 | }
51 |
52 | #include "utility/wifi_spi.h"
53 | #include "IPAddress.h"
54 |
55 | #include "WiFiSpiClient.h"
56 | #include "WiFiSpiServer.h"
57 | #include "WiFiSpiUdp.h"
58 |
59 |
60 | class WiFiSpiClass
61 | {
62 | public:
63 | /*
64 | * Initialization of the library.
65 | *
66 | * param pin: SS pin, default value get default pin
67 | * param max_speed: maximum speed of SPI interface
68 | * param in_spi: pointer to SPI Class
69 | * param hwResetPin: number of the PIN connected to ESP's RESET or -1
70 | */
71 | static void init(int8_t pin = -1, uint32_t max_speed = 0, SPIClass *in_spi = &SPI, int8_t hwResetPin = -1);
72 |
73 | private:
74 | static int16_t _state[MAX_SOCK_NUM];
75 | static uint16_t _server_port[MAX_SOCK_NUM];
76 |
77 | static int8_t hwResetPin;
78 |
79 | static const char *protocolVer;
80 |
81 | public:
82 | WiFiSpiClass();
83 |
84 | /*
85 | * Get the first socket available
86 | */
87 | static uint8_t getSocket();
88 |
89 | /*
90 | * Get firmware version
91 | */
92 | static const char* firmwareVersion();
93 |
94 |
95 | /* Start Wifi connection for OPEN networks
96 | *
97 | * param ssid: Pointer to the SSID string.
98 | */
99 | uint8_t begin(const char* ssid);
100 |
101 | /* Start Wifi connection with WEP encryption.
102 | * Configure a key into the device. The key type (WEP-40, WEP-104)
103 | * is determined by the size of the key (5 bytes for WEP-40, 13 bytes for WEP-104).
104 | *
105 | * param ssid: Pointer to the SSID string.
106 | * param key_idx: The key index to set. Valid values are 0-3.
107 | * param key: Key input buffer.
108 | */
109 | /// uint8_t begin(const char* ssid, uint8_t key_idx, const char* key);
110 |
111 | /* Start Wifi connection with passphrase
112 | * the most secure supported mode will be automatically selected
113 | *
114 | * param ssid: Pointer to the SSID string.
115 | * param passphrase: Passphrase. Valid characters in a passphrase
116 | * must be between ASCII 32-126 (decimal).
117 | */
118 | uint8_t begin(const char* ssid, const char *passphrase);
119 |
120 | /* Change Ip configuration settings disabling the dhcp client
121 | *
122 | * param local_ip: Static ip configuration
123 | */
124 | bool config(IPAddress local_ip);
125 |
126 | /* Change Ip configuration settings disabling the dhcp client
127 | *
128 | * param local_ip: Static ip configuration
129 | * param dns_server: IP configuration for DNS server 1
130 | */
131 | bool config(IPAddress local_ip, IPAddress dns_server);
132 |
133 | /* Change Ip configuration settings disabling the dhcp client
134 | *
135 | * param local_ip: Static ip configuration
136 | * param dns_server: IP configuration for DNS server 1
137 | * param gateway : Static gateway configuration
138 | */
139 | bool config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway);
140 |
141 | /* Change Ip configuration settings disabling the dhcp client
142 | *
143 | * param local_ip: Static ip configuration
144 | * param dns_server: IP configuration for DNS server 1
145 | * param gateway: Static gateway configuration
146 | * param subnet: Static Subnet mask
147 | */
148 | bool config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway, IPAddress subnet);
149 |
150 | /* Change DNS Ip configuration
151 | *
152 | * param dns_server1: ip configuration for DNS server 1
153 | */
154 | bool setDNS(IPAddress dns_server1);
155 |
156 | /* Change DNS Ip configuration
157 | *
158 | * param dns_server1: ip configuration for DNS server 1
159 | * param dns_server2: ip configuration for DNS server 2
160 | *
161 | */
162 | bool setDNS(IPAddress dns_server1, IPAddress dns_server2);
163 |
164 | /*
165 | * Disconnect from the network
166 | *
167 | * return: one value of wl_status_t enum
168 | */
169 | int disconnect(void);
170 |
171 | /*
172 | * Get the interface MAC address.
173 | *
174 | * return: pointer to uint8_t array with length WL_MAC_ADDR_LENGTH
175 | */
176 | uint8_t* macAddress(uint8_t* mac);
177 |
178 | /*
179 | * Get the interface IP address.
180 | *
181 | * return: Ip address value
182 | */
183 | IPAddress localIP();
184 |
185 | /*
186 | * Get the interface subnet mask address.
187 | *
188 | * return: subnet mask address value
189 | */
190 | IPAddress subnetMask();
191 |
192 | /*
193 | * Get the gateway ip address.
194 | *
195 | * return: gateway ip address value
196 | */
197 | IPAddress gatewayIP();
198 |
199 | /*
200 | * Return the current SSID associated with the network
201 | *
202 | * return: ssid string
203 | */
204 | char* SSID();
205 |
206 | /*
207 | * Return the current BSSID associated with the network.
208 | * It is the MAC address of the Access Point
209 | *
210 | * return: pointer to uint8_t array with length WL_MAC_ADDR_LENGTH
211 | */
212 | uint8_t* BSSID();
213 |
214 | /*
215 | * Return the current RSSI /Received Signal Strength in dBm)
216 | * associated with the network
217 | *
218 | * return: signed value
219 | */
220 | int32_t RSSI();
221 |
222 | /*
223 | * Return the Encryption Type associated with the network
224 | *
225 | * return: one value of wl_enc_type enum
226 | */
227 | ///uint8_t encryptionType();
228 |
229 | /*
230 | * Start scan WiFi networks available
231 | *
232 | * return: Number of discovered networks
233 | */
234 | int8_t scanNetworks();
235 |
236 | /*
237 | * Return the SSID discovered during the network scan.
238 | *
239 | * param networkItem: specify from which network item want to get the information
240 | *
241 | * return: ssid string of the specified item on the networks scanned list
242 | */
243 | char* SSID(uint8_t networkItem);
244 |
245 | /*
246 | * Return the encryption type of the networks discovered during the scanNetworks
247 | *
248 | * param networkItem: specify from which network item want to get the information
249 | *
250 | * return: encryption type (enum wl_enc_type) of the specified item on the networks scanned list
251 | */
252 | uint8_t encryptionType(uint8_t networkItem);
253 |
254 | /*
255 | * Return the RSSI of the networks discovered during the scanNetworks
256 | *
257 | * param networkItem: specify from which network item want to get the information
258 | *
259 | * return: signed value of RSSI of the specified item on the networks scanned list
260 | */
261 | int32_t RSSI(uint8_t networkItem);
262 |
263 | /*
264 | * Return Connection status.
265 | *
266 | * return: one of the value defined in wl_status_t
267 | */
268 | uint8_t status();
269 |
270 | /*
271 | * Resolve the given hostname to an IP address.
272 | * param aHostname: Name to be resolved
273 | * param aResult: IPAddress structure to store the returned IP address
274 | * result: 1 if aIPAddrString was successfully converted to an IP address,
275 | * else error code
276 | */
277 | int8_t hostByName(const char* aHostname, IPAddress& aResult);
278 |
279 | /*
280 | * Perform software reset of the ESP8266 module.
281 | * The reset succeedes only if the SPI communication is not broken.
282 | * After the reset wait for the ESP8266 to came to life again. Typically, the ESP8266 boots within 100 ms,
283 | * but with the WifiManager installed on ESP it can be a couple of seconds.
284 | */
285 | static void softReset(void);
286 |
287 | /*
288 | * Perform hardware reset of the ESP8266 module. The PIN connected to ESP's reset must be declared in init()
289 | * After the reset wait for the ESP8266 to came to life again. Typically, the ESP8266 boots within 100 ms,
290 | * but with the WifiManager installed on ESP it can be a couple of seconds.
291 | * This function waits for 200 ms.
292 | */
293 | static void hardReset(void);
294 |
295 | /*
296 | * Get slave protocol version
297 | */
298 | static const char* protocolVersion();
299 |
300 | /*
301 | * Get master protocol version
302 | */
303 | static const char* masterProtocolVersion();
304 |
305 | /*
306 | * Check protocol version
307 | * result: 1 if protocol version of both master and slave match
308 | * 0 otherwise
309 | */
310 | static uint8_t checkProtocolVersion();
311 |
312 | /*
313 | */
314 | static uint8_t setSSLFingerprint(uint8_t* fingerprint);
315 |
316 | /*
317 | * The following classes need r/w access to private arrays
318 | */
319 | friend class WiFiSpiClient;
320 | friend class WiFiSpiServer;
321 | friend class WiFiSpiUdp;
322 | };
323 |
324 | extern WiFiSpiClass WiFiSpi;
325 |
326 | #endif
327 |
--------------------------------------------------------------------------------
/src/WiFiSpiClient.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | WiFiSpiClient.cpp - Library for Arduino SPI connection to ESP8266
3 | Copyright (c) 2017 Jiri Bilek. All rights reserved.
4 |
5 | -----
6 |
7 | Based on WiFiClient.cpp - Library for Arduino Wifi shield.
8 | Copyright (c) 2011-2014 Arduino LLC. All right reserved.
9 |
10 | This library is free software; you can redistribute it and/or
11 | modify it under the terms of the GNU Lesser General Public
12 | License as published by the Free Software Foundation; either
13 | version 2.1 of the License, or (at your option) any later version.
14 |
15 | This library is distributed in the hope that it will be useful,
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 | Lesser General Public License for more details.
19 |
20 | You should have received a copy of the GNU Lesser General Public
21 | License along with this library; if not, write to the Free Software
22 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 | */
24 |
25 | extern "C" {
26 | #include "utility/wl_definitions.h"
27 | #include "utility/wl_types.h"
28 | #include
29 | #include "utility/debug.h"
30 | }
31 |
32 | #include "WiFiSpi.h"
33 | #include "WiFiSpiClient.h"
34 | #include "utility/wifi_spi.h"
35 | #include "utility/srvspi_drv.h"
36 | #include "utility/wifispi_drv.h"
37 |
38 | WiFiSpiClient::WiFiSpiClient() : _sock(SOCK_NOT_AVAIL) {
39 | }
40 |
41 | WiFiSpiClient::WiFiSpiClient(uint8_t sock) : _sock(sock) {
42 | }
43 |
44 | /*
45 | *
46 | */
47 | int WiFiSpiClient::connect(const char* host, uint16_t port)
48 | {
49 | IPAddress remote_addr;
50 | if (WiFiSpi.hostByName(host, remote_addr))
51 | {
52 | return _connect(remote_addr, port, false);
53 | }
54 | return 0;
55 | }
56 |
57 | /*
58 | *
59 | */
60 | int WiFiSpiClient::connect(IPAddress ip, uint16_t port)
61 | {
62 | return _connect(ip, port, false);
63 | }
64 |
65 | /*
66 | *
67 | */
68 | int WiFiSpiClient::connectSSL(const char* host, uint16_t port)
69 | {
70 | IPAddress remote_addr;
71 | if (WiFiSpi.hostByName(host, remote_addr))
72 | {
73 | return _connect(remote_addr, port, true);
74 | }
75 | return 0;
76 | }
77 |
78 | /*
79 | *
80 | */
81 | int WiFiSpiClient::connectSSL(IPAddress ip, uint16_t port)
82 | {
83 | return _connect(ip, port, true);
84 | }
85 |
86 | /*
87 | *
88 | */
89 | int WiFiSpiClient::_connect(IPAddress ip, uint16_t port, bool isSSL)
90 | {
91 | _sock = WiFiSpiClass::getSocket();
92 | if (_sock != SOCK_NOT_AVAIL)
93 | {
94 | if (! ServerSpiDrv::startClient(uint32_t(ip), port, _sock, (isSSL ? TCP_MODE_WITH_TLS : TCP_MODE)))
95 | return 0; // unsuccessfull
96 |
97 | WiFiSpiClass::_state[_sock] = _sock;
98 | }
99 | else
100 | {
101 | Serial.println("No Socket available");
102 | return 0;
103 | }
104 | return 1;
105 | }
106 |
107 | /*
108 | *
109 | */
110 | size_t WiFiSpiClient::write(const uint8_t *buf, size_t size)
111 | {
112 | if (_sock >= MAX_SOCK_NUM || size == 0)
113 | {
114 | setWriteError();
115 | return 0;
116 | }
117 |
118 | if (!ServerSpiDrv::sendData(_sock, buf, size))
119 | {
120 | setWriteError();
121 | return 0;
122 | }
123 |
124 | return size;
125 | }
126 |
127 | /*
128 | *
129 | */
130 | int WiFiSpiClient::available()
131 | {
132 | if (_sock == SOCK_NOT_AVAIL)
133 | return 0;
134 | else
135 | return ServerSpiDrv::availData(_sock);
136 | }
137 |
138 | /*
139 | *
140 | */
141 | int WiFiSpiClient::read()
142 | {
143 | int16_t b;
144 | ServerSpiDrv::getData(_sock, &b); // returns -1 when error
145 | return b;
146 | }
147 |
148 | /*
149 | Reads data into a buffer.
150 | Return: 0 = success, size bytes read
151 | -1 = error (either no data or communication error)
152 | */
153 | int WiFiSpiClient::read(uint8_t* buf, size_t size) {
154 | // sizeof(size_t) is architecture dependent
155 | // but we need a 16 bit data type here
156 | uint16_t _size = size;
157 | if (!ServerSpiDrv::getDataBuf(_sock, buf, &_size))
158 | return -1;
159 | return 0;
160 | }
161 |
162 | /*
163 | *
164 | */
165 | int WiFiSpiClient::peek()
166 | {
167 | int16_t b;
168 | ServerSpiDrv::getData(_sock, &b, 1); // returns -1 when error
169 | return b;
170 | }
171 |
172 | /*
173 | *
174 | */
175 | void WiFiSpiClient::flush() {
176 | // TODO: a real check to ensure transmission has been completed
177 | }
178 |
179 | /*
180 | *
181 | */
182 | void WiFiSpiClient::stop() {
183 | if (_sock == SOCK_NOT_AVAIL)
184 | return;
185 |
186 | ServerSpiDrv::stopClient(_sock);
187 |
188 | int count = 0;
189 | // wait maximum 5 secs for the connection to close
190 | while (status() != CLOSED && ++count < 500)
191 | delay(10);
192 |
193 | if (WiFiSpiClass::_server_port[_sock] == 0)
194 | WiFiSpiClass::_state[_sock] = NA_STATE; // Close only if it isn't server connection
195 |
196 | _sock = SOCK_NOT_AVAIL;
197 | }
198 |
199 | /*
200 | *
201 | */
202 | uint8_t WiFiSpiClient::connected()
203 | {
204 | if (_sock == SOCK_NOT_AVAIL)
205 | return 0;
206 | else
207 | return (status() == ESTABLISHED);
208 | }
209 |
210 | /*
211 | *
212 | */
213 | uint8_t WiFiSpiClient::status()
214 | {
215 | if (_sock == SOCK_NOT_AVAIL)
216 | return CLOSED;
217 | else
218 | return ServerSpiDrv::getClientState(_sock);
219 | }
220 |
221 | /*
222 | *
223 | */
224 | WiFiSpiClient::operator bool() {
225 | return (_sock != SOCK_NOT_AVAIL);
226 | }
227 |
228 | /*
229 | *
230 | */
231 | uint8_t WiFiSpiClient::verifySSL(uint8_t* fingerprint, const char *host) {
232 | if (_sock == SOCK_NOT_AVAIL || host[0] == 0)
233 | return 0;
234 |
235 | return ServerSpiDrv::verifySSLClient(_sock, fingerprint, host);
236 | }
237 |
238 | /*
239 | *
240 | */
241 | IPAddress WiFiSpiClient::remoteIP()
242 | {
243 | uint8_t _remoteIp[4];
244 | uint16_t _remotePort;
245 |
246 | if (WiFiSpiDrv::getRemoteData(_sock, _remoteIp, &_remotePort))
247 | return IPAddress(_remoteIp);
248 | else
249 | return IPAddress(0UL);
250 | }
251 |
252 | /*
253 | *
254 | */
255 | uint16_t WiFiSpiClient::remotePort()
256 | {
257 | uint8_t _remoteIp[4];
258 | uint16_t _remotePort;
259 |
260 | if (WiFiSpiDrv::getRemoteData(_sock, _remoteIp, &_remotePort))
261 | return _remotePort;
262 | else
263 | return 0;
264 | }
265 |
--------------------------------------------------------------------------------
/src/WiFiSpiClient.h:
--------------------------------------------------------------------------------
1 | /*
2 | WiFiSpiClient.h - Library for Arduino with ESP8266 as slave.
3 | Copyright (c) 2017 Jiri Bilek. All right reserved.
4 |
5 | ---
6 |
7 | Based on WiFiClient.h - Library for Arduino Wifi shield.
8 | Copyright (c) 2011-2014 Arduino LLC. All right reserved.
9 |
10 | This library is free software; you can redistribute it and/or
11 | modify it under the terms of the GNU Lesser General Public
12 | License as published by the Free Software Foundation; either
13 | version 2.1 of the License, or (at your option) any later version.
14 |
15 | This library is distributed in the hope that it will be useful,
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 | Lesser General Public License for more details.
19 |
20 | You should have received a copy of the GNU Lesser General Public
21 | License along with this library; if not, write to the Free Software
22 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 | */
24 |
25 | #ifndef _WIFISPICLIENT_H_INCLUDED
26 | #define _WIFISPICLIENT_H_INCLUDED
27 |
28 | #include "Arduino.h"
29 | #include "Print.h"
30 | #include "Client.h"
31 | #include "IPAddress.h"
32 |
33 | class WiFiSpiClient : public Client {
34 |
35 | private:
36 | uint8_t _sock; //not used
37 |
38 | public:
39 | WiFiSpiClient();
40 | WiFiSpiClient(uint8_t sock);
41 | virtual ~WiFiSpiClient() {};
42 |
43 | uint8_t status();
44 | virtual int connect(IPAddress ip, uint16_t port);
45 | virtual int connect(const char *host, uint16_t port);
46 | virtual int connectSSL(IPAddress ip, uint16_t port);
47 | virtual int connectSSL(const char *host, uint16_t port);
48 |
49 | uint8_t verifySSL(uint8_t* fingerprint, const char *host);
50 |
51 | virtual size_t write(const uint8_t *buf, size_t size);
52 | virtual size_t write(uint8_t b)
53 | { return write(&b, 1); }
54 | virtual size_t write(const char *str)
55 | { return write(reinterpret_cast(str), strlen(str)); }
56 | virtual size_t write(const void *str, size_t size)
57 | { return write(reinterpret_cast(str), size); }
58 | virtual int available();
59 | virtual int read();
60 | virtual int read(uint8_t *buf, size_t size);
61 | virtual int peek();
62 | virtual void flush();
63 | virtual void stop();
64 | virtual uint8_t connected();
65 | virtual operator bool();
66 |
67 | using Print::write;
68 |
69 | // Return the IP address of the host who sent the current incoming packet
70 | IPAddress remoteIP();
71 |
72 | // Return the port of the host who sent the current incoming packet
73 | uint16_t remotePort();
74 |
75 | private:
76 | int _connect(IPAddress ip, uint16_t port, bool isSSL);
77 |
78 | };
79 |
80 | #endif
81 |
--------------------------------------------------------------------------------
/src/WiFiSpiServer.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | WiFiSPIServer.cpp - Library for Arduino Wifi SPI connection with ESP8266.
3 | Copyright (c) 2017 Jiri Bilek. All right reserved.
4 |
5 | ---
6 |
7 | Based on WiFiServer.cpp - Library for Arduino Wifi shield.
8 | Copyright (c) 2011-2014 Arduino LLC. All right reserved.
9 |
10 | This library is free software; you can redistribute it and/or
11 | modify it under the terms of the GNU Lesser General Public
12 | License as published by the Free Software Foundation; either
13 | version 2.1 of the License, or (at your option) any later version.
14 |
15 | This library is distributed in the hope that it will be useful,
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 | Lesser General Public License for more details.
19 |
20 | You should have received a copy of the GNU Lesser General Public
21 | License along with this library; if not, write to the Free Software
22 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 | */
24 |
25 | #include
26 | #include "utility/srvspi_drv.h"
27 |
28 | extern "C" {
29 | #include "utility/debug.h"
30 | }
31 |
32 | #include "WiFiSpi.h"
33 | #include "WiFiSpiClient.h"
34 | #include "WiFiSpiServer.h"
35 |
36 | WiFiSpiServer::WiFiSpiServer(uint16_t port)
37 | {
38 | _port = port;
39 | }
40 |
41 | /*
42 | *
43 | */
44 | void WiFiSpiServer::begin()
45 | {
46 | uint8_t sock = WiFiSpiClass::getSocket();
47 |
48 | if (sock != SOCK_NOT_AVAIL)
49 | {
50 | _sock = sock;
51 | ServerSpiDrv::startServer(_port, _sock);
52 | WiFiSpiClass::_server_port[_sock] = _port;
53 | WiFiSpiClass::_state[_sock] = _sock;
54 | }
55 | }
56 |
57 | /*
58 | *
59 | */
60 | WiFiSpiClient WiFiSpiServer::available(uint8_t* status)
61 | {
62 | WiFiSpiClient client(_sock);
63 |
64 | uint8_t _client_status = client.status(); // creates Client object on ESP side if there is established connection
65 | // uint8_t _server_status = this->status(); removed, may be related with the comment below, running fine without it
66 |
67 | if (status != NULL)
68 | *status = _client_status;
69 |
70 | // TODO: If server is not in listen state, restart it (code present in original WiFiServer.h). I think it is useless.
71 |
72 | if (_client_status == ESTABLISHED)
73 | return client;
74 |
75 | return WiFiSpiClient(SOCK_NOT_AVAIL); // closed Client
76 | }
77 |
78 | /*
79 | *
80 | */
81 | uint8_t WiFiSpiServer::status() {
82 | return ServerSpiDrv::getServerState(0);
83 | }
84 |
85 | /*
86 | *
87 | */
88 | size_t WiFiSpiServer::write(uint8_t b)
89 | {
90 | return write(&b, 1);
91 | }
92 |
93 | /*
94 | *
95 | */
96 | size_t WiFiSpiServer::write(const uint8_t *buffer, size_t size)
97 | {
98 | size_t n = 0;
99 | WiFiSpiClient client(_sock);
100 |
101 | if (client.status() == ESTABLISHED)
102 | n = client.write(buffer, size);
103 |
104 | return n;
105 | }
106 |
107 | /*
108 | *
109 | */
110 | void WiFiSpiServer::stop()
111 | {
112 | ServerSpiDrv::stopServer(_sock);
113 |
114 | WiFiSpiClass::_server_port[_sock] = 0;
115 | WiFiSpiClass::_state[_sock] = NA_STATE;
116 | }
117 |
118 |
--------------------------------------------------------------------------------
/src/WiFiSpiServer.h:
--------------------------------------------------------------------------------
1 | /*
2 | WiFiSPIServer.h - Library for Arduino Wifi SPI connection with ESP8266.
3 | Copyright (c) 2017 Jiri Bilek. All right reserved.
4 |
5 | ---
6 |
7 | Based on WiFiServer.h - Library for Arduino Wifi shield.
8 | Copyright (c) 2011-2014 Arduino LLC. All right reserved.
9 |
10 | This library is free software; you can redistribute it and/or
11 | modify it under the terms of the GNU Lesser General Public
12 | License as published by the Free Software Foundation; either
13 | version 2.1 of the License, or (at your option) any later version.
14 |
15 | This library is distributed in the hope that it will be useful,
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 | Lesser General Public License for more details.
19 |
20 | You should have received a copy of the GNU Lesser General Public
21 | License along with this library; if not, write to the Free Software
22 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 | */
24 |
25 | #ifndef _WIFISPISERVER_H_INCLUDED
26 | #define _WIFISPISERVER_H_INCLUDED
27 |
28 | extern "C" {
29 | #include "utility/wl_definitions.h"
30 | }
31 |
32 | #include "Server.h"
33 |
34 | class WiFiSpiClient;
35 |
36 | class WiFiSpiServer : public Server {
37 | private:
38 | uint16_t _port;
39 | void* pcb;
40 | uint8_t _sock;
41 |
42 | public:
43 | WiFiSpiServer(uint16_t port);
44 | WiFiSpiClient available(uint8_t* status = NULL);
45 |
46 | void begin();
47 | virtual size_t write(uint8_t);
48 | virtual size_t write(const uint8_t *buf, size_t size);
49 | uint8_t status();
50 |
51 | void stop();
52 |
53 | using Print::write;
54 | };
55 |
56 | #endif
57 |
--------------------------------------------------------------------------------
/src/WiFiSpiUdp.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | WiFiSPIUdp.cpp - Library for Arduino Wifi SPI connection with ESP8266.
3 | Copyright (c) 2017 Jiri Bilek. All right reserved.
4 |
5 | ---
6 |
7 | Based on WiFiUdp.cpp - Library for Arduino Wifi shield.
8 | Copyright (c) 2011-2014 Arduino LLC. All right reserved.
9 |
10 | This library is free software; you can redistribute it and/or
11 | modify it under the terms of the GNU Lesser General Public
12 | License as published by the Free Software Foundation; either
13 | version 2.1 of the License, or (at your option) any later version.
14 |
15 | This library is distributed in the hope that it will be useful,
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 | Lesser General Public License for more details.
19 |
20 | You should have received a copy of the GNU Lesser General Public
21 | License along with this library; if not, write to the Free Software
22 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 | */
24 |
25 | extern "C" {
26 | #include "utility/debug.h"
27 | #include "utility/wifi_spi.h"
28 | }
29 | #include
30 | #include "utility/srvspi_drv.h"
31 | #include "utility/wifispi_drv.h"
32 |
33 | #include "WiFiSpi.h"
34 | #include "WiFiSpiUdp.h"
35 |
36 |
37 | /* Constructor */
38 | WiFiSpiUdp::WiFiSpiUdp() : _sock(SOCK_NOT_AVAIL) {}
39 |
40 | /*
41 | * Starts WiFiSpiUdp socket, listening at local port PORT
42 | */
43 | uint8_t WiFiSpiUdp::begin(uint16_t port)
44 | {
45 | uint8_t sock = WiFiSpiClass::getSocket();
46 | if (sock != SOCK_NOT_AVAIL)
47 | {
48 | if (ServerSpiDrv::startServer(port, sock, UDP_MODE))
49 | {
50 | WiFiSpiClass::_server_port[sock] = port;
51 | WiFiSpiClass::_state[sock] = sock;
52 | _sock = sock;
53 | _port = port;
54 | return 1;
55 | }
56 | }
57 | return 0;
58 | }
59 |
60 | /*
61 | * Starts WiFiSpiUdp socket, listening at port PORT for multicast messages from IP
62 | * Returns 1 if successful, 0 on failure
63 | */
64 | uint8_t WiFiSpiUdp::beginMulticast(IPAddress ip, uint16_t port)
65 | {
66 | uint8_t sock = WiFiSpiClass::getSocket();
67 | if (sock != SOCK_NOT_AVAIL)
68 | {
69 | if (ServerSpiDrv::startServerMulticast(uint32_t(ip), port, sock))
70 | {
71 | WiFiSpiClass::_server_port[sock] = port;
72 | WiFiSpiClass::_state[sock] = sock;
73 | _sock = sock;
74 | _port = port;
75 | return 1;
76 | }
77 | }
78 | return 0;
79 | }
80 |
81 | /*
82 | * Returns number of bytes available in the current packet
83 | */
84 | int WiFiSpiUdp::available()
85 | {
86 | if (_sock != SOCK_NOT_AVAIL)
87 | return ServerSpiDrv::availData(_sock);
88 |
89 | return 0;
90 | }
91 |
92 | /*
93 | * Releases any resources being used by this WiFiSpiUdp instance
94 | */
95 | void WiFiSpiUdp::stop()
96 | {
97 | ServerSpiDrv::stopServer(_sock);
98 |
99 | WiFiSpiClass::_server_port[_sock] = 0;
100 | WiFiSpiClass::_state[_sock] = NA_STATE;
101 | }
102 |
103 | /*
104 | *
105 | */
106 | int WiFiSpiUdp::beginPacket(const char *host, uint16_t port)
107 | {
108 | // Look up the host first
109 | IPAddress remote_addr;
110 | if (WiFiSpi.hostByName(host, remote_addr))
111 | return beginPacket(remote_addr, port);
112 | else
113 | return 0;
114 | }
115 |
116 | /*
117 | *
118 | */
119 | int WiFiSpiUdp::beginPacket(IPAddress ip, uint16_t port)
120 | {
121 | if (_sock == SOCK_NOT_AVAIL)
122 | return 0; // No socket available
123 |
124 | if (! ServerSpiDrv::beginUdpPacket(uint32_t(ip), port, _sock))
125 | return 0; // Client not opened
126 | else
127 | return 1;
128 | }
129 |
130 | /*
131 | *
132 | */
133 | int WiFiSpiUdp::endPacket()
134 | {
135 | return ServerSpiDrv::sendUdpData(_sock);
136 | }
137 |
138 | /*
139 | *
140 | */
141 | size_t WiFiSpiUdp::write(uint8_t byte)
142 | {
143 | return write(&byte, 1);
144 | }
145 |
146 | /*
147 | *
148 | */
149 | size_t WiFiSpiUdp::write(const uint8_t *buffer, size_t size)
150 | {
151 | if (ServerSpiDrv::insertDataBuf(_sock, buffer, size))
152 | return size;
153 | else
154 | return 0;
155 | }
156 |
157 | /*
158 | *
159 | */
160 | int WiFiSpiUdp::parsePacket()
161 | {
162 | return ServerSpiDrv::parsePacket(_sock);
163 | }
164 |
165 | /*
166 | *
167 | */
168 | int WiFiSpiUdp::read()
169 | {
170 | int16_t b;
171 | ServerSpiDrv::getData(_sock, &b); // returns -1 when error
172 | return b;
173 | }
174 |
175 | /*
176 | *
177 | */
178 | int WiFiSpiUdp::read(unsigned char* buffer, size_t len)
179 | {
180 | // sizeof(size_t) is architecture dependent
181 | // but we need a 16 bit data type here
182 | uint16_t _size = len;
183 |
184 | if (!ServerSpiDrv::getDataBuf(_sock, buffer, &_size))
185 | return -1;
186 | else
187 | return 0;
188 | }
189 |
190 | /*
191 | *
192 | */
193 | int WiFiSpiUdp::peek()
194 | {
195 | int16_t b;
196 | ServerSpiDrv::getData(_sock, &b, 1); // returns -1 when error
197 | return b;
198 | }
199 |
200 | /*
201 | *
202 | */
203 | void WiFiSpiUdp::flush()
204 | {
205 | // TODO: a real check to ensure transmission has been completed
206 | }
207 |
208 | /*
209 | *
210 | */
211 | IPAddress WiFiSpiUdp::remoteIP()
212 | {
213 | uint8_t _remoteIp[4];
214 | uint16_t _remotePort;
215 |
216 | if (WiFiSpiDrv::getRemoteData(_sock, _remoteIp, &_remotePort))
217 | return IPAddress(_remoteIp);
218 | else
219 | return IPAddress(0UL);
220 | }
221 |
222 | /*
223 | *
224 | */
225 | uint16_t WiFiSpiUdp::remotePort()
226 | {
227 | uint8_t _remoteIp[4];
228 | uint16_t _remotePort;
229 |
230 | if (WiFiSpiDrv::getRemoteData(_sock, _remoteIp, &_remotePort))
231 | return _remotePort;
232 | else
233 | return 0;
234 | }
235 |
236 |
--------------------------------------------------------------------------------
/src/WiFiSpiUdp.h:
--------------------------------------------------------------------------------
1 | /*
2 | WiFiSPIUdp.h - Library for Arduino Wifi SPI connection with ESP8266.
3 | Copyright (c) 2017 Jiri Bilek. All right reserved.
4 |
5 | ---
6 |
7 | Based on WiFiUdp.h - Library for Arduino Wifi shield.
8 | Copyright (c) 2011-2014 Arduino LLC. All right reserved.
9 |
10 | This library is free software; you can redistribute it and/or
11 | modify it under the terms of the GNU Lesser General Public
12 | License as published by the Free Software Foundation; either
13 | version 2.1 of the License, or (at your option) any later version.
14 |
15 | This library is distributed in the hope that it will be useful,
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 | Lesser General Public License for more details.
19 |
20 | You should have received a copy of the GNU Lesser General Public
21 | License along with this library; if not, write to the Free Software
22 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 | */
24 |
25 | #ifndef _WIFISPIUDP_H_INCLUDED
26 | #define _WIFISPIUDP_H_INCLUDED
27 |
28 | #include
29 |
30 | #define UDP_TX_PACKET_MAX_SIZE 24
31 |
32 | class WiFiSpiUdp : public UDP {
33 | private:
34 | uint8_t _sock; // socket ID for Wiz5100
35 | uint16_t _port; // local port to listen on
36 |
37 | public:
38 | WiFiSpiUdp(); // Constructor
39 | virtual uint8_t begin(uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
40 | virtual uint8_t beginMulticast(IPAddress, uint16_t); // initialize, start listening on specified multicast IP address and port. Returns 1 if successful, 0 on failure
41 | virtual void stop(); // Finish with the UDP socket
42 |
43 | // Sending UDP packets
44 |
45 | // Start building up a packet to send to the remote host specific in ip and port
46 | // Returns 1 if successful, 0 if there was a problem with the supplied IP address or port
47 | virtual int beginPacket(IPAddress ip, uint16_t port);
48 |
49 | // Start building up a packet to send to the remote host specific in host and port
50 | // Returns 1 if successful, 0 if there was a problem resolving the hostname or port
51 | virtual int beginPacket(const char *host, uint16_t port);
52 |
53 | // Finish off this packet and send it
54 | // Returns 1 if the packet was sent successfully, 0 if there was an error
55 | virtual int endPacket();
56 |
57 | // Write a single byte into the packet
58 | virtual size_t write(uint8_t);
59 |
60 | // Write size bytes from buffer into the packet
61 | virtual size_t write(const uint8_t *buffer, size_t size);
62 |
63 | using Print::write;
64 |
65 | // Start processing the next available incoming packet
66 | // Discards current packet, if any is present!
67 | // Returns the size of the packet in bytes, or 0 if no packets are available
68 | virtual int parsePacket();
69 |
70 | // Number of bytes remaining in the current packet
71 | virtual int available();
72 |
73 | // Read a single byte from the current packet
74 | virtual int read();
75 |
76 | // Read up to len bytes from the current packet and place them into buffer
77 | // Returns the number of bytes read, or 0 if none are available
78 | virtual int read(unsigned char* buffer, size_t len);
79 |
80 | // Read up to len characters from the current packet and place them into buffer
81 | // Returns the number of characters read, or 0 if none are available
82 | virtual int read(char* buffer, size_t len) { return read((unsigned char*)buffer, len); };
83 |
84 | // Return the next byte from the current packet without moving on to the next byte
85 | virtual int peek();
86 |
87 | virtual void flush(); // Finish reading the current packet
88 |
89 | // Return the IP address of the host who sent the current incoming packet
90 | virtual IPAddress remoteIP();
91 |
92 | // Return the port of the host who sent the current incoming packet
93 | virtual uint16_t remotePort();
94 | };
95 |
96 | #endif
97 |
--------------------------------------------------------------------------------
/src/config.h:
--------------------------------------------------------------------------------
1 | /*
2 | config.h - Library for Arduino SPI connection to ESP8266
3 | Copyright (c) 2019 Jiri Bilek. All rights reserved.
4 |
5 | This library is free software; you can redistribute it and/or
6 | modify it under the terms of the GNU Lesser General Public
7 | License as published by the Free Software Foundation; either
8 | version 2.1 of the License, or (at your option) any later version.
9 |
10 | This library is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | Lesser General Public License for more details.
14 |
15 | You should have received a copy of the GNU Lesser General Public
16 | License along with this library; if not, write to the Free Software
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 |
19 | -----------------------------------------------------
20 |
21 | This file is a "center of configuration options". All important options for the
22 | library are concentrated here.
23 | */
24 |
25 | #ifndef _CONFIG_H_INCLUDED
26 | #define _CONFIG_H_INCLUDED
27 |
28 | // Uncomment the following define if the safe reset circuit (https://github.com/JiriBilek/WiFiSpiESP/issues/6)
29 | // is connected to SS pin on ESP8266. This allows the SS signal to behave exactly
30 | // according SPI specification (goes low before transmission and high after)
31 | #define ESP8266_SAFE_RESET_IMPLEMENTED
32 |
33 | // Allow debugging information to be print on Serial
34 | #define ESPSPI_DEBUG_OPTION
35 |
36 | // Print information about received bad message on Serial
37 | //#define ESPSPI_DEBUG_OPTION_BAD_MESSAGE
38 |
39 | #endif
40 |
--------------------------------------------------------------------------------
/src/utility/debug.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | debug.c - Library for Arduino Wifi shield.
3 | Copyright (c) 2011-2014 Arduino. All right reserved.
4 |
5 | This library is free software; you can redistribute it and/or
6 | modify it under the terms of the GNU Lesser General Public
7 | License as published by the Free Software Foundation; either
8 | version 2.1 of the License, or (at your option) any later version.
9 |
10 | This library is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | Lesser General Public License for more details.
14 |
15 | You should have received a copy of the GNU Lesser General Public
16 | License along with this library; if not, write to the Free Software
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 | //*********************************************/
20 | //
21 | // File: debug.c
22 | //
23 | // Author: Jiri Bilek
24 | //
25 | //********************************************/
26 |
27 | #include "debug.h"
28 |
29 | #if defined(ESPSPI_DEBUG_OPTION)
30 |
31 | #include
32 |
33 | // Only filename without path
34 | const char *DbgFileName(const char *s)
35 | {
36 | const char *p = s + strlen(s);
37 | while (--p > s)
38 | {
39 | if (*p == '/' || *p == '\\')
40 | return p + 1;
41 | }
42 |
43 | return s;
44 | }
45 |
46 | #endif
47 |
--------------------------------------------------------------------------------
/src/utility/debug.h:
--------------------------------------------------------------------------------
1 | /*
2 | debug.h - Library for Arduino Wifi shield.
3 | Copyright (c) 2011-2014 Arduino. All right reserved.
4 |
5 | This library is free software; you can redistribute it and/or
6 | modify it under the terms of the GNU Lesser General Public
7 | License as published by the Free Software Foundation; either
8 | version 2.1 of the License, or (at your option) any later version.
9 |
10 | This library is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | Lesser General Public License for more details.
14 |
15 | You should have received a copy of the GNU Lesser General Public
16 | License along with this library; if not, write to the Free Software
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 | //*********************************************/
20 | //
21 | // File: debug.h
22 | //
23 | // Author: dlf (Metodo2 srl)
24 | //
25 | //********************************************/
26 |
27 |
28 | #ifndef _DEBUG_H_INCLUDED
29 | #define _DEBUG_H_INCLUDED
30 |
31 | #define DBGOUT Serial
32 |
33 | #include
34 | #include
35 | #include "../config.h"
36 |
37 | const char *DbgFileName(const char *s);
38 |
39 |
40 | #define PRINT_FILE_LINE() do { \
41 | DBGOUT.print("[");DBGOUT.print(DbgFileName(__FILE__)); \
42 | DBGOUT.print(":");DBGOUT.print(__LINE__);DBGOUT.print("]");\
43 | }while (0);
44 |
45 | #if defined(ESPSPI_DEBUG_OPTION)
46 |
47 | #define INFO(format, args...) do { \
48 | char buf[250]; \
49 | sprintf(buf, format, args); \
50 | DBGOUT.println(buf); \
51 | } while(0);
52 |
53 | #define INFO1(x) do { PRINT_FILE_LINE() DBGOUT.print(" I: ");\
54 | DBGOUT.println(x); \
55 | }while (0);
56 |
57 |
58 | #define INFO2(x,y) do { PRINT_FILE_LINE() DBGOUT.print(" I: ");\
59 | DBGOUT.print(x,16);DBGOUT.print(",");DBGOUT.println(y,16); \
60 | }while (0);
61 |
62 |
63 | #else
64 | #define INFO1(x) do {} while(0);
65 | #define INFO2(x,y) do {} while(0);
66 | #define INFO(format, args...) do {} while(0);
67 | #endif
68 |
69 | #if defined(ESPSPI_DEBUG_OPTION)
70 | #define WARN(args) do { PRINT_FILE_LINE() \
71 | DBGOUT.print(" W: "); DBGOUT.println(args); \
72 | }while (0);
73 | #define WARN2(arg1,args) do { PRINT_FILE_LINE() \
74 | DBGOUT.print(" W: "); DBGOUT.print(arg1); DBGOUT.println(args); \
75 | }while (0);
76 | #else
77 | #define WARN(args) do {} while (0);
78 | #define WARN2(arg1,args) do {} while (0);
79 | #endif
80 |
81 | #endif
82 |
--------------------------------------------------------------------------------
/src/utility/espspi_drv.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | espspi_drv.cpp - Library for Arduino SPI connection with ESP8266
3 |
4 | Copyright (c) 2017 Jiri Bilek. All right reserved.
5 |
6 | This library is free software; you can redistribute it and/or
7 | modify it under the terms of the GNU Lesser General Public
8 | License as published by the Free Software Foundation; either
9 | version 2.1 of the License, or (at your option) any later version.
10 |
11 | This library is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | Lesser General Public License for more details.
15 |
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 "../config.h"
22 | #include "espspi_drv.h"
23 |
24 | // Read and check one byte from the input
25 | #if defined(ESPSPI_DEBUG_OPTION_BAD_MESSAGE)
26 | #define READ_AND_CHECK_BYTE(c, err) \
27 | do { \
28 | uint8_t _b = espSpiProxy.readByte(); \
29 | if (_b != (c)) { \
30 | Serial.print(err); \
31 | Serial.print(" exp:"); Serial.print(c, HEX); \
32 | Serial.print(", got:"); Serial.print(_b, HEX); \
33 | return 0; \
34 | } \
35 | } while (false)
36 | #else
37 | #define READ_AND_CHECK_BYTE(c, err) \
38 | do { \
39 | if (espSpiProxy.readByte() != (c)) \
40 | return 0; \
41 | } while (false)
42 | #endif
43 |
44 | /*
45 | Sends a command to ESP. If numParam == 0 ends the command otherwise keeps it open.
46 |
47 | Cmd Struct Message
48 | _______________________________________________________________________
49 | | START CMD | C/R | CMD | N.PARAM | PARAM LEN | PARAM | .. | END CMD |
50 | |___________|______|______|_________|___________|________|____|_________|
51 | | 8 bit | 1bit | 7bit | 8bit | 8bit | nbytes | .. | 8bit |
52 | |___________|______|______|_________|___________|________|____|_________|
53 |
54 | The last byte (position 31) is crc8.
55 | */
56 | void EspSpiDrv::sendCmd(const uint8_t cmd, const uint8_t numParam)
57 | {
58 | WAIT_FOR_SLAVE_RX_READY();
59 |
60 | // Send Spi START CMD
61 | espSpiProxy.writeByte(START_CMD);
62 |
63 | // Send Spi C + cmd
64 | espSpiProxy.writeByte(cmd & ~(REPLY_FLAG));
65 |
66 | // Send Spi numParam
67 | espSpiProxy.writeByte(numParam);
68 |
69 | // If numParam == 0 send END CMD and flush
70 | if (numParam == 0)
71 | endCmd();
72 | }
73 |
74 | /*
75 | Ends a command and flushes the buffer
76 | */
77 | void EspSpiDrv::endCmd()
78 | {
79 | espSpiProxy.writeByte(END_CMD);
80 | espSpiProxy.flush(MESSAGE_FINISHED);
81 | }
82 |
83 | /*
84 | Sends a parameter.
85 | param ... parameter value
86 | param_len ... length of the parameter
87 | */
88 | void EspSpiDrv::sendParam(const uint8_t* param, const uint8_t param_len)
89 | {
90 | // Send paramLen
91 | espSpiProxy.writeByte(param_len);
92 |
93 | // Send param data
94 | for (int i=0; i> 8);
121 |
122 | // Send param data
123 | for (uint16_t i=0; i 0)
215 | {
216 | for (uint8_t i=0; i
44 | #include "debug.h"
45 |
46 | // The command codes are fixed by ESP8266 hardware
47 | #define CMD_WRITESTATUS 0x01
48 | #define CMD_WRITEDATA 0x02
49 | #define CMD_READDATA 0x03
50 | #define CMD_READSTATUS 0x04
51 |
52 | // Message indicators
53 | #define MESSAGE_FINISHED 0xDF
54 | #define MESSAGE_CONTINUES 0xDC
55 |
56 | // SPI Status
57 | enum {
58 | SPISLAVE_RX_BUSY,
59 | SPISLAVE_RX_READY,
60 | SPISLAVE_RX_CRC_PROCESSING,
61 | SPISLAVE_RX_ERROR
62 | };
63 | enum {
64 | SPISLAVE_TX_NODATA,
65 | SPISLAVE_TX_READY,
66 | SPISLAVE_TX_PREPARING_DATA,
67 | SPISLAVE_TX_WAITING_FOR_CONFIRM
68 | };
69 |
70 | // How long we will wait for slave to be ready
71 | #define SLAVE_RX_READY_TIMEOUT 3000UL
72 | #define SLAVE_TX_READY_TIMEOUT 3000UL
73 |
74 | // How long will be SS held high when starting transmission
75 | //#define SS_PULSE_DELAY_MICROSECONDS 50
76 |
77 |
78 | class EspSpiProxy
79 | {
80 | private:
81 | SPIClass *spi_obj;
82 |
83 | uint8_t _ss_pin;
84 | uint8_t buffer[32];
85 | uint8_t buflen;
86 | uint8_t bufpos;
87 |
88 | void _pulseSS(bool start)
89 | {
90 | if (_ss_pin >= 0)
91 | {
92 |
93 | #if defined(ESP8266_SAFE_RESET_IMPLEMENTED)
94 | if (start) {
95 | digitalWrite(_ss_pin, LOW);
96 | delayMicroseconds(20); // 10us is low (some errors), 15 is ok, 25 us is safe for speeds > 4MHz
97 | }
98 | else {
99 | digitalWrite(_ss_pin, HIGH);
100 | }
101 | #else
102 | if (start) { // tested ok: 5, 15 / 5
103 | digitalWrite(_ss_pin, HIGH);
104 | delayMicroseconds(5);
105 |
106 | digitalWrite(_ss_pin, LOW);
107 | delayMicroseconds(20); // 10us is low (some errors), 15 is ok, 25 us is safe for speeds > 4MHz
108 | }
109 | else {
110 | digitalWrite(_ss_pin, HIGH);
111 | delayMicroseconds(5);
112 | digitalWrite(_ss_pin, LOW);
113 | }
114 | #endif
115 |
116 | }
117 | }
118 |
119 | public:
120 | EspSpiProxy()
121 | {
122 | _ss_pin = -1;
123 | buflen = 0;
124 | }
125 |
126 | void begin(uint8_t pin, SPIClass *in_spi)
127 | {
128 | spi_obj = in_spi;
129 |
130 | _ss_pin = pin;
131 | pinMode(_ss_pin, OUTPUT);
132 | #if defined(ESP8266_SAFE_RESET_IMPLEMENTED)
133 | digitalWrite(_ss_pin, HIGH);
134 | #else
135 | digitalWrite(_ss_pin, LOW); // Safe value for ESP8266 GPIO15
136 | #endif
137 | }
138 |
139 | uint16_t readStatus()
140 | {
141 | _pulseSS(true);
142 |
143 | spi_obj->transfer(CMD_READSTATUS);
144 | uint16_t status = (spi_obj->transfer(0) | ((uint16_t)(spi_obj->transfer(0)) << 8));
145 |
146 | _pulseSS(false);
147 |
148 | return status;
149 | }
150 |
151 | void writeStatus(uint8_t status)
152 | {
153 | _pulseSS(true);
154 |
155 | spi_obj->transfer(CMD_WRITESTATUS);
156 | spi_obj->transfer(status);
157 | spi_obj->transfer(status ^ 0xff); // byte inverted value as a check
158 |
159 | _pulseSS(false);
160 | }
161 |
162 | void readData(uint8_t* buf)
163 | {
164 | _pulseSS(true);
165 |
166 | spi_obj->transfer(CMD_READDATA);
167 | spi_obj->transfer(0x00);
168 | for(uint8_t i=0; i<32; i++) {
169 | buf[i] = spi_obj->transfer(0); // the value is not important
170 | }
171 |
172 | _pulseSS(false);
173 | }
174 |
175 | void writeData(uint8_t * data)
176 | {
177 | _pulseSS(true);
178 |
179 | spi_obj->transfer(CMD_WRITEDATA);
180 | spi_obj->transfer(0x00);
181 |
182 | for (uint8_t i = 0; i < 32; ++i)
183 | spi_obj->transfer(data[i]);
184 |
185 | _pulseSS(false);
186 | }
187 |
188 |
189 | void flush(uint8_t indicator)
190 | {
191 | // Is buffer empty?
192 | if (buflen == 0)
193 | return;
194 |
195 | // Message state indicator
196 | buffer[0] = indicator;
197 |
198 | // Pad the buffer with zeroes
199 | while (buflen < 30)
200 | buffer[++buflen] = 0;
201 |
202 | // Compute CRC8
203 | buffer[31] = crc8(buffer, 31);
204 |
205 | // Wait for slave ready
206 | // TODO: move the waiting loop to writeByte (defer waiting)
207 | uint8_t s = waitForSlaveRxReady();
208 | if (s == SPISLAVE_RX_READY || s == SPISLAVE_RX_ERROR) // Error state can't be recovered, we can send new data
209 | {
210 | // Try to send the buffer 10 times, we may not be stuck in an endless loop
211 | for (uint8_t i=0; i<10; ++i)
212 | {
213 | // Send the buffer
214 | writeData(buffer);
215 |
216 | if (waitForSlaveRxConfirmation())
217 | break;
218 | else
219 | WARN("Bad CRC, retransmitting");
220 | }
221 | }
222 |
223 | buflen = 0;
224 | }
225 |
226 | void writeByte(uint8_t b)
227 | {
228 | bufpos = 0; // discard input data in the buffer
229 |
230 | if (buflen >= 30)
231 | flush(MESSAGE_CONTINUES);
232 |
233 | buffer[++buflen] = b;
234 | }
235 |
236 | uint8_t readByte()
237 | {
238 | buflen = 0; // discard output data in the buffer
239 |
240 | if (bufpos >= 31) // the buffer segment was read
241 | {
242 | if (buffer[0] != MESSAGE_CONTINUES)
243 | return 0;
244 |
245 | bufpos = 0; // read next chunk
246 |
247 | // Wait for the slave
248 | waitForSlaveTxReady();
249 | }
250 |
251 | if (bufpos == 0) // buffer empty
252 | {
253 | uint32_t thisTime = millis();
254 |
255 | do {
256 | readData(buffer);
257 |
258 | if (buffer[31] == crc8(buffer, 31))
259 | break;
260 |
261 | WARN("Bad CRC, request repeated");
262 |
263 | } while (millis() - thisTime < 200); // repeat until crc is ok or 200 ms elapsed
264 |
265 | // Send confirmation to the slave (done through querying a status)
266 | readStatus();
267 |
268 | // Check the buffer for correctness
269 | if (buffer[0] != MESSAGE_FINISHED && buffer[0] != MESSAGE_CONTINUES)
270 | return 0; // incorrect message (should not happen)
271 |
272 | bufpos = 1;
273 | }
274 | return buffer[bufpos++];
275 | }
276 |
277 | /*
278 | Waits for slave receiver ready status.
279 | Return: receiver status
280 | */
281 | int8_t waitForSlaveRxReady()
282 | {
283 | uint32_t startTime = millis();
284 | uint16_t status = 0;
285 |
286 | do
287 | {
288 | status = readStatus();
289 |
290 | if ((status & 0xff) == ((status >> 8) ^ 0xff)) // check the xor
291 | {
292 | uint16_t s = (status >> 4) & 0x0f;
293 | if (s == SPISLAVE_RX_READY || s == SPISLAVE_RX_ERROR) // From the perspective of rx state the error is the same as ready
294 | return ((status >> 4) & 0x0f); // status
295 | }
296 |
297 | yield();
298 | } while (millis() - startTime < SLAVE_RX_READY_TIMEOUT);
299 |
300 | WARN2("Slave rx is not ready, status ", (status >> 4) & 0x0f);
301 |
302 | return ((status >> 4) & 0x0f); // timeout
303 | }
304 |
305 |
306 |
307 | /*
308 | Waits for slave transmitter ready status.
309 | Return: transmitter status
310 | */
311 | int8_t waitForSlaveTxReady()
312 | {
313 | uint32_t startTime = millis();
314 | uint16_t status = 0;
315 |
316 | do
317 | {
318 | status = readStatus();
319 |
320 | if ((status & 0xff) == ((status >> 8) ^ 0xff)) // check the xor
321 | {
322 | if ((status & 0x0f) == SPISLAVE_TX_READY)
323 | return (status & 0x0f); // status
324 | }
325 |
326 | yield();
327 | } while (millis() - startTime < SLAVE_TX_READY_TIMEOUT);
328 |
329 | WARN2("Slave tx is not ready, status ", status & 0x0f);
330 |
331 | return (status & 0x0f); // timeout
332 | }
333 |
334 | /*
335 | Waits for slave receiver read confirmation or rejection status.
336 | Status SPISLAVE_RX_CRC_PROCESSING holds the loop, SPISLAVE_RX_ERROR exits with error, other exits ok
337 | Return: receiver read data ok
338 | */
339 | int8_t waitForSlaveRxConfirmation()
340 | {
341 | uint32_t startTime = millis();
342 | uint16_t status = 0;
343 |
344 | do
345 | {
346 | status = readStatus();
347 |
348 | if ((status & 0xff) == ((status >> 8) ^ 0xff)) // check the xor
349 | {
350 | uint8_t stat = (status >> 4) & 0x0f;
351 |
352 | if (stat == SPISLAVE_RX_ERROR)
353 | return false; // Error status
354 | else if (stat != SPISLAVE_RX_CRC_PROCESSING)
355 | return true; // OK status
356 |
357 | // Slave is still processing the CRC
358 | }
359 |
360 | yield();
361 | } while (millis() - startTime < SLAVE_RX_READY_TIMEOUT);
362 |
363 | WARN2("Slave rx (confirm) is not ready, status ", (status >> 4) & 0x0f);
364 |
365 | return true; // timeout - we can't retransmit in order not to replay old data, assume everything is ok
366 | }
367 |
368 | /*
369 | * Compute crc8 with polynom 0x107 (x^8 + x^2 + x + 1)
370 | * Lookup table idea: https://lentz.com.au/blog/tag/crc-table-generator
371 | */
372 | uint8_t crc8(uint8_t *buffer, uint8_t bufLen)
373 | {
374 | static const uint8_t PROGMEM tableLow[] = { 0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15,
375 | 0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D };
376 | static const uint8_t PROGMEM tableHigh[] = { 0x00, 0x70, 0xE0, 0x90, 0xC7, 0xB7, 0x27, 0x57,
377 | 0x89, 0xF9, 0x69, 0x19, 0x4E, 0x3E, 0xAE, 0xDE };
378 |
379 | uint8_t crcValue = 0x00;
380 |
381 | for (int i = 0; i < bufLen; ++i) {
382 | crcValue ^= buffer[i];
383 | crcValue = pgm_read_byte(tableLow + (crcValue & 0x0f)) ^
384 | pgm_read_byte(tableHigh +((crcValue >> 4) & 0x0f));
385 | }
386 |
387 | return crcValue;
388 | }
389 |
390 | /*
391 | * Puts the SS low (required for successfull boot) and resets the ESP
392 | */
393 | void hardReset(int8_t hwResetPin)
394 | {
395 | #if !defined(ESP8266_SAFE_RESET_IMPLEMENTED)
396 | digitalWrite(_ss_pin, LOW); // Safe value for ESP8266 GPIO15
397 | #endif
398 | digitalWrite(hwResetPin, LOW);
399 | delay(50);
400 | digitalWrite(hwResetPin, HIGH);
401 | delay(200);
402 | }
403 |
404 | };
405 |
406 | extern EspSpiProxy espSpiProxy;
407 |
408 | #endif
409 |
410 |
--------------------------------------------------------------------------------
/src/utility/srvspi_drv.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | srvspi_drv.cpp - Library for Arduino Wifi SPI connection with ESP8266.
3 | Copyright (c) 2017 Jiri Bilek. All right reserved.
4 |
5 | ---
6 |
7 | Based on server_drv.cpp - Library for Arduino Wifi shield.
8 | Copyright (c) 2011-2014 Arduino. All right reserved.
9 |
10 | This library is free software; you can redistribute it and/or
11 | modify it under the terms of the GNU Lesser General Public
12 | License as published by the Free Software Foundation; either
13 | version 2.1 of the License, or (at your option) any later version.
14 |
15 | This library is distributed in the hope that it will be useful,
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 | Lesser General Public License for more details.
19 |
20 | You should have received a copy of the GNU Lesser General Public
21 | License along with this library; if not, write to the Free Software
22 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 | */
24 |
25 | #include "srvspi_drv.h"
26 |
27 | #include "Arduino.h"
28 | #include "espspi_drv.h"
29 |
30 | extern "C" {
31 | #include "wl_types.h"
32 | #include "debug.h"
33 | }
34 |
35 | #define FPSTR(pstr_pointer) (reinterpret_cast(pstr_pointer))
36 |
37 | /*
38 | Start server TCP / UDP on port specified
39 | */
40 | bool ServerSpiDrv::startServer(uint16_t port, uint8_t sock, uint8_t protMode)
41 | {
42 | // Send Command
43 | EspSpiDrv::sendCmd(START_SERVER_TCP_CMD, PARAM_NUMS_3);
44 | EspSpiDrv::sendParam(reinterpret_cast(&port), sizeof(port));
45 | EspSpiDrv::sendParam(sock);
46 | EspSpiDrv::sendParam(protMode);
47 | EspSpiDrv::endCmd();
48 |
49 | uint8_t _data = 0;
50 | uint8_t _dataLen = sizeof(_data);
51 | if (!EspSpiDrv::waitResponseCmd(START_SERVER_TCP_CMD, PARAM_NUMS_1, &_data, &_dataLen))
52 | {
53 | WARN(FPSTR(WiFiSpiDrv::ERROR_WAITRESPONSE));
54 | _data = 0;
55 | }
56 |
57 | return (_data == 1); // return value 1 means ok
58 | }
59 |
60 | /*
61 | Start server UDP Multicast on port specified listening given ip address
62 | */
63 | bool ServerSpiDrv::startServerMulticast(const uint32_t ipAddress, const uint16_t port, const uint8_t sock)
64 | {
65 | // Send Command
66 | EspSpiDrv::sendCmd(START_SERVER_MULTICAST_CMD, PARAM_NUMS_3);
67 | EspSpiDrv::sendParam(reinterpret_cast(&ipAddress), sizeof(ipAddress));
68 | EspSpiDrv::sendParam(reinterpret_cast(&port), sizeof(port));
69 | EspSpiDrv::sendParam(sock);
70 | EspSpiDrv::endCmd();
71 |
72 | uint8_t _data = 0;
73 | uint8_t _dataLen = sizeof(_data);
74 | if (!EspSpiDrv::waitResponseCmd(START_SERVER_MULTICAST_CMD, PARAM_NUMS_1, &_data, &_dataLen))
75 | {
76 | WARN(FPSTR(WiFiSpiDrv::ERROR_WAITRESPONSE));
77 | _data = 0;
78 | }
79 |
80 | return (_data == 1); // return value 1 means ok
81 | }
82 |
83 | /*
84 | *
85 | */
86 | void ServerSpiDrv::stopServer(uint8_t sock)
87 | {
88 | // Send Command
89 | EspSpiDrv::sendCmd(STOP_SERVER_TCP_CMD, PARAM_NUMS_1);
90 | EspSpiDrv::sendParam(sock);
91 | EspSpiDrv::endCmd();
92 |
93 | if (!EspSpiDrv::waitResponseCmd(STOP_SERVER_TCP_CMD, PARAM_NUMS_0, NULL, NULL))
94 | {
95 | WARN(FPSTR(WiFiSpiDrv::ERROR_WAITRESPONSE));
96 | }
97 | }
98 |
99 | /*
100 | Start client TCP on port specified
101 | Note: protMode is ignored
102 | */
103 | bool ServerSpiDrv::startClient(uint32_t ipAddress, uint16_t port, uint8_t sock, uint8_t protMode)
104 | {
105 | // Send Command
106 | EspSpiDrv::sendCmd(START_CLIENT_TCP_CMD, PARAM_NUMS_4);
107 | EspSpiDrv::sendParam(reinterpret_cast(&ipAddress), sizeof(ipAddress));
108 | EspSpiDrv::sendParam(reinterpret_cast(&port), sizeof(port));
109 | EspSpiDrv::sendParam(sock);
110 | EspSpiDrv::sendParam(protMode);
111 | EspSpiDrv::endCmd();
112 |
113 | // Wait for reply
114 |
115 | // Extended waiting time for status SPISLAVE_TX_PREPARING_DATA
116 | for (int i=1; i<10; ++i)
117 | {
118 | if (espSpiProxy.waitForSlaveTxReady() != SPISLAVE_TX_PREPARING_DATA)
119 | break; // The state is either SPISLAVE_TX_READY or SPISLAVE_TX_NODATA with timeout
120 | WARN(F("Status: Preparing data"));
121 | }
122 |
123 | uint8_t _data = 0;
124 | uint8_t _dataLen = sizeof(_data);
125 | if (!EspSpiDrv::waitResponseCmd(START_CLIENT_TCP_CMD, PARAM_NUMS_1, &_data, &_dataLen))
126 | {
127 | WARN(FPSTR(WiFiSpiDrv::ERROR_WAITRESPONSE));
128 | _data = 0;
129 | }
130 |
131 | return (_data == 1); // return value 1 means ok
132 | }
133 |
134 | /*
135 | *
136 | */
137 | void ServerSpiDrv::stopClient(uint8_t sock)
138 | {
139 | // Send Command
140 | EspSpiDrv::sendCmd(STOP_CLIENT_TCP_CMD, PARAM_NUMS_1);
141 | EspSpiDrv::sendParam(sock);
142 | EspSpiDrv::endCmd();
143 |
144 | uint8_t _data = 0;
145 | uint8_t _dataLen = sizeof(_data);
146 | if (!EspSpiDrv::waitResponseCmd(STOP_CLIENT_TCP_CMD, PARAM_NUMS_1, &_data, &_dataLen))
147 | {
148 | WARN(FPSTR(WiFiSpiDrv::ERROR_WAITRESPONSE));
149 | }
150 | }
151 |
152 | /*
153 | *
154 | */
155 | uint8_t ServerSpiDrv::getServerState(uint8_t sock)
156 | {
157 | // Send Command
158 | EspSpiDrv::sendCmd(GET_STATE_TCP_CMD, PARAM_NUMS_1);
159 | EspSpiDrv::sendParam(sock);
160 | EspSpiDrv::endCmd();
161 |
162 | uint8_t _data = 0;
163 | uint8_t _dataLen = sizeof(_data);
164 | if (!EspSpiDrv::waitResponseCmd(GET_STATE_TCP_CMD, PARAM_NUMS_1, &_data, &_dataLen))
165 | {
166 | WARN(FPSTR(WiFiSpiDrv::ERROR_WAITRESPONSE));
167 | _data = CLOSED;
168 | }
169 |
170 | return (_data ? ESTABLISHED : CLOSED);
171 | }
172 |
173 | /*
174 | *
175 | */
176 | uint8_t ServerSpiDrv::getClientState(const uint8_t sock)
177 | {
178 | // Send Command
179 | EspSpiDrv::sendCmd(GET_CLIENT_STATE_TCP_CMD, PARAM_NUMS_1);
180 | EspSpiDrv::sendParam(sock);
181 | EspSpiDrv::endCmd();
182 |
183 | // Wait for reply
184 | uint8_t _data = -1;
185 | uint8_t _dataLen = sizeof(_data);
186 | if (!EspSpiDrv::waitResponseCmd(GET_CLIENT_STATE_TCP_CMD, PARAM_NUMS_1, &_data, &_dataLen))
187 | {
188 | WARN(FPSTR(WiFiSpiDrv::ERROR_WAITRESPONSE));
189 | _data = 0;
190 | }
191 |
192 | return (_data ? ESTABLISHED : CLOSED);
193 | }
194 |
195 | /*
196 | *
197 | */
198 | uint16_t ServerSpiDrv::availData(const uint8_t sock)
199 | {
200 | // Send Command
201 | EspSpiDrv::sendCmd(AVAIL_DATA_TCP_CMD, PARAM_NUMS_1);
202 | EspSpiDrv::sendParam(sock);
203 | EspSpiDrv::endCmd();
204 |
205 | // Wait for reply
206 | uint16_t _data16;
207 | uint8_t _dataLen = sizeof(_data16);
208 | if (!EspSpiDrv::waitResponseCmd(AVAIL_DATA_TCP_CMD, PARAM_NUMS_1, reinterpret_cast(&_data16), &_dataLen))
209 | {
210 | WARN(FPSTR(WiFiSpiDrv::ERROR_WAITRESPONSE));
211 | _data16 = 0;
212 | }
213 |
214 | return _data16;
215 | }
216 |
217 | /*
218 | *
219 | */
220 | bool ServerSpiDrv::getData(const uint8_t sock, int16_t *data, const uint8_t peek)
221 | {
222 | // Send Command
223 | EspSpiDrv::sendCmd(GET_DATA_TCP_CMD, PARAM_NUMS_2);
224 | EspSpiDrv::sendParam(sock);
225 | EspSpiDrv::sendParam(peek);
226 | EspSpiDrv::endCmd();
227 |
228 | // Wait for reply
229 | int16_t _data16 = -1; // -1 is error indicator
230 | uint8_t _dataLen = sizeof(_data16);
231 | if (!EspSpiDrv::waitResponseCmd(GET_DATA_TCP_CMD, PARAM_NUMS_1, reinterpret_cast(&_data16), &_dataLen))
232 | {
233 | WARN(FPSTR(WiFiSpiDrv::ERROR_WAITRESPONSE));
234 | _dataLen = 0;
235 | }
236 | else
237 | *data = _data16;
238 |
239 | return (_dataLen == sizeof(_data16));
240 | }
241 |
242 | /*
243 | Reads data into a buffer. There must be enough data for the whole buffer or the return code is false (error).
244 | It is not very clever but it is how the original WiFi library works.
245 | */
246 | bool ServerSpiDrv::getDataBuf(const uint8_t sock, uint8_t *_data, uint16_t *_dataLen)
247 | {
248 | // Send Command
249 | EspSpiDrv::sendCmd(GET_DATABUF_TCP_CMD, PARAM_NUMS_2);
250 | EspSpiDrv::sendParam(sock);
251 | EspSpiDrv::sendParam(reinterpret_cast(_dataLen), sizeof(*_dataLen));
252 | EspSpiDrv::endCmd();
253 |
254 | // Wait for reply (length is 16 bit integer)
255 | uint16_t _dataLenRead = *_dataLen;
256 | if (!EspSpiDrv::waitResponseCmd16(GET_DATABUF_TCP_CMD, PARAM_NUMS_1, _data, &_dataLenRead))
257 | {
258 | WARN(FPSTR(WiFiSpiDrv::ERROR_WAITRESPONSE));
259 | _dataLenRead = 0;
260 | }
261 |
262 | if (_dataLenRead != *_dataLen)
263 | return false;
264 |
265 | return true;
266 | }
267 |
268 | /*
269 | Works for UDP connection only
270 | */
271 | bool ServerSpiDrv::insertDataBuf(uint8_t sock, const uint8_t *data, uint16_t _len)
272 | {
273 | // Send Command
274 | EspSpiDrv::sendCmd(INSERT_DATABUF_CMD, PARAM_NUMS_2);
275 | EspSpiDrv::sendParam(sock);
276 | EspSpiDrv::sendBuffer(data, _len);
277 | EspSpiDrv::endCmd();
278 |
279 | // Wait for reply
280 | uint16_t _data16;
281 | uint8_t _dataLen = sizeof(_data16);
282 | if (!EspSpiDrv::waitResponseCmd(INSERT_DATABUF_CMD, PARAM_NUMS_1, reinterpret_cast(&_data16), &_dataLen))
283 | {
284 | WARN(FPSTR(WiFiSpiDrv::ERROR_WAITRESPONSE));
285 | _data16 = 0;
286 | }
287 | return (_dataLen == sizeof(_data16) && _data16 == _len);
288 | }
289 |
290 | /*
291 | *
292 | */
293 | bool ServerSpiDrv::sendUdpData(uint8_t sock)
294 | {
295 | // Send Command
296 | EspSpiDrv::sendCmd(SEND_DATA_UDP_CMD, PARAM_NUMS_1);
297 | EspSpiDrv::sendParam(sock);
298 | EspSpiDrv::endCmd();
299 |
300 | // Wait for reply
301 | uint8_t _data = 0;
302 | uint8_t _dataLen = sizeof(_data);
303 | if (!EspSpiDrv::waitResponseCmd(SEND_DATA_UDP_CMD, PARAM_NUMS_1, &_data, &_dataLen))
304 | {
305 | WARN(FPSTR(WiFiSpiDrv::ERROR_WAITRESPONSE));
306 | _data = 0;
307 | }
308 |
309 | return (_data == 1);
310 | }
311 |
312 | /*
313 | *
314 | */
315 | bool ServerSpiDrv::sendData(const uint8_t sock, const uint8_t *data, const uint16_t len)
316 | {
317 | // Send Command
318 | EspSpiDrv::sendCmd(SEND_DATA_TCP_CMD, PARAM_NUMS_2);
319 | EspSpiDrv::sendParam(sock);
320 | EspSpiDrv::sendBuffer(data, len);
321 | EspSpiDrv::endCmd();
322 |
323 | // Wait for reply
324 | uint16_t _data16;
325 | uint8_t _dataLen = sizeof(_data16);
326 | if (!EspSpiDrv::waitResponseCmd(SEND_DATA_TCP_CMD, PARAM_NUMS_1, reinterpret_cast(&_data16), &_dataLen))
327 | {
328 | WARN(FPSTR(WiFiSpiDrv::ERROR_WAITRESPONSE));
329 | _data16 = 0;
330 | }
331 | return (_dataLen == sizeof(_data16) && _data16 == len);
332 | }
333 |
334 | /*
335 | Opens UDP communication on defined IP address and port
336 | */
337 | bool ServerSpiDrv::beginUdpPacket(uint32_t ipAddress, uint16_t port, uint8_t sock)
338 | {
339 | // Send Command
340 | EspSpiDrv::sendCmd(BEGIN_UDP_PACKET_CMD, PARAM_NUMS_3);
341 | EspSpiDrv::sendParam(reinterpret_cast(&ipAddress), sizeof(ipAddress));
342 | EspSpiDrv::sendParam(reinterpret_cast(&port), sizeof(port));
343 | EspSpiDrv::sendParam(sock);
344 | EspSpiDrv::endCmd();
345 |
346 | // Wait for reply
347 |
348 | // Extended waiting time for status SPISLAVE_TX_PREPARING_DATA
349 | for (int i=1; i<10; ++i)
350 | {
351 | if (espSpiProxy.waitForSlaveTxReady() != SPISLAVE_TX_PREPARING_DATA)
352 | break; // The state is either SPISLAVE_TX_READY or SPISLAVE_TX_NODATA with timeout
353 | WARN(F("Status: Preparing data")); ///
354 | }
355 |
356 | uint8_t _data = 0;
357 | uint8_t _dataLen = sizeof(_data);
358 | if (!EspSpiDrv::waitResponseCmd(BEGIN_UDP_PACKET_CMD, PARAM_NUMS_1, &_data, &_dataLen))
359 | {
360 | WARN(FPSTR(WiFiSpiDrv::ERROR_WAITRESPONSE));
361 | _data = 0;
362 | }
363 |
364 | return (_data == 1); // return value 1 means ok
365 | }
366 |
367 | /*
368 | *
369 | */
370 | uint16_t ServerSpiDrv::parsePacket(const uint8_t sock)
371 | {
372 | // Send Command
373 | EspSpiDrv::sendCmd(UDP_PARSE_PACKET_CMD, PARAM_NUMS_1);
374 | EspSpiDrv::sendParam(sock);
375 | EspSpiDrv::endCmd();
376 |
377 | // Wait for reply
378 | uint16_t _data16;
379 | uint8_t _dataLen = sizeof(_data16);
380 | if (!EspSpiDrv::waitResponseCmd(UDP_PARSE_PACKET_CMD, PARAM_NUMS_1, reinterpret_cast(&_data16), &_dataLen))
381 | {
382 | WARN(FPSTR(WiFiSpiDrv::ERROR_WAITRESPONSE));
383 | _data16 = 0;
384 | }
385 |
386 | return _data16;
387 | }
388 |
389 | /*
390 | * Sends verifySSL command
391 | * fingerprint - SHA1 of server certificate - must be 20 bytes (not character string!)
392 | * host - host name
393 | */
394 | uint8_t ServerSpiDrv::verifySSLClient(const uint8_t sock, uint8_t *fingerprint, const char *host)
395 | {
396 | // Send Command
397 | EspSpiDrv::sendCmd(VERIFY_SSL_CLIENT_CMD, PARAM_NUMS_3);
398 | EspSpiDrv::sendParam(fingerprint, 20);
399 | EspSpiDrv::sendParam(reinterpret_cast(host), strlen(host));
400 | EspSpiDrv::sendParam(sock);
401 | EspSpiDrv::endCmd();
402 |
403 | // Wait for reply
404 |
405 | uint8_t _data = 0;
406 | uint8_t _dataLen = sizeof(_data);
407 | if (!EspSpiDrv::waitResponseCmd(VERIFY_SSL_CLIENT_CMD, PARAM_NUMS_1, &_data, &_dataLen))
408 | {
409 | WARN(FPSTR(WiFiSpiDrv::ERROR_WAITRESPONSE));
410 | _data = 0;
411 | }
412 |
413 | return _data; // return value 1 means ok
414 | }
415 |
--------------------------------------------------------------------------------
/src/utility/srvspi_drv.h:
--------------------------------------------------------------------------------
1 | /*
2 | srvspi_drv.h - Library for Arduino Wifi SPI connection with ESP8266.
3 | Copyright (c) 2017 Jiri Bilek. All right reserved.
4 |
5 | ---
6 |
7 | Based on server_drv.h - Library for Arduino Wifi shield.
8 | Copyright (c) 2011-2014 Arduino. All right reserved.
9 |
10 | This library is free software; you can redistribute it and/or
11 | modify it under the terms of the GNU Lesser General Public
12 | License as published by the Free Software Foundation; either
13 | version 2.1 of the License, or (at your option) any later version.
14 |
15 | This library is distributed in the hope that it will be useful,
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 | Lesser General Public License for more details.
19 |
20 | You should have received a copy of the GNU Lesser General Public
21 | License along with this library; if not, write to the Free Software
22 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 | */
24 |
25 | #ifndef _SRVSPI_DRV_H_INCLUDED
26 | #define _SRVSPI_DRV_H_INCLUDED
27 |
28 | #include
29 | #include "wifi_spi.h"
30 |
31 | typedef enum eProtMode {
32 | TCP_MODE,
33 | UDP_MODE,
34 | TCP_MODE_WITH_TLS }
35 | tProtMode;
36 |
37 | class ServerSpiDrv
38 | {
39 | public:
40 |
41 | // Start server TCP / UDP on port specified
42 | static bool startServer(const uint16_t port, const uint8_t sock, const uint8_t protMode=TCP_MODE);
43 |
44 | // Start server UDP Multicast on port specified listening given ip address
45 | static bool startServerMulticast(const uint32_t ipAddress, const uint16_t port, const uint8_t sock);
46 |
47 | static void stopServer(const uint8_t sock);
48 |
49 | static bool startClient(const uint32_t ipAddress, const uint16_t port, const uint8_t sock, const uint8_t protMode=TCP_MODE);
50 |
51 | static void stopClient(const uint8_t sock);
52 |
53 | static uint8_t getServerState(const uint8_t sock);
54 |
55 | static uint8_t getClientState(const uint8_t sock);
56 |
57 | static bool getData(const uint8_t sock, int16_t *data, uint8_t peek = 0);
58 |
59 | static bool getDataBuf(const uint8_t sock, uint8_t *data, uint16_t *len);
60 |
61 | static bool sendData(const uint8_t sock, const uint8_t *data, const uint16_t len);
62 |
63 | static bool sendUdpData(const uint8_t sock);
64 |
65 | static bool insertDataBuf(const uint8_t sock, const uint8_t *_data, const uint16_t _dataLen);
66 |
67 | static uint16_t availData(const uint8_t sock);
68 |
69 | /// static uint8_t checkDataSent(uint8_t sock);
70 |
71 | static bool beginUdpPacket(uint32_t ip, uint16_t port, uint8_t sock);
72 |
73 | static uint16_t parsePacket(const uint8_t sock);
74 |
75 | static uint8_t verifySSLClient(const uint8_t sock, uint8_t *fingerprint, const char *host);
76 | };
77 |
78 | #endif
79 |
--------------------------------------------------------------------------------
/src/utility/wifi_spi.h:
--------------------------------------------------------------------------------
1 | /*
2 | wifi_spi.h - Library for Arduino Wifi SPI connection with ESP8266.
3 | Copyright (c) 2017 Jiri Bilek. All right reserved.
4 |
5 | ---
6 |
7 | Based on wifi_spi.h - Library for Arduino Wifi shield.
8 | Copyright (c) 2011-2014 Arduino. All right reserved.
9 |
10 | This library is free software; you can redistribute it and/or
11 | modify it under the terms of the GNU Lesser General Public
12 | License as published by the Free Software Foundation; either
13 | version 2.1 of the License, or (at your option) any later version.
14 |
15 | This library is distributed in the hope that it will be useful,
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 | Lesser General Public License for more details.
19 |
20 | You should have received a copy of the GNU Lesser General Public
21 | License along with this library; if not, write to the Free Software
22 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 | */
24 |
25 | #ifndef _WIFI_SPI_H_INCLUDED
26 | #define _WIFI_SPI_H_INCLUDED
27 |
28 | #include
29 | #include "wl_definitions.h"
30 |
31 | #define REPLY_FLAG 1<<7
32 |
33 | #define START_CMD 0xE0
34 | #define END_CMD 0xEE
35 | //#define ERR_CMD 0xEF
36 |
37 | enum {
38 | SET_NET_CMD = 0x10,
39 | SET_PASSPHRASE_CMD = 0x11,
40 | SET_KEY_CMD = 0x12,
41 | // TEST_CMD = 0x13,
42 | SET_IP_CONFIG_CMD = 0x14,
43 | // SET_DNS_CONFIG_CMD = 0x15,
44 |
45 | GET_CONN_STATUS_CMD = 0x20,
46 | GET_IPADDR_CMD = 0x21,
47 | GET_MACADDR_CMD = 0x22,
48 | GET_CURR_SSID_CMD = 0x23,
49 | GET_CURR_BSSID_CMD = 0x24,
50 | GET_CURR_RSSI_CMD = 0x25,
51 | GET_CURR_ENCT_CMD = 0x26,
52 | SCAN_NETWORKS = 0x27,
53 | START_SERVER_TCP_CMD = 0x28,
54 | GET_STATE_TCP_CMD = 0x29,
55 | DATA_SENT_TCP_CMD = 0x2A,
56 | AVAIL_DATA_TCP_CMD = 0x2B,
57 | GET_DATA_TCP_CMD = 0x2C,
58 | START_CLIENT_TCP_CMD = 0x2D,
59 | STOP_CLIENT_TCP_CMD = 0x2E,
60 | GET_CLIENT_STATE_TCP_CMD = 0x2F,
61 | DISCONNECT_CMD = 0x30,
62 | GET_IDX_SSID_CMD = 0x31,
63 | GET_IDX_RSSI_CMD = 0x32,
64 | GET_IDX_ENCT_CMD = 0x33,
65 | REQ_HOST_BY_NAME_CMD = 0x34,
66 | GET_HOST_BY_NAME_CMD = 0x35,
67 | START_SCAN_NETWORKS = 0x36,
68 | GET_FW_VERSION_CMD = 0x37,
69 | GET_TEST_CMD = 0x38,
70 | SEND_DATA_UDP_CMD = 0x39,
71 | GET_REMOTE_DATA_CMD = 0x3A,
72 |
73 | // Not present in original protocol, added for ESP8266
74 | STOP_SERVER_TCP_CMD = 0x3B,
75 | GET_SCANNED_DATA_CMD = 0x3C,
76 | BEGIN_UDP_PACKET_CMD = 0x3D,
77 | UDP_PARSE_PACKET_CMD = 0x3E,
78 | SOFTWARE_RESET_CMD = 0x3F,
79 |
80 | GET_PROTOCOL_VERSION_CMD = 0x50,
81 | VERIFY_SSL_CLIENT_CMD = 0x51,
82 | START_SERVER_MULTICAST_CMD = 0x52,
83 | SET_SSL_FINGERPRINT_CMD = 0x53,
84 |
85 | // All command with DATA_FLAG 0x40 send a 16bit Len
86 |
87 | SEND_DATA_TCP_CMD = 0x44,
88 | GET_DATABUF_TCP_CMD = 0x45,
89 | INSERT_DATABUF_CMD = 0x46,
90 | };
91 |
92 |
93 | enum wl_tcp_state {
94 | CLOSED = 0,
95 | ESTABLISHED = 4
96 | };
97 |
98 | /*enum wl_tcp_state {
99 | CLOSED = 0,
100 | LISTEN = 1,
101 | SYN_SENT = 2,
102 | SYN_RCVD = 3,
103 | ESTABLISHED = 4,
104 | FIN_WAIT_1 = 5,
105 | FIN_WAIT_2 = 6,
106 | CLOSE_WAIT = 7,
107 | CLOSING = 8,
108 | LAST_ACK = 9,
109 | TIME_WAIT = 10
110 | };*/
111 |
112 |
113 | enum numParams{
114 | PARAM_NUMS_0,
115 | PARAM_NUMS_1,
116 | PARAM_NUMS_2,
117 | PARAM_NUMS_3,
118 | PARAM_NUMS_4,
119 | PARAM_NUMS_5,
120 | MAX_PARAM_NUMS
121 | };
122 |
123 | #define MAX_PARAMS MAX_PARAM_NUMS-1
124 | #define PARAM_LEN_SIZE 1
125 |
126 | typedef struct __attribute__((__packed__))
127 | {
128 | uint8_t paramLen;
129 | char* param;
130 | } tParam;
131 |
132 | #endif
133 |
--------------------------------------------------------------------------------
/src/utility/wifispi_drv.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | wifispi_drv.cpp - Library for Arduino SPI connection to ESP8266
3 | Copyright (c) 2017 Jiri Bilek. All right reserved.
4 |
5 | ---
6 |
7 | Based on wifi_drv.cpp - Library for Arduino Wifi shield.
8 | Copyright (c) 2011-2014 Arduino. All right reserved.
9 |
10 | This library is free software; you can redistribute it and/or
11 | modify it under the terms of the GNU Lesser General Public
12 | License as published by the Free Software Foundation; either
13 | version 2.1 of the License, or (at your option) any later version.
14 |
15 | This library is distributed in the hope that it will be useful,
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 | Lesser General Public License for more details.
19 |
20 | You should have received a copy of the GNU Lesser General Public
21 | License along with this library; if not, write to the Free Software
22 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 | */
24 |
25 | #include
26 | #include
27 | #include
28 |
29 | #include "Arduino.h"
30 |
31 | #include "espspi_proxy.h"
32 | #include "espspi_drv.h"
33 | #include "wifispi_drv.h"
34 |
35 | extern "C" {
36 | #include "wl_types.h"
37 | #include "debug.h"
38 | }
39 |
40 | #define FPSTR(pstr_pointer) (reinterpret_cast(pstr_pointer))
41 |
42 | SPIClass *WiFiSpiDrv::spi_obj;
43 |
44 | // Array of data to cache the information related to the networks discovered
45 | char WiFiSpiDrv::_networkSsid[] = {0};
46 | int32_t WiFiSpiDrv::_networkRssi = 0;
47 | uint8_t WiFiSpiDrv::_networkEncr = 0;
48 |
49 | // Cached values of retrieved data
50 | char WiFiSpiDrv::_ssid[] = {0};
51 | uint8_t WiFiSpiDrv::_bssid[] = {0};
52 | uint8_t WiFiSpiDrv::_mac[] = {0};
53 | uint8_t WiFiSpiDrv::_localIp[] = {0};
54 | uint8_t WiFiSpiDrv::_subnetMask[] = {0};
55 | uint8_t WiFiSpiDrv::_gatewayIp[] = {0};
56 |
57 | // Firmware and protocol version
58 | char WiFiSpiDrv::fwVersion[] = {0};
59 | char WiFiSpiDrv::protocolVersion[] = {0};
60 |
61 | // Static private class members
62 | const char WiFiSpiDrv::ERROR_WAITRESPONSE[] PROGMEM = "Error waitResponse";
63 | const char WiFiSpiDrv::ERROR_BADREPLY[] PROGMEM = "Error badReply";
64 |
65 | // Private Methods
66 |
67 | /*
68 | *
69 | */
70 | int8_t WiFiSpiDrv::getNetworkData(uint8_t *ip, uint8_t *mask, uint8_t *gwip)
71 | {
72 | tParam params[PARAM_NUMS_3] = { {WL_IPV4_LENGTH, (char*)ip}, {WL_IPV4_LENGTH, (char*)mask}, {WL_IPV4_LENGTH, (char*)gwip}};
73 |
74 | // Send Command
75 | EspSpiDrv::sendCmd(GET_IPADDR_CMD, PARAM_NUMS_0);
76 |
77 | if (!EspSpiDrv::waitResponseParams(GET_IPADDR_CMD, PARAM_NUMS_3, params))
78 | {
79 | WARN(FPSTR(ERROR_WAITRESPONSE));
80 | return WL_FAILURE;
81 | }
82 |
83 | return WL_SUCCESS;
84 | }
85 |
86 | /*
87 | *
88 | */
89 | int8_t WiFiSpiDrv::getScannedData(uint8_t networkItem, char *ssid, int32_t *rssi, uint8_t *encr)
90 | {
91 | tParam params[PARAM_NUMS_3] = { {WL_SSID_MAX_LENGTH, (char*)ssid}, {sizeof(*rssi), (char*)rssi}, {sizeof(*encr), (char*)encr}};
92 |
93 | // Send Command
94 | EspSpiDrv::sendCmd(GET_SCANNED_DATA_CMD, PARAM_NUMS_1);
95 | EspSpiDrv::sendParam(networkItem);
96 | EspSpiDrv::endCmd();
97 |
98 | ssid[0] = 0; // Default is empty SSID
99 |
100 | if (!EspSpiDrv::waitResponseParams(GET_SCANNED_DATA_CMD, PARAM_NUMS_3, params))
101 | {
102 | WARN(FPSTR(ERROR_WAITRESPONSE));
103 | return WL_FAILURE;
104 | }
105 |
106 | ssid[params[0].paramLen] = 0; // end of string
107 |
108 | return WL_SUCCESS;
109 | }
110 |
111 | /*
112 | *
113 | */
114 | bool WiFiSpiDrv::getRemoteData(uint8_t sock, uint8_t *ip, uint16_t *port)
115 | {
116 | tParam params[PARAM_NUMS_2] = { {4, (char*)ip}, {sizeof(*port), (char*)port} };
117 |
118 | // Send Command
119 | EspSpiDrv::sendCmd(GET_REMOTE_DATA_CMD, PARAM_NUMS_1);
120 | EspSpiDrv::sendParam(sock);
121 | EspSpiDrv::endCmd();
122 |
123 | if (!EspSpiDrv::waitResponseParams(GET_REMOTE_DATA_CMD, PARAM_NUMS_2, params))
124 | {
125 | WARN(FPSTR(ERROR_WAITRESPONSE));
126 | return false;
127 | }
128 |
129 | return true;
130 | }
131 |
132 |
133 | // Public Methods
134 |
135 | /*
136 | *
137 | */
138 | void WiFiSpiDrv::wifiDriverInit(uint8_t pin, uint32_t max_speed, SPIClass *in_spi)
139 | {
140 | spi_obj = in_spi;
141 | spi_obj->begin();
142 |
143 | if (max_speed != 0)
144 | spi_obj->beginTransaction(SPISettings(max_speed, MSBFIRST, SPI_MODE0));
145 |
146 | espSpiProxy.begin(pin, spi_obj);
147 | }
148 |
149 | /*
150 | *
151 | */
152 | int8_t WiFiSpiDrv::wifiSetNetwork(const char* ssid, uint8_t ssid_len)
153 | {
154 | // Test the input
155 | if (ssid_len > WL_SSID_MAX_LENGTH)
156 | return WL_FAILURE;
157 |
158 | // Send Command
159 | EspSpiDrv::sendCmd(SET_NET_CMD, PARAM_NUMS_1);
160 | EspSpiDrv::sendParam(reinterpret_cast(ssid), ssid_len);
161 | EspSpiDrv::endCmd();
162 |
163 | // Wait for reply
164 | uint8_t _data = -1;
165 | uint8_t _dataLen = sizeof(_data);
166 | if (!EspSpiDrv::waitResponseCmd(SET_NET_CMD, PARAM_NUMS_1, &_data, &_dataLen))
167 | {
168 | WARN(FPSTR(ERROR_WAITRESPONSE));
169 | _data = WL_FAILURE;
170 | }
171 |
172 | return _data;
173 | }
174 |
175 | /*
176 | * Connects to AP with given parameters
177 | * Returns: status - see getConnectionStatus()
178 | */
179 | uint8_t WiFiSpiDrv::wifiSetPassphrase(const char* ssid, const uint8_t ssid_len, const char *passphrase, const uint8_t len)
180 | {
181 | // Test the input
182 | if (ssid_len > WL_SSID_MAX_LENGTH || len > WL_WPA_KEY_MAX_LENGTH)
183 | return WL_FAILURE;
184 |
185 | // Send Command
186 | EspSpiDrv::sendCmd(SET_PASSPHRASE_CMD, PARAM_NUMS_2);
187 | EspSpiDrv::sendParam(reinterpret_cast(ssid), ssid_len);
188 | EspSpiDrv::sendParam(reinterpret_cast(passphrase), len);
189 | EspSpiDrv::endCmd();
190 |
191 | // Wait for reply
192 | uint8_t _data = -1;
193 | uint8_t _dataLen = sizeof(_data);
194 | if (!EspSpiDrv::waitResponseCmd(SET_PASSPHRASE_CMD, PARAM_NUMS_1, &_data, &_dataLen))
195 | {
196 | WARN(FPSTR(ERROR_WAITRESPONSE));
197 | _data = WL_FAILURE;
198 | }
199 |
200 | return _data;
201 | }
202 |
203 | /*
204 | *
205 | */
206 | bool WiFiSpiDrv::config(uint32_t local_ip, uint32_t gateway, uint32_t subnet, uint32_t dns_server1, uint32_t dns_server2)
207 | {
208 | // Send Command
209 | EspSpiDrv::sendCmd(SET_IP_CONFIG_CMD, PARAM_NUMS_5);
210 | EspSpiDrv::sendParam(reinterpret_cast(&local_ip), sizeof(local_ip));
211 | EspSpiDrv::sendParam(reinterpret_cast(&gateway), sizeof(gateway));
212 | EspSpiDrv::sendParam(reinterpret_cast(&subnet), sizeof(subnet));
213 | EspSpiDrv::sendParam(reinterpret_cast(&dns_server1), sizeof(dns_server1));
214 | EspSpiDrv::sendParam(reinterpret_cast(&dns_server2), sizeof(dns_server2));
215 | EspSpiDrv::endCmd();
216 |
217 | // Wait for reply
218 | uint8_t _data = false;
219 | uint8_t _dataLen = sizeof(_data);
220 | if (!EspSpiDrv::waitResponseCmd(SET_IP_CONFIG_CMD, PARAM_NUMS_1, &_data, &_dataLen))
221 | {
222 | WARN(FPSTR(ERROR_WAITRESPONSE));
223 | _data = false;
224 | }
225 |
226 | return _data;
227 | }
228 |
229 | /*
230 | *
231 | */
232 | uint8_t WiFiSpiDrv::disconnect()
233 | {
234 | // Send Command
235 | EspSpiDrv::sendCmd(DISCONNECT_CMD, PARAM_NUMS_0);
236 |
237 | // Wait for reply
238 | uint8_t _data = -1;
239 | uint8_t _dataLen = sizeof(_data);
240 | if (!EspSpiDrv::waitResponseCmd(DISCONNECT_CMD, PARAM_NUMS_1, &_data, &_dataLen))
241 | {
242 | WARN(FPSTR(ERROR_WAITRESPONSE));
243 | _data = WL_FAILURE;
244 | }
245 |
246 | return _data;
247 | }
248 |
249 | /*
250 | *
251 | */
252 | uint8_t WiFiSpiDrv::getConnectionStatus()
253 | {
254 | // Send Command
255 | EspSpiDrv::sendCmd(GET_CONN_STATUS_CMD, PARAM_NUMS_0);
256 |
257 | // Wait for reply
258 | uint8_t _data = -1;
259 | uint8_t _dataLen = sizeof(_data);
260 | if (!EspSpiDrv::waitResponseCmd(GET_CONN_STATUS_CMD, PARAM_NUMS_1, &_data, &_dataLen))
261 | {
262 | WARN(FPSTR(ERROR_WAITRESPONSE));
263 | }
264 |
265 | return _data;
266 | }
267 |
268 | /*
269 | *
270 | */
271 | uint8_t* WiFiSpiDrv::getMacAddress()
272 | {
273 | // Send Command
274 | EspSpiDrv::sendCmd(GET_MACADDR_CMD, PARAM_NUMS_0);
275 |
276 | // Wait for reply
277 | uint8_t _dataLen = WL_MAC_ADDR_LENGTH;
278 | if (!EspSpiDrv::waitResponseCmd(GET_MACADDR_CMD, PARAM_NUMS_1, _mac, &_dataLen))
279 | {
280 | WARN(FPSTR(ERROR_WAITRESPONSE));
281 | }
282 |
283 | if (_dataLen != WL_MAC_ADDR_LENGTH)
284 | {
285 | WARN(FPSTR(ERROR_BADREPLY));
286 | }
287 |
288 | return _mac;
289 | }
290 |
291 | /*
292 | *
293 | */
294 | int8_t WiFiSpiDrv::getIpAddress(IPAddress& ip)
295 | {
296 | int8_t status = getNetworkData(_localIp, _subnetMask, _gatewayIp);
297 | if (status == WL_SUCCESS)
298 | ip = _localIp;
299 |
300 | return status;
301 | }
302 |
303 | /*
304 | *
305 | */
306 | int8_t WiFiSpiDrv::getSubnetMask(IPAddress& mask)
307 | {
308 | int8_t status = getNetworkData(_localIp, _subnetMask, _gatewayIp);
309 | if (status == WL_SUCCESS)
310 | mask = _subnetMask;
311 |
312 | return status;
313 | }
314 |
315 | /*
316 | *
317 | */
318 | int8_t WiFiSpiDrv::getGatewayIP(IPAddress& ip)
319 | {
320 | int8_t status = getNetworkData(_localIp, _subnetMask, _gatewayIp);
321 | if (status == WL_SUCCESS)
322 | ip = _gatewayIp;
323 |
324 | return status;
325 | }
326 |
327 | /*
328 | *
329 | */
330 | char* WiFiSpiDrv::getCurrentSSID()
331 | {
332 | // Send Command
333 | EspSpiDrv::sendCmd(GET_CURR_SSID_CMD, PARAM_NUMS_0);
334 |
335 | // Wait for reply
336 | uint8_t _dataLen = WL_SSID_MAX_LENGTH;
337 | if (!EspSpiDrv::waitResponseCmd(GET_CURR_SSID_CMD, PARAM_NUMS_1, reinterpret_cast(_ssid), &_dataLen))
338 | {
339 | WARN(FPSTR(ERROR_WAITRESPONSE));
340 | }
341 |
342 | _ssid[_dataLen] = 0; // terminate the string
343 |
344 | return _ssid;
345 | }
346 |
347 | /*
348 | *
349 | */
350 | uint8_t* WiFiSpiDrv::getCurrentBSSID()
351 | {
352 | // Send Command
353 | EspSpiDrv::sendCmd(GET_CURR_BSSID_CMD, PARAM_NUMS_0);
354 |
355 | // Wait for reply
356 | uint8_t _dataLen = WL_MAC_ADDR_LENGTH;
357 | if (!EspSpiDrv::waitResponseCmd(GET_CURR_BSSID_CMD, PARAM_NUMS_1, _bssid, &_dataLen))
358 | {
359 | WARN(FPSTR(ERROR_WAITRESPONSE));
360 | }
361 |
362 | if (_dataLen != WL_MAC_ADDR_LENGTH)
363 | {
364 | WARN(FPSTR(ERROR_BADREPLY));
365 | }
366 |
367 | return _bssid;
368 | }
369 |
370 | /*
371 | *
372 | */
373 | int32_t WiFiSpiDrv::getCurrentRSSI()
374 | {
375 | // Send Command
376 | EspSpiDrv::sendCmd(GET_CURR_RSSI_CMD, PARAM_NUMS_0);
377 |
378 | // Wait for reply
379 | int32_t _rssi;
380 | uint8_t _dataLen = sizeof(_rssi);
381 | if (!EspSpiDrv::waitResponseCmd(GET_CURR_RSSI_CMD, PARAM_NUMS_1, reinterpret_cast(&_rssi), &_dataLen))
382 | {
383 | WARN(FPSTR(ERROR_WAITRESPONSE));
384 | _dataLen = 0;
385 | }
386 |
387 | if (_dataLen != sizeof(_rssi))
388 | {
389 | WARN(FPSTR(ERROR_BADREPLY));
390 | }
391 |
392 | return _rssi;
393 | }
394 |
395 | /*
396 | *
397 | */
398 | int8_t WiFiSpiDrv::startScanNetworks()
399 | {
400 | // Send Command
401 | EspSpiDrv::sendCmd(START_SCAN_NETWORKS, PARAM_NUMS_0);
402 |
403 | int8_t _data = -1;
404 | uint8_t _dataLen = sizeof(_data);
405 | if (!EspSpiDrv::waitResponseCmd(START_SCAN_NETWORKS, PARAM_NUMS_1, reinterpret_cast(&_data), &_dataLen))
406 | {
407 | WARN(FPSTR(ERROR_WAITRESPONSE));
408 | }
409 |
410 | return _data;
411 | }
412 |
413 | /*
414 | *
415 | */
416 | int8_t WiFiSpiDrv::getScanNetworks()
417 | {
418 | // Send Command
419 | EspSpiDrv::sendCmd(SCAN_NETWORKS, PARAM_NUMS_0);
420 |
421 | int8_t _data = -1;
422 | uint8_t _dataLen = sizeof(_data);
423 | if (!EspSpiDrv::waitResponseCmd(SCAN_NETWORKS, PARAM_NUMS_1, reinterpret_cast(&_data), &_dataLen))
424 | {
425 | WARN(FPSTR(ERROR_WAITRESPONSE));
426 | }
427 |
428 | return _data;
429 | }
430 |
431 | /*
432 | *
433 | */
434 | char* WiFiSpiDrv::getSSIDNetworks(uint8_t networkItem)
435 | {
436 | int8_t status = getScannedData(networkItem, _networkSsid, &_networkRssi, &_networkEncr);
437 | if (status != WL_SUCCESS)
438 | _networkSsid[0] = 0; // Empty string
439 |
440 | return _networkSsid;
441 | }
442 |
443 | /*
444 | *
445 | */
446 | uint8_t WiFiSpiDrv::getEncTypeNetworks(uint8_t networkItem)
447 | {
448 | int8_t status = getScannedData(networkItem, _networkSsid, &_networkRssi, &_networkEncr);
449 | if (status != WL_SUCCESS)
450 | return 0;
451 |
452 | return _networkEncr;
453 | }
454 |
455 | /*
456 | *
457 | */
458 | int32_t WiFiSpiDrv::getRSSINetworks(uint8_t networkItem)
459 | {
460 | int8_t status = getScannedData(networkItem, _networkSsid, &_networkRssi, &_networkEncr);
461 | if (status != WL_SUCCESS)
462 | return 0;
463 |
464 | return _networkRssi;
465 | }
466 |
467 | /*
468 | *
469 | */
470 | int8_t WiFiSpiDrv::getHostByName(const char* aHostname, IPAddress& aResult)
471 | {
472 | // Send Command
473 | EspSpiDrv::sendCmd(GET_HOST_BY_NAME_CMD, PARAM_NUMS_1);
474 | EspSpiDrv::sendParam(reinterpret_cast(aHostname), strlen(aHostname));
475 | EspSpiDrv::endCmd();
476 |
477 | // Wait for reply
478 | uint8_t _ipAddr[WL_IPV4_LENGTH];
479 | uint8_t _status;
480 |
481 | tParam params[PARAM_NUMS_2] = { {sizeof(_status), (char*)&_status}, {sizeof(_ipAddr), (char*)_ipAddr}};
482 |
483 | // Extended waiting time for status SPISLAVE_PREPARING_DATA
484 | for (int i=1; i<10; ++i)
485 | {
486 | if (espSpiProxy.waitForSlaveTxReady() != SPISLAVE_TX_PREPARING_DATA)
487 | break; // The state is either SPISLAVE_TX_READY or SPISLAVE_TX_NODATA with timeout
488 | WARN(F("Status: Preparing data"));
489 | }
490 |
491 | if (!EspSpiDrv::waitResponseParams(GET_HOST_BY_NAME_CMD, PARAM_NUMS_2, params))
492 | {
493 | WARN(FPSTR(ERROR_WAITRESPONSE));
494 | return WL_FAILURE;
495 | }
496 |
497 | if (params[0].paramLen != sizeof(_status) || params[1].paramLen != sizeof(_ipAddr))
498 | {
499 | WARN(FPSTR(ERROR_BADREPLY));
500 | return 0;
501 | }
502 |
503 | aResult = _ipAddr;
504 |
505 | return _status;
506 | }
507 |
508 | /*
509 | *
510 | */
511 | const char* WiFiSpiDrv::getFwVersion()
512 | {
513 | // Send Command
514 | EspSpiDrv::sendCmd(GET_FW_VERSION_CMD, PARAM_NUMS_0);
515 |
516 | // Wait for reply
517 | uint8_t _dataLen = WL_FW_VER_LENGTH;
518 | if (!EspSpiDrv::waitResponseCmd(GET_FW_VERSION_CMD, PARAM_NUMS_1, (uint8_t*)fwVersion, &_dataLen))
519 | {
520 | WARN(FPSTR(ERROR_WAITRESPONSE));
521 | }
522 |
523 | return fwVersion;
524 | }
525 |
526 | /*
527 | * Perform remote software reset of the ESP8266 module.
528 | * The reset succeedes only if the SPI communication is not broken.
529 | * The function does not wait for the ESP8266.
530 | */
531 | void WiFiSpiDrv::softReset(void) {
532 | // Send Command
533 | EspSpiDrv::sendCmd(SOFTWARE_RESET_CMD, PARAM_NUMS_0);
534 |
535 | // Wait for reply
536 | if (!EspSpiDrv::waitResponseCmd(SOFTWARE_RESET_CMD, PARAM_NUMS_0, NULL, NULL))
537 | {
538 | WARN(FPSTR(ERROR_WAITRESPONSE));
539 | }
540 | }
541 |
542 | /*
543 | *
544 | */
545 | const char* WiFiSpiDrv::getProtocolVersion()
546 | {
547 | // Send Command
548 | EspSpiDrv::sendCmd(GET_PROTOCOL_VERSION_CMD, PARAM_NUMS_0);
549 |
550 | // Wait for reply
551 | uint8_t _dataLen = WL_PROTOCOL_VER_LENGTH;
552 | if (!EspSpiDrv::waitResponseCmd(GET_PROTOCOL_VERSION_CMD, PARAM_NUMS_1, (uint8_t*)protocolVersion, &_dataLen))
553 | {
554 | WARN(FPSTR(ERROR_WAITRESPONSE));
555 | }
556 |
557 | return protocolVersion;
558 | }
559 |
560 | uint8_t WiFiSpiDrv::setSSLFingerprint(uint8_t *fingerprint)
561 | {
562 | // Send Command
563 | if (fingerprint == nullptr) // clear the saved fingerprint
564 | {
565 | EspSpiDrv::sendCmd(SET_SSL_FINGERPRINT_CMD, PARAM_NUMS_0);
566 | }
567 | else // set the fingerprint
568 | {
569 | EspSpiDrv::sendCmd(SET_SSL_FINGERPRINT_CMD, PARAM_NUMS_1);
570 | EspSpiDrv::sendParam(fingerprint, 20);
571 | EspSpiDrv::endCmd();
572 | }
573 |
574 | // Wait for reply
575 |
576 | uint8_t _data = 0;
577 | uint8_t _dataLen = sizeof(_data);
578 | if (!EspSpiDrv::waitResponseCmd(SET_SSL_FINGERPRINT_CMD, PARAM_NUMS_1, &_data, &_dataLen))
579 | {
580 | WARN(FPSTR(WiFiSpiDrv::ERROR_WAITRESPONSE));
581 | _data = 0;
582 | }
583 |
584 | return _data; // return value 1 means ok
585 | }
586 |
587 |
588 | WiFiSpiDrv wiFiSPIDrv;
589 |
590 |
--------------------------------------------------------------------------------
/src/utility/wifispi_drv.h:
--------------------------------------------------------------------------------
1 | /*
2 | wifispi_drv.h - Library for Arduino SPI connection to ESP8266
3 | Copyright (c) 2017 Jiri Bilek. All right reserved.
4 |
5 | ---
6 |
7 | Based on: wifi_drv.h - Library for Arduino Wifi shield.
8 | Copyright (c) 2011-2014 Arduino. All right reserved.
9 |
10 | This library is free software; you can redistribute it and/or
11 | modify it under the terms of the GNU Lesser General Public
12 | License as published by the Free Software Foundation; either
13 | version 2.1 of the License, or (at your option) any later version.
14 |
15 | This library is distributed in the hope that it will be useful,
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 | Lesser General Public License for more details.
19 |
20 | You should have received a copy of the GNU Lesser General Public
21 | License along with this library; if not, write to the Free Software
22 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 | */
24 |
25 | #ifndef _WIFISPI_DRV_H_INCLUDED
26 | #define _WIFISPI_DRV_H_INCLUDED
27 |
28 | #include
29 | #include "wifi_spi.h"
30 | #include "IPAddress.h"
31 | #include
32 |
33 | // Key index length
34 | ///#define KEY_IDX_LEN 1
35 | // 100 ms secs of delay to test if the connection is established
36 | #define WL_DELAY_START_CONNECTION 100
37 | // Firmware version string length (format a.b.c)
38 | #define WL_FW_VER_LENGTH 6
39 | // Protocol version string length (format a.b.c)
40 | #define WL_PROTOCOL_VER_LENGTH 6
41 |
42 | #define DUMMY_DATA 0xFF
43 |
44 |
45 | class WiFiSpiDrv
46 | {
47 | private:
48 | // SPI object
49 | static SPIClass *spi_obj;
50 |
51 | // settings of requested network
52 | static char _networkSsid[WL_SSID_MAX_LENGTH+1];
53 | static int32_t _networkRssi;
54 | static uint8_t _networkEncr;
55 |
56 | // firmware version string in the format a.b.c
57 | static char fwVersion[WL_FW_VER_LENGTH];
58 | // protocol version string in the format a.b.c
59 | static char protocolVersion[WL_PROTOCOL_VER_LENGTH];
60 |
61 | // settings of current selected network
62 | static char _ssid[WL_SSID_MAX_LENGTH+1];
63 | static uint8_t _bssid[WL_MAC_ADDR_LENGTH];
64 | static uint8_t _mac[WL_MAC_ADDR_LENGTH];
65 | static uint8_t _localIp[WL_IPV4_LENGTH];
66 | static uint8_t _subnetMask[WL_IPV4_LENGTH];
67 | static uint8_t _gatewayIp[WL_IPV4_LENGTH];
68 |
69 | /*
70 | * Get network Data information
71 | */
72 | static int8_t getNetworkData(uint8_t *ip, uint8_t *mask, uint8_t *gwip);
73 |
74 | /*
75 | * Get scanned data information
76 | */
77 | static int8_t getScannedData(uint8_t networkItem, char *ssid, int32_t *rssi, uint8_t *encr);
78 |
79 | static uint8_t reqHostByName(const char* aHostname);
80 |
81 | static int getHostByName(IPAddress& aResult);
82 |
83 | public:
84 | // Public constant strings
85 | static const char ERROR_WAITRESPONSE[] PROGMEM; // "Error waitResponse"
86 | static const char ERROR_BADREPLY[] PROGMEM; // "Error badReply"
87 |
88 | /*
89 | * Driver initialization, pin is GPIO port number used as SS
90 | */
91 | static void wifiDriverInit(uint8_t pin, uint32_t max_speed = 0, SPIClass *in_spi = &SPI);
92 |
93 | /*
94 | * Set the desired network which the connection manager should try to
95 | * connect to.
96 | *
97 | * The ssid of the desired network should be specified.
98 | *
99 | * param ssid: The ssid of the desired network.
100 | * param ssid_len: Lenght of ssid string.
101 | * return: WL_SUCCESS or WL_FAILURE
102 | */
103 | static int8_t wifiSetNetwork(const char* ssid, uint8_t ssid_len);
104 |
105 | /* Start Wifi connection with passphrase
106 | * the most secure supported mode will be automatically selected
107 | *
108 | * param ssid: Pointer to the SSID string.
109 | * param ssid_len: Length of ssid string.
110 | * param passphrase: Passphrase. Valid characters in a passphrase
111 | * must be between ASCII 32-126 (decimal).
112 | * param len: Length of passphrase string.
113 | * return: WL_SUCCESS or WL_FAILURE
114 | */
115 | static uint8_t wifiSetPassphrase(const char* ssid, const uint8_t ssid_len, const char *passphrase, const uint8_t len);
116 |
117 | /* Start Wifi connection with WEP encryption.
118 | * Configure a key into the device. The key type (WEP-40, WEP-104)
119 | * is determined by the size of the key (5 bytes for WEP-40, 13 bytes for WEP-104).
120 | *
121 | * param ssid: Pointer to the SSID string.
122 | * param ssid_len: Lenght of ssid string.
123 | * param key_idx: The key index to set. Valid values are 0-3.
124 | * param key: Key input buffer.
125 | * param len: Lenght of key string.
126 | * return: WL_SUCCESS or WL_FAILURE
127 | */
128 | /// static int8_t wifiSetKey(const char* ssid, uint8_t ssid_len, uint8_t key_idx, const void *key, const uint8_t len);
129 |
130 | /* Set ip configuration disabling dhcp client
131 | *
132 | * param local_ip: Static ip configuration
133 | * param gateway: Static gateway configuration
134 | * param subnet: Static subnet mask configuration
135 | * param dns_server1: Static DNS server1 configuration
136 | * param dns_server2: Static DNS server2 configuration
137 | */
138 | static bool config(uint32_t local_ip, uint32_t gateway, uint32_t subnet, uint32_t dns_server1, uint32_t dns_server2);
139 |
140 | /* Set DNS ip configuration
141 | *
142 | * param validParams: set the number of parameters that we want to change
143 | * i.e. validParams = 1 means that we'll change only dns_server1
144 | * validParams = 2 means that we'll change dns_server1 and dns_server2
145 | * param dns_server1: Static DNS server1 configuration
146 | * param dns_server2: Static DNS server2 configuration
147 | */
148 | /// static void setDNS(uint8_t validParams, uint32_t dns_server1, uint32_t dns_server2);
149 |
150 | /*
151 | * Disconnect from the network
152 | *
153 | * return: WL_SUCCESS or WL_FAILURE
154 | */
155 | static uint8_t disconnect();
156 |
157 | /*
158 | * Disconnect from the network
159 | *
160 | * return: one value of wl_status_t enum
161 | */
162 | static uint8_t getConnectionStatus();
163 |
164 | /*
165 | * Get the interface MAC address.
166 | *
167 | * return: pointer to uint8_t array with length WL_MAC_ADDR_LENGTH
168 | */
169 | static uint8_t* getMacAddress();
170 |
171 | /*
172 | * Get the interface IP address.
173 | *
174 | * return: copy the ip address value in IPAddress object
175 | */
176 | static int8_t getIpAddress(IPAddress& ip);
177 |
178 | /*
179 | * Get the interface subnet mask address.
180 | *
181 | * return: copy the subnet mask address value in IPAddress object
182 | */
183 | static int8_t getSubnetMask(IPAddress& mask);
184 |
185 | /*
186 | * Get the gateway ip address.
187 | *
188 | * return: copy the gateway ip address value in IPAddress object
189 | */
190 | static int8_t getGatewayIP(IPAddress& ip);
191 |
192 | /*
193 | * Return the current SSID associated with the network
194 | *
195 | * return: ssid string
196 | */
197 | static char* getCurrentSSID();
198 |
199 | /*
200 | * Return the current BSSID associated with the network.
201 | * It is the MAC address of the Access Point
202 | *
203 | * return: pointer to uint8_t array with length WL_MAC_ADDR_LENGTH
204 | */
205 | static uint8_t* getCurrentBSSID();
206 |
207 | /*
208 | * Return the current RSSI /Received Signal Strength in dBm)
209 | * associated with the network
210 | *
211 | * return: signed value
212 | */
213 | static int32_t getCurrentRSSI();
214 |
215 | /*
216 | * Return the Encryption Type associated with the network
217 | *
218 | * return: one value of wl_enc_type enum
219 | */
220 | /// static uint8_t getCurrentEncryptionType();
221 |
222 | /*
223 | * Start scan WiFi networks available
224 | *
225 | * return: Number of discovered networks
226 | */
227 | static int8_t startScanNetworks();
228 |
229 | /*
230 | * Get the networks available
231 | *
232 | * return: Number of discovered networks
233 | */
234 | static int8_t getScanNetworks();
235 |
236 | /*
237 | * Return the SSID discovered during the network scan.
238 | *
239 | * param networkItem: specify from which network item want to get the information
240 | *
241 | * return: ssid string of the specified item on the networks scanned list
242 | */
243 | static char* getSSIDNetworks(uint8_t networkItem);
244 |
245 | /*
246 | * Return the RSSI of the networks discovered during the scanNetworks
247 | *
248 | * param networkItem: specify from which network item want to get the information
249 | *
250 | * return: signed value of RSSI of the specified item on the networks scanned list
251 | */
252 | static int32_t getRSSINetworks(uint8_t networkItem);
253 |
254 | /*
255 | * Return the encryption type of the networks discovered during the scanNetworks
256 | *
257 | * param networkItem: specify from which network item want to get the information
258 | *
259 | * return: encryption type (enum wl_enc_type) of the specified item on the networks scanned list
260 | */
261 | static uint8_t getEncTypeNetworks(uint8_t networkItem);
262 |
263 | /*
264 | * Resolve the given hostname to an IP address.
265 | * param aHostname: Name to be resolved
266 | * param aResult: IPAddress structure to store the returned IP address
267 | * result: 1 if aIPAddrString was successfully converted to an IP address,
268 | * 0 error, hostname not found
269 | * -1 error, command was not performed
270 | */
271 | static int8_t getHostByName(const char* aHostname, IPAddress& aResult);
272 |
273 | /*
274 | * Get the firmware version
275 | * result: version as string with this format a.b.c
276 | */
277 | static const char* getFwVersion();
278 |
279 | /*
280 | * Get remote Data information on UDP socket
281 | */
282 | static bool getRemoteData(uint8_t sock, uint8_t *ip, uint16_t *port);
283 |
284 | /*
285 | * Perform software reset of the ESP8266 module.
286 | * The reset succeedes only if the SPI communication is not broken.
287 | * After the reset wait for the ESP8266 to came to life again. Typically, the ESP8266 boots within 100 ms,
288 | * but with the WifiManager installed on ESP it can be a couple of seconds.
289 | */
290 | static void softReset(void);
291 |
292 | /*
293 | * Get the SPI protocol version
294 | * result: version as string with this format a.b.c
295 | */
296 | static const char* getProtocolVersion();
297 |
298 | /*
299 | * Sets or clears the certificate fingerprint for SSL connection
300 | * fingerprint - SHA1 of server certificate - must be 20 bytes (not character string!)
301 | */
302 | static uint8_t setSSLFingerprint(uint8_t *fingerprint);
303 |
304 | };
305 |
306 | extern WiFiSpiDrv wiFiSpiDrv;
307 |
308 | #endif
309 |
--------------------------------------------------------------------------------
/src/utility/wl_definitions.h:
--------------------------------------------------------------------------------
1 | /*
2 | wl_definitions.h - Library for Arduino Wifi shield.
3 | Copyright (c) 2011-2014 Arduino. All right reserved.
4 |
5 | This library is free software; you can redistribute it and/or
6 | modify it under the terms of the GNU Lesser General Public
7 | License as published by the Free Software Foundation; either
8 | version 2.1 of the License, or (at your option) any later version.
9 |
10 | This library is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | Lesser General Public License for more details.
14 |
15 | You should have received a copy of the GNU Lesser General Public
16 | License along with this library; if not, write to the Free Software
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 | /*
20 | * wl_definitions.h
21 | *
22 | * Created on: Mar 6, 2011
23 | * Author: dlafauci
24 | */
25 |
26 | #ifndef _WL_DEFINITIONS_H_INCLUDED
27 | #define _WL_DEFINITIONS_H_INCLUDED
28 |
29 | // Maximum size of a SSID
30 | #define WL_SSID_MAX_LENGTH 32
31 | // Length of passphrase. Valid lengths are 8-63.
32 | #define WL_WPA_KEY_MAX_LENGTH 63
33 | // Length of key in bytes. Valid values are 5 and 13.
34 | #define WL_WEP_KEY_MAX_LENGTH 13
35 | // Size of a MAC-address or BSSID
36 | #define WL_MAC_ADDR_LENGTH 6
37 | // Size of a MAC-address or BSSID
38 | #define WL_IPV4_LENGTH 4
39 | // Maximum size of a SSID list
40 | #define WL_NETWORKS_LIST_MAXNUM 10
41 | // Maxmium number of socket
42 | #define MAX_SOCK_NUM 4
43 | // Socket not available constant
44 | #define SOCK_NOT_AVAIL 255
45 | // Default state value for Wifi state field
46 | #define NA_STATE -1
47 | // Maximum waiting time to establish wifi connection is 10 s (in WL_DELAY_START_CONNECTION = 100 ms)
48 | #define WL_MAX_ATTEMPT_CONNECTION 100
49 |
50 | typedef enum {
51 | WL_NO_SHIELD = 255,
52 | WL_IDLE_STATUS = 0,
53 | WL_NO_SSID_AVAIL,
54 | WL_SCAN_COMPLETED,
55 | WL_CONNECTED,
56 | WL_CONNECT_FAILED,
57 | WL_CONNECTION_LOST,
58 | WL_DISCONNECTED
59 | } wl_status_t;
60 |
61 | /* Encryption modes */
62 | /*enum wl_enc_type { // Values map to 802.11 encryption suites...
63 | ENC_TYPE_WEP = 5,
64 | ENC_TYPE_TKIP = 2,
65 | ENC_TYPE_CCMP = 4,
66 | // ... except these two, 7 and 8 are reserved in 802.11-2007
67 | ENC_TYPE_NONE = 7,
68 | ENC_TYPE_AUTO = 8
69 | };*/
70 |
71 |
72 | #endif /* WL_DEFINITIONS_H_ */
73 |
--------------------------------------------------------------------------------
/src/utility/wl_types.h:
--------------------------------------------------------------------------------
1 | /*
2 | wl_types.h - Library for Arduino Wifi shield.
3 | Copyright (c) 2011-2014 Arduino. All right reserved.
4 |
5 | This library is free software; you can redistribute it and/or
6 | modify it under the terms of the GNU Lesser General Public
7 | License as published by the Free Software Foundation; either
8 | version 2.1 of the License, or (at your option) any later version.
9 |
10 | This library is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | Lesser General Public License for more details.
14 |
15 | You should have received a copy of the GNU Lesser General Public
16 | License along with this library; if not, write to the Free Software
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 | /*
20 | * wl_types.h
21 | *
22 | * Created on: Jul 30, 2010
23 | * Author: dlafauci
24 | */
25 |
26 |
27 | #ifndef _WL_TYPES_H_INCLUDED
28 | #define _WL_TYPES_H_INCLUDED
29 |
30 | #include
31 |
32 | typedef enum {
33 | WL_FAILURE = -1,
34 | WL_SUCCESS = 1,
35 | } wl_error_code_t;
36 |
37 | /* Authentication modes */
38 | enum wl_auth_mode {
39 | AUTH_MODE_INVALID,
40 | AUTH_MODE_AUTO,
41 | AUTH_MODE_OPEN_SYSTEM,
42 | AUTH_MODE_SHARED_KEY,
43 | AUTH_MODE_WPA,
44 | AUTH_MODE_WPA2,
45 | AUTH_MODE_WPA_PSK,
46 | AUTH_MODE_WPA2_PSK
47 | };
48 |
49 | #endif //_WL_TYPES_H_
50 |
--------------------------------------------------------------------------------