Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: iot_water_monitor_v2
Revision 0:9fa9929d1a8c, committed 2017-12-12
- Comitter:
- DuyLionTran
- Date:
- Tue Dec 12 15:57:57 2017 +0000
- Commit message:
- version 1.6
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.gitignore Tue Dec 12 15:57:57 2017 +0000 @@ -0,0 +1,10 @@ +atmel-rf-driver/* +atmel-rf-driver +esp8266-driver/* +esp8266-driver +mcr20a-rf-driver/* +mcr20a-rf-driver +stm-spirit1-rf-driver +stm-spirit1-rf-driver/* +wifi-x-nucleo-idw01m1 +wifi-x-nucleo-idw01m1/*
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ESP8266.cpp Tue Dec 12 15:57:57 2017 +0000
@@ -0,0 +1,327 @@
+/* ESP8266 Example
+ * Copyright (c) 2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ESP8266.h"
+
+#define ESP8266_DEFAULT_BAUD_RATE 115200
+
+ESP8266::ESP8266(PinName tx, PinName rx, bool debug)
+ : _serial(tx, rx, ESP8266_DEFAULT_BAUD_RATE),
+ _parser(&_serial),
+ _packets(0),
+ _packets_end(&_packets)
+{
+ _serial.set_baud( ESP8266_DEFAULT_BAUD_RATE );
+ _parser.debug_on(debug);
+ _parser.set_delimiter("\r\n");
+}
+
+int ESP8266::get_firmware_version()
+{
+ _parser.send("AT+GMR");
+ int version;
+ if(_parser.recv("SDK version:%d", &version) && _parser.recv("OK")) {
+ return version;
+ } else {
+ // Older firmware versions do not prefix the version with "SDK version: "
+ return -1;
+ }
+
+}
+
+bool ESP8266::startup(int mode)
+{
+ //only 3 valid modes
+ if(mode < 1 || mode > 3) {
+ return false;
+ }
+
+ bool success = _parser.send("AT+CWMODE_CUR=%d", mode)
+ && _parser.recv("OK")
+ && _parser.send("AT+CIPMUX=1")
+ && _parser.recv("OK");
+
+ _parser.oob("+IPD", callback(this, &ESP8266::_packet_handler));
+
+ return success;
+}
+
+bool ESP8266::reset(void)
+{
+ for (int i = 0; i < 2; i++) {
+ if (_parser.send("AT+RST")
+ && _parser.recv("OK\r\nready")) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool ESP8266::dhcp(bool enabled, int mode)
+{
+ //only 3 valid modes
+ if(mode < 0 || mode > 2) {
+ return false;
+ }
+
+ return _parser.send("AT+CWDHCP_CUR=%d,%d", enabled?1:0, mode)
+ && _parser.recv("OK");
+}
+
+bool ESP8266::connect(const char *ap, const char *passPhrase)
+{
+ return _parser.send("AT+CWJAP_CUR=\"%s\",\"%s\"", ap, passPhrase)
+ && _parser.recv("OK");
+}
+
+bool ESP8266::disconnect(void)
+{
+ return _parser.send("AT+CWQAP") && _parser.recv("OK");
+}
+
+const char *ESP8266::getIPAddress(void)
+{
+ if (!(_parser.send("AT+CIFSR")
+ && _parser.recv("+CIFSR:STAIP,\"%15[^\"]\"", _ip_buffer)
+ && _parser.recv("OK"))) {
+ return 0;
+ }
+
+ return _ip_buffer;
+}
+
+const char *ESP8266::getMACAddress(void)
+{
+ if (!(_parser.send("AT+CIFSR")
+ && _parser.recv("+CIFSR:STAMAC,\"%17[^\"]\"", _mac_buffer)
+ && _parser.recv("OK"))) {
+ return 0;
+ }
+
+ return _mac_buffer;
+}
+
+const char *ESP8266::getGateway()
+{
+ if (!(_parser.send("AT+CIPSTA_CUR?")
+ && _parser.recv("+CIPSTA_CUR:gateway:\"%15[^\"]\"", _gateway_buffer)
+ && _parser.recv("OK"))) {
+ return 0;
+ }
+
+ return _gateway_buffer;
+}
+
+const char *ESP8266::getNetmask()
+{
+ if (!(_parser.send("AT+CIPSTA_CUR?")
+ && _parser.recv("+CIPSTA_CUR:netmask:\"%15[^\"]\"", _netmask_buffer)
+ && _parser.recv("OK"))) {
+ return 0;
+ }
+
+ return _netmask_buffer;
+}
+
+int8_t ESP8266::getRSSI()
+{
+ int8_t rssi;
+ char bssid[18];
+
+ if (!(_parser.send("AT+CWJAP_CUR?")
+ && _parser.recv("+CWJAP_CUR::\"%*[^\"]\",\"%17[^\"]\"", bssid)
+ && _parser.recv("OK"))) {
+ return 0;
+ }
+
+ if (!(_parser.send("AT+CWLAP=\"\",\"%s\",", bssid)
+ && _parser.recv("+CWLAP:(%*d,\"%*[^\"]\",%hhd,", &rssi)
+ && _parser.recv("OK"))) {
+ return 0;
+ }
+
+ return rssi;
+}
+
+bool ESP8266::isConnected(void)
+{
+ return getIPAddress() != 0;
+}
+
+int ESP8266::scan(WiFiAccessPoint *res, unsigned limit)
+{
+ unsigned cnt = 0;
+ nsapi_wifi_ap_t ap;
+
+ if (!_parser.send("AT+CWLAP")) {
+ return NSAPI_ERROR_DEVICE_ERROR;
+ }
+
+ while (recv_ap(&ap)) {
+ if (cnt < limit) {
+ res[cnt] = WiFiAccessPoint(ap);
+ }
+
+ cnt++;
+ if (limit != 0 && cnt >= limit) {
+ break;
+ }
+ }
+
+ return cnt;
+}
+
+bool ESP8266::open(const char *type, int id, const char* addr, int port)
+{
+ //IDs only 0-4
+ if(id > 4) {
+ return false;
+ }
+ return _parser.send("AT+CIPSTART=%d,\"%s\",\"%s\",%d", id, type, addr, port)
+ && _parser.recv("OK");
+}
+
+bool ESP8266::dns_lookup(const char* name, char* ip)
+{
+ return _parser.send("AT+CIPDOMAIN=\"%s\"", name) && _parser.recv("+CIPDOMAIN:%s%*[\r]%*[\n]", ip);
+}
+
+bool ESP8266::send(int id, const void *data, uint32_t amount)
+{
+ //May take a second try if device is busy
+ for (unsigned i = 0; i < 2; i++) {
+ if (_parser.send("AT+CIPSEND=%d,%d", id, amount)
+ && _parser.recv(">")
+ && _parser.write((char*)data, (int)amount) >= 0) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void ESP8266::_packet_handler()
+{
+ int id;
+ uint32_t amount;
+
+ // parse out the packet
+ if (!_parser.recv(",%d,%d:", &id, &amount)) {
+ return;
+ }
+
+ struct packet *packet = (struct packet*)malloc(
+ sizeof(struct packet) + amount);
+ if (!packet) {
+ return;
+ }
+
+ packet->id = id;
+ packet->len = amount;
+ packet->next = 0;
+
+ if (!(_parser.read((char*)(packet + 1), amount))) {
+ free(packet);
+ return;
+ }
+
+ // append to packet list
+ *_packets_end = packet;
+ _packets_end = &packet->next;
+}
+
+int32_t ESP8266::recv(int id, void *data, uint32_t amount)
+{
+ while (true) {
+ // check if any packets are ready for us
+ for (struct packet **p = &_packets; *p; p = &(*p)->next) {
+ if ((*p)->id == id) {
+ struct packet *q = *p;
+
+ if (q->len <= amount) { // Return and remove full packet
+ memcpy(data, q+1, q->len);
+
+ if (_packets_end == &(*p)->next) {
+ _packets_end = p;
+ }
+ *p = (*p)->next;
+
+ uint32_t len = q->len;
+ free(q);
+ return len;
+ } else { // return only partial packet
+ memcpy(data, q+1, amount);
+
+ q->len -= amount;
+ memmove(q+1, (uint8_t*)(q+1) + amount, q->len);
+
+ return amount;
+ }
+ }
+ }
+
+ // Check for inbound packets
+ if (!_parser.process_oob()) {
+ return -1;
+ }
+ }
+}
+
+bool ESP8266::close(int id)
+{
+ //May take a second try if device is busy
+ for (unsigned i = 0; i < 2; i++) {
+ if (_parser.send("AT+CIPCLOSE=%d", id)
+ && _parser.recv("OK")) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void ESP8266::setTimeout(uint32_t timeout_ms)
+{
+ _parser.set_timeout(timeout_ms);
+}
+
+bool ESP8266::readable()
+{
+ return _serial.FileHandle::readable();
+}
+
+bool ESP8266::writeable()
+{
+ return _serial.FileHandle::writable();
+}
+
+void ESP8266::attach(Callback<void()> func)
+{
+ _serial.sigio(func);
+}
+
+bool ESP8266::recv_ap(nsapi_wifi_ap_t *ap)
+{
+ int sec;
+ bool ret = _parser.recv("+CWLAP:(%d,\"%32[^\"]\",%hhd,\"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx\",%d", &sec, ap->ssid,
+ &ap->rssi, &ap->bssid[0], &ap->bssid[1], &ap->bssid[2], &ap->bssid[3], &ap->bssid[4],
+ &ap->bssid[5], &ap->channel);
+
+ ap->security = sec < 5 ? (nsapi_security_t)sec : NSAPI_SECURITY_UNKNOWN;
+
+ return ret;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ESP8266.h Tue Dec 12 15:57:57 2017 +0000
@@ -0,0 +1,228 @@
+/* ESP8266Interface Example
+ * Copyright (c) 2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ESP8266_H
+#define ESP8266_H
+
+#include "ATCmdParser.h"
+
+/** ESP8266Interface class.
+ This is an interface to a ESP8266 radio.
+ */
+class ESP8266
+{
+public:
+ ESP8266(PinName tx, PinName rx, bool debug=false);
+
+ /**
+ * Check firmware version of ESP8266
+ *
+ * @return integer firmware version or -1 if firmware query command gives outdated response
+ */
+ int get_firmware_version(void);
+
+ /**
+ * Startup the ESP8266
+ *
+ * @param mode mode of WIFI 1-client, 2-host, 3-both
+ * @return true only if ESP8266 was setup correctly
+ */
+ bool startup(int mode);
+
+ /**
+ * Reset ESP8266
+ *
+ * @return true only if ESP8266 resets successfully
+ */
+ bool reset(void);
+
+ /**
+ * Enable/Disable DHCP
+ *
+ * @param enabled DHCP enabled when true
+ * @param mode mode of DHCP 0-softAP, 1-station, 2-both
+ * @return true only if ESP8266 enables/disables DHCP successfully
+ */
+ bool dhcp(bool enabled, int mode);
+
+ /**
+ * Connect ESP8266 to AP
+ *
+ * @param ap the name of the AP
+ * @param passPhrase the password of AP
+ * @return true only if ESP8266 is connected successfully
+ */
+ bool connect(const char *ap, const char *passPhrase);
+
+ /**
+ * Disconnect ESP8266 from AP
+ *
+ * @return true only if ESP8266 is disconnected successfully
+ */
+ bool disconnect(void);
+
+ /**
+ * Get the IP address of ESP8266
+ *
+ * @return null-teriminated IP address or null if no IP address is assigned
+ */
+ const char *getIPAddress(void);
+
+ /**
+ * Get the MAC address of ESP8266
+ *
+ * @return null-terminated MAC address or null if no MAC address is assigned
+ */
+ const char *getMACAddress(void);
+
+ /** Get the local gateway
+ *
+ * @return Null-terminated representation of the local gateway
+ * or null if no network mask has been recieved
+ */
+ const char *getGateway();
+
+ /** Get the local network mask
+ *
+ * @return Null-terminated representation of the local network mask
+ * or null if no network mask has been recieved
+ */
+ const char *getNetmask();
+
+ /* Return RSSI for active connection
+ *
+ * @return Measured RSSI
+ */
+ int8_t getRSSI();
+
+ /**
+ * Check if ESP8266 is conenected
+ *
+ * @return true only if the chip has an IP address
+ */
+ bool isConnected(void);
+
+ /** Scan for available networks
+ *
+ * @param ap Pointer to allocated array to store discovered AP
+ * @param limit Size of allocated @a res array, or 0 to only count available AP
+ * @return Number of entries in @a res, or if @a count was 0 number of available networks, negative on error
+ * see @a nsapi_error
+ */
+ int scan(WiFiAccessPoint *res, unsigned limit);
+
+ /**Perform a dns query
+ *
+ * @param name Hostname to resolve
+ * @param ip Buffer to store IP address
+ * @return 0 true on success, false on failure
+ */
+ bool dns_lookup(const char *name, char *ip);
+
+ /**
+ * Open a socketed connection
+ *
+ * @param type the type of socket to open "UDP" or "TCP"
+ * @param id id to give the new socket, valid 0-4
+ * @param port port to open connection with
+ * @param addr the IP address of the destination
+ * @return true only if socket opened successfully
+ */
+ bool open(const char *type, int id, const char* addr, int port);
+
+ /**
+ * Sends data to an open socket
+ *
+ * @param id id of socket to send to
+ * @param data data to be sent
+ * @param amount amount of data to be sent - max 1024
+ * @return true only if data sent successfully
+ */
+ bool send(int id, const void *data, uint32_t amount);
+
+ /**
+ * Receives data from an open socket
+ *
+ * @param id id to receive from
+ * @param data placeholder for returned information
+ * @param amount number of bytes to be received
+ * @return the number of bytes received
+ */
+ int32_t recv(int id, void *data, uint32_t amount);
+
+ /**
+ * Closes a socket
+ *
+ * @param id id of socket to close, valid only 0-4
+ * @return true only if socket is closed successfully
+ */
+ bool close(int id);
+
+ /**
+ * Allows timeout to be changed between commands
+ *
+ * @param timeout_ms timeout of the connection
+ */
+ void setTimeout(uint32_t timeout_ms);
+
+ /**
+ * Checks if data is available
+ */
+ bool readable();
+
+ /**
+ * Checks if data can be written
+ */
+ bool writeable();
+
+ /**
+ * Attach a function to call whenever network state has changed
+ *
+ * @param func A pointer to a void function, or 0 to set as none
+ */
+ void attach(Callback<void()> func);
+
+ /**
+ * Attach a function to call whenever network state has changed
+ *
+ * @param obj pointer to the object to call the member function on
+ * @param method pointer to the member function to call
+ */
+ template <typename T, typename M>
+ void attach(T *obj, M method) {
+ attach(Callback<void()>(obj, method));
+ }
+
+private:
+ UARTSerial _serial;
+ ATCmdParser _parser;
+
+ struct packet {
+ struct packet *next;
+ int id;
+ uint32_t len;
+ // data follows
+ } *_packets, **_packets_end;
+ void _packet_handler();
+ bool recv_ap(nsapi_wifi_ap_t *ap);
+
+ char _ip_buffer[16];
+ char _gateway_buffer[16];
+ char _netmask_buffer[16];
+ char _mac_buffer[18];
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ESP8266Interface.cpp Tue Dec 12 15:57:57 2017 +0000
@@ -0,0 +1,309 @@
+/* ESP8266 implementation of NetworkInterfaceAPI
+ * Copyright (c) 2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string.h>
+#include "ESP8266Interface.h"
+#include "mbed_debug.h"
+
+// Various timeouts for different ESP8266 operations
+#ifndef ESP8266_CONNECT_TIMEOUT
+#define ESP8266_CONNECT_TIMEOUT 15000
+#endif
+#ifndef ESP8266_SEND_TIMEOUT
+#define ESP8266_SEND_TIMEOUT 500
+#endif
+#ifndef ESP8266_RECV_TIMEOUT
+#define ESP8266_RECV_TIMEOUT 500
+#endif
+#ifndef ESP8266_MISC_TIMEOUT
+#define ESP8266_MISC_TIMEOUT 500
+#endif
+
+// Firmware version
+#define ESP8266_VERSION 2
+
+// ESP8266Interface implementation
+ESP8266Interface::ESP8266Interface(PinName tx, PinName rx, bool debug)
+ : _esp(tx, rx, debug)
+{
+ memset(_ids, 0, sizeof(_ids));
+ memset(_cbs, 0, sizeof(_cbs));
+
+ _esp.attach(this, &ESP8266Interface::event);
+}
+
+int ESP8266Interface::connect(const char *ssid, const char *pass, nsapi_security_t security,
+ uint8_t channel)
+{
+ if (channel != 0) {
+ return NSAPI_ERROR_UNSUPPORTED;
+ }
+
+ set_credentials(ssid, pass, security);
+ return connect();
+}
+
+int ESP8266Interface::connect()
+{
+ _esp.setTimeout(ESP8266_CONNECT_TIMEOUT);
+
+ if (!_esp.reset()) {
+ return NSAPI_ERROR_DEVICE_ERROR;
+ }
+
+ _esp.setTimeout(ESP8266_MISC_TIMEOUT);
+
+ if (_esp.get_firmware_version() != ESP8266_VERSION) {
+ debug("ESP8266: ERROR: Firmware incompatible with this driver.\
+ \r\nUpdate to v%d - https://developer.mbed.org/teams/ESP8266/wiki/Firmware-Update\r\n",ESP8266_VERSION);
+ return NSAPI_ERROR_DEVICE_ERROR;
+ }
+
+ _esp.setTimeout(ESP8266_CONNECT_TIMEOUT);
+
+ if (!_esp.startup(3)) {
+ return NSAPI_ERROR_DEVICE_ERROR;
+ }
+
+ if (!_esp.dhcp(true, 1)) {
+ return NSAPI_ERROR_DHCP_FAILURE;
+ }
+
+ if (!_esp.connect(ap_ssid, ap_pass)) {
+ return NSAPI_ERROR_NO_CONNECTION;
+ }
+
+ if (!_esp.getIPAddress()) {
+ return NSAPI_ERROR_DHCP_FAILURE;
+ }
+
+ return NSAPI_ERROR_OK;
+}
+
+int ESP8266Interface::set_credentials(const char *ssid, const char *pass, nsapi_security_t security)
+{
+ memset(ap_ssid, 0, sizeof(ap_ssid));
+ strncpy(ap_ssid, ssid, sizeof(ap_ssid));
+
+ memset(ap_pass, 0, sizeof(ap_pass));
+ strncpy(ap_pass, pass, sizeof(ap_pass));
+
+ ap_sec = security;
+
+ return 0;
+}
+
+int ESP8266Interface::set_channel(uint8_t channel)
+{
+ return NSAPI_ERROR_UNSUPPORTED;
+}
+
+
+int ESP8266Interface::disconnect()
+{
+ _esp.setTimeout(ESP8266_MISC_TIMEOUT);
+
+ if (!_esp.disconnect()) {
+ return NSAPI_ERROR_DEVICE_ERROR;
+ }
+
+ return NSAPI_ERROR_OK;
+}
+
+const char *ESP8266Interface::get_ip_address()
+{
+ return _esp.getIPAddress();
+}
+
+const char *ESP8266Interface::get_mac_address()
+{
+ return _esp.getMACAddress();
+}
+
+const char *ESP8266Interface::get_gateway()
+{
+ return _esp.getGateway();
+}
+
+const char *ESP8266Interface::get_netmask()
+{
+ return _esp.getNetmask();
+}
+
+int8_t ESP8266Interface::get_rssi()
+{
+ return _esp.getRSSI();
+}
+
+int ESP8266Interface::scan(WiFiAccessPoint *res, unsigned count)
+{
+ return _esp.scan(res, count);
+}
+
+struct esp8266_socket {
+ int id;
+ nsapi_protocol_t proto;
+ bool connected;
+ SocketAddress addr;
+};
+
+int ESP8266Interface::socket_open(void **handle, nsapi_protocol_t proto)
+{
+ // Look for an unused socket
+ int id = -1;
+
+ for (int i = 0; i < ESP8266_SOCKET_COUNT; i++) {
+ if (!_ids[i]) {
+ id = i;
+ _ids[i] = true;
+ break;
+ }
+ }
+
+ if (id == -1) {
+ return NSAPI_ERROR_NO_SOCKET;
+ }
+
+ struct esp8266_socket *socket = new struct esp8266_socket;
+ if (!socket) {
+ return NSAPI_ERROR_NO_SOCKET;
+ }
+
+ socket->id = id;
+ socket->proto = proto;
+ socket->connected = false;
+ *handle = socket;
+ return 0;
+}
+
+int ESP8266Interface::socket_close(void *handle)
+{
+ struct esp8266_socket *socket = (struct esp8266_socket *)handle;
+ int err = 0;
+ _esp.setTimeout(ESP8266_MISC_TIMEOUT);
+
+ if (socket->connected && !_esp.close(socket->id)) {
+ err = NSAPI_ERROR_DEVICE_ERROR;
+ }
+
+ socket->connected = false;
+ _ids[socket->id] = false;
+ delete socket;
+ return err;
+}
+
+int ESP8266Interface::socket_bind(void *handle, const SocketAddress &address)
+{
+ return NSAPI_ERROR_UNSUPPORTED;
+}
+
+int ESP8266Interface::socket_listen(void *handle, int backlog)
+{
+ return NSAPI_ERROR_UNSUPPORTED;
+}
+
+int ESP8266Interface::socket_connect(void *handle, const SocketAddress &addr)
+{
+ struct esp8266_socket *socket = (struct esp8266_socket *)handle;
+ _esp.setTimeout(ESP8266_MISC_TIMEOUT);
+
+ const char *proto = (socket->proto == NSAPI_UDP) ? "UDP" : "TCP";
+ if (!_esp.open(proto, socket->id, addr.get_ip_address(), addr.get_port())) {
+ return NSAPI_ERROR_DEVICE_ERROR;
+ }
+
+ socket->connected = true;
+ return 0;
+}
+
+int ESP8266Interface::socket_accept(void *server, void **socket, SocketAddress *addr)
+{
+ return NSAPI_ERROR_UNSUPPORTED;
+}
+
+int ESP8266Interface::socket_send(void *handle, const void *data, unsigned size)
+{
+ struct esp8266_socket *socket = (struct esp8266_socket *)handle;
+ _esp.setTimeout(ESP8266_SEND_TIMEOUT);
+
+ if (!_esp.send(socket->id, data, size)) {
+ return NSAPI_ERROR_DEVICE_ERROR;
+ }
+
+ return size;
+}
+
+int ESP8266Interface::socket_recv(void *handle, void *data, unsigned size)
+{
+ struct esp8266_socket *socket = (struct esp8266_socket *)handle;
+ _esp.setTimeout(ESP8266_RECV_TIMEOUT);
+
+ int32_t recv = _esp.recv(socket->id, data, size);
+ if (recv < 0) {
+ return NSAPI_ERROR_WOULD_BLOCK;
+ }
+
+ return recv;
+}
+
+int ESP8266Interface::socket_sendto(void *handle, const SocketAddress &addr, const void *data, unsigned size)
+{
+ struct esp8266_socket *socket = (struct esp8266_socket *)handle;
+
+ if (socket->connected && socket->addr != addr) {
+ _esp.setTimeout(ESP8266_MISC_TIMEOUT);
+ if (!_esp.close(socket->id)) {
+ return NSAPI_ERROR_DEVICE_ERROR;
+ }
+ socket->connected = false;
+ }
+
+ if (!socket->connected) {
+ int err = socket_connect(socket, addr);
+ if (err < 0) {
+ return err;
+ }
+ socket->addr = addr;
+ }
+
+ return socket_send(socket, data, size);
+}
+
+int ESP8266Interface::socket_recvfrom(void *handle, SocketAddress *addr, void *data, unsigned size)
+{
+ struct esp8266_socket *socket = (struct esp8266_socket *)handle;
+ int ret = socket_recv(socket, data, size);
+ if (ret >= 0 && addr) {
+ *addr = socket->addr;
+ }
+
+ return ret;
+}
+
+void ESP8266Interface::socket_attach(void *handle, void (*callback)(void *), void *data)
+{
+ struct esp8266_socket *socket = (struct esp8266_socket *)handle;
+ _cbs[socket->id].callback = callback;
+ _cbs[socket->id].data = data;
+}
+
+void ESP8266Interface::event() {
+ for (int i = 0; i < ESP8266_SOCKET_COUNT; i++) {
+ if (_cbs[i].callback) {
+ _cbs[i].callback(_cbs[i].data);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ESP8266Interface.h Tue Dec 12 15:57:57 2017 +0000
@@ -0,0 +1,275 @@
+/* ESP8266 implementation of NetworkInterfaceAPI
+ * Copyright (c) 2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ESP8266_INTERFACE_H
+#define ESP8266_INTERFACE_H
+
+#include "mbed.h"
+#include "ESP8266.h"
+
+
+#define ESP8266_SOCKET_COUNT 5
+
+/** ESP8266Interface class
+ * Implementation of the NetworkStack for the ESP8266
+ */
+class ESP8266Interface : public NetworkStack, public WiFiInterface
+{
+public:
+ /** ESP8266Interface lifetime
+ * @param tx TX pin
+ * @param rx RX pin
+ * @param debug Enable debugging
+ */
+ ESP8266Interface(PinName tx, PinName rx, bool debug = false);
+
+ /** Start the interface
+ *
+ * Attempts to connect to a WiFi network. Requires ssid and passphrase to be set.
+ * If passphrase is invalid, NSAPI_ERROR_AUTH_ERROR is returned.
+ *
+ * @return 0 on success, negative error code on failure
+ */
+ virtual int connect();
+
+ /** Start the interface
+ *
+ * Attempts to connect to a WiFi network.
+ *
+ * @param ssid Name of the network to connect to
+ * @param pass Security passphrase to connect to the network
+ * @param security Type of encryption for connection (Default: NSAPI_SECURITY_NONE)
+ * @param channel This parameter is not supported, setting it to anything else than 0 will result in NSAPI_ERROR_UNSUPPORTED
+ * @return 0 on success, or error code on failure
+ */
+ virtual int connect(const char *ssid, const char *pass, nsapi_security_t security = NSAPI_SECURITY_NONE,
+ uint8_t channel = 0);
+
+ /** Set the WiFi network credentials
+ *
+ * @param ssid Name of the network to connect to
+ * @param pass Security passphrase to connect to the network
+ * @param security Type of encryption for connection
+ * (defaults to NSAPI_SECURITY_NONE)
+ * @return 0 on success, or error code on failure
+ */
+ virtual int set_credentials(const char *ssid, const char *pass, nsapi_security_t security = NSAPI_SECURITY_NONE);
+
+ /** Set the WiFi network channel - NOT SUPPORTED
+ *
+ * This function is not supported and will return NSAPI_ERROR_UNSUPPORTED
+ *
+ * @param channel Channel on which the connection is to be made, or 0 for any (Default: 0)
+ * @return Not supported, returns NSAPI_ERROR_UNSUPPORTED
+ */
+ virtual int set_channel(uint8_t channel);
+
+ /** Stop the interface
+ * @return 0 on success, negative on failure
+ */
+ virtual int disconnect();
+
+ /** Get the internally stored IP address
+ * @return IP address of the interface or null if not yet connected
+ */
+ virtual const char *get_ip_address();
+
+ /** Get the internally stored MAC address
+ * @return MAC address of the interface
+ */
+ virtual const char *get_mac_address();
+
+ /** Get the local gateway
+ *
+ * @return Null-terminated representation of the local gateway
+ * or null if no network mask has been recieved
+ */
+ virtual const char *get_gateway();
+
+ /** Get the local network mask
+ *
+ * @return Null-terminated representation of the local network mask
+ * or null if no network mask has been recieved
+ */
+ virtual const char *get_netmask();
+
+ /** Gets the current radio signal strength for active connection
+ *
+ * @return Connection strength in dBm (negative value)
+ */
+ virtual int8_t get_rssi();
+
+ /** Scan for available networks
+ *
+ * This function will block.
+ *
+ * @param ap Pointer to allocated array to store discovered AP
+ * @param count Size of allocated @a res array, or 0 to only count available AP
+ * @param timeout Timeout in milliseconds; 0 for no timeout (Default: 0)
+ * @return Number of entries in @a, or if @a count was 0 number of available networks, negative on error
+ * see @a nsapi_error
+ */
+ virtual int scan(WiFiAccessPoint *res, unsigned count);
+
+ /** Translates a hostname to an IP address with specific version
+ *
+ * The hostname may be either a domain name or an IP address. If the
+ * hostname is an IP address, no network transactions will be performed.
+ *
+ * If no stack-specific DNS resolution is provided, the hostname
+ * will be resolve using a UDP socket on the stack.
+ *
+ * @param address Destination for the host SocketAddress
+ * @param host Hostname to resolve
+ * @param version IP version of address to resolve, NSAPI_UNSPEC indicates
+ * version is chosen by the stack (defaults to NSAPI_UNSPEC)
+ * @return 0 on success, negative error code on failure
+ */
+ using NetworkInterface::gethostbyname;
+
+ /** Add a domain name server to list of servers to query
+ *
+ * @param addr Destination for the host address
+ * @return 0 on success, negative error code on failure
+ */
+ using NetworkInterface::add_dns_server;
+
+protected:
+ /** Open a socket
+ * @param handle Handle in which to store new socket
+ * @param proto Type of socket to open, NSAPI_TCP or NSAPI_UDP
+ * @return 0 on success, negative on failure
+ */
+ virtual int socket_open(void **handle, nsapi_protocol_t proto);
+
+ /** Close the socket
+ * @param handle Socket handle
+ * @return 0 on success, negative on failure
+ * @note On failure, any memory associated with the socket must still
+ * be cleaned up
+ */
+ virtual int socket_close(void *handle);
+
+ /** Bind a server socket to a specific port
+ * @param handle Socket handle
+ * @param address Local address to listen for incoming connections on
+ * @return 0 on success, negative on failure.
+ */
+ virtual int socket_bind(void *handle, const SocketAddress &address);
+
+ /** Start listening for incoming connections
+ * @param handle Socket handle
+ * @param backlog Number of pending connections that can be queued up at any
+ * one time [Default: 1]
+ * @return 0 on success, negative on failure
+ */
+ virtual int socket_listen(void *handle, int backlog);
+
+ /** Connects this TCP socket to the server
+ * @param handle Socket handle
+ * @param address SocketAddress to connect to
+ * @return 0 on success, negative on failure
+ */
+ virtual int socket_connect(void *handle, const SocketAddress &address);
+
+ /** Accept a new connection.
+ * @param handle Handle in which to store new socket
+ * @param server Socket handle to server to accept from
+ * @return 0 on success, negative on failure
+ * @note This call is not-blocking, if this call would block, must
+ * immediately return NSAPI_ERROR_WOULD_WAIT
+ */
+ virtual int socket_accept(void *handle, void **socket, SocketAddress *address);
+
+ /** Send data to the remote host
+ * @param handle Socket handle
+ * @param data The buffer to send to the host
+ * @param size The length of the buffer to send
+ * @return Number of written bytes on success, negative on failure
+ * @note This call is not-blocking, if this call would block, must
+ * immediately return NSAPI_ERROR_WOULD_WAIT
+ */
+ virtual int socket_send(void *handle, const void *data, unsigned size);
+
+ /** Receive data from the remote host
+ * @param handle Socket handle
+ * @param data The buffer in which to store the data received from the host
+ * @param size The maximum length of the buffer
+ * @return Number of received bytes on success, negative on failure
+ * @note This call is not-blocking, if this call would block, must
+ * immediately return NSAPI_ERROR_WOULD_WAIT
+ */
+ virtual int socket_recv(void *handle, void *data, unsigned size);
+
+ /** Send a packet to a remote endpoint
+ * @param handle Socket handle
+ * @param address The remote SocketAddress
+ * @param data The packet to be sent
+ * @param size The length of the packet to be sent
+ * @return The number of written bytes on success, negative on failure
+ * @note This call is not-blocking, if this call would block, must
+ * immediately return NSAPI_ERROR_WOULD_WAIT
+ */
+ virtual int socket_sendto(void *handle, const SocketAddress &address, const void *data, unsigned size);
+
+ /** Receive a packet from a remote endpoint
+ * @param handle Socket handle
+ * @param address Destination for the remote SocketAddress or null
+ * @param buffer The buffer for storing the incoming packet data
+ * If a packet is too long to fit in the supplied buffer,
+ * excess bytes are discarded
+ * @param size The length of the buffer
+ * @return The number of received bytes on success, negative on failure
+ * @note This call is not-blocking, if this call would block, must
+ * immediately return NSAPI_ERROR_WOULD_WAIT
+ */
+ virtual int socket_recvfrom(void *handle, SocketAddress *address, void *buffer, unsigned size);
+
+ /** Register a callback on state change of the socket
+ * @param handle Socket handle
+ * @param callback Function to call on state change
+ * @param data Argument to pass to callback
+ * @note Callback may be called in an interrupt context.
+ */
+ virtual void socket_attach(void *handle, void (*callback)(void *), void *data);
+
+ /** Provide access to the NetworkStack object
+ *
+ * @return The underlying NetworkStack object
+ */
+ virtual NetworkStack *get_stack()
+ {
+ return this;
+ }
+
+private:
+ ESP8266 _esp;
+ bool _ids[ESP8266_SOCKET_COUNT];
+
+ char ap_ssid[33]; /* 32 is what 802.11 defines as longest possible name; +1 for the \0 */
+ nsapi_security_t ap_sec;
+ uint8_t ap_ch;
+ char ap_pass[64]; /* The longest allowed passphrase */
+
+ void event();
+
+ struct {
+ void (*callback)(void *);
+ void *data;
+ } _cbs[ESP8266_SOCKET_COUNT];
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/README.md Tue Dec 12 15:57:57 2017 +0000
@@ -0,0 +1,188 @@
+# Easy Connect - Easily add all supported connectivity methods to your mbed OS project
+
+You may want to give the users of your application the possibility to switch between connectivity methods. The `NetworkInterface` API makes this easy, but you still need a mechanism for the user to chooce the method, and perhaps throw in some `#define`'s. Easy Connect handles all of this for you. Just declare the desired connectivity method in your `mbed_app.json` file and call `easy_connect()` from your application.
+
+## Specifying the connectivity method
+
+Add the following to your `mbed_app.json` file:
+
+```json
+{
+ "config": {
+ "network-interface":{
+ "help": "options are ETHERNET, WIFI_ESP8266, WIFI_IDW0XX1, WIFI_ODIN, WIFI_RTW, MESH_LOWPAN_ND, MESH_THREAD, CELLULAR_ONBOARD",
+ "value": "ETHERNET"
+ }
+ },
+ "target_overrides": {
+ "*": {
+ "target.features_add": ["NANOSTACK", "LOWPAN_ROUTER", "COMMON_PAL"],
+ "mbed-mesh-api.6lowpan-nd-channel-page": 0,
+ "mbed-mesh-api.6lowpan-nd-channel": 12
+ }
+ }
+}
+```
+
+If you select `ETHERNET` with `UBLOX_ODIN_EVK_W2` you must add this to your `target-overrides` section in `mbed_app.json`:
+
+```json
+ "UBLOX_EVK_ODIN_W2": {
+ "target.device_has_remove": ["EMAC"]
+ }
+```
+
+If you select `WIFI_ESP8266`, `WIFI_IDW0XX1`, `WIFI_ODIN` or `WIFI_RTW`, you also need to add the WiFi SSID and password:
+
+```json
+ "config": {
+ "network-interface":{
+ "help": "options are ETHERNET, WIFI_ESP8266, WIFI_IDW0XX1, WIFI_ODIN, WIFI_RTW, MESH_LOWPAN_ND, MESH_THREAD, CELLULAR_ONBOARD",
+ "value": "WIFI_ESP8266"
+ },
+ "esp8266-tx": {
+ "help": "Pin used as TX (connects to ESP8266 RX)",
+ "value": "PTD3"
+ },
+ "esp8266-rx": {
+ "help": "Pin used as RX (connects to ESP8266 TX)",
+ "value": "PTD2"
+ },
+ "esp8266-debug": {
+ "value": true
+ },
+ "wifi-ssid": {
+ "value": "\"SSID\""
+ },
+ "wifi-password": {
+ "value": "\"Password\""
+ }
+ }
+```
+
+If you use `MESH_LOWPAN_ND` or `MESH_THREAD` you need to specify your radio module:
+
+```json
+ "config": {
+ "network-interface":{
+ "help": "options are ETHERNET, WIFI_ESP8266, WIFI_IDW0XX1, WIFI_ODIN, WIFI_RTW, MESH_LOWPAN_ND, MESH_THREAD, CELLULAR_ONBOARD",
+ "value": "MESH_LOWPAN_ND"
+ },
+ "mesh_radio_type": {
+ "help": "options are ATMEL, MCR20, SPIRIT1, EFR32",
+ "value": "ATMEL"
+ }
+ }
+```
+
+If you use `CELLULAR_ONBOARD` (for which user documentation can be found [here](https://docs.mbed.com/docs/mbed-os-api-reference/en/latest/APIs/communication/cellular/)) you must specify the following:
+
+```json
+ "target_overrides": {
+ "*": {
+ "ppp-cell-iface.apn-lookup": true
+ }
+ }
+```
+...and you may also need to specify one or more of the following:
+
+```json
+ "config": {
+ "cellular-apn": {
+ "help": "Please provide the APN string for your SIM if it is not already included in APN_db.h.",
+ "value": "\"my_sims_apn\""
+ },
+ "cellular-username": {
+ "help": "May or may not be required for your APN, please consult your SIM provider.",
+ "value": "\"my_sim_apns_username\""
+ },
+ "cellular-password": {
+ "help": "May or may not be required for your APN, please consult your SIM provider.",
+ "value": "\"my_sim_apns_password\""
+ },
+ "cellular-sim-pin": {
+ "help": "Please provide the PIN for your SIM (as a four digit string) if your SIM is normally locked",
+ "value": "\"1234\""
+ }
+ }
+```
+
+None of the optional settings need to be specified for the `UBLOX_C030_U201` cellular target, for which the APN settings are in `APN_db.h`.
+
+## Using Easy Connect from your application
+
+Easy Connect has just one function that returns either a `NetworkInterface`-pointer or `NULL`:
+
+```cpp
+#include "easy-connect.h"
+
+int main(int, char**) {
+ NetworkInterface* network = easy_connect(true); /* has 1 argument, enable_logging (pass in true to log to serial port) */
+ if (!network) {
+ printf("Connecting to the network failed... See serial output.\r\n");
+ return 1;
+ }
+
+ // Rest of your program
+}
+```
+
+## Configuration examples
+
+There are many things that you have to modify for all of the combinations. Examples for configurations are available for example in the [mbed-os-example-client](https://github.com/ARMmbed/mbed-os-example-client/tree/master/configs) repository.
+
+## Compilation error NanostackRfPhyAtmel.cpp
+
+If you encounter a compilation error such as below, you need to add an `.mbedignore` file that tells the mbed compiler to skip compiling the files that require Nanostack. By default, the mbed compiler compiles every single file from all folders.
+
+```
+Scan: env
+Compile [ 0.2%]: NanostackRfPhyAtmel.cpp
+[Fatal Error] NanostackRfPhyAtmel.cpp@18,44: nanostack/platform/arm_hal_phy.h: No such file or directory
+[ERROR] ./easy-connect/atmel-rf-driver/source/NanostackRfPhyAtmel.cpp:18:44: fatal error: nanostack/platform/arm_hal_phy.h: No such file or directory
+ #include "nanostack/platform/arm_hal_phy.h"
+ ^
+compilation terminated.
+
+```
+
+An example of a suitable `.mbedignore` file is available in the [mbed-os-example-client](https://github.com/ARMmbed/mbed-os-example-client/tree/master/configs) repository.
+
+## Linking error with UBLOX_EVK_ODIN_W2
+
+If you get a linking error such as below, you are compiling the `WIFI_ODIN` with the `EMAC override` section in `mbed_app.json`. Remove the `EMAC override` from your `mbed_app.json`.
+
+```
+Link: tls-client
+./mbed-os/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/sdk/TOOLCHAIN_GCC_ARM/libublox-odin-w2-driver.a(OdinWiFiInterface.o): In function `OdinWiFiInterface::handle_wlan_status_started(wlan_status_started_s*)':
+OdinWiFiInterface.cpp:(.text._ZN17OdinWiFiInterface26handle_wlan_status_startedEP21wlan_status_started_s+0x46): undefined reference to `wifi_emac_get_interface()'
+OdinWiFiInterface.cpp:(.text._ZN17OdinWiFiInterface26handle_wlan_status_startedEP21wlan_status_started_s+0x4c): undefined reference to `wifi_emac_init_mem()'
+collect2: error: ld returned 1 exit status
+[ERROR] ./mbed-os/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/sdk/TOOLCHAIN_GCC_ARM/libublox-odin-w2-driver.a(OdinWiFiInterface.o): In function `OdinWiFiInterface::handle_wlan_status_started(wlan_status_started_s*)':
+OdinWiFiInterface.cpp:(.text._ZN17OdinWiFiInterface26handle_wlan_status_startedEP21wlan_status_started_s+0x46): undefined reference to `wifi_emac_get_interface()'
+OdinWiFiInterface.cpp:(.text._ZN17OdinWiFiInterface26handle_wlan_status_startedEP21wlan_status_started_s+0x4c): undefined reference to `wifi_emac_init_mem()'
+collect2: error: ld returned 1 exit status
+
+[mbed] ERROR: "/usr/bin/python" returned error code 1.
+```
+
+## Network errors
+
+If Easy Connect cannot connect to the network, it returns a network error with an error code. To see what the error code means, see the [mbed OS Communication API](https://os.mbed.com/docs/latest/reference/network-socket.html).
+
+## CR/LF in serial output
+
+If you want to avoid using `\r\n` in your printouts and just use normal C style `\n` instead, please specify these to your `mbed_app.json`:
+
+```json
+ "target_overrides": {
+ "*": {
+ "platform.stdio-baud-rate": 115200,
+ "platform.stdio-convert-newlines": true
+ }
+ }
+```
+
+## Extra defines
+
+If you'd like to use Easy Connect with mbed Client then you're in luck. Easy Connect automatically defines the `MBED_SERVER_ADDRESS` macro depending on your connectivity method (either IPv4 or IPv6 address). Use this address to connect to the right instance of mbed Device Connector.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easy-connect.h Tue Dec 12 15:57:57 2017 +0000
@@ -0,0 +1,223 @@
+#ifndef __EASY_CONNECT_H__
+#define __EASY_CONNECT_H__
+
+#include "mbed.h"
+
+#define ETHERNET 1
+#define WIFI_ESP8266 2
+#define MESH_LOWPAN_ND 3
+#define MESH_THREAD 4
+#define WIFI_ODIN 5
+#define WIFI_RTW 6
+#define CELLULAR_ONBOARD 7
+#define WIFI_IDW0XX1 8
+
+#if MBED_CONF_APP_NETWORK_INTERFACE == WIFI_ESP8266
+#include "ESP8266Interface.h"
+
+#ifdef MBED_CONF_APP_ESP8266_DEBUG
+ESP8266Interface wifi(MBED_CONF_APP_ESP8266_TX, MBED_CONF_APP_ESP8266_RX, MBED_CONF_APP_ESP8266_DEBUG);
+#else
+ESP8266Interface wifi(MBED_CONF_APP_ESP8266_TX, MBED_CONF_APP_ESP8266_RX);
+#endif
+
+#elif MBED_CONF_APP_NETWORK_INTERFACE == WIFI_ODIN
+#include "OdinWiFiInterface.h"
+
+OdinWiFiInterface wifi;
+#elif MBED_CONF_APP_NETWORK_INTERFACE == WIFI_RTW
+#include "RTWInterface.h"
+RTWInterface wifi;
+#elif MBED_CONF_APP_NETWORK_INTERFACE == WIFI_IDW0XX1
+#include "SpwfSAInterface.h"
+SpwfSAInterface wifi(MBED_CONF_APP_WIFI_TX, MBED_CONF_APP_WIFI_RX);
+#elif MBED_CONF_APP_NETWORK_INTERFACE == ETHERNET
+#include "EthernetInterface.h"
+EthernetInterface eth;
+#elif MBED_CONF_APP_NETWORK_INTERFACE == MESH_LOWPAN_ND
+#define MESH
+#include "NanostackInterface.h"
+LoWPANNDInterface mesh;
+#elif MBED_CONF_APP_NETWORK_INTERFACE == MESH_THREAD
+#define MESH
+#include "NanostackInterface.h"
+ThreadInterface mesh;
+#elif MBED_CONF_APP_NETWORK_INTERFACE == CELLULAR_ONBOARD
+#include "OnboardCellularInterface.h"
+OnboardCellularInterface cellular;
+#else
+#error "No connectivity method chosen. Please add 'config.network-interfaces.value' to your mbed_app.json (see README.md for more information)."
+#endif
+
+#if defined(MESH)
+
+// Define macros for radio type
+#define ATMEL 1
+#define MCR20 2
+#define SPIRIT1 3
+#define EFR32 4
+
+#if MBED_CONF_APP_MESH_RADIO_TYPE == ATMEL
+#include "NanostackRfPhyAtmel.h"
+NanostackRfPhyAtmel rf_phy(ATMEL_SPI_MOSI, ATMEL_SPI_MISO, ATMEL_SPI_SCLK, ATMEL_SPI_CS,
+ ATMEL_SPI_RST, ATMEL_SPI_SLP, ATMEL_SPI_IRQ, ATMEL_I2C_SDA, ATMEL_I2C_SCL);
+#elif MBED_CONF_APP_MESH_RADIO_TYPE == MCR20
+#include "NanostackRfPhyMcr20a.h"
+NanostackRfPhyMcr20a rf_phy(MCR20A_SPI_MOSI, MCR20A_SPI_MISO, MCR20A_SPI_SCLK, MCR20A_SPI_CS, MCR20A_SPI_RST, MCR20A_SPI_IRQ);
+#elif MBED_CONF_APP_MESH_RADIO_TYPE == SPIRIT1
+#include "NanostackRfPhySpirit1.h"
+NanostackRfPhySpirit1 rf_phy(SPIRIT1_SPI_MOSI, SPIRIT1_SPI_MISO, SPIRIT1_SPI_SCLK,
+ SPIRIT1_DEV_IRQ, SPIRIT1_DEV_CS, SPIRIT1_DEV_SDN, SPIRIT1_BRD_LED);
+#elif MBED_CONF_APP_MESH_RADIO_TYPE == EFR32
+#include "NanostackRfPhyEfr32.h"
+NanostackRfPhyEfr32 rf_phy;
+#endif //MBED_CONF_APP_RADIO_TYPE
+#endif //MESH
+
+#ifndef MESH
+// This is address to mbed Device Connector
+#define MBED_SERVER_ADDRESS "coap://api.connector.mbed.com:5684"
+#else
+// This is address to mbed Device Connector
+#define MBED_SERVER_ADDRESS "coaps://[2607:f0d0:2601:52::20]:5684"
+#endif
+
+#ifdef MBED_CONF_APP_ESP8266_SSID
+#define MBED_CONF_APP_WIFI_SSID MBED_CONF_APP_ESP8266_SSID
+#endif
+
+#ifdef MBED_CONF_APP_ESP8266_PASSWORD
+#define MBED_CONF_APP_WIFI_PASSWORD MBED_CONF_APP_ESP8266_PASSWORD
+#endif
+
+/* \brief print_MAC - print_MAC - helper function to print out MAC address
+ * in: network_interface - pointer to network i/f
+ * bool log-messages print out logs or not
+ * MAC address is print, if it can be acquired & log_messages is true.
+ *
+ */
+void print_MAC(NetworkInterface* network_interface, bool log_messages) {
+#if MBED_CONF_APP_NETWORK_INTERFACE != CELLULAR_ONBOARD
+ const char *mac_addr = network_interface->get_mac_address();
+ if (mac_addr == NULL) {
+ if (log_messages) {
+ printf("[EasyConnect] ERROR - No MAC address\n");
+ }
+ return;
+ }
+ if (log_messages) {
+ printf("[EasyConnect] MAC address %s\n", mac_addr);
+ }
+#endif
+}
+
+
+/* \brief easy_connect - easy_connect function to connect the pre-defined network bearer,
+ * config done via mbed_app.json (see README.md for details).
+ * IN: bool log_messages print out diagnostics or not.
+ *
+ */
+NetworkInterface* easy_connect(bool log_messages = false) {
+ NetworkInterface* network_interface = 0;
+ int connect_success = -1;
+ /// This should be removed once mbedOS supports proper dual-stack
+#if defined (MESH) || (MBED_CONF_LWIP_IPV6_ENABLED==true)
+ printf("[EasyConnect] IPv6 mode\n");
+#else
+ printf("[EasyConnect] IPv4 mode\n");
+#endif
+
+#if MBED_CONF_APP_NETWORK_INTERFACE == WIFI_ESP8266
+ if (log_messages) {
+ printf("[EasyConnect] Using WiFi (ESP8266) \n");
+ printf("[EasyConnect] Connecting to WiFi %s\n", MBED_CONF_APP_WIFI_SSID);
+ }
+ network_interface = &wifi;
+ connect_success = wifi.connect(MBED_CONF_APP_WIFI_SSID, MBED_CONF_APP_WIFI_PASSWORD, NSAPI_SECURITY_WPA_WPA2);
+#elif MBED_CONF_APP_NETWORK_INTERFACE == WIFI_ODIN
+ if (log_messages) {
+ printf("[EasyConnect] Using WiFi (ODIN) \n");
+ printf("[EasyConnect] Connecting to WiFi %s\n", MBED_CONF_APP_WIFI_SSID);
+ }
+ network_interface = &wifi;
+ connect_success = wifi.connect(MBED_CONF_APP_WIFI_SSID, MBED_CONF_APP_WIFI_PASSWORD, NSAPI_SECURITY_WPA_WPA2);
+#elif MBED_CONF_APP_NETWORK_INTERFACE == WIFI_RTW
+ if (log_messages) {
+ printf("[EasyConnect] Using WiFi (RTW)\n");
+ printf("[EasyConnect] Connecting to WiFi %s\n", MBED_CONF_APP_WIFI_SSID);
+ }
+ network_interface = &wifi;
+ connect_success = wifi.connect(MBED_CONF_APP_WIFI_SSID, MBED_CONF_APP_WIFI_PASSWORD, NSAPI_SECURITY_WPA_WPA2);
+#elif MBED_CONF_APP_NETWORK_INTERFACE == WIFI_IDW0XX1
+ if (log_messages) {
+ printf("[EasyConnect] Using WiFi (X-NUCLEO-IDW0XX1)\n");
+ printf("[EasyConnect] Connecting to WiFi %s\n", MBED_CONF_APP_WIFI_SSID);
+ }
+ network_interface = &wifi;
+ connect_success = wifi.connect(MBED_CONF_APP_WIFI_SSID, MBED_CONF_APP_WIFI_PASSWORD, NSAPI_SECURITY_WPA_WPA2);
+#elif MBED_CONF_APP_NETWORK_INTERFACE == CELLULAR_ONBOARD
+# ifdef MBED_CONF_APP_CELLULAR_SIM_PIN
+ cellular.set_sim_pin(MBED_CONF_APP_CELLULAR_SIM_PIN);
+# endif
+# ifdef MBED_CONF_APP_CELLULAR_APN
+# ifndef MBED_CONF_APP_CELLULAR_USERNAME
+# define MBED_CONF_APP_CELLULAR_USERNAME 0
+# endif
+# ifndef MBED_CONF_APP_CELLULAR_PASSWORD
+# define MBED_CONF_APP_CELLULAR_PASSWORD 0
+# endif
+ cellular.set_credentials(MBED_CONF_APP_CELLULAR_APN, MBED_CONF_APP_CELLULAR_USERNAME, MBED_CONF_APP_CELLULAR_PASSWORD);
+ if (log_messages) {
+ printf("[EasyConnect] Connecting using Cellular interface and APN %s\n", MBED_CONF_APP_CELLULAR_APN);
+ }
+# else
+ if (log_messages) {
+ printf("[EasyConnect] Connecting using Cellular interface and default APN\n");
+ }
+# endif
+ connect_success = cellular.connect();
+ network_interface = &cellular;
+#elif MBED_CONF_APP_NETWORK_INTERFACE == ETHERNET
+ if (log_messages) {
+ printf("[EasyConnect] Using Ethernet\n");
+ }
+ network_interface = ð
+ connect_success = eth.connect();
+#endif
+
+#ifdef MESH
+ if (log_messages) {
+ printf("[EasyConnect] Using Mesh\n");
+ printf("[EasyConnect] Connecting to Mesh..\n");
+ }
+ network_interface = &mesh;
+ mesh.initialize(&rf_phy);
+ connect_success = mesh.connect();
+#endif
+ if(connect_success == 0) {
+ if (log_messages) {
+ printf("[EasyConnect] Connected to Network successfully\n");
+ print_MAC(network_interface, log_messages);
+ }
+ } else {
+ if (log_messages) {
+ print_MAC(network_interface, log_messages);
+ printf("[EasyConnect] Connection to Network Failed %d!\n", connect_success);
+ }
+ return NULL;
+ }
+ const char *ip_addr = network_interface->get_ip_address();
+ if (ip_addr == NULL) {
+ if (log_messages) {
+ printf("[EasyConnect] ERROR - No IP address\n");
+ }
+ return NULL;
+ }
+
+ if (log_messages) {
+ printf("[EasyConnect] IP address %s\n", ip_addr);
+ }
+ return network_interface;
+}
+
+#endif // __EASY_CONNECT_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed_lib.json Tue Dec 12 15:57:57 2017 +0000
@@ -0,0 +1,9 @@
+{
+ "name": "easy-connect",
+ "target_overrides": {
+ "*": {
+ "target.features_add": ["COMMON_PAL"]
+ }
+ }
+}
+