This is an example of BLE GATT Client, which receives broadcast data from BLE_Server_BME280 ( a GATT server) , then transfers values up to mbed Device Connector (cloud).

Please refer details about BLEClient_mbedDevConn below. https://github.com/soramame21/BLEClient_mbedDevConn

The location of required BLE GATT server, BLE_Server_BME280, is at here. https://developer.mbed.org/users/edamame22/code/BLE_Server_BME280/

Committer:
Ren Boting
Date:
Tue Sep 05 11:56:13 2017 +0900
Revision:
2:b894b3508057
Parent:
0:29983394c6b6
Update all libraries and reform main.cpp

Who changed what in which revision?

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