CUSTOMIZED FOR WATER MONITOR
Revision 0:c9094fbda0bd, committed 2017-12-07
- Comitter:
- DuyLionTran
- Date:
- Thu Dec 07 17:07:08 2017 +0000
- Commit message:
- CUSTOMIZED FOR WATER MONITOR
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.gitignore Thu Dec 07 17:07:08 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 Thu Dec 07 17:07:08 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 Thu Dec 07 17:07:08 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 Thu Dec 07 17:07:08 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 Thu Dec 07 17:07:08 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 Thu Dec 07 17:07:08 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 Thu Dec 07 17:07:08 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 Thu Dec 07 17:07:08 2017 +0000 @@ -0,0 +1,9 @@ +{ + "name": "easy-connect", + "target_overrides": { + "*": { + "target.features_add": ["COMMON_PAL"] + } + } +} +