Added support for WNC M14A2A Cellular LTE Data Module.

Dependencies:   WNC14A2AInterface

Dependents:   http-example-wnc http-example-wnc-modified

Committer:
root@developer-sjc-cyan-compiler.local.mbed.org
Date:
Sun Apr 23 18:40:51 2017 +0000
Revision:
5:391eac6a0a94
Parent:
0:2563b0415d1f
Added tag att_cellular_K64_wnc_14A2A_20170423 for changeset daf182af022b

Who changed what in which revision?

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