Maggie Mei / emw3162-driver-mbed-os-5

Fork of emw3162-driver by Maggie Mei

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers EMW3162.cpp Source File

EMW3162.cpp

00001 /* EMW3162 Example
00002  * Copyright (c) 2015 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #include "EMW3162.h"
00018 
00019 EMW3162::EMW3162(PinName tx, PinName rx, bool debug)
00020     : _serial(tx, rx, 1024), _parser(_serial)
00021     , _packets(0), _packets_end(&_packets)
00022 {
00023     _serial.baud(115200);
00024     _parser.debugOn(debug);
00025 }
00026 
00027 bool EMW3162::startup(void)
00028 {
00029     bool success = reset("FACTORY");
00030 
00031     _parser.oob("+EVENT=SOCKET", this, &EMW3162::_packet_handler);
00032 
00033     return success;
00034 }
00035 
00036 bool EMW3162::reset(const char *reset)
00037 {
00038     for (int i = 0; i < 2; i++) {
00039         if (_parser.send("AT+%s", reset)
00040             && _parser.recv("+OK")) {
00041             return true;
00042         }
00043     }
00044 
00045     return false;
00046 }
00047 
00048 bool EMW3162::dhcp(bool enabled)
00049 {
00050     return _parser.send("AT+DHCP=%s", enabled ? "ON":"OFF")
00051         && _parser.recv("+OK");
00052 }
00053 
00054 bool EMW3162::connect(const char *ap, const char *passPhrase)
00055 {
00056     return _parser.send("AT+WSTA=%s,%s", ap, passPhrase)
00057         && _parser.recv("+OK")
00058         && _parser.send("AT+EVENT=ON")
00059         && _parser.recv("+OK")
00060         && _parser.recv("+EVENT=WIFI_LINK,STATION_UP");
00061 }
00062 
00063 bool EMW3162::disconnect(void)
00064 {
00065     
00066     return _parser.send("AT+WLANF=STA,OFF")
00067         && _parser.recv("+OK")
00068         && _parser.recv("+EVENT=WIFI_LINK,STATION_DOWN")
00069         && _parser.send("AT+EVENT=OFF")
00070         && _parser.recv("+OK");
00071 }
00072 
00073 const char *EMW3162::getIPAddress(void)
00074 {
00075     if (!(_parser.send("AT+IPCONFIG")
00076         && _parser.recv("%*[^,],%*[^,],%*[^,],%[^,]%*[^#]#", _ip_buffer))) {
00077         return 0;
00078     }
00079 
00080     return _ip_buffer;
00081 }
00082 
00083 const char *EMW3162::getMACAddress(void)
00084 {
00085     if (!(_parser.send("AT+WMAC")
00086         && _parser.recv("%*[^=]=%[^#]#", _mac_buffer))) {
00087         return 0;
00088     }
00089 
00090     return _mac_buffer;
00091 }
00092 
00093 bool EMW3162::isConnected(void)
00094 {
00095     return getIPAddress() != 0;
00096 }
00097 
00098 int EMW3162::open(const char *type, int id, const char* addr, int port)
00099 {
00100     int state1 = 0, state2 = 0;
00101     state1 = _parser.send("AT+CON1=%s,%d,%d,%s", type, id, port, addr)
00102         && _parser.recv("+OK")
00103         && _parser.send("AT+SAVE")
00104         && _parser.recv("+OK")
00105         && reset("REBOOT")
00106         && _parser.recv("+EVENT=REBOOT");
00107     
00108     wait(3);
00109     char conType[10];       // UDP/TCP connection type: SERVER, CLIENT, BROADCAST, UNICAST
00110     int socketId;           // UDP/TCP socket id
00111     
00112     // Receive wifi connect event
00113     state2 = _parser.recv("+EVENT=WIFI_LINK,STATION_UP")
00114         && _parser.recv("+EVENT=%[^,],CONNECT,%d", conType, &socketId);
00115     
00116     if (state1 && state2)
00117         return socketId;
00118     else
00119         return -1;
00120 }
00121 
00122 bool EMW3162::send(int id, const void *data, uint32_t amount)
00123 {
00124     //May take a second try if device is busy
00125     for (unsigned i = 0; i < 2; i++) {
00126         if (_parser.send("AT+SSEND=%d,%d", id, amount)
00127             && _parser.recv(">")
00128             && _parser.write((char*)data, (int)amount) >= 0
00129             && _parser.recv("+OK")) {
00130             //wait(3);
00131             return true;
00132         }
00133     }
00134 
00135     return false;
00136 }
00137 
00138 void EMW3162::_packet_handler()
00139 {
00140     int id;
00141     uint32_t amount;
00142 
00143     // parse out the packet
00144     if (!_parser.recv(",%d,%d,", &id, &amount)) {
00145         return;
00146     }
00147 
00148     struct packet *packet = (struct packet*)malloc(
00149             sizeof(struct packet) + amount);
00150     if (!packet) {
00151         return;
00152     }
00153 
00154     packet->id = id;
00155     packet->len = amount;
00156     packet->next = 0;
00157 
00158     if (!(_parser.read((char*)(packet + 1), amount))) {
00159         free(packet);
00160         return;
00161     }
00162 
00163     // append to packet list
00164     *_packets_end = packet;
00165     _packets_end = &packet->next;
00166 }
00167 
00168 int32_t EMW3162::recv(int id, void *data, uint32_t amount)
00169 {
00170     while (true) {
00171         // check if any packets are ready for us
00172         for (struct packet **p = &_packets; *p; p = &(*p)->next) {
00173             if ((*p)->id == id) {
00174                 struct packet *q = *p;
00175 
00176                 if (q->len <= amount) { // Return and remove full packet
00177                     memcpy(data, q+1, q->len);
00178 
00179                     if (_packets_end == &(*p)->next) {
00180                         _packets_end = p;
00181                     }
00182                     *p = (*p)->next;
00183 
00184                     uint32_t len = q->len;
00185                     free(q);
00186                     return len;
00187                 } else { // return only partial packet
00188                     memcpy(data, q+1, amount);
00189 
00190                     q->len -= amount;
00191                     memmove(q+1, (uint8_t*)(q+1) + amount, q->len);
00192 
00193                     return amount;
00194                 }
00195             }
00196         }
00197 
00198         // Wait for inbound packet
00199         if (!_parser.recv("#")) {
00200             return -1;
00201         }
00202     }
00203 }
00204 
00205 bool EMW3162::close(int id)
00206 {
00207     //May take a second try if device is busy
00208     for (unsigned i = 0; i < 2; i++) {
00209         if (_parser.send("AT+CONF=1,OFF")
00210             && _parser.recv("+OK")) {
00211             char conType[10];  // Used for UDP/TCP connection type: SERVER, CLIENT, BROADCAST, UNICAST
00212             int socketId;      // Used for UDP/TCP socket id
00213             
00214             _parser.recv("+EVENT=%[^,],DISCONNECT,%d", conType, &socketId);
00215             return true;
00216         }
00217     }
00218 
00219     return false;
00220 }
00221 
00222 void EMW3162::setTimeout(uint32_t timeout_ms)
00223 {
00224     _parser.setTimeout(timeout_ms);
00225 }
00226 
00227 bool EMW3162::readable()
00228 {
00229     return _serial.readable();
00230 }
00231 
00232 bool EMW3162::writeable()
00233 {
00234     return _serial.writeable();
00235 }
00236 
00237 void EMW3162::attach(Callback<void()> func)
00238 {
00239     _serial.attach(func);
00240 }