Fork of my MQTTGateway

Dependencies:   mbed-http

Committer:
vpcola
Date:
Sat Apr 08 14:45:51 2017 +0000
Revision:
0:f1d3878b8dd9
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
vpcola 0:f1d3878b8dd9 1 /* ESP8266 implementation of NetworkInterfaceAPI
vpcola 0:f1d3878b8dd9 2 * Copyright (c) 2015 ARM Limited
vpcola 0:f1d3878b8dd9 3 *
vpcola 0:f1d3878b8dd9 4 * Licensed under the Apache License, Version 2.0 (the "License");
vpcola 0:f1d3878b8dd9 5 * you may not use this file except in compliance with the License.
vpcola 0:f1d3878b8dd9 6 * You may obtain a copy of the License at
vpcola 0:f1d3878b8dd9 7 *
vpcola 0:f1d3878b8dd9 8 * http://www.apache.org/licenses/LICENSE-2.0
vpcola 0:f1d3878b8dd9 9 *
vpcola 0:f1d3878b8dd9 10 * Unless required by applicable law or agreed to in writing, software
vpcola 0:f1d3878b8dd9 11 * distributed under the License is distributed on an "AS IS" BASIS,
vpcola 0:f1d3878b8dd9 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
vpcola 0:f1d3878b8dd9 13 * See the License for the specific language governing permissions and
vpcola 0:f1d3878b8dd9 14 * limitations under the License.
vpcola 0:f1d3878b8dd9 15 */
vpcola 0:f1d3878b8dd9 16
vpcola 0:f1d3878b8dd9 17 #include <string.h>
vpcola 0:f1d3878b8dd9 18 #include "ESP8266Interface.h"
vpcola 0:f1d3878b8dd9 19
vpcola 0:f1d3878b8dd9 20 // Various timeouts for different ESP8266 operations
vpcola 0:f1d3878b8dd9 21 #define ESP8266_CONNECT_TIMEOUT 15000
vpcola 0:f1d3878b8dd9 22 #define ESP8266_SEND_TIMEOUT 500
vpcola 0:f1d3878b8dd9 23 #define ESP8266_RECV_TIMEOUT 0
vpcola 0:f1d3878b8dd9 24 #define ESP8266_MISC_TIMEOUT 500
vpcola 0:f1d3878b8dd9 25
vpcola 0:f1d3878b8dd9 26 // ESP8266Interface implementation
vpcola 0:f1d3878b8dd9 27 ESP8266Interface::ESP8266Interface(PinName tx, PinName rx, bool debug)
vpcola 0:f1d3878b8dd9 28 : _esp(tx, rx, debug)
vpcola 0:f1d3878b8dd9 29 {
vpcola 0:f1d3878b8dd9 30 memset(_ids, 0, sizeof(_ids));
vpcola 0:f1d3878b8dd9 31 memset(_cbs, 0, sizeof(_cbs));
vpcola 0:f1d3878b8dd9 32
vpcola 0:f1d3878b8dd9 33 _esp.attach(this, &ESP8266Interface::event);
vpcola 0:f1d3878b8dd9 34 }
vpcola 0:f1d3878b8dd9 35
vpcola 0:f1d3878b8dd9 36 int ESP8266Interface::connect(const char *ssid, const char *pass, nsapi_security_t security,
vpcola 0:f1d3878b8dd9 37 uint8_t channel)
vpcola 0:f1d3878b8dd9 38 {
vpcola 0:f1d3878b8dd9 39 if (channel != 0) {
vpcola 0:f1d3878b8dd9 40 return NSAPI_ERROR_UNSUPPORTED;
vpcola 0:f1d3878b8dd9 41 }
vpcola 0:f1d3878b8dd9 42
vpcola 0:f1d3878b8dd9 43 set_credentials(ssid, pass, security);
vpcola 0:f1d3878b8dd9 44 return connect();
vpcola 0:f1d3878b8dd9 45 }
vpcola 0:f1d3878b8dd9 46
vpcola 0:f1d3878b8dd9 47 int ESP8266Interface::connect()
vpcola 0:f1d3878b8dd9 48 {
vpcola 0:f1d3878b8dd9 49 _esp.setTimeout(ESP8266_CONNECT_TIMEOUT);
vpcola 0:f1d3878b8dd9 50
vpcola 0:f1d3878b8dd9 51 if (!_esp.startup(3)) {
vpcola 0:f1d3878b8dd9 52 return NSAPI_ERROR_DEVICE_ERROR;
vpcola 0:f1d3878b8dd9 53 }
vpcola 0:f1d3878b8dd9 54
vpcola 0:f1d3878b8dd9 55 if (!_esp.dhcp(true, 1)) {
vpcola 0:f1d3878b8dd9 56 return NSAPI_ERROR_DHCP_FAILURE;
vpcola 0:f1d3878b8dd9 57 }
vpcola 0:f1d3878b8dd9 58
vpcola 0:f1d3878b8dd9 59 if (!_esp.connect(ap_ssid, ap_pass)) {
vpcola 0:f1d3878b8dd9 60 return NSAPI_ERROR_NO_CONNECTION;
vpcola 0:f1d3878b8dd9 61 }
vpcola 0:f1d3878b8dd9 62
vpcola 0:f1d3878b8dd9 63 if (!_esp.getIPAddress()) {
vpcola 0:f1d3878b8dd9 64 return NSAPI_ERROR_DHCP_FAILURE;
vpcola 0:f1d3878b8dd9 65 }
vpcola 0:f1d3878b8dd9 66
vpcola 0:f1d3878b8dd9 67 return NSAPI_ERROR_OK;
vpcola 0:f1d3878b8dd9 68 }
vpcola 0:f1d3878b8dd9 69
vpcola 0:f1d3878b8dd9 70 int ESP8266Interface::set_credentials(const char *ssid, const char *pass, nsapi_security_t security)
vpcola 0:f1d3878b8dd9 71 {
vpcola 0:f1d3878b8dd9 72 memset(ap_ssid, 0, sizeof(ap_ssid));
vpcola 0:f1d3878b8dd9 73 strncpy(ap_ssid, ssid, sizeof(ap_ssid));
vpcola 0:f1d3878b8dd9 74
vpcola 0:f1d3878b8dd9 75 memset(ap_pass, 0, sizeof(ap_pass));
vpcola 0:f1d3878b8dd9 76 strncpy(ap_pass, pass, sizeof(ap_pass));
vpcola 0:f1d3878b8dd9 77
vpcola 0:f1d3878b8dd9 78 ap_sec = security;
vpcola 0:f1d3878b8dd9 79
vpcola 0:f1d3878b8dd9 80 return 0;
vpcola 0:f1d3878b8dd9 81 }
vpcola 0:f1d3878b8dd9 82
vpcola 0:f1d3878b8dd9 83 int ESP8266Interface::set_channel(uint8_t channel)
vpcola 0:f1d3878b8dd9 84 {
vpcola 0:f1d3878b8dd9 85 return NSAPI_ERROR_UNSUPPORTED;
vpcola 0:f1d3878b8dd9 86 }
vpcola 0:f1d3878b8dd9 87
vpcola 0:f1d3878b8dd9 88
vpcola 0:f1d3878b8dd9 89 int ESP8266Interface::disconnect()
vpcola 0:f1d3878b8dd9 90 {
vpcola 0:f1d3878b8dd9 91 _esp.setTimeout(ESP8266_MISC_TIMEOUT);
vpcola 0:f1d3878b8dd9 92
vpcola 0:f1d3878b8dd9 93 if (!_esp.disconnect()) {
vpcola 0:f1d3878b8dd9 94 return NSAPI_ERROR_DEVICE_ERROR;
vpcola 0:f1d3878b8dd9 95 }
vpcola 0:f1d3878b8dd9 96
vpcola 0:f1d3878b8dd9 97 return NSAPI_ERROR_OK;
vpcola 0:f1d3878b8dd9 98 }
vpcola 0:f1d3878b8dd9 99
vpcola 0:f1d3878b8dd9 100 const char *ESP8266Interface::get_ip_address()
vpcola 0:f1d3878b8dd9 101 {
vpcola 0:f1d3878b8dd9 102 return _esp.getIPAddress();
vpcola 0:f1d3878b8dd9 103 }
vpcola 0:f1d3878b8dd9 104
vpcola 0:f1d3878b8dd9 105 const char *ESP8266Interface::get_mac_address()
vpcola 0:f1d3878b8dd9 106 {
vpcola 0:f1d3878b8dd9 107 return _esp.getMACAddress();
vpcola 0:f1d3878b8dd9 108 }
vpcola 0:f1d3878b8dd9 109
vpcola 0:f1d3878b8dd9 110 const char *ESP8266Interface::get_gateway()
vpcola 0:f1d3878b8dd9 111 {
vpcola 0:f1d3878b8dd9 112 return _esp.getGateway();
vpcola 0:f1d3878b8dd9 113 }
vpcola 0:f1d3878b8dd9 114
vpcola 0:f1d3878b8dd9 115 const char *ESP8266Interface::get_netmask()
vpcola 0:f1d3878b8dd9 116 {
vpcola 0:f1d3878b8dd9 117 return _esp.getNetmask();
vpcola 0:f1d3878b8dd9 118 }
vpcola 0:f1d3878b8dd9 119
vpcola 0:f1d3878b8dd9 120 int8_t ESP8266Interface::get_rssi()
vpcola 0:f1d3878b8dd9 121 {
vpcola 0:f1d3878b8dd9 122 return _esp.getRSSI();
vpcola 0:f1d3878b8dd9 123 }
vpcola 0:f1d3878b8dd9 124
vpcola 0:f1d3878b8dd9 125 int ESP8266Interface::scan(WiFiAccessPoint *res, unsigned count)
vpcola 0:f1d3878b8dd9 126 {
vpcola 0:f1d3878b8dd9 127 return _esp.scan(res, count);
vpcola 0:f1d3878b8dd9 128 }
vpcola 0:f1d3878b8dd9 129
vpcola 0:f1d3878b8dd9 130 struct esp8266_socket {
vpcola 0:f1d3878b8dd9 131 int id;
vpcola 0:f1d3878b8dd9 132 nsapi_protocol_t proto;
vpcola 0:f1d3878b8dd9 133 bool connected;
vpcola 0:f1d3878b8dd9 134 SocketAddress addr;
vpcola 0:f1d3878b8dd9 135 };
vpcola 0:f1d3878b8dd9 136
vpcola 0:f1d3878b8dd9 137 int ESP8266Interface::socket_open(void **handle, nsapi_protocol_t proto)
vpcola 0:f1d3878b8dd9 138 {
vpcola 0:f1d3878b8dd9 139 // Look for an unused socket
vpcola 0:f1d3878b8dd9 140 int id = -1;
vpcola 0:f1d3878b8dd9 141
vpcola 0:f1d3878b8dd9 142 for (int i = 0; i < ESP8266_SOCKET_COUNT; i++) {
vpcola 0:f1d3878b8dd9 143 if (!_ids[i]) {
vpcola 0:f1d3878b8dd9 144 id = i;
vpcola 0:f1d3878b8dd9 145 _ids[i] = true;
vpcola 0:f1d3878b8dd9 146 break;
vpcola 0:f1d3878b8dd9 147 }
vpcola 0:f1d3878b8dd9 148 }
vpcola 0:f1d3878b8dd9 149
vpcola 0:f1d3878b8dd9 150 if (id == -1) {
vpcola 0:f1d3878b8dd9 151 return NSAPI_ERROR_NO_SOCKET;
vpcola 0:f1d3878b8dd9 152 }
vpcola 0:f1d3878b8dd9 153
vpcola 0:f1d3878b8dd9 154 struct esp8266_socket *socket = new struct esp8266_socket;
vpcola 0:f1d3878b8dd9 155 if (!socket) {
vpcola 0:f1d3878b8dd9 156 return NSAPI_ERROR_NO_SOCKET;
vpcola 0:f1d3878b8dd9 157 }
vpcola 0:f1d3878b8dd9 158
vpcola 0:f1d3878b8dd9 159 socket->id = id;
vpcola 0:f1d3878b8dd9 160 socket->proto = proto;
vpcola 0:f1d3878b8dd9 161 socket->connected = false;
vpcola 0:f1d3878b8dd9 162 *handle = socket;
vpcola 0:f1d3878b8dd9 163 return 0;
vpcola 0:f1d3878b8dd9 164 }
vpcola 0:f1d3878b8dd9 165
vpcola 0:f1d3878b8dd9 166 int ESP8266Interface::socket_close(void *handle)
vpcola 0:f1d3878b8dd9 167 {
vpcola 0:f1d3878b8dd9 168 struct esp8266_socket *socket = (struct esp8266_socket *)handle;
vpcola 0:f1d3878b8dd9 169 int err = 0;
vpcola 0:f1d3878b8dd9 170 _esp.setTimeout(ESP8266_MISC_TIMEOUT);
vpcola 0:f1d3878b8dd9 171
vpcola 0:f1d3878b8dd9 172 if (!_esp.close(socket->id)) {
vpcola 0:f1d3878b8dd9 173 err = NSAPI_ERROR_DEVICE_ERROR;
vpcola 0:f1d3878b8dd9 174 }
vpcola 0:f1d3878b8dd9 175
vpcola 0:f1d3878b8dd9 176 _ids[socket->id] = false;
vpcola 0:f1d3878b8dd9 177 delete socket;
vpcola 0:f1d3878b8dd9 178 return err;
vpcola 0:f1d3878b8dd9 179 }
vpcola 0:f1d3878b8dd9 180
vpcola 0:f1d3878b8dd9 181 int ESP8266Interface::socket_bind(void *handle, const SocketAddress &address)
vpcola 0:f1d3878b8dd9 182 {
vpcola 0:f1d3878b8dd9 183 return NSAPI_ERROR_UNSUPPORTED;
vpcola 0:f1d3878b8dd9 184 }
vpcola 0:f1d3878b8dd9 185
vpcola 0:f1d3878b8dd9 186 int ESP8266Interface::socket_listen(void *handle, int backlog)
vpcola 0:f1d3878b8dd9 187 {
vpcola 0:f1d3878b8dd9 188 return NSAPI_ERROR_UNSUPPORTED;
vpcola 0:f1d3878b8dd9 189 }
vpcola 0:f1d3878b8dd9 190
vpcola 0:f1d3878b8dd9 191 int ESP8266Interface::socket_connect(void *handle, const SocketAddress &addr)
vpcola 0:f1d3878b8dd9 192 {
vpcola 0:f1d3878b8dd9 193 struct esp8266_socket *socket = (struct esp8266_socket *)handle;
vpcola 0:f1d3878b8dd9 194 _esp.setTimeout(ESP8266_MISC_TIMEOUT);
vpcola 0:f1d3878b8dd9 195
vpcola 0:f1d3878b8dd9 196 const char *proto = (socket->proto == NSAPI_UDP) ? "UDP" : "TCP";
vpcola 0:f1d3878b8dd9 197 if (!_esp.open(proto, socket->id, addr.get_ip_address(), addr.get_port())) {
vpcola 0:f1d3878b8dd9 198 return NSAPI_ERROR_DEVICE_ERROR;
vpcola 0:f1d3878b8dd9 199 }
vpcola 0:f1d3878b8dd9 200
vpcola 0:f1d3878b8dd9 201 socket->connected = true;
vpcola 0:f1d3878b8dd9 202 return 0;
vpcola 0:f1d3878b8dd9 203 }
vpcola 0:f1d3878b8dd9 204
vpcola 0:f1d3878b8dd9 205 int ESP8266Interface::socket_accept(void *server, void **socket, SocketAddress *addr)
vpcola 0:f1d3878b8dd9 206 {
vpcola 0:f1d3878b8dd9 207 return NSAPI_ERROR_UNSUPPORTED;
vpcola 0:f1d3878b8dd9 208 }
vpcola 0:f1d3878b8dd9 209
vpcola 0:f1d3878b8dd9 210 int ESP8266Interface::socket_send(void *handle, const void *data, unsigned size)
vpcola 0:f1d3878b8dd9 211 {
vpcola 0:f1d3878b8dd9 212 struct esp8266_socket *socket = (struct esp8266_socket *)handle;
vpcola 0:f1d3878b8dd9 213 _esp.setTimeout(ESP8266_SEND_TIMEOUT);
vpcola 0:f1d3878b8dd9 214
vpcola 0:f1d3878b8dd9 215 if (!_esp.send(socket->id, data, size)) {
vpcola 0:f1d3878b8dd9 216 return NSAPI_ERROR_DEVICE_ERROR;
vpcola 0:f1d3878b8dd9 217 }
vpcola 0:f1d3878b8dd9 218
vpcola 0:f1d3878b8dd9 219 return size;
vpcola 0:f1d3878b8dd9 220 }
vpcola 0:f1d3878b8dd9 221
vpcola 0:f1d3878b8dd9 222 int ESP8266Interface::socket_recv(void *handle, void *data, unsigned size)
vpcola 0:f1d3878b8dd9 223 {
vpcola 0:f1d3878b8dd9 224 struct esp8266_socket *socket = (struct esp8266_socket *)handle;
vpcola 0:f1d3878b8dd9 225 _esp.setTimeout(ESP8266_RECV_TIMEOUT);
vpcola 0:f1d3878b8dd9 226
vpcola 0:f1d3878b8dd9 227 int32_t recv = _esp.recv(socket->id, data, size);
vpcola 0:f1d3878b8dd9 228 if (recv < 0) {
vpcola 0:f1d3878b8dd9 229 return NSAPI_ERROR_WOULD_BLOCK;
vpcola 0:f1d3878b8dd9 230 }
vpcola 0:f1d3878b8dd9 231
vpcola 0:f1d3878b8dd9 232 return recv;
vpcola 0:f1d3878b8dd9 233 }
vpcola 0:f1d3878b8dd9 234
vpcola 0:f1d3878b8dd9 235 int ESP8266Interface::socket_sendto(void *handle, const SocketAddress &addr, const void *data, unsigned size)
vpcola 0:f1d3878b8dd9 236 {
vpcola 0:f1d3878b8dd9 237 struct esp8266_socket *socket = (struct esp8266_socket *)handle;
vpcola 0:f1d3878b8dd9 238
vpcola 0:f1d3878b8dd9 239 if (socket->connected && socket->addr != addr) {
vpcola 0:f1d3878b8dd9 240 _esp.setTimeout(ESP8266_MISC_TIMEOUT);
vpcola 0:f1d3878b8dd9 241 if (!_esp.close(socket->id)) {
vpcola 0:f1d3878b8dd9 242 return NSAPI_ERROR_DEVICE_ERROR;
vpcola 0:f1d3878b8dd9 243 }
vpcola 0:f1d3878b8dd9 244 socket->connected = false;
vpcola 0:f1d3878b8dd9 245 }
vpcola 0:f1d3878b8dd9 246
vpcola 0:f1d3878b8dd9 247 if (!socket->connected) {
vpcola 0:f1d3878b8dd9 248 int err = socket_connect(socket, addr);
vpcola 0:f1d3878b8dd9 249 if (err < 0) {
vpcola 0:f1d3878b8dd9 250 return err;
vpcola 0:f1d3878b8dd9 251 }
vpcola 0:f1d3878b8dd9 252 socket->addr = addr;
vpcola 0:f1d3878b8dd9 253 }
vpcola 0:f1d3878b8dd9 254
vpcola 0:f1d3878b8dd9 255 return socket_send(socket, data, size);
vpcola 0:f1d3878b8dd9 256 }
vpcola 0:f1d3878b8dd9 257
vpcola 0:f1d3878b8dd9 258 int ESP8266Interface::socket_recvfrom(void *handle, SocketAddress *addr, void *data, unsigned size)
vpcola 0:f1d3878b8dd9 259 {
vpcola 0:f1d3878b8dd9 260 struct esp8266_socket *socket = (struct esp8266_socket *)handle;
vpcola 0:f1d3878b8dd9 261 int ret = socket_recv(socket, data, size);
vpcola 0:f1d3878b8dd9 262 if (ret >= 0 && addr) {
vpcola 0:f1d3878b8dd9 263 *addr = socket->addr;
vpcola 0:f1d3878b8dd9 264 }
vpcola 0:f1d3878b8dd9 265
vpcola 0:f1d3878b8dd9 266 return ret;
vpcola 0:f1d3878b8dd9 267 }
vpcola 0:f1d3878b8dd9 268
vpcola 0:f1d3878b8dd9 269 void ESP8266Interface::socket_attach(void *handle, void (*callback)(void *), void *data)
vpcola 0:f1d3878b8dd9 270 {
vpcola 0:f1d3878b8dd9 271 struct esp8266_socket *socket = (struct esp8266_socket *)handle;
vpcola 0:f1d3878b8dd9 272 _cbs[socket->id].callback = callback;
vpcola 0:f1d3878b8dd9 273 _cbs[socket->id].data = data;
vpcola 0:f1d3878b8dd9 274 }
vpcola 0:f1d3878b8dd9 275
vpcola 0:f1d3878b8dd9 276 void ESP8266Interface::event() {
vpcola 0:f1d3878b8dd9 277 for (int i = 0; i < ESP8266_SOCKET_COUNT; i++) {
vpcola 0:f1d3878b8dd9 278 if (_cbs[i].callback) {
vpcola 0:f1d3878b8dd9 279 _cbs[i].callback(_cbs[i].data);
vpcola 0:f1d3878b8dd9 280 }
vpcola 0:f1d3878b8dd9 281 }
vpcola 0:f1d3878b8dd9 282 }