my customized lib

Committer:
DuyLionTran
Date:
Sun Nov 26 15:08:14 2017 +0000
Revision:
0:8094b249013c
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
DuyLionTran 0:8094b249013c 1 /* ESP8266 Example
DuyLionTran 0:8094b249013c 2 * Copyright (c) 2015 ARM Limited
DuyLionTran 0:8094b249013c 3 *
DuyLionTran 0:8094b249013c 4 * Licensed under the Apache License, Version 2.0 (the "License");
DuyLionTran 0:8094b249013c 5 * you may not use this file except in compliance with the License.
DuyLionTran 0:8094b249013c 6 * You may obtain a copy of the License at
DuyLionTran 0:8094b249013c 7 *
DuyLionTran 0:8094b249013c 8 * http://www.apache.org/licenses/LICENSE-2.0
DuyLionTran 0:8094b249013c 9 *
DuyLionTran 0:8094b249013c 10 * Unless required by applicable law or agreed to in writing, software
DuyLionTran 0:8094b249013c 11 * distributed under the License is distributed on an "AS IS" BASIS,
DuyLionTran 0:8094b249013c 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
DuyLionTran 0:8094b249013c 13 * See the License for the specific language governing permissions and
DuyLionTran 0:8094b249013c 14 * limitations under the License.
DuyLionTran 0:8094b249013c 15 */
DuyLionTran 0:8094b249013c 16
DuyLionTran 0:8094b249013c 17 #include "ESP8266.h"
DuyLionTran 0:8094b249013c 18
DuyLionTran 0:8094b249013c 19 ESP8266::ESP8266(PinName tx, PinName rx, bool debug)
DuyLionTran 0:8094b249013c 20 : _serial(tx, rx, 1024), _parser(_serial)
DuyLionTran 0:8094b249013c 21 , _packets(0), _packets_end(&_packets)
DuyLionTran 0:8094b249013c 22 {
DuyLionTran 0:8094b249013c 23 _serial.baud(115200);
DuyLionTran 0:8094b249013c 24 _parser.debugOn(debug);
DuyLionTran 0:8094b249013c 25 }
DuyLionTran 0:8094b249013c 26
DuyLionTran 0:8094b249013c 27 bool ESP8266::startup(int mode)
DuyLionTran 0:8094b249013c 28 {
DuyLionTran 0:8094b249013c 29 //only 3 valid modes
DuyLionTran 0:8094b249013c 30 if(mode < 1 || mode > 3) {
DuyLionTran 0:8094b249013c 31 return false;
DuyLionTran 0:8094b249013c 32 }
DuyLionTran 0:8094b249013c 33
DuyLionTran 0:8094b249013c 34 bool success = reset()
DuyLionTran 0:8094b249013c 35 && _parser.send("AT+CWMODE=%d", mode)
DuyLionTran 0:8094b249013c 36 && _parser.recv("OK")
DuyLionTran 0:8094b249013c 37 && _parser.send("AT+CIPMUX=1")
DuyLionTran 0:8094b249013c 38 && _parser.recv("OK");
DuyLionTran 0:8094b249013c 39
DuyLionTran 0:8094b249013c 40 _parser.oob("+IPD", this, &ESP8266::_packet_handler);
DuyLionTran 0:8094b249013c 41
DuyLionTran 0:8094b249013c 42 return success;
DuyLionTran 0:8094b249013c 43 }
DuyLionTran 0:8094b249013c 44
DuyLionTran 0:8094b249013c 45 bool ESP8266::reset(void)
DuyLionTran 0:8094b249013c 46 {
DuyLionTran 0:8094b249013c 47 for (int i = 0; i < 2; i++) {
DuyLionTran 0:8094b249013c 48 if (_parser.send("AT+RST")
DuyLionTran 0:8094b249013c 49 && _parser.recv("OK\r\nready")) {
DuyLionTran 0:8094b249013c 50 return true;
DuyLionTran 0:8094b249013c 51 }
DuyLionTran 0:8094b249013c 52 }
DuyLionTran 0:8094b249013c 53
DuyLionTran 0:8094b249013c 54 return false;
DuyLionTran 0:8094b249013c 55 }
DuyLionTran 0:8094b249013c 56
DuyLionTran 0:8094b249013c 57 bool ESP8266::dhcp(bool enabled, int mode)
DuyLionTran 0:8094b249013c 58 {
DuyLionTran 0:8094b249013c 59 //only 3 valid modes
DuyLionTran 0:8094b249013c 60 if(mode < 0 || mode > 2) {
DuyLionTran 0:8094b249013c 61 return false;
DuyLionTran 0:8094b249013c 62 }
DuyLionTran 0:8094b249013c 63
DuyLionTran 0:8094b249013c 64 return _parser.send("AT+CWDHCP=%d,%d", enabled?1:0, mode)
DuyLionTran 0:8094b249013c 65 && _parser.recv("OK");
DuyLionTran 0:8094b249013c 66 }
DuyLionTran 0:8094b249013c 67
DuyLionTran 0:8094b249013c 68 bool ESP8266::connect(const char *ap, const char *passPhrase)
DuyLionTran 0:8094b249013c 69 {
DuyLionTran 0:8094b249013c 70 return _parser.send("AT+CWJAP=\"%s\",\"%s\"", ap, passPhrase)
DuyLionTran 0:8094b249013c 71 && _parser.recv("OK");
DuyLionTran 0:8094b249013c 72 }
DuyLionTran 0:8094b249013c 73
DuyLionTran 0:8094b249013c 74 bool ESP8266::disconnect(void)
DuyLionTran 0:8094b249013c 75 {
DuyLionTran 0:8094b249013c 76 return _parser.send("AT+CWQAP") && _parser.recv("OK");
DuyLionTran 0:8094b249013c 77 }
DuyLionTran 0:8094b249013c 78
DuyLionTran 0:8094b249013c 79 const char *ESP8266::getIPAddress(void)
DuyLionTran 0:8094b249013c 80 {
DuyLionTran 0:8094b249013c 81 if (!(_parser.send("AT+CIFSR")
DuyLionTran 0:8094b249013c 82 && _parser.recv("+CIFSR:STAIP,\"%15[^\"]\"", _ip_buffer)
DuyLionTran 0:8094b249013c 83 && _parser.recv("OK"))) {
DuyLionTran 0:8094b249013c 84 return 0;
DuyLionTran 0:8094b249013c 85 }
DuyLionTran 0:8094b249013c 86
DuyLionTran 0:8094b249013c 87 return _ip_buffer;
DuyLionTran 0:8094b249013c 88 }
DuyLionTran 0:8094b249013c 89
DuyLionTran 0:8094b249013c 90 const char *ESP8266::getMACAddress(void)
DuyLionTran 0:8094b249013c 91 {
DuyLionTran 0:8094b249013c 92 if (!(_parser.send("AT+CIFSR")
DuyLionTran 0:8094b249013c 93 && _parser.recv("+CIFSR:STAMAC,\"%17[^\"]\"", _mac_buffer)
DuyLionTran 0:8094b249013c 94 && _parser.recv("OK"))) {
DuyLionTran 0:8094b249013c 95 return 0;
DuyLionTran 0:8094b249013c 96 }
DuyLionTran 0:8094b249013c 97
DuyLionTran 0:8094b249013c 98 return _mac_buffer;
DuyLionTran 0:8094b249013c 99 }
DuyLionTran 0:8094b249013c 100
DuyLionTran 0:8094b249013c 101 const char *ESP8266::getGateway()
DuyLionTran 0:8094b249013c 102 {
DuyLionTran 0:8094b249013c 103 if (!(_parser.send("AT+CIPSTA?")
DuyLionTran 0:8094b249013c 104 && _parser.recv("+CIPSTA:gateway:\"%15[^\"]\"", _gateway_buffer)
DuyLionTran 0:8094b249013c 105 && _parser.recv("OK"))) {
DuyLionTran 0:8094b249013c 106 return 0;
DuyLionTran 0:8094b249013c 107 }
DuyLionTran 0:8094b249013c 108
DuyLionTran 0:8094b249013c 109 return _gateway_buffer;
DuyLionTran 0:8094b249013c 110 }
DuyLionTran 0:8094b249013c 111
DuyLionTran 0:8094b249013c 112 const char *ESP8266::getNetmask()
DuyLionTran 0:8094b249013c 113 {
DuyLionTran 0:8094b249013c 114 if (!(_parser.send("AT+CIPSTA?")
DuyLionTran 0:8094b249013c 115 && _parser.recv("+CIPSTA:netmask:\"%15[^\"]\"", _netmask_buffer)
DuyLionTran 0:8094b249013c 116 && _parser.recv("OK"))) {
DuyLionTran 0:8094b249013c 117 return 0;
DuyLionTran 0:8094b249013c 118 }
DuyLionTran 0:8094b249013c 119
DuyLionTran 0:8094b249013c 120 return _netmask_buffer;
DuyLionTran 0:8094b249013c 121 }
DuyLionTran 0:8094b249013c 122
DuyLionTran 0:8094b249013c 123 int8_t ESP8266::getRSSI()
DuyLionTran 0:8094b249013c 124 {
DuyLionTran 0:8094b249013c 125 int8_t rssi;
DuyLionTran 0:8094b249013c 126 char bssid[18];
DuyLionTran 0:8094b249013c 127
DuyLionTran 0:8094b249013c 128 if (!(_parser.send("AT+CWJAP?")
DuyLionTran 0:8094b249013c 129 && _parser.recv("+CWJAP:\"%*[^\"]\",\"%17[^\"]\"", bssid)
DuyLionTran 0:8094b249013c 130 && _parser.recv("OK"))) {
DuyLionTran 0:8094b249013c 131 return 0;
DuyLionTran 0:8094b249013c 132 }
DuyLionTran 0:8094b249013c 133
DuyLionTran 0:8094b249013c 134 if (!(_parser.send("AT+CWLAP=\"\",\"%s\",", bssid)
DuyLionTran 0:8094b249013c 135 && _parser.recv("+CWLAP:(%*d,\"%*[^\"]\",%hhd,", &rssi)
DuyLionTran 0:8094b249013c 136 && _parser.recv("OK"))) {
DuyLionTran 0:8094b249013c 137 return 0;
DuyLionTran 0:8094b249013c 138 }
DuyLionTran 0:8094b249013c 139
DuyLionTran 0:8094b249013c 140 return rssi;
DuyLionTran 0:8094b249013c 141 }
DuyLionTran 0:8094b249013c 142
DuyLionTran 0:8094b249013c 143 bool ESP8266::isConnected(void)
DuyLionTran 0:8094b249013c 144 {
DuyLionTran 0:8094b249013c 145 return getIPAddress() != 0;
DuyLionTran 0:8094b249013c 146 }
DuyLionTran 0:8094b249013c 147
DuyLionTran 0:8094b249013c 148 int ESP8266::scan(WiFiAccessPoint *res, unsigned limit)
DuyLionTran 0:8094b249013c 149 {
DuyLionTran 0:8094b249013c 150 unsigned cnt = 0;
DuyLionTran 0:8094b249013c 151 nsapi_wifi_ap_t ap;
DuyLionTran 0:8094b249013c 152
DuyLionTran 0:8094b249013c 153 if (!_parser.send("AT+CWLAP")) {
DuyLionTran 0:8094b249013c 154 return NSAPI_ERROR_DEVICE_ERROR;
DuyLionTran 0:8094b249013c 155 }
DuyLionTran 0:8094b249013c 156
DuyLionTran 0:8094b249013c 157 while (recv_ap(&ap)) {
DuyLionTran 0:8094b249013c 158 if (cnt < limit) {
DuyLionTran 0:8094b249013c 159 res[cnt] = WiFiAccessPoint(ap);
DuyLionTran 0:8094b249013c 160 }
DuyLionTran 0:8094b249013c 161
DuyLionTran 0:8094b249013c 162 cnt++;
DuyLionTran 0:8094b249013c 163 if (limit != 0 && cnt >= limit) {
DuyLionTran 0:8094b249013c 164 break;
DuyLionTran 0:8094b249013c 165 }
DuyLionTran 0:8094b249013c 166 }
DuyLionTran 0:8094b249013c 167
DuyLionTran 0:8094b249013c 168 return cnt;
DuyLionTran 0:8094b249013c 169 }
DuyLionTran 0:8094b249013c 170
DuyLionTran 0:8094b249013c 171 bool ESP8266::open(const char *type, int id, const char* addr, int port)
DuyLionTran 0:8094b249013c 172 {
DuyLionTran 0:8094b249013c 173 //IDs only 0-4
DuyLionTran 0:8094b249013c 174 if(id > 4) {
DuyLionTran 0:8094b249013c 175 return false;
DuyLionTran 0:8094b249013c 176 }
DuyLionTran 0:8094b249013c 177
DuyLionTran 0:8094b249013c 178 return _parser.send("AT+CIPSTART=%d,\"%s\",\"%s\",%d", id, type, addr, port)
DuyLionTran 0:8094b249013c 179 && _parser.recv("OK");
DuyLionTran 0:8094b249013c 180 }
DuyLionTran 0:8094b249013c 181
DuyLionTran 0:8094b249013c 182 bool ESP8266::send(int id, const void *data, uint32_t amount)
DuyLionTran 0:8094b249013c 183 {
DuyLionTran 0:8094b249013c 184 //May take a second try if device is busy
DuyLionTran 0:8094b249013c 185 for (unsigned i = 0; i < 2; i++) {
DuyLionTran 0:8094b249013c 186 if (_parser.send("AT+CIPSEND=%d,%d", id, amount)
DuyLionTran 0:8094b249013c 187 && _parser.recv(">")
DuyLionTran 0:8094b249013c 188 && _parser.write((char*)data, (int)amount) >= 0) {
DuyLionTran 0:8094b249013c 189 return true;
DuyLionTran 0:8094b249013c 190 }
DuyLionTran 0:8094b249013c 191 }
DuyLionTran 0:8094b249013c 192
DuyLionTran 0:8094b249013c 193 return false;
DuyLionTran 0:8094b249013c 194 }
DuyLionTran 0:8094b249013c 195
DuyLionTran 0:8094b249013c 196 void ESP8266::_packet_handler()
DuyLionTran 0:8094b249013c 197 {
DuyLionTran 0:8094b249013c 198 int id;
DuyLionTran 0:8094b249013c 199 uint32_t amount;
DuyLionTran 0:8094b249013c 200
DuyLionTran 0:8094b249013c 201 // parse out the packet
DuyLionTran 0:8094b249013c 202 if (!_parser.recv(",%d,%d:", &id, &amount)) {
DuyLionTran 0:8094b249013c 203 return;
DuyLionTran 0:8094b249013c 204 }
DuyLionTran 0:8094b249013c 205
DuyLionTran 0:8094b249013c 206 struct packet *packet = (struct packet*)malloc(
DuyLionTran 0:8094b249013c 207 sizeof(struct packet) + amount);
DuyLionTran 0:8094b249013c 208 if (!packet) {
DuyLionTran 0:8094b249013c 209 return;
DuyLionTran 0:8094b249013c 210 }
DuyLionTran 0:8094b249013c 211
DuyLionTran 0:8094b249013c 212 packet->id = id;
DuyLionTran 0:8094b249013c 213 packet->len = amount;
DuyLionTran 0:8094b249013c 214 packet->next = 0;
DuyLionTran 0:8094b249013c 215
DuyLionTran 0:8094b249013c 216 if (!(_parser.read((char*)(packet + 1), amount))) {
DuyLionTran 0:8094b249013c 217 free(packet);
DuyLionTran 0:8094b249013c 218 return;
DuyLionTran 0:8094b249013c 219 }
DuyLionTran 0:8094b249013c 220
DuyLionTran 0:8094b249013c 221 // append to packet list
DuyLionTran 0:8094b249013c 222 *_packets_end = packet;
DuyLionTran 0:8094b249013c 223 _packets_end = &packet->next;
DuyLionTran 0:8094b249013c 224 }
DuyLionTran 0:8094b249013c 225
DuyLionTran 0:8094b249013c 226 int32_t ESP8266::recv(int id, void *data, uint32_t amount)
DuyLionTran 0:8094b249013c 227 {
DuyLionTran 0:8094b249013c 228 while (true) {
DuyLionTran 0:8094b249013c 229 // check if any packets are ready for us
DuyLionTran 0:8094b249013c 230 for (struct packet **p = &_packets; *p; p = &(*p)->next) {
DuyLionTran 0:8094b249013c 231 if ((*p)->id == id) {
DuyLionTran 0:8094b249013c 232 struct packet *q = *p;
DuyLionTran 0:8094b249013c 233
DuyLionTran 0:8094b249013c 234 if (q->len <= amount) { // Return and remove full packet
DuyLionTran 0:8094b249013c 235 memcpy(data, q+1, q->len);
DuyLionTran 0:8094b249013c 236
DuyLionTran 0:8094b249013c 237 if (_packets_end == &(*p)->next) {
DuyLionTran 0:8094b249013c 238 _packets_end = p;
DuyLionTran 0:8094b249013c 239 }
DuyLionTran 0:8094b249013c 240 *p = (*p)->next;
DuyLionTran 0:8094b249013c 241
DuyLionTran 0:8094b249013c 242 uint32_t len = q->len;
DuyLionTran 0:8094b249013c 243 free(q);
DuyLionTran 0:8094b249013c 244 return len;
DuyLionTran 0:8094b249013c 245 } else { // return only partial packet
DuyLionTran 0:8094b249013c 246 memcpy(data, q+1, amount);
DuyLionTran 0:8094b249013c 247
DuyLionTran 0:8094b249013c 248 q->len -= amount;
DuyLionTran 0:8094b249013c 249 memmove(q+1, (uint8_t*)(q+1) + amount, q->len);
DuyLionTran 0:8094b249013c 250
DuyLionTran 0:8094b249013c 251 return amount;
DuyLionTran 0:8094b249013c 252 }
DuyLionTran 0:8094b249013c 253 }
DuyLionTran 0:8094b249013c 254 }
DuyLionTran 0:8094b249013c 255
DuyLionTran 0:8094b249013c 256 // Wait for inbound packet
DuyLionTran 0:8094b249013c 257 if (!_parser.recv("OK")) {
DuyLionTran 0:8094b249013c 258 return -1;
DuyLionTran 0:8094b249013c 259 }
DuyLionTran 0:8094b249013c 260 }
DuyLionTran 0:8094b249013c 261 }
DuyLionTran 0:8094b249013c 262
DuyLionTran 0:8094b249013c 263 bool ESP8266::close(int id)
DuyLionTran 0:8094b249013c 264 {
DuyLionTran 0:8094b249013c 265 //May take a second try if device is busy
DuyLionTran 0:8094b249013c 266 for (unsigned i = 0; i < 2; i++) {
DuyLionTran 0:8094b249013c 267 if (_parser.send("AT+CIPCLOSE=%d", id)
DuyLionTran 0:8094b249013c 268 && _parser.recv("OK")) {
DuyLionTran 0:8094b249013c 269 return true;
DuyLionTran 0:8094b249013c 270 }
DuyLionTran 0:8094b249013c 271 }
DuyLionTran 0:8094b249013c 272
DuyLionTran 0:8094b249013c 273 return false;
DuyLionTran 0:8094b249013c 274 }
DuyLionTran 0:8094b249013c 275
DuyLionTran 0:8094b249013c 276 void ESP8266::setTimeout(uint32_t timeout_ms)
DuyLionTran 0:8094b249013c 277 {
DuyLionTran 0:8094b249013c 278 _parser.setTimeout(timeout_ms);
DuyLionTran 0:8094b249013c 279 }
DuyLionTran 0:8094b249013c 280
DuyLionTran 0:8094b249013c 281 bool ESP8266::readable()
DuyLionTran 0:8094b249013c 282 {
DuyLionTran 0:8094b249013c 283 return _serial.readable();
DuyLionTran 0:8094b249013c 284 }
DuyLionTran 0:8094b249013c 285
DuyLionTran 0:8094b249013c 286 bool ESP8266::writeable()
DuyLionTran 0:8094b249013c 287 {
DuyLionTran 0:8094b249013c 288 return _serial.writeable();
DuyLionTran 0:8094b249013c 289 }
DuyLionTran 0:8094b249013c 290
DuyLionTran 0:8094b249013c 291 void ESP8266::attach(Callback<void()> func)
DuyLionTran 0:8094b249013c 292 {
DuyLionTran 0:8094b249013c 293 _serial.attach(func);
DuyLionTran 0:8094b249013c 294 }
DuyLionTran 0:8094b249013c 295
DuyLionTran 0:8094b249013c 296 bool ESP8266::recv_ap(nsapi_wifi_ap_t *ap)
DuyLionTran 0:8094b249013c 297 {
DuyLionTran 0:8094b249013c 298 int sec;
DuyLionTran 0:8094b249013c 299 bool ret = _parser.recv("+CWLAP:(%d,\"%32[^\"]\",%hhd,\"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx\",%d", &sec, ap->ssid,
DuyLionTran 0:8094b249013c 300 &ap->rssi, &ap->bssid[0], &ap->bssid[1], &ap->bssid[2], &ap->bssid[3], &ap->bssid[4],
DuyLionTran 0:8094b249013c 301 &ap->bssid[5], &ap->channel);
DuyLionTran 0:8094b249013c 302
DuyLionTran 0:8094b249013c 303 ap->security = sec < 5 ? (nsapi_security_t)sec : NSAPI_SECURITY_UNKNOWN;
DuyLionTran 0:8094b249013c 304
DuyLionTran 0:8094b249013c 305 return ret;
DuyLionTran 0:8094b249013c 306 }