WifiHQ
WiFlyHQ.h
00001 /*-
00002  * Copyright (c) 2012 Darran Hunt (darran [at] hunt dot net dot nz)
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  *
00014  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
00015  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
00016  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
00017  * THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00018  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00019  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
00020  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
00021  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
00022  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
00023  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00024  */
00025 
00026 /* Release history
00027  *
00028  * Version  Date         Description
00029  * 0.1      25-Mar-2012  First release.
00030  * 0.2      09-Apr-2012  Added features to support http servers.
00031  *                       - added an httpserver.ino example.
00032  *                       - added sendChunk() and sendChunkln() to send chunked HTTP bodies.
00033  *                       - added terminal() method for simple terminal access via debug stream
00034  *                       - replaced getFreeMemory() with simpler version that works with 0 bytes
00035  *                       - turned peek buffer into a circular buffer to fix bug with detecting
00036  *                         *CLOS* and *OPEN* after a partial match.
00037  *                       - Added new TCP connection detection via *OPEN* match from available().
00038  *                         isConnected() can now be polled until a client connects.
00039  *                       - made the match() function public, handy for matching text in a stream.
00040  *                       - Added a getProtocol() function to get current set of protocols.
00041  * 0.3      21-Apr-2012  Added createAdhocNetwork() to create an Ad Hoc WiFi network.
00042  *                       Optimised the setopt() and getopt() function so they handle
00043  *                       integer conversions and refactored all of the set and get functions.
00044  *                       Added a multMatch_P() function to match serial data against multiple
00045  *                       progmem strings.
00046  *                       Added failure detection to the join() function to quickly detect
00047  *                       a failure rather than relying on a timeout.
00048  *                       Added setJoin() and getJoin() function for access to the wlan join parameter.
00049  *                       Refactored getres() to use the new multiMatch_P() function.
00050  *
00051  */
00052 
00053 #ifndef _WIFLYHQ_H_
00054 #define _WIFLYHQ_H_
00055 
00056 #include <Arduino.h>
00057 #include <Stream.h>
00058 #include <avr/pgmspace.h>
00059 #include <IPAddress.h>
00060 
00061 /* IP Protocol bits */
00062 #define WIFLY_PROTOCOL_UDP              0x01
00063 #define WIFLY_PROTOCOL_TCP              0x02
00064 #define WIFLY_PROTOCOL_SECURE           0x04
00065 #define WIFLY_PROTOCOL_TCP_CLIENT       0x08
00066 #define WIFLY_PROTOCOL_HTTP             0x10    /* HTTP Client mode */
00067 #define WIFLY_PROTOCOL_RAW              0x20
00068 #define WIFLY_PROTOCOL_SMTP             0x40
00069 
00070 /* IP Flag bits */
00071 #define WIFLY_FLAG_TCP_KEEP             0x01    /* Keep TCP connection alive when wifi lost */
00072 #define WIFLY_FLAG_TCP_NODELAY          0x02
00073 #define WIFLY_FLAG_TCP_RETRY            0x04
00074 #define WIFLY_FLAG_UDP_RETRY            0x08
00075 #define WIFLY_FLAG_DNS_CACHING          0x10
00076 #define WIFLY_FLAG_ARP_CACHING          0x20
00077 #define WIFLY_FLAG_UDP_AUTO_PAIR        0x40
00078 #define WIFLY_FLAG_ADD_TIMESTAMP        0x80
00079 
00080 /* UART mode bits */
00081 #define WIFLY_UART_MODE_NOECHO          0x01
00082 #define WIFLY_UART_MODE_DATA_TRIGGER    0x02
00083 #define WIFLY_UART_MODE_SLEEP_RX_BREAK  0x08
00084 #define WIFLY_UART_MODE_RX_BUFFER       0x10
00085 
00086 /* DHCP modes */
00087 #define WIFLY_DHCP_MODE_OFF             0x00    /* No DHCP, static IP mode */
00088 #define WIFLY_DHCP_MODE_ON              0x01    /* get IP, Gateway, and DNS from AP */
00089 #define WIFLY_DHCP_MODE_AUTOIP          0x02    /* Used with Adhoc networks */
00090 #define WIFLY_DHCP_MODE_CACHE           0x03    /* Use previous DHCP address based on lease */
00091 #define WIFLY_DHCP_MODE_SERVER          0x04    /* Server DHCP IP addresses? */
00092 
00093 /* WLAN Join modes */
00094 #define WIFLY_WLAN_JOIN_MANUAL          0x00    /* Don't auto-join a network */
00095 #define WIFLY_WLAN_JOIN_AUTO            0x01    /* Auto-join network set in SSID, passkey, and channel. */
00096 #define WIFLY_WLAN_JOIN_ANY             0x02    /* Ignore SSID and join strongest network using passkey. */
00097 #define WIFLY_WLAN_JOIN_ADHOC           0x04    /* Create an Adhoc network using SSID, Channel, IP and NetMask */
00098 
00099 #define WIFLY_DEFAULT_TIMEOUT           500     /* 500 milliseconds */
00100 
00101 class WFDebug : public Stream {
00102 public:
00103     WFDebug();
00104     void begin(Stream *debugPrint);
00105 
00106     virtual size_t write(uint8_t byte);
00107     virtual int read() { return debug->read(); }
00108     virtual int available() { return debug->available(); }
00109     virtual void flush() { return debug->flush(); }
00110     virtual int peek() { return debug->peek(); }
00111 
00112     using Print::write;
00113 private:
00114     Stream *debug;
00115 };
00116 
00117 class WiFly : public Stream {
00118 public:
00119     WiFly();
00120     
00121     boolean begin(Stream *serialdev, Stream *debugPrint = NULL);
00122     
00123     char *getSSID(char *buf, int size);
00124     uint8_t getJoin();
00125     char *getDeviceID(char *buf, int size);    
00126     char *getIP(char *buf, int size);
00127     uint16_t getPort();
00128     char *getNetmask(char *buf, int size);
00129     char *getGateway(char *buf, int size);
00130     char *getDNS(char *buf, int size);
00131     char *getMAC(char *buf, int size);
00132     int8_t getDHCPMode();
00133 
00134     uint16_t getConnection();
00135     int8_t getRSSI();
00136 
00137     bool setJoin(uint8_t join);
00138     boolean setDeviceID(const char *buf);
00139     boolean setBaud(uint32_t baud);
00140     uint32_t getBaud();
00141     uint8_t getUartMode();
00142     uint8_t getIpFlags();
00143     uint8_t getProtocol();
00144 
00145     uint8_t getFlushChar();
00146     uint16_t getFlushSize();
00147     uint16_t getFlushTimeout();
00148 
00149     char *getHostIP(char *buf, int size);
00150     uint16_t getHostPort();
00151 
00152     boolean setSSID(const char *buf);
00153     boolean setIP(const char *buf);
00154     boolean setIP(const __FlashStringHelper *buf);
00155     boolean setPort(const uint16_t port);
00156     boolean setNetmask(const char *buf);
00157     boolean setNetmask(const __FlashStringHelper *buf);
00158     boolean setGateway(const char *buf);
00159     boolean setDNS(const char *buf);
00160     boolean setChannel(uint8_t channel);
00161     boolean setKey(const char *buf);
00162     boolean setPassphrase(const char *buf);
00163     boolean setSpaceReplace(const char *buf);
00164     boolean setDHCP(const uint8_t mode);
00165 
00166     boolean setHostIP(const char *buf);
00167     boolean setHostIP(const __FlashStringHelper *buf);
00168     boolean setHostPort(const uint16_t port);
00169     boolean setHost(const char *buf, uint16_t port);
00170 
00171     boolean setProtocol(const uint8_t protocol);
00172     boolean setIpProtocol(const uint8_t protocol);      /* obsolete */
00173     boolean setIpFlags(const uint8_t flags);
00174     boolean setUartMode(const uint8_t mode);
00175 
00176     boolean setBroadcastInterval(const uint8_t seconds);
00177 
00178     boolean setTimeAddress(const char *buf);
00179     boolean setTimePort(const uint16_t port);
00180     boolean setTimezone(const uint8_t zone);
00181     boolean setTimeEnable(const uint16_t enable);
00182 
00183     boolean setAdhocBeacon(const uint16_t msecs);
00184     boolean setAdhocProbe(const uint16_t secs);
00185     uint16_t getAdhocBeacon();
00186     uint16_t getAdhocProbe();
00187     uint16_t getAdhocReboot();
00188 
00189     boolean setFlushTimeout(const uint16_t timeout);
00190     boolean setFlushChar(const char flushChar);
00191     boolean setFlushSize(uint16_t size);
00192     boolean enableDataTrigger(const uint16_t flushtime=10, const char flushChar=0, const uint16_t flushSize=64);
00193     boolean disableDataTrigger();
00194     boolean enableUdpAutoPair();
00195     boolean disableUdpAutoPair();
00196 
00197     boolean setIOFunc(const uint8_t func);
00198 
00199     char *getTime(char *buf, int size);
00200     uint32_t getUptime();
00201     uint8_t getTimezone();
00202     uint32_t getRTC();
00203 
00204     bool getHostByName(const char *hostname, char *buf, int size);
00205     boolean ping(const char *host);
00206 
00207     boolean enableDHCP();
00208     boolean disableDHCP();
00209     
00210     boolean createAdhocNetwork(const char *ssid, uint8_t channel);
00211     boolean join(const char *ssid, uint16_t timeout=20000);
00212     boolean join(uint16_t timeout=20000);
00213     boolean leave();
00214     boolean isAssociated();
00215 
00216     boolean save();
00217     boolean reboot();
00218     boolean factoryRestore();
00219 
00220     boolean sendto(const uint8_t *data, uint16_t size, const char *host, uint16_t port);
00221     boolean sendto(const uint8_t *data, uint16_t size, IPAddress host, uint16_t port);
00222     boolean sendto(const char *data, const char *host, uint16_t port);
00223     boolean sendto(const char *data, IPAddress host, uint16_t port);
00224     boolean sendto(const __FlashStringHelper *data, const char *host, uint16_t port);
00225     boolean sendto(const __FlashStringHelper *data, IPAddress host, uint16_t port);
00226 
00227     void enableHostRestore();
00228     void disableHostRestore();
00229 
00230     boolean open(const char *addr, int port=80, boolean block=true);
00231     boolean open(IPAddress addr, int port=80, boolean block=true);
00232     boolean close();
00233     boolean openComplete();
00234     boolean isConnected();
00235     boolean isInCommandMode();
00236     
00237     virtual size_t write(uint8_t byte);
00238     virtual int read();
00239     virtual int available();
00240     virtual void flush();
00241     virtual int peek();
00242 
00243     char *iptoa(IPAddress addr, char *buf, int size);
00244     IPAddress atoip(char *buf);
00245     boolean isDotQuad(const char *addr);
00246 
00247     void sendChunk(const char *str);
00248     void sendChunk(const __FlashStringHelper *str);
00249     void sendChunkln(const char *str);
00250     void sendChunkln(const __FlashStringHelper *str);
00251     void sendChunkln(void);
00252 
00253     int getFreeMemory();
00254     void terminal();
00255   
00256     using Print::write;
00257 
00258     void dbgBegin(int size=256);
00259     void dbgDump();
00260     void dbgEnd();
00261     boolean debugOn;
00262 
00263     boolean match(const char *str, uint16_t timeout=WIFLY_DEFAULT_TIMEOUT);
00264     boolean match(const __FlashStringHelper *str, uint16_t timeout=WIFLY_DEFAULT_TIMEOUT);
00265     int multiMatch_P(uint16_t timeout, uint8_t count, ...);
00266     int gets(char *buf, int size, uint16_t timeout=WIFLY_DEFAULT_TIMEOUT);
00267     int getsTerm(char *buf, int size, char term, uint16_t timeout=WIFLY_DEFAULT_TIMEOUT);
00268     void flushRx(int timeout=WIFLY_DEFAULT_TIMEOUT);
00269 
00270   private:
00271     void init(void);
00272 
00273     void dump(const char *str);
00274 
00275     boolean sendto(
00276         const uint8_t *data,
00277         uint16_t size,
00278         const __FlashStringHelper *flashData,
00279         const char *host,
00280         uint16_t port);
00281 
00282     boolean match_P(const prog_char *str, uint16_t timeout=WIFLY_DEFAULT_TIMEOUT);
00283     int8_t multiMatch_P(const prog_char *str[], uint8_t count, uint16_t timeout=WIFLY_DEFAULT_TIMEOUT);
00284 
00285     void send_P(const prog_char *str);
00286     void send(const char *str);
00287     void send(const char ch);
00288     boolean enterCommandMode();
00289     boolean exitCommandMode();
00290     boolean setPrompt();
00291     boolean getPrompt(uint16_t timeout=WIFLY_DEFAULT_TIMEOUT);
00292     boolean checkPrompt(const char *str);
00293     int getResponse(char *buf, int size, uint16_t timeout=WIFLY_DEFAULT_TIMEOUT);
00294     boolean readTimeout(char *ch, uint16_t timeout=WIFLY_DEFAULT_TIMEOUT);
00295     boolean startCommand();
00296     boolean finishCommand();
00297     char *getopt(int opt, char *buf, int size);
00298     uint32_t getopt(int opt, uint8_t base=DEC);
00299     boolean setopt(const prog_char *cmd, const char *buf, const __FlashStringHelper *buf_P=NULL);
00300     boolean setopt(const prog_char *opt, const uint32_t value, uint8_t base=DEC);
00301     boolean getres(char *buf, int size);
00302 
00303     boolean checkStream(const prog_char *str, boolean peeked);
00304     boolean checkClose(boolean peeked);
00305     boolean checkOpen(boolean peeked);
00306 
00307     boolean hide();
00308 
00309     boolean inCommandMode;
00310     int  exitCommand;
00311     boolean dhcp;
00312     bool restoreHost;
00313     bool restoreHostStored;
00314     char lastHost[32];
00315     uint16_t lastPort;
00316 
00317     boolean tcpMode;
00318     boolean udpAutoPair;
00319 
00320     boolean connected;
00321     boolean connecting;
00322     struct {
00323         uint8_t tcp;
00324         uint8_t assoc;
00325         uint8_t authen;
00326         uint8_t dnsServer;
00327         uint8_t dnsFound;
00328         uint8_t channel;
00329     } status;
00330 
00331     Stream *serial;     /* Serial interface to WiFly */
00332     
00333     WFDebug debug;      /* Internal debug channel. */
00334 
00335     /*  for dbgDump() */
00336     char *dbgBuf;
00337     int dbgInd;
00338     int dbgMax;
00339 };
00340 
00341 #endif
 All Classes Functions