Generic Pelion Device Management example for various Advantech modules.

This example is known to work great on the following platforms:

Example Functionality

This example showcases the following device functionality:

  • On timer button increment, simulate Pelion LWM2M button resource change

Use this example with Mbed CLI

1. Import the application into your desktop:

mbed import https://os.mbed.com/teams/Advantech/code/pelion-example-common
cd pelion-example-common

2. Download your developer certificate from pelion portal

3. Compile the program

mbed compile -t <toolchain> -m <TARGET_BOARD>

(supported toolchains : GCC_ARM / ARM / IAR)

4. Copy the binary file pelion-example-common.bin to your mbed device.

Committer:
chuanga
Date:
Tue Mar 12 13:48:39 2019 +0800
Revision:
0:43ff9e3bc244
copying sources from github repository

Who changed what in which revision?

UserRevisionLine numberNew contents of line
chuanga 0:43ff9e3bc244 1 /* ESP32 implementation of NetworkInterfaceAPI
chuanga 0:43ff9e3bc244 2 * Copyright (c) 2015 ARM Limited
chuanga 0:43ff9e3bc244 3 * Copyright (c) 2017 Renesas Electronics Corporation
chuanga 0:43ff9e3bc244 4 *
chuanga 0:43ff9e3bc244 5 * Licensed under the Apache License, Version 2.0 (the "License");
chuanga 0:43ff9e3bc244 6 * you may not use this file except in compliance with the License.
chuanga 0:43ff9e3bc244 7 * You may obtain a copy of the License at
chuanga 0:43ff9e3bc244 8 *
chuanga 0:43ff9e3bc244 9 * http://www.apache.org/licenses/LICENSE-2.0
chuanga 0:43ff9e3bc244 10 *
chuanga 0:43ff9e3bc244 11 * Unless required by applicable law or agreed to in writing, software
chuanga 0:43ff9e3bc244 12 * distributed under the License is distributed on an "AS IS" BASIS,
chuanga 0:43ff9e3bc244 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
chuanga 0:43ff9e3bc244 14 * See the License for the specific language governing permissions and
chuanga 0:43ff9e3bc244 15 * limitations under the License.
chuanga 0:43ff9e3bc244 16 */
chuanga 0:43ff9e3bc244 17
chuanga 0:43ff9e3bc244 18 #include <string.h>
chuanga 0:43ff9e3bc244 19 #include "ESP32Stack.h"
chuanga 0:43ff9e3bc244 20
chuanga 0:43ff9e3bc244 21 // ESP32Stack implementation
chuanga 0:43ff9e3bc244 22 ESP32Stack::ESP32Stack(PinName en, PinName io0, PinName tx, PinName rx, bool debug,
chuanga 0:43ff9e3bc244 23 PinName rts, PinName cts, int baudrate)
chuanga 0:43ff9e3bc244 24 {
chuanga 0:43ff9e3bc244 25 _esp = ESP32::getESP32Inst(en, io0, tx, rx, debug, rts, cts, baudrate);
chuanga 0:43ff9e3bc244 26 memset(_local_ports, 0, sizeof(_local_ports));
chuanga 0:43ff9e3bc244 27 }
chuanga 0:43ff9e3bc244 28
chuanga 0:43ff9e3bc244 29 struct esp32_socket {
chuanga 0:43ff9e3bc244 30 int id;
chuanga 0:43ff9e3bc244 31 nsapi_protocol_t proto;
chuanga 0:43ff9e3bc244 32 bool connected;
chuanga 0:43ff9e3bc244 33 SocketAddress addr;
chuanga 0:43ff9e3bc244 34 int keepalive; // TCP
chuanga 0:43ff9e3bc244 35 bool accept_id;
chuanga 0:43ff9e3bc244 36 bool tcp_server;
chuanga 0:43ff9e3bc244 37 };
chuanga 0:43ff9e3bc244 38
chuanga 0:43ff9e3bc244 39 int ESP32Stack::socket_open(void **handle, nsapi_protocol_t proto)
chuanga 0:43ff9e3bc244 40 {
chuanga 0:43ff9e3bc244 41 // Look for an unused socket
chuanga 0:43ff9e3bc244 42 int id = _esp->get_free_id();
chuanga 0:43ff9e3bc244 43
chuanga 0:43ff9e3bc244 44 if (id == -1) {
chuanga 0:43ff9e3bc244 45 return NSAPI_ERROR_NO_SOCKET;
chuanga 0:43ff9e3bc244 46 }
chuanga 0:43ff9e3bc244 47
chuanga 0:43ff9e3bc244 48 struct esp32_socket *socket = new struct esp32_socket;
chuanga 0:43ff9e3bc244 49 if (!socket) {
chuanga 0:43ff9e3bc244 50 return NSAPI_ERROR_NO_SOCKET;
chuanga 0:43ff9e3bc244 51 }
chuanga 0:43ff9e3bc244 52
chuanga 0:43ff9e3bc244 53 socket->id = id;
chuanga 0:43ff9e3bc244 54 socket->proto = proto;
chuanga 0:43ff9e3bc244 55 socket->connected = false;
chuanga 0:43ff9e3bc244 56 socket->keepalive = 0;
chuanga 0:43ff9e3bc244 57 socket->accept_id = false;
chuanga 0:43ff9e3bc244 58 socket->tcp_server = false;
chuanga 0:43ff9e3bc244 59 *handle = socket;
chuanga 0:43ff9e3bc244 60 return 0;
chuanga 0:43ff9e3bc244 61 }
chuanga 0:43ff9e3bc244 62
chuanga 0:43ff9e3bc244 63 int ESP32Stack::socket_close(void *handle)
chuanga 0:43ff9e3bc244 64 {
chuanga 0:43ff9e3bc244 65 struct esp32_socket *socket = (struct esp32_socket *)handle;
chuanga 0:43ff9e3bc244 66 int err = 0;
chuanga 0:43ff9e3bc244 67
chuanga 0:43ff9e3bc244 68 if (!socket) {
chuanga 0:43ff9e3bc244 69 return NSAPI_ERROR_NO_SOCKET;
chuanga 0:43ff9e3bc244 70 }
chuanga 0:43ff9e3bc244 71
chuanga 0:43ff9e3bc244 72 if (!_esp->close(socket->id, socket->accept_id)) {
chuanga 0:43ff9e3bc244 73 err = NSAPI_ERROR_DEVICE_ERROR;
chuanga 0:43ff9e3bc244 74 }
chuanga 0:43ff9e3bc244 75
chuanga 0:43ff9e3bc244 76 if (socket->tcp_server) {
chuanga 0:43ff9e3bc244 77 _esp->del_server();
chuanga 0:43ff9e3bc244 78 }
chuanga 0:43ff9e3bc244 79 _local_ports[socket->id] = 0;
chuanga 0:43ff9e3bc244 80
chuanga 0:43ff9e3bc244 81 delete socket;
chuanga 0:43ff9e3bc244 82 return err;
chuanga 0:43ff9e3bc244 83 }
chuanga 0:43ff9e3bc244 84
chuanga 0:43ff9e3bc244 85 int ESP32Stack::socket_bind(void *handle, const SocketAddress &address)
chuanga 0:43ff9e3bc244 86 {
chuanga 0:43ff9e3bc244 87 struct esp32_socket *socket = (struct esp32_socket *)handle;
chuanga 0:43ff9e3bc244 88
chuanga 0:43ff9e3bc244 89 if (!socket) {
chuanga 0:43ff9e3bc244 90 return NSAPI_ERROR_NO_SOCKET;
chuanga 0:43ff9e3bc244 91 }
chuanga 0:43ff9e3bc244 92
chuanga 0:43ff9e3bc244 93 if (socket->proto == NSAPI_UDP) {
chuanga 0:43ff9e3bc244 94 if(address.get_addr().version != NSAPI_UNSPEC) {
chuanga 0:43ff9e3bc244 95 return NSAPI_ERROR_UNSUPPORTED;
chuanga 0:43ff9e3bc244 96 }
chuanga 0:43ff9e3bc244 97
chuanga 0:43ff9e3bc244 98 for(int id = 0; id < ESP32::SOCKET_COUNT; id++) {
chuanga 0:43ff9e3bc244 99 if(_local_ports[id] == address.get_port() && id != socket->id) { // Port already reserved by another socket
chuanga 0:43ff9e3bc244 100 return NSAPI_ERROR_PARAMETER;
chuanga 0:43ff9e3bc244 101 } else if (id == socket->id && socket->connected) {
chuanga 0:43ff9e3bc244 102 return NSAPI_ERROR_PARAMETER;
chuanga 0:43ff9e3bc244 103 }
chuanga 0:43ff9e3bc244 104 }
chuanga 0:43ff9e3bc244 105 _local_ports[socket->id] = address.get_port();
chuanga 0:43ff9e3bc244 106 return 0;
chuanga 0:43ff9e3bc244 107 }
chuanga 0:43ff9e3bc244 108
chuanga 0:43ff9e3bc244 109 socket->addr = address;
chuanga 0:43ff9e3bc244 110 return 0;
chuanga 0:43ff9e3bc244 111 }
chuanga 0:43ff9e3bc244 112
chuanga 0:43ff9e3bc244 113 int ESP32Stack::socket_listen(void *handle, int backlog)
chuanga 0:43ff9e3bc244 114 {
chuanga 0:43ff9e3bc244 115 struct esp32_socket *socket = (struct esp32_socket *)handle;
chuanga 0:43ff9e3bc244 116
chuanga 0:43ff9e3bc244 117 (void)backlog;
chuanga 0:43ff9e3bc244 118
chuanga 0:43ff9e3bc244 119 if (!socket) {
chuanga 0:43ff9e3bc244 120 return NSAPI_ERROR_NO_SOCKET;
chuanga 0:43ff9e3bc244 121 }
chuanga 0:43ff9e3bc244 122
chuanga 0:43ff9e3bc244 123 if (socket->proto != NSAPI_TCP) {
chuanga 0:43ff9e3bc244 124 return NSAPI_ERROR_UNSUPPORTED;
chuanga 0:43ff9e3bc244 125 }
chuanga 0:43ff9e3bc244 126
chuanga 0:43ff9e3bc244 127 if (!_esp->cre_server(socket->addr.get_port())) {
chuanga 0:43ff9e3bc244 128 return NSAPI_ERROR_DEVICE_ERROR;
chuanga 0:43ff9e3bc244 129 }
chuanga 0:43ff9e3bc244 130
chuanga 0:43ff9e3bc244 131 socket->tcp_server = true;
chuanga 0:43ff9e3bc244 132 return 0;
chuanga 0:43ff9e3bc244 133 }
chuanga 0:43ff9e3bc244 134
chuanga 0:43ff9e3bc244 135 int ESP32Stack::socket_connect(void *handle, const SocketAddress &addr)
chuanga 0:43ff9e3bc244 136 {
chuanga 0:43ff9e3bc244 137 struct esp32_socket *socket = (struct esp32_socket *)handle;
chuanga 0:43ff9e3bc244 138
chuanga 0:43ff9e3bc244 139 if (!socket) {
chuanga 0:43ff9e3bc244 140 return NSAPI_ERROR_NO_SOCKET;
chuanga 0:43ff9e3bc244 141 }
chuanga 0:43ff9e3bc244 142
chuanga 0:43ff9e3bc244 143 if (socket->proto == NSAPI_UDP) {
chuanga 0:43ff9e3bc244 144 if (!_esp->open("UDP", socket->id, addr.get_ip_address(), addr.get_port(), _local_ports[socket->id])) {
chuanga 0:43ff9e3bc244 145 return NSAPI_ERROR_DEVICE_ERROR;
chuanga 0:43ff9e3bc244 146 }
chuanga 0:43ff9e3bc244 147 } else {
chuanga 0:43ff9e3bc244 148 if (!_esp->open("TCP", socket->id, addr.get_ip_address(), addr.get_port(), socket->keepalive)) {
chuanga 0:43ff9e3bc244 149 return NSAPI_ERROR_DEVICE_ERROR;
chuanga 0:43ff9e3bc244 150 }
chuanga 0:43ff9e3bc244 151 }
chuanga 0:43ff9e3bc244 152
chuanga 0:43ff9e3bc244 153 socket->connected = true;
chuanga 0:43ff9e3bc244 154 return 0;
chuanga 0:43ff9e3bc244 155 }
chuanga 0:43ff9e3bc244 156
chuanga 0:43ff9e3bc244 157 int ESP32Stack::socket_accept(void *server, void **socket, SocketAddress *addr)
chuanga 0:43ff9e3bc244 158 {
chuanga 0:43ff9e3bc244 159 struct esp32_socket *socket_new = new struct esp32_socket;
chuanga 0:43ff9e3bc244 160 int id;
chuanga 0:43ff9e3bc244 161
chuanga 0:43ff9e3bc244 162 if (!socket_new) {
chuanga 0:43ff9e3bc244 163 return NSAPI_ERROR_NO_SOCKET;
chuanga 0:43ff9e3bc244 164 }
chuanga 0:43ff9e3bc244 165
chuanga 0:43ff9e3bc244 166 if (!_esp->accept(&id)) {
chuanga 0:43ff9e3bc244 167 delete socket_new;
chuanga 0:43ff9e3bc244 168 return NSAPI_ERROR_NO_SOCKET;
chuanga 0:43ff9e3bc244 169 }
chuanga 0:43ff9e3bc244 170
chuanga 0:43ff9e3bc244 171 socket_new->id = id;
chuanga 0:43ff9e3bc244 172 socket_new->proto = NSAPI_TCP;
chuanga 0:43ff9e3bc244 173 socket_new->connected = true;
chuanga 0:43ff9e3bc244 174 socket_new->accept_id = true;
chuanga 0:43ff9e3bc244 175 socket_new->tcp_server = false;
chuanga 0:43ff9e3bc244 176 *socket = socket_new;
chuanga 0:43ff9e3bc244 177
chuanga 0:43ff9e3bc244 178 return 0;
chuanga 0:43ff9e3bc244 179 }
chuanga 0:43ff9e3bc244 180
chuanga 0:43ff9e3bc244 181 int ESP32Stack::socket_send(void *handle, const void *data, unsigned size)
chuanga 0:43ff9e3bc244 182 {
chuanga 0:43ff9e3bc244 183 struct esp32_socket *socket = (struct esp32_socket *)handle;
chuanga 0:43ff9e3bc244 184
chuanga 0:43ff9e3bc244 185 if (!socket) {
chuanga 0:43ff9e3bc244 186 return NSAPI_ERROR_NO_SOCKET;
chuanga 0:43ff9e3bc244 187 }
chuanga 0:43ff9e3bc244 188
chuanga 0:43ff9e3bc244 189 if (!_esp->send(socket->id, data, size)) {
chuanga 0:43ff9e3bc244 190 return NSAPI_ERROR_DEVICE_ERROR;
chuanga 0:43ff9e3bc244 191 }
chuanga 0:43ff9e3bc244 192
chuanga 0:43ff9e3bc244 193 return size;
chuanga 0:43ff9e3bc244 194 }
chuanga 0:43ff9e3bc244 195
chuanga 0:43ff9e3bc244 196 int ESP32Stack::socket_recv(void *handle, void *data, unsigned size)
chuanga 0:43ff9e3bc244 197 {
chuanga 0:43ff9e3bc244 198 struct esp32_socket *socket = (struct esp32_socket *)handle;
chuanga 0:43ff9e3bc244 199
chuanga 0:43ff9e3bc244 200 if (!socket) {
chuanga 0:43ff9e3bc244 201 return NSAPI_ERROR_NO_SOCKET;
chuanga 0:43ff9e3bc244 202 }
chuanga 0:43ff9e3bc244 203
chuanga 0:43ff9e3bc244 204 int32_t recv = _esp->recv(socket->id, data, size);
chuanga 0:43ff9e3bc244 205 if (recv == -1) {
chuanga 0:43ff9e3bc244 206 return NSAPI_ERROR_WOULD_BLOCK;
chuanga 0:43ff9e3bc244 207 } else if (recv < 0) {
chuanga 0:43ff9e3bc244 208 return NSAPI_ERROR_NO_SOCKET;
chuanga 0:43ff9e3bc244 209 } else {
chuanga 0:43ff9e3bc244 210 // do nothing
chuanga 0:43ff9e3bc244 211 }
chuanga 0:43ff9e3bc244 212
chuanga 0:43ff9e3bc244 213 return recv;
chuanga 0:43ff9e3bc244 214 }
chuanga 0:43ff9e3bc244 215
chuanga 0:43ff9e3bc244 216 int ESP32Stack::socket_sendto(void *handle, const SocketAddress &addr, const void *data, unsigned size)
chuanga 0:43ff9e3bc244 217 {
chuanga 0:43ff9e3bc244 218 struct esp32_socket *socket = (struct esp32_socket *)handle;
chuanga 0:43ff9e3bc244 219
chuanga 0:43ff9e3bc244 220 if (!socket) {
chuanga 0:43ff9e3bc244 221 return NSAPI_ERROR_NO_SOCKET;
chuanga 0:43ff9e3bc244 222 }
chuanga 0:43ff9e3bc244 223
chuanga 0:43ff9e3bc244 224 if (socket->connected && socket->addr != addr) {
chuanga 0:43ff9e3bc244 225 if (!_esp->close(socket->id, socket->accept_id)) {
chuanga 0:43ff9e3bc244 226 return NSAPI_ERROR_DEVICE_ERROR;
chuanga 0:43ff9e3bc244 227 }
chuanga 0:43ff9e3bc244 228 socket->connected = false;
chuanga 0:43ff9e3bc244 229 }
chuanga 0:43ff9e3bc244 230
chuanga 0:43ff9e3bc244 231 if (!socket->connected) {
chuanga 0:43ff9e3bc244 232 int err = socket_connect(socket, addr);
chuanga 0:43ff9e3bc244 233 if (err < 0) {
chuanga 0:43ff9e3bc244 234 return err;
chuanga 0:43ff9e3bc244 235 }
chuanga 0:43ff9e3bc244 236 socket->addr = addr;
chuanga 0:43ff9e3bc244 237 }
chuanga 0:43ff9e3bc244 238
chuanga 0:43ff9e3bc244 239 return socket_send(socket, data, size);
chuanga 0:43ff9e3bc244 240 }
chuanga 0:43ff9e3bc244 241
chuanga 0:43ff9e3bc244 242 int ESP32Stack::socket_recvfrom(void *handle, SocketAddress *addr, void *data, unsigned size)
chuanga 0:43ff9e3bc244 243 {
chuanga 0:43ff9e3bc244 244 struct esp32_socket *socket = (struct esp32_socket *)handle;
chuanga 0:43ff9e3bc244 245
chuanga 0:43ff9e3bc244 246 if (!socket) {
chuanga 0:43ff9e3bc244 247 return NSAPI_ERROR_NO_SOCKET;
chuanga 0:43ff9e3bc244 248 }
chuanga 0:43ff9e3bc244 249
chuanga 0:43ff9e3bc244 250 int ret = socket_recv(socket, data, size);
chuanga 0:43ff9e3bc244 251 if (ret >= 0 && addr) {
chuanga 0:43ff9e3bc244 252 *addr = socket->addr;
chuanga 0:43ff9e3bc244 253 }
chuanga 0:43ff9e3bc244 254
chuanga 0:43ff9e3bc244 255 return ret;
chuanga 0:43ff9e3bc244 256 }
chuanga 0:43ff9e3bc244 257
chuanga 0:43ff9e3bc244 258 void ESP32Stack::socket_attach(void *handle, void (*callback)(void *), void *data)
chuanga 0:43ff9e3bc244 259 {
chuanga 0:43ff9e3bc244 260 struct esp32_socket *socket = (struct esp32_socket *)handle;
chuanga 0:43ff9e3bc244 261
chuanga 0:43ff9e3bc244 262 if (!socket) {
chuanga 0:43ff9e3bc244 263 return;
chuanga 0:43ff9e3bc244 264 }
chuanga 0:43ff9e3bc244 265
chuanga 0:43ff9e3bc244 266 _esp->socket_attach(socket->id, callback, data);
chuanga 0:43ff9e3bc244 267 }
chuanga 0:43ff9e3bc244 268
chuanga 0:43ff9e3bc244 269 nsapi_error_t ESP32Stack::setsockopt(nsapi_socket_t handle, int level,
chuanga 0:43ff9e3bc244 270 int optname, const void *optval, unsigned optlen)
chuanga 0:43ff9e3bc244 271 {
chuanga 0:43ff9e3bc244 272 struct esp32_socket *socket = (struct esp32_socket *)handle;
chuanga 0:43ff9e3bc244 273
chuanga 0:43ff9e3bc244 274 if (!optlen) {
chuanga 0:43ff9e3bc244 275 return NSAPI_ERROR_PARAMETER;
chuanga 0:43ff9e3bc244 276 } else if (!socket) {
chuanga 0:43ff9e3bc244 277 return NSAPI_ERROR_NO_SOCKET;
chuanga 0:43ff9e3bc244 278 }
chuanga 0:43ff9e3bc244 279
chuanga 0:43ff9e3bc244 280 if (level == NSAPI_SOCKET && socket->proto == NSAPI_TCP) {
chuanga 0:43ff9e3bc244 281 switch (optname) {
chuanga 0:43ff9e3bc244 282 case NSAPI_KEEPALIVE: {
chuanga 0:43ff9e3bc244 283 if(socket->connected) {// ESP32 limitation, keepalive needs to be given before connecting
chuanga 0:43ff9e3bc244 284 return NSAPI_ERROR_UNSUPPORTED;
chuanga 0:43ff9e3bc244 285 }
chuanga 0:43ff9e3bc244 286
chuanga 0:43ff9e3bc244 287 if (optlen == sizeof(int)) {
chuanga 0:43ff9e3bc244 288 int secs = *(int *)optval;
chuanga 0:43ff9e3bc244 289 if (secs >= 0 && secs <= 7200) {
chuanga 0:43ff9e3bc244 290 socket->keepalive = secs;
chuanga 0:43ff9e3bc244 291 return NSAPI_ERROR_OK;
chuanga 0:43ff9e3bc244 292 }
chuanga 0:43ff9e3bc244 293 }
chuanga 0:43ff9e3bc244 294 return NSAPI_ERROR_PARAMETER;
chuanga 0:43ff9e3bc244 295 }
chuanga 0:43ff9e3bc244 296 }
chuanga 0:43ff9e3bc244 297 }
chuanga 0:43ff9e3bc244 298
chuanga 0:43ff9e3bc244 299 return NSAPI_ERROR_UNSUPPORTED;
chuanga 0:43ff9e3bc244 300 }
chuanga 0:43ff9e3bc244 301
chuanga 0:43ff9e3bc244 302 nsapi_error_t ESP32Stack::getsockopt(nsapi_socket_t handle, int level,
chuanga 0:43ff9e3bc244 303 int optname, void *optval, unsigned *optlen)
chuanga 0:43ff9e3bc244 304 {
chuanga 0:43ff9e3bc244 305 struct esp32_socket *socket = (struct esp32_socket *)handle;
chuanga 0:43ff9e3bc244 306
chuanga 0:43ff9e3bc244 307 if (!optval || !optlen) {
chuanga 0:43ff9e3bc244 308 return NSAPI_ERROR_PARAMETER;
chuanga 0:43ff9e3bc244 309 } else if (!socket) {
chuanga 0:43ff9e3bc244 310 return NSAPI_ERROR_NO_SOCKET;
chuanga 0:43ff9e3bc244 311 }
chuanga 0:43ff9e3bc244 312
chuanga 0:43ff9e3bc244 313 if (level == NSAPI_SOCKET && socket->proto == NSAPI_TCP) {
chuanga 0:43ff9e3bc244 314 switch (optname) {
chuanga 0:43ff9e3bc244 315 case NSAPI_KEEPALIVE: {
chuanga 0:43ff9e3bc244 316 if(*optlen > sizeof(int)) {
chuanga 0:43ff9e3bc244 317 *optlen = sizeof(int);
chuanga 0:43ff9e3bc244 318 }
chuanga 0:43ff9e3bc244 319 memcpy(optval, &(socket->keepalive), *optlen);
chuanga 0:43ff9e3bc244 320 return NSAPI_ERROR_OK;
chuanga 0:43ff9e3bc244 321 }
chuanga 0:43ff9e3bc244 322 }
chuanga 0:43ff9e3bc244 323 }
chuanga 0:43ff9e3bc244 324
chuanga 0:43ff9e3bc244 325 return NSAPI_ERROR_UNSUPPORTED;
chuanga 0:43ff9e3bc244 326 }
chuanga 0:43ff9e3bc244 327