OneNet_IoT_demo for ASC platform

Dependencies:   Common_lib ESP8266 EdpKit_lib cJSON_lib driver_mbed_HP20x driver_mbed_TH02 wifi_example

Fork of mbed-os-example-esp8266 by ESP8266

Committer:
sarahmarshy
Date:
Thu Jan 12 22:05:15 2017 +0000
Revision:
1:b4a718e62e0b
Parent:
0:b887535f68bf
Update esp8266-driver

Who changed what in which revision?

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