Version of easy-connect with the u-blox cellular platforms C027 and C030 added.

Dependents:   HelloMQTT

Committer:
RobMeades
Date:
Fri Nov 03 13:01:23 2017 +0000
Revision:
6:304d3ba87a01
Parent:
0:19aa55d66228
Add comment concerning N2XX baud rate.

Who changed what in which revision?

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