my customized lib

Committer:
DuyLionTran
Date:
Sun Nov 26 15:08:14 2017 +0000
Revision:
0:8094b249013c
Initial commit

Who changed what in which revision?

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