GSwifiInterface library (interface for GainSpan Wi-Fi GS1011 modules) Please see https://mbed.org/users/gsfan/notebook/GSwifiInterface/

Dependents:   GSwifiInterface_HelloWorld GSwifiInterface_HelloServo GSwifiInterface_UDPEchoServer GSwifiInterface_UDPEchoClient ... more

Fork of WiflyInterface by mbed official

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers GSwifi.cpp Source File

GSwifi.cpp

00001 /* Copyright (C) 2019 gsfan, 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 
00019 #include "mbed.h"
00020 #include "GSwifi.h"
00021 #include <string>
00022 #include <algorithm>
00023 
00024 GSwifi * GSwifi::_inst;
00025 
00026 #ifdef CFG_SPI_DATAINTERFACE
00027 GSwifi::GSwifi(PinName tx, PinName rx, PinName cts, PinName rts, PinName reset,
00028   PinName mosi, PinName miso, PinName sclk, PinName cs, PinName wake,
00029   PinName alarm, int baud, int freq):
00030     _gs(tx, rx), _spi(mosi, miso, sclk), _wake(wake), _reset(reset)
00031 #else
00032 GSwifi::GSwifi(PinName tx, PinName rx, PinName cts, PinName rts, PinName reset, PinName alarm, int baud):
00033     _gs(tx, rx), _reset(reset)
00034 #endif
00035 {
00036     _inst = this;
00037     memset(&_state, 0, sizeof(_state));
00038     memset(&_con, 0, sizeof(_con));
00039     _state.initialized = false;
00040     _state.datainterface = false;
00041     _state.status = STAT_READY;
00042     _state.cid = -1;
00043 #ifdef CFG_EXTENDED_MEMORY1
00044     int n = CFG_EXTENDED_SIZE1 / (CFG_MAX_SOCKETS + 1);
00045     _state.buf = new CircBuffer<char>(n - 1, (void*)CFG_EXTENDED_MEMORY1);
00046 #ifdef CFG_ENABLE_RTOS
00047     for (int i = 0; i < CFG_MAX_SOCKETS; i ++) {
00048         _con[i].buf = new CircBuffer<char>(n - 1, (void*)(CFG_EXTENDED_MEMORY1 + (n * (i + 1))));
00049         if (_con[i].buf == NULL)
00050             error("CircBuffer failed");
00051     }
00052     _threadPoll = NULL;
00053 #endif
00054 #else // CFG_EXTENDED_MEMORY
00055     _state.buf = new CircBuffer<char>(CFG_DATA_SIZE);
00056 #ifdef CFG_ENABLE_RTOS
00057     for (int i = 0; i < CFG_MAX_SOCKETS; i ++) {
00058         _con[i].buf = new CircBuffer<char>(CFG_DATA_SIZE);
00059         if (_con[i].buf == NULL)
00060             error("CircBuffer failed");
00061     }
00062     _threadPoll = NULL;
00063 #endif
00064 #endif // CFG_EXTENDED_MEMORY
00065 
00066     setReset(true);
00067     initUart(cts, rts, alarm, baud);
00068 #ifdef CFG_SPI_DATAINTERFACE
00069     initSpi (cs, freq);
00070 #endif
00071     setAlarm(true);
00072     wait_ms(10);
00073     setAlarm(false);
00074     wait_ms(100);
00075     setReset(false);
00076     wait_ms(100);
00077 }
00078 
00079 int GSwifi::join()
00080 {
00081     int i;
00082     bool r = -1;
00083 
00084     _state.wm = WM_INFRASTRUCTURE;
00085     _state.initialized = true;
00086     if (!strlen(_state.name)) {
00087         strncpy(_state.name, CFG_DHCPNAME, sizeof(_state.name));
00088     }
00089 #ifdef CFG_SPI_DATAINTERFACE
00090 //    if (strstr(
00091 #endif
00092     clearFlags();
00093     _state.buf->flush();
00094     _state.mode = MODE_COMMAND;
00095     sendCommand(NULL, RES_NULL, 0);
00096     if (cmdE(false)) return -1;
00097     if (_flow) {
00098         cmdR(true);
00099     }
00100     cmdBDATA(true);
00101     if (cmdNMAC()) return -1;
00102     cmdWREGDOMAIN(CFG_WREGDOMAIN);
00103     cmdWM(0); // infrastructure
00104     wait_ms(100);
00105 
00106     switch (_state.sec) {
00107     case SEC_NONE:
00108     case SEC_OPEN:
00109     case SEC_WEP:
00110         cmdNDHCP(_state.dhcp, _state.name, DEFAULT_WAIT_RESP_TIMEOUT);
00111         if (! _state.dhcp) {
00112             cmdNSET(_state.ip, _state.netmask, _state.ip);
00113         }
00114         cmdWAUTH(_state.sec);
00115         if (_state.sec != SEC_NONE) {
00116             cmdWWEP(1, _state.pass);
00117             wait_ms(100);
00118         }
00119         for (i = 0; i < CFG_TRYJOIN; i ++) {
00120             r = cmdWA(_state.ssid);
00121             if (!r) break;
00122             DBG("retry\r\n");
00123             wait_ms(1000);
00124         }
00125         break;
00126     case SEC_WPA_PSK:
00127     case SEC_WPA2_PSK:
00128         cmdNDHCP(_state.dhcp, _state.name, DEFAULT_WAIT_RESP_TIMEOUT);
00129         if (! _state.dhcp) {
00130             cmdNSET(_state.ip, _state.netmask, _state.ip);
00131         }
00132         cmdWAUTH(0);
00133         cmdWPAPSK(_state.ssid, _state.pass);
00134         wait_ms(100);
00135         for (i = 0; i < CFG_TRYJOIN; i ++) {
00136             r = cmdWA(_state.ssid);
00137             if (!r) break;
00138             DBG("retry\r\n");
00139             wait_ms(1000);
00140 
00141             if (_state.dhcp && i == CFG_TRYJOIN - 1) {
00142                 cmdNDHCP(0, NULL, DEFAULT_WAIT_RESP_TIMEOUT);
00143                 r = cmdWA(_state.ssid);
00144                 if (!r && _state.dhcp) {
00145                     wait_ms(1000);
00146                     r = cmdNDHCP(_state.dhcp, NULL, CFG_TIMEOUT);
00147                 }
00148                 break;
00149             }
00150         }
00151         break;
00152     case SEC_WPA_ENT:
00153     case SEC_WPA2_ENT:
00154         cmdWAUTH(0);
00155         DBG("Can't support security\r\n");
00156         break;
00157     case SEC_WPS_BUTTON:
00158         cmdNDHCP(false);
00159         if (! _state.dhcp) {
00160             cmdNSET(_state.ip, _state.netmask, _state.ip);
00161         }
00162         cmdWAUTH(0);
00163         r = cmdWWPS(true);
00164         if (r) break;
00165         if (_state.dhcp) {
00166             r = cmdNDHCP(_state.dhcp, _state.name);
00167         }
00168         cmdWSTATUS();
00169         cmdWPAPSK(_state.ssid, _state.pass);
00170         break;
00171     case SEC_WPS_PIN:
00172         cmdNDHCP(false);
00173         if (! _state.dhcp) {
00174             cmdNSET(_state.ip, _state.netmask, _state.ip);
00175         }
00176         cmdWAUTH(0);
00177         r = cmdWWPS(true, _state.pass);
00178         if (r) break;
00179         if (_state.dhcp) {
00180             r = cmdNDHCP(_state.dhcp, _state.name);
00181         }
00182         cmdWSTATUS();
00183         cmdWPAPSK(_state.ssid, _state.pass);
00184         break;
00185     default:
00186         DBG("Can't use security\r\n");
00187         break;
00188     }
00189 
00190     if (!r) {
00191         // connected
00192         if (! _state.dhcp) {
00193             cmdDNSSET(_state.nameserver);
00194         }
00195         _state.associated = true;
00196 #ifdef CFG_ENABLE_RTOS
00197         _threadPoll = new Thread(&threadPoll);
00198 //        _threadPoll = new Thread(&threadPoll, NULL, osPriorityLow);
00199 #endif
00200     }
00201     return r;
00202 }
00203 
00204 int GSwifi::adhock ()
00205 {
00206     bool r = -1;
00207 
00208     _state.wm = WM_ADHOCK;
00209     _state.initialized = true;
00210     clearFlags();
00211     _state.buf->flush();
00212     _state.mode = MODE_COMMAND;
00213     sendCommand(NULL, RES_NULL, 0);
00214     if (cmdE(false)) return -1;
00215     if (_flow) {
00216         cmdR(true);
00217     }
00218     if (cmdNMAC()) return -1;
00219     cmdBDATA(true);
00220     cmdWREGDOMAIN(CFG_WREGDOMAIN);
00221     cmdWM(1); // adhock
00222     wait_ms(100);
00223 
00224     cmdNDHCP(false);
00225     if (! _state.dhcp) {
00226         cmdNSET(_state.ip, _state.netmask, _state.ip);
00227     }
00228 
00229     switch (_state.sec) {
00230     case SEC_NONE:
00231     case SEC_OPEN:
00232     case SEC_WEP:
00233         cmdWAUTH(_state.sec);
00234         if (_state.sec != SEC_NONE) {
00235             cmdWWEP(1, _state.pass);
00236             wait_ms(100);
00237         }
00238         r = cmdWA(_state.ssid);
00239         break;
00240     default:
00241         DBG("Can't use security\r\n");
00242         break;
00243     }
00244 
00245     if (!r) {
00246         // connected
00247         _state.associated = true;
00248     }
00249     return r;
00250 }
00251 
00252 int GSwifi::limitedap ()
00253 {
00254     bool r = -1;
00255 
00256     _state.wm = WM_LIMITEDAP;
00257     _state.initialized = true;
00258     if (!strlen(_state.name)) {
00259         strncpy(_state.name, CFG_DNSNAME, sizeof(_state.name));
00260     }
00261     clearFlags();
00262     _state.buf->flush();
00263     _state.mode = MODE_COMMAND;
00264     sendCommand(NULL, RES_NULL, 0);
00265     if (cmdE(false)) return -1;
00266     if (_flow) {
00267         cmdR(true);
00268     }
00269     if (cmdNMAC()) return -1;
00270     cmdBDATA(true);
00271     cmdWREGDOMAIN(CFG_WREGDOMAIN);
00272     cmdWM(2); // limitedap
00273     wait_ms(100);
00274 
00275     cmdNDHCP(false);
00276     if (! _state.dhcp) {
00277         cmdNSET(_state.ip, _state.netmask, _state.ip);
00278         cmdDNSSET(_state.ip);
00279     }
00280     cmdDHCPSRVR(true);
00281     cmdDNS(true, _state.name);
00282 
00283     switch (_state.sec) {
00284     case SEC_NONE:
00285     case SEC_OPEN:
00286     case SEC_WEP:
00287         cmdWAUTH(_state.sec);
00288         if (_state.sec != SEC_NONE) {
00289             cmdWWEP(1, _state.pass);
00290             wait_ms(100);
00291         }
00292         r = cmdWA(_state.ssid);
00293         break;
00294     default:
00295         DBG("Can't use security\r\n");
00296         break;
00297     }
00298 
00299     if (!r) {
00300         // connected
00301         _state.associated = true;
00302     }
00303     return r;
00304 }
00305 
00306 int GSwifi::dissociate()
00307 {
00308     int i;
00309 
00310     // if already disconnected, return
00311     if (!_state.associated)
00312         return 0;
00313 
00314 #ifdef CFG_ENABLE_RTOS
00315     if (_threadPoll) {
00316         _threadPoll->terminate();
00317         delete _threadPoll;
00318     }
00319 #endif
00320     for (i = 0; i < 16; i ++) {
00321         if (_con[i].buf) {
00322             _con[i].buf->flush();
00323         }
00324     }
00325     cmdNCLOSEALL();
00326     cmdWD();
00327     cmdNDHCP(false);
00328     wait_ms(100);
00329 
00330     _state.associated = false;
00331     return 0;
00332 
00333 }
00334 
00335 bool GSwifi::isAssociated()
00336 {
00337     return _state.associated;
00338 }
00339 
00340 void GSwifi::poll () {
00341 #ifndef CFG_ENABLE_RTOS
00342     static int t = 0;
00343     static Timer timer;
00344 
00345     if (_state.wm == WM_INFRASTRUCTURE && (! isAssociated()) && _state.ssid) {
00346       if (t == 0 || timer.read() > CFG_RECONNECT) {
00347         // Wi-Fi re-associate
00348         if (_state.initialized) {
00349             if (cmdWA(_state.ssid)) {
00350                 timer.reset();
00351                 timer.start();
00352                 t = 1;
00353             } else {
00354                 _state.associated = true;
00355                 timer.stop();
00356                 t = 0;
00357             }
00358         } else {
00359             if (join()) {
00360                 timer.reset();
00361                 timer.start();
00362                 t = 1;
00363             } else {
00364                 timer.stop();
00365                 t = 0;
00366             }
00367         }
00368       }
00369     }
00370 #else
00371     if (_state.wm == WM_INFRASTRUCTURE && (! isAssociated()) && _state.ssid) {
00372         // Wi-Fi re-associate
00373         if (_state.initialized) {
00374             if (!cmdWA(_state.ssid)) {
00375                 _state.associated = true;
00376             }
00377         } else {
00378             join();
00379         }
00380     }
00381 #endif
00382 
00383     for (int i = 0; i < 16; i ++) {
00384         if (isConnected(i) && _con[i].received && _con[i].buf != NULL)
00385           if (_con[i].func != NULL && !_con[i].buf->isEmpty()) {
00386             _con[i].func(i);
00387             if (_con[i].buf->isEmpty()) {
00388                 _con[i].received = false;
00389             }
00390         }
00391     }
00392 
00393 #ifdef CFG_ENABLE_HTTPD
00394     httpdPoll();
00395 #endif
00396 }
00397 
00398 #ifdef CFG_ENABLE_RTOS
00399 void GSwifi::threadPoll (void const *args) {
00400     GSwifi * _wifi = GSwifi::getInstance();
00401     if (_wifi == NULL)
00402         error("Socket constructor error: no wifly instance available!\r\n");
00403 
00404     INFO("threadPoll");
00405     for (;;) {
00406         Thread::signal_wait(1);
00407         Thread::wait(1000);
00408         INFO("disassociated");
00409         while (!_wifi->isAssociated()){
00410             _wifi->poll();
00411             Thread::wait(CFG_RECONNECT * 1000);
00412         }
00413     }
00414 }
00415 #endif
00416 
00417 GSwifi::Status GSwifi::getStatus () {
00418     return _state.status;
00419 }
00420 
00421 int GSwifi::setMacAddress (const char *mac) {
00422     if (cmdNMAC(mac)) return -1;
00423     strncpy(_state.mac, mac, sizeof(_state.mac));
00424     return 0;
00425 }
00426 
00427 int GSwifi::getMacAddress (char *mac) {
00428     if (cmdNMAC()) return -1;
00429     strcpy(mac, _state.mac);
00430     return 0;
00431 }
00432 
00433 int GSwifi::setAddress (const char *name) {
00434     _state.dhcp = true;
00435     strncpy(_state.name, name, sizeof(_state.name));
00436     return 0;
00437 }
00438 
00439 int GSwifi::setAddress (const char *ip, const char *netmask, const char *gateway, const char *dns, const char *name) {
00440     _state.dhcp = false;
00441     strncpy(_state.ip, ip, sizeof(_state.ip));
00442     strncpy(_state.netmask, netmask, sizeof(_state.netmask));
00443     strncpy(_state.gateway, gateway, sizeof(_state.gateway));
00444     if (dns) {
00445         strncpy(_state.nameserver, dns, sizeof(_state.nameserver));
00446     }
00447     if (name) {
00448         strncpy(_state.name, name, sizeof(_state.name));
00449     }
00450     return 0;
00451 }
00452 
00453 int GSwifi::getAddress (char *ip, char *netmask, char *gateway) {
00454     strcpy(ip, _state.ip);
00455     strcpy(netmask, _state.netmask);
00456     strcpy(gateway, _state.gateway);
00457     return 0;
00458 }
00459 
00460 int GSwifi::setSsid (Security sec, const char *ssid, const char *phrase) {
00461     int i;
00462 
00463     _state.sec = sec;
00464 
00465     // change all ' ' in '$' in the ssid and the passphrase
00466     strncpy(_state.ssid, ssid, sizeof(_state.ssid));
00467     for (i = 0; i < strlen(_state.ssid); i++) {
00468         if (_state.ssid[i] == ' ')
00469             _state.ssid[i] = '$';
00470     }
00471 
00472     if (sec == SEC_WEP) {
00473         if (strlen(phrase) == 5 || strlen(phrase) == 13) {
00474             for (i = 0; i < strlen(phrase); i++) {
00475                 _state.pass[i * 2] = '0' + ((phrase[i] >> 4) & 0x0f);
00476                 _state.pass[i * 2 + 1] = '0' + (phrase[i + 1] & 0x0f);
00477             }
00478         } else {
00479             strncpy(_state.pass, phrase, strlen(phrase));
00480         }
00481     } else {
00482         strncpy(_state.pass, phrase, sizeof(_state.pass));
00483     }
00484     for (i = 0; i < strlen(_state.pass); i++) {
00485         if (_state.pass[i] == ' ')
00486             _state.pass[i] = '$';
00487     }
00488     return 0;
00489 }
00490