David Smart / WiflyInterface Featured

Dependents:   Smart-WiFly-WebServer PUB_WiflyInterface_Demo

Fork of WiflyInterface by mbed official

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Wifly.h Source File

Wifly.h

00001 /* Copyright (C) 2012 mbed.org, MIT License
00002  *
00003  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
00004  * and associated documentation files (the "Software"), to deal in the Software without restriction,
00005  * including without limitation the rights to use, copy, modify, merge, publish, distribute,
00006  * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
00007  * furnished to do so, subject to the following conditions:
00008  *
00009  * The above copyright notice and this permission notice shall be included in all copies or
00010  * substantial portions of the Software.
00011  *
00012  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
00013  * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00014  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
00015  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00016  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00017  *
00018  * @section DESCRIPTION
00019  *
00020  * Wifly RN131-C, wifi module
00021  *
00022  * Datasheet:
00023  * http://dlnmh9ip6v2uc.cloudfront.net/datasheets/Wireless/WiFi/WiFly-RN-UM.pdf
00024  *
00025  * Changes relative to mbed official version and others as identified
00026  * in the thread http://mbed.org/forum/team-165-components-community/topic/4844/?page=1#comment-24108
00027  * Wifly:
00028  * @li increase default timeout to 2500 msec
00029  * @li add additional security options
00030  * @li add ability to set security after constructor 
00031  * @li improve commands on the APIs
00032  * @li add baud() api
00033  * @li add setConnectionState() api
00034  * @li add getWiflyVersionString() api
00035  * @li add getWiflyVersion() api
00036  * @li add SWUpdateWifly() api
00037  * @li update for RawSerial instead of Serial
00038  * @li revise #define DEBUG interface
00039  * @li reduced some of the C++ string processing for reduced memory
00040  * @li changed size of auto-send from 1024 to 1420
00041  * @li add ability to disable remote (telnet) config
00042  * @li add retry to to the sendCommnand() api
00043  * @li correct is_connected() api to return true if associated
00044  * @li revise reset to gather Wifly version number and version string
00045  * @li reduce compiler warnings
00046  * @li derived from 4:0bcec6272784
00047  */
00048 
00049 #ifndef WIFLY_H
00050 #define WIFLY_H
00051 
00052 #include "mbed.h"
00053 #include "RawSerial.h"
00054 #include "CBuffer.h"
00055 
00056 #define DEFAULT_WAIT_RESP_TIMEOUT 5000
00057 
00058 enum Security {     // See Wifly user manual Table 2-13.
00059     NONE        = 0,
00060     WEP_128     = 1,
00061     WPA1        = 2,
00062     WPA_MIXED   = 3,
00063     WPA         = 3,  // maintained for backward compatibility
00064     WPA2_PSK    = 4,
00065     ADHOC       = 6,
00066     WPE_64      = 8,
00067     WEP_64      = 8   // probably what the last one should have been
00068 };
00069 
00070 enum Protocol {
00071     UDP = (1 << 0),
00072     TCP = (1 << 1)
00073 };
00074 
00075 /** the Wifly object
00076 *
00077 * This object controls the Wifly module.
00078 */
00079 class Wifly
00080 {
00081 
00082 public:
00083     /**
00084     * Constructor
00085     *
00086     * @param tx mbed pin to use for tx line of Serial interface
00087     * @param rx mbed pin to use for rx line of Serial interface
00088     * @param reset reset pin of the wifi module ()
00089     * @param tcp_status connection status pin of the wifi module (GPIO 6)
00090     * @param ssid ssid of the network
00091     * @param phrase WEP or WPA key
00092     * @param sec Security type (NONE, WEP_128, WPA1, WPA | WPA_MIXED, WPA2_PSK, WEP_64 )
00093     */
00094     Wifly(PinName tx, PinName rx, PinName reset, PinName tcp_status, const char * ssid, const char * phrase, Security sec);
00095 
00096     /**
00097     * Destructor to clean up
00098     */
00099     ~Wifly();
00100     
00101     /** Optional means to set/reset the security
00102     *
00103     * If join() has not been called, then you can revise the security parameters
00104     * from those in the constructor.
00105     *
00106     * @param ssid ssid of the network
00107     * @param phrase WEP or WPA key
00108     * @param sec Security type (NONE, WEP_128, WPA1, WPA | WPA_MIXED, WPA2_PSK, WEP_64 )
00109     */
00110     void SetSecurity(const char * ssid, const char * phrase, Security sec);
00111 
00112     /**
00113     * Configure the wifi module with the parameters contained in the constructor.
00114     *
00115     * @return true if successful, false otherwise.
00116     */
00117     bool configure();
00118 
00119     /**
00120     * Connect the wifi module to the ssid contained in the constructor.
00121     *
00122     * @return true if connected, false otherwise
00123     */
00124     bool join();
00125 
00126     /**
00127     * Disconnect the wifly module from the access point
00128     *
00129     * @return true if successful
00130     */
00131     bool disconnect();
00132 
00133     /**
00134     * Open a tcp connection with the specified host on the specified port
00135     *
00136     * @param host host (can be either an ip address or a name. If a name is provided, a dns request will be established)
00137     * @param port port
00138     * @return true if successful
00139     */
00140     bool connect(const char * host, int port);
00141 
00142 
00143     /**
00144     * Set the protocol (UDP or TCP)
00145     *
00146     * @param p protocol
00147     * @return true if successful
00148     */
00149     bool setProtocol(Protocol p);
00150 
00151     /**
00152     * Reset the wifi module
00153     */
00154     void reset();
00155     
00156     /**
00157     * Reboot the wifi module
00158     *
00159     * @return true if it could send the command, false otherwise
00160     */
00161     bool reboot();
00162 
00163     /**
00164     * Check if characters are available
00165     *
00166     * @return number of available characters
00167     */
00168     int readable();
00169 
00170     /**
00171     * Check if characters are available
00172     *
00173     * @return number of available characters
00174     */
00175     int writeable();
00176 
00177     /**
00178     * Check if associated with an access point (was checking if tcp link is active)
00179     *
00180     * Follow this example to improve the automatic recovery
00181     * after a lost association.
00182     *
00183     * @code
00184     * WiflyInterface eth(p28, p27, p23, p24, "ssid", "pass", WPA);
00185     * 
00186     * if (0 == eth.init()) {
00187     *     eth.baud(230400);     // speed up the interface
00188     *     do {
00189     *         if (0 == eth.connect()) {
00190     *             linkup = true;    // led indicator
00191     *             while (eth.is_connected()) {
00192     *                 wait_ms(1000);
00193     *             }
00194     *             linkup = false;   // led indicator
00195     *             eth.disconnect();
00196     *             wait_ms(1000);
00197     *         }
00198     *     } while (1);
00199     * } else {
00200     *     wait(5);    // ... failed to initialize, rebooting...
00201     *     mbed_reset();
00202     * }
00203     * @endcode
00204     *
00205     * @return true if successful
00206     */
00207     bool is_connected();
00208 
00209     /**
00210     * Read a character
00211     *
00212     * @return the character read
00213     */
00214     char getc();
00215 
00216     /**
00217     * Flush the buffer
00218     */
00219     void flush();
00220 
00221     /**
00222     * Write a character
00223     *
00224     * @param the character which will be written
00225     * @return the character written
00226     */
00227     int putc(char c);
00228 
00229 
00230     /**
00231     * To enter in command mode (we can configure the module)
00232     *
00233     * @return true if successful, false otherwise
00234     */
00235     bool cmdMode();
00236 
00237     /**
00238     * To exit the command mode
00239     *
00240     * @return true if successful, false otherwise
00241     */
00242     bool exit();
00243 
00244     /**
00245     * Close a tcp connection, and exit command mode.
00246     *
00247     * @return true if successful
00248     */
00249     bool close();
00250 
00251     /**
00252     * Send a string to the wifi module by serial port. This function desactivates 
00253     * the user interrupt handler when a character is received to analyze the response 
00254     * from the wifi module.
00255     *
00256     * Useful to send a command to the module and wait a response.
00257     *
00258     * @param str string to be sent
00259     * @param len string length
00260     * @param ACK string which must be acknowledge by the wifi module. 
00261     *           If ACK == NULL, no string has to be acknowledged. (default: NULL)
00262     * @param res this field will contain the response from the wifi module, 
00263     *           result of a command sent. This field is available only 
00264     *           if ACK == NULL AND res != NULL (default: NULL)
00265     * @param timeout is the time in msec to wait for the acknowledge
00266     *
00267     * @return true if ACK has been found in the response from the wifi module. 
00268     * @return false if there is not a correct response in the timeout.
00269     */
00270     int send(const char * str, int len, const char * ACK = NULL, char * res = NULL, int timeout = DEFAULT_WAIT_RESP_TIMEOUT);
00271 
00272     /**
00273     * Put the device in command mode.
00274     *
00275     * @param str string to be sent
00276     * @param ACK string which must be acknowledge by the wifi module. If ACK == NULL, no string has to be acknoledged. (default: "NO")
00277     * @param res this field will contain the response from the wifi module, result of a command sent. This field is available only if ACK = "NO" AND res != NULL (default: NULL)
00278     * @param timeout is the time in msec to wait for the acknowledge
00279     *
00280     * @return true if successful, false if it failed.
00281     */
00282     bool sendCommand(const char * cmd, const char * ack = NULL, char * res = NULL, int timeout = DEFAULT_WAIT_RESP_TIMEOUT);
00283     
00284     /**
00285     * Return true if the module is using dhcp
00286     *
00287     * @return true if the module is using dhcp
00288     */
00289     bool isDHCP() {
00290         return state.dhcp;
00291     }
00292 
00293     /**
00294     * gets the host ip address
00295     *
00296     * @param host is a pointer to the host string to look up
00297     * @param ip contains the host IP in a string after the lookup.
00298     * @param sizeof_ip is the size of the buffer pointed to by ip
00299     * @return true if successful
00300     */
00301     bool gethostbyname(const char * host, char * ip);
00302 
00303     /**
00304     * Set the baud rate between the ARM and the WiFly.
00305     *
00306     * This will set the WiFly module baud rate first and then
00307     * set the ARM interface to match it. If it cannot get the proper 
00308     * acknowledge response, it will go on a hunt through the range 
00309     * of standard baud rates.
00310     *
00311     * @note Baud rate must be one of 2400, 4800, 9600, 19200, 38400, 57600,
00312     *       115200, 230400, 460800, or 921600. (See Wifly manual 2.3.64)
00313     * @note Baud rate of 230400 has been seen to be marginal w/o flow control.
00314     * @note Setting a baud rate to a 460800 or above may be unrecoverable
00315     *       without resetting the Wifly module.
00316     *
00317     * @param baudrate is the desired baudrate.
00318     *
00319     * @return true if it succeeded, which means that communications can continue, 
00320     * @return false if it failed to establish a communication link.
00321     */
00322     bool baud(int baudrate);
00323 
00324 
00325     /**
00326     * Sets the connection state. 
00327     *
00328     * Typically used by external apps that detect an incoming connection.
00329     *
00330     * @param state sets the connection state to true or false
00331     */
00332     void setConnectionState(bool state);
00333 
00334 
00335     /**
00336     * Get the version information from the Wifly module.
00337     *
00338     * @return the version information as a string, or NULL
00339     */
00340     char * getWiflyVersionString();
00341     
00342     
00343     /**
00344     * Get the software version from the Wifly module.
00345     *
00346     * This extracts the basic version number (e.g. 2.38, 4.00)
00347     * as a float.
00348     *
00349     * @return the software version number as a float.
00350     */
00351     float getWiflyVersion();
00352 
00353     /**
00354     * Update the software in the Wifly module.
00355     *
00356     * This attempts to connect to the microchip site, download
00357     * a software update, install it as the primary image, and 
00358     * reboot to activate that image. It is compile-time defined
00359     * to try for 30 seconds.
00360     *
00361     * @param file is the name of the file to fetch, to update to.
00362     *        The strlen(file) cannot exceed 60, and is typically
00363     *        like this: "Wifly7-475.mif"
00364     * @return true if success or false for failure.
00365     */
00366     bool SWUpdateWifly(const char * file);
00367     
00368     /**
00369     * determine if the module is in command mode
00370     *
00371     * @return true if in command mode, false otherwise
00372     */
00373     bool isCmdMode() {
00374         return state.cmd_mode;
00375     }
00376 
00377     static Wifly * getInstance() {
00378         return inst;
00379     };
00380 
00381 protected:
00382     RawSerial wifi;
00383     DigitalOut reset_pin;
00384     DigitalIn tcp_status;
00385     int baudrate;
00386     char phrase[65];
00387     char ssid[33];
00388     char * wiflyVersionString;
00389     float swVersion;
00390     const char * ip;
00391     const char * netmask;
00392     const char * gateway;
00393     CircBuffer<char> buf_wifly;
00394 
00395     static Wifly * inst;
00396 
00397     void attach_rx(bool null);
00398     void handler_rx(void);
00399     void flushIn(int timeout_ms = -1);
00400     uint16_t hextoi(char * p);
00401 
00402     typedef struct STATE {
00403         bool associated;
00404         bool tcp;
00405         bool dhcp;
00406         Security sec;
00407         Protocol proto;
00408         bool cmd_mode;
00409     } State;
00410 
00411     State state;
00412     char * getStringSecurity();
00413     
00414     /**
00415     * Allocate space for the parameter (ssid or passphrase)
00416     * and then fix it (change ' ' to '$').
00417     *
00418     * @param dst is a reference to the private member pointer.
00419     * @param dstLen is the size of the destination buffer
00420     * @param src is a pointer to a passed in string.
00421     * @returns true if the src phrase was placed in the dst buffer.
00422     */
00423     bool FixPhrase(char * dst, size_t dstLen, const char * src);
00424 
00425     /**
00426     * Gather the Wifly module version information for later queries
00427     */
00428     void GatherLogonInfo();
00429 
00430 };
00431 
00432 #endif