WifiHQ
 All Classes Files Functions Pages
WiFlyHQ.h
Go to the documentation of this file.
1 /*-
2  * Copyright (c) 2012 Darran Hunt (darran [at] hunt dot net dot nz)
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
15  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
16  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
17  * THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
20  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
21  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
22  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
23  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 /* Release history
27  *
28  * Version Date Description
29  * 0.1 25-Mar-2012 First release.
30  * 0.2 09-Apr-2012 Added features to support http servers.
31  * - added an httpserver.ino example.
32  * - added sendChunk() and sendChunkln() to send chunked HTTP bodies.
33  * - added terminal() method for simple terminal access via debug stream
34  * - replaced getFreeMemory() with simpler version that works with 0 bytes
35  * - turned peek buffer into a circular buffer to fix bug with detecting
36  * *CLOS* and *OPEN* after a partial match.
37  * - Added new TCP connection detection via *OPEN* match from available().
38  * isConnected() can now be polled until a client connects.
39  * - made the match() function public, handy for matching text in a stream.
40  * - Added a getProtocol() function to get current set of protocols.
41  * 0.3 21-Apr-2012 Added createAdhocNetwork() to create an Ad Hoc WiFi network.
42  * Optimised the setopt() and getopt() function so they handle
43  * integer conversions and refactored all of the set and get functions.
44  * Added a multMatch_P() function to match serial data against multiple
45  * progmem strings.
46  * Added failure detection to the join() function to quickly detect
47  * a failure rather than relying on a timeout.
48  * Added setJoin() and getJoin() function for access to the wlan join parameter.
49  * Refactored getres() to use the new multiMatch_P() function.
50  *
51  */
52 
69 #ifndef _WIFLYHQ_H_
70 #define _WIFLYHQ_H_
71 
72 #include <Arduino.h>
73 #include <Stream.h>
74 #include <avr/pgmspace.h>
75 #include <IPAddress.h>
76 
77 /* IP Protocol bits */
78 #define WIFLY_PROTOCOL_UDP 0x01
79 #define WIFLY_PROTOCOL_TCP 0x02
80 #define WIFLY_PROTOCOL_SECURE 0x04
81 #define WIFLY_PROTOCOL_TCP_CLIENT 0x08
82 #define WIFLY_PROTOCOL_HTTP 0x10 /* HTTP Client mode */
83 #define WIFLY_PROTOCOL_RAW 0x20
84 #define WIFLY_PROTOCOL_SMTP 0x40
85 
86 /* IP Flag bits */
87 #define WIFLY_FLAG_TCP_KEEP 0x01 /* Keep TCP connection alive when wifi lost */
88 #define WIFLY_FLAG_TCP_NODELAY 0x02
89 #define WIFLY_FLAG_TCP_RETRY 0x04
90 #define WIFLY_FLAG_UDP_RETRY 0x08
91 #define WIFLY_FLAG_DNS_CACHING 0x10
92 #define WIFLY_FLAG_ARP_CACHING 0x20
93 #define WIFLY_FLAG_UDP_AUTO_PAIR 0x40
94 #define WIFLY_FLAG_ADD_TIMESTAMP 0x80
95 
96 /* UART mode bits */
97 #define WIFLY_UART_MODE_NOECHO 0x01
98 #define WIFLY_UART_MODE_DATA_TRIGGER 0x02
99 #define WIFLY_UART_MODE_SLEEP_RX_BREAK 0x08
100 #define WIFLY_UART_MODE_RX_BUFFER 0x10
101 
102 /* DHCP modes */
103 #define WIFLY_DHCP_MODE_OFF 0x00 /* No DHCP, static IP mode */
104 #define WIFLY_DHCP_MODE_ON 0x01 /* get IP, Gateway, and DNS from AP */
105 #define WIFLY_DHCP_MODE_AUTOIP 0x02 /* Used with Adhoc networks */
106 #define WIFLY_DHCP_MODE_CACHE 0x03 /* Use previous DHCP address based on lease */
107 #define WIFLY_DHCP_MODE_SERVER 0x04 /* Server DHCP IP addresses? */
108 
109 /* WLAN Join modes */
110 #define WIFLY_WLAN_JOIN_MANUAL 0x00 /* Don't auto-join a network */
111 #define WIFLY_WLAN_JOIN_AUTO 0x01 /* Auto-join network set in SSID, passkey, and channel. */
112 #define WIFLY_WLAN_JOIN_ANY 0x02 /* Ignore SSID and join strongest network using passkey. */
113 #define WIFLY_WLAN_JOIN_ADHOC 0x04 /* Create an Adhoc network using SSID, Channel, IP and NetMask */
114 
115 #define WIFLY_DEFAULT_TIMEOUT 500 /* 500 milliseconds */
116 
117 #define WIFLY_MODE_WPA 0
118 #define WIFLY_MODE_WEP 1
119 
120 class WFDebug : public Stream {
121 public:
122  WFDebug();
123  void begin(Stream *debugPrint);
124 
125  virtual size_t write(uint8_t byte);
126  virtual int read() { return debug->read(); }
127  virtual int available() { return debug->available(); }
128  virtual void flush() { return debug->flush(); }
129  virtual int peek() { return debug->peek(); }
130 
131  using Print::write;
132 private:
133  Stream *debug;
134 };
135 
136 class WiFly : public Stream {
137 public:
138  WiFly();
139 
140  boolean begin(Stream *serialdev, Stream *debugPrint = NULL);
141 
142  char *getSSID(char *buf, int size);
143  uint8_t getJoin();
144  char *getDeviceID(char *buf, int size);
145  char *getIP(char *buf, int size);
146  uint16_t getPort();
147  char *getNetmask(char *buf, int size);
148  char *getGateway(char *buf, int size);
149  char *getDNS(char *buf, int size);
150  char *getMAC(char *buf, int size);
151  int8_t getDHCPMode();
152  uint32_t getRate();
153  uint8_t getTxPower();
154 
155  uint16_t getConnection();
156  int8_t getRSSI();
157 
158  bool setJoin(uint8_t join);
159  boolean setDeviceID(const char *buf);
160  boolean setBaud(uint32_t baud);
161  uint32_t getBaud();
162  uint8_t getUartMode();
163  uint8_t getIpFlags();
164  uint8_t getProtocol();
165 
166  uint8_t getFlushChar();
167  uint16_t getFlushSize();
168  uint16_t getFlushTimeout();
169 
170  char getSpaceReplace(void);
171 
172  char *getHostIP(char *buf, int size);
173  uint16_t getHostPort();
174 
175  boolean setSSID(const char *buf);
176  boolean setIP(const char *buf);
177  boolean setIP(const __FlashStringHelper *buf);
178  boolean setPort(const uint16_t port);
179  boolean setNetmask(const char *buf);
180  boolean setNetmask(const __FlashStringHelper *buf);
181  boolean setGateway(const char *buf);
182  boolean setDNS(const char *buf);
183  boolean setChannel(uint8_t channel);
184  boolean setKey(const char *buf);
185  boolean setPassphrase(const char *buf);
186  boolean setSpaceReplace(char ch);
187  boolean setDHCP(const uint8_t mode);
188  boolean setRate(uint32_t rate);
189  boolean setTxPower(uint8_t dBm);
190 
191  boolean setHostIP(const char *buf);
192  boolean setHostIP(const __FlashStringHelper *buf);
193  boolean setHostPort(const uint16_t port);
194  boolean setHost(const char *buf, uint16_t port);
195 
196  boolean setProtocol(const uint8_t protocol);
197  boolean setIpProtocol(const uint8_t protocol); /* obsolete */
198  boolean setIpFlags(const uint8_t flags);
199  boolean setUartMode(const uint8_t mode);
200 
201  boolean setBroadcastInterval(const uint8_t seconds);
202 
203  boolean setTimeAddress(const char *buf);
204  boolean setTimePort(const uint16_t port);
205  boolean setTimezone(const uint8_t zone);
206  boolean setTimeEnable(const uint16_t enable);
207 
208  boolean setAdhocBeacon(const uint16_t msecs);
209  boolean setAdhocProbe(const uint16_t secs);
210  uint16_t getAdhocBeacon();
211  uint16_t getAdhocProbe();
212  uint16_t getAdhocReboot();
213 
214  boolean setFlushTimeout(const uint16_t timeout);
215  boolean setFlushChar(const char flushChar);
216  boolean setFlushSize(uint16_t size);
217  boolean enableDataTrigger(const uint16_t flushtime=10, const char flushChar=0, const uint16_t flushSize=64);
218  boolean disableDataTrigger();
219  boolean enableUdpAutoPair();
220  boolean disableUdpAutoPair();
221 
222  boolean setIOFunc(const uint8_t func);
223 
224  char *getTime(char *buf, int size);
225  uint32_t getUptime();
226  uint8_t getTimezone();
227  uint32_t getRTC();
228 
229  bool getHostByName(const char *hostname, char *buf, int size);
230  boolean ping(const char *host);
231 
232  boolean enableDHCP();
233  boolean disableDHCP();
234 
235  boolean createAdhocNetwork(const char *ssid, uint8_t channel);
236  boolean join(const char *ssid, uint16_t timeout=20000);
237  boolean join(uint16_t timeout=20000);
238  boolean join(const char *ssid, const char *password, bool dhcp=true, uint8_t mode=WIFLY_MODE_WPA, uint16_t timeout=20000);
239  boolean leave();
240  boolean isAssociated();
241 
242  boolean save();
243  boolean reboot();
244  boolean factoryRestore();
245 
246  boolean sendto(const uint8_t *data, uint16_t size, const char *host, uint16_t port);
247  boolean sendto(const uint8_t *data, uint16_t size, IPAddress host, uint16_t port);
248  boolean sendto(const char *data, const char *host, uint16_t port);
249  boolean sendto(const char *data, IPAddress host, uint16_t port);
250  boolean sendto(const __FlashStringHelper *data, const char *host, uint16_t port);
251  boolean sendto(const __FlashStringHelper *data, IPAddress host, uint16_t port);
252 
253  void enableHostRestore();
254  void disableHostRestore();
255 
256  boolean open(const char *addr, int port=80, boolean block=true);
257  boolean open(IPAddress addr, int port=80, boolean block=true);
258  boolean close();
259  boolean openComplete();
260  boolean isConnected();
261  boolean isInCommandMode();
262 
263  virtual size_t write(uint8_t byte);
264  virtual int read();
265  virtual int available();
266  virtual void flush();
267  virtual int peek();
268 
269  char *iptoa(IPAddress addr, char *buf, int size);
270  IPAddress atoip(char *buf);
271  boolean isDotQuad(const char *addr);
272 
273  void sendChunk(const char *str);
274  void sendChunk(const __FlashStringHelper *str);
275  void sendChunkln(const char *str);
276  void sendChunkln(const __FlashStringHelper *str);
277  void sendChunkln(void);
278 
279  int getFreeMemory();
280  void terminal();
281 
282  using Print::write;
283 
284  void dbgBegin(int size=256);
285  void dbgDump();
286  void dbgEnd();
287  boolean debugOn;
288 
289  boolean match(const char *str, uint16_t timeout=WIFLY_DEFAULT_TIMEOUT);
290  boolean match(const __FlashStringHelper *str, uint16_t timeout=WIFLY_DEFAULT_TIMEOUT);
291  int multiMatch_P(uint16_t timeout, uint8_t count, ...);
292  int gets(char *buf, int size, uint16_t timeout=WIFLY_DEFAULT_TIMEOUT);
293  int getsTerm(char *buf, int size, char term, uint16_t timeout=WIFLY_DEFAULT_TIMEOUT);
294  void flushRx(int timeout=WIFLY_DEFAULT_TIMEOUT);
295 
296  boolean setFtpDefaults(void);
297  boolean setFtpAddress(const char *addr);
298  boolean setFtpPort(uint16_t port);
299  boolean setFtpDirectory(const char *dir);
300  boolean setFtpUser(const char *user);
301  boolean setFtpPassword(const char *password);
302  boolean setFtpFilename(const char *filename);
303  boolean setFtpTimer(uint16_t msecs);
304  boolean setFtpMode(uint8_t mode);
305 
306  boolean ftpGet(
307  const char *addr,
308  const char *dir,
309  const char *user,
310  const char *password,
311  const char *filename);
312 
313  private:
314  void init(void);
315 
316  void dump(const char *str);
317 
318  boolean sendto(
319  const uint8_t *data,
320  uint16_t size,
321  const __FlashStringHelper *flashData,
322  const char *host,
323  uint16_t port);
324 
325  boolean match_P(const prog_char *str, uint16_t timeout=WIFLY_DEFAULT_TIMEOUT);
326  int8_t multiMatch_P(const prog_char *str[], uint8_t count, uint16_t timeout=WIFLY_DEFAULT_TIMEOUT);
327 
328  void send_P(const prog_char *str);
329  void send(const char *str);
330  void send(const char ch);
331  boolean enterCommandMode();
332  boolean exitCommandMode();
333  boolean setPrompt();
334  boolean getPrompt(uint16_t timeout=WIFLY_DEFAULT_TIMEOUT);
335  boolean checkPrompt(const char *str);
336  int getResponse(char *buf, int size, uint16_t timeout=WIFLY_DEFAULT_TIMEOUT);
337  boolean readTimeout(char *ch, uint16_t timeout=WIFLY_DEFAULT_TIMEOUT);
338  boolean startCommand();
339  boolean finishCommand();
340  char *getopt(int opt, char *buf, int size);
341  uint32_t getopt(int opt, uint8_t base=DEC);
342  boolean setopt(const prog_char *cmd, const char *buf=NULL, const __FlashStringHelper *buf_P=NULL, bool spacesub=false);
343  boolean setopt(const prog_char *opt, const uint32_t value, uint8_t base=DEC);
344  boolean getres(char *buf, int size);
345 
346  boolean checkStream(const prog_char *str, boolean peeked);
347  boolean checkClose(boolean peeked);
348  boolean checkOpen(boolean peeked);
349 
350  boolean hide();
351 
352  boolean inCommandMode;
353  int exitCommand;
354  boolean dhcp;
355  bool restoreHost;
356  bool restoreHostStored;
357  char lastHost[32];
358  uint16_t lastPort;
359 
360  boolean tcpMode;
361  boolean udpAutoPair;
362 
363  boolean connected;
364  boolean connecting;
365  struct {
366  uint8_t tcp;
367  uint8_t assoc;
368  uint8_t authen;
369  uint8_t dnsServer;
370  uint8_t dnsFound;
371  uint8_t channel;
372  } status;
373 
374  Stream *serial; /* Serial interface to WiFly */
375 
376  WFDebug debug; /* Internal debug channel. */
377 
378  char replaceChar; /* The space replacement character */
379 
380  /* for dbgDump() */
381  char *dbgBuf;
382  int dbgInd;
383  int dbgMax;
384 };
385 
386 #endif