Modified version of easy-connect for W5500 Ethernet components

Dependents:   http-webserver-example mbed-os-example-sockets

Fork of easy-connect by Sergei G

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers easy-connect.cpp Source File

easy-connect.cpp

00001 /*
00002  * FILE: easy-connect.cpp
00003  *
00004  * Copyright (c) 2015 - 2017 ARM Limited. All rights reserved.
00005  * SPDX-License-Identifier: Apache-2.0
00006  * Licensed under the Apache License, Version 2.0 (the License); you may
00007  * not use this file except in compliance with the License.
00008  * You may obtain a copy of the License at
00009  *
00010  * http://www.apache.org/licenses/LICENSE-2.0
00011  *
00012  * Unless required by applicable law or agreed to in writing, software
00013  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
00014  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015  * See the License for the specific language governing permissions and
00016  * limitations under the License.
00017  */
00018 
00019 #include "mbed.h"
00020 #include "easy-connect.h"
00021 
00022 /*
00023  * Instantiate the configured network interface
00024  */
00025 #if MBED_CONF_APP_NETWORK_INTERFACE == WIFI_ESP8266
00026 #include "ESP8266Interface.h"
00027 #define EASY_CONNECT_WIFI_TYPE "ESP8266"
00028 
00029 #ifdef MBED_CONF_APP_ESP8266_DEBUG
00030 ESP8266Interface wifi(MBED_CONF_EASY_CONNECT_WIFI_ESP8266_TX, MBED_CONF_EASY_CONNECT_WIFI_ESP8266_RX, MBED_CONF_EASY_CONNECT_WIFI_ESP8266_DEBUG);
00031 #else
00032 ESP8266Interface wifi(MBED_CONF_EASY_CONNECT_WIFI_ESP8266_TX, MBED_CONF_EASY_CONNECT_WIFI_ESP8266_RX);
00033 #endif
00034 
00035 #elif MBED_CONF_APP_NETWORK_INTERFACE == WIFI_ODIN
00036 #define EASY_CONNECT_WIFI_TYPE "Odin"
00037 #include "OdinWiFiInterface.h"
00038 OdinWiFiInterface wifi;
00039 
00040 #elif MBED_CONF_APP_NETWORK_INTERFACE == WIFI_RTW
00041 #define EASY_CONNECT_WIFI_TYPE "RTW"
00042 #include "RTWInterface.h"
00043 RTWInterface wifi;
00044 
00045 #elif MBED_CONF_APP_NETWORK_INTERFACE == WIFI_IDW0XX1
00046 #include "SpwfSAInterface.h"
00047 
00048 #if MBED_CONF_IDW0XX1_EXPANSION_BOARD == IDW01M1
00049 #define EASY_CONNECT_WIFI_TYPE "IDW01M1"
00050 SpwfSAInterface wifi(MBED_CONF_EASY_CONNECT_WIFI_IDW01M1_TX, MBED_CONF_EASY_CONNECT_WIFI_IDW01M1_RX);
00051 #endif //  MBED_CONF_IDW0XX1_EXPANSION_BOARD == IDW01M1
00052 
00053 #if MBED_CONF_IDW0XX1_EXPANSION_BOARD == IDW04A1
00054 #define EASY_CONNECT_WIFI_TYPE "IDW04A1"
00055 SpwfSAInterface wifi(MBED_CONF_EASY_CONNECT_WIFI_IDW04A1_TX, MBED_CONF_EASY_CONNECT_WIFI_IDW04A1_RX);
00056 #endif //  MBED_CONF_IDW0XX1_EXPANSION_BOARD == IDW04A1
00057 
00058 #elif MBED_CONF_APP_NETWORK_INTERFACE == WIFI_ISM43362
00059 #include "ISM43362Interface.h"
00060 #define EASY_CONNECT_WIFI_TYPE "ISM43362"
00061 
00062 #ifdef MBED_CONF_APP_ISM43362_DEBUG
00063 ISM43362Interface wifi(true);
00064 #else
00065 ISM43362Interface wifi;
00066 #endif
00067 
00068 #elif MBED_CONF_APP_NETWORK_INTERFACE == ETHERNET
00069 #include "EthernetInterface.h"
00070 EthernetInterface eth;
00071 
00072 #elif MBED_CONF_APP_NETWORK_INTERFACE == MESH_LOWPAN_ND
00073 #define EASY_CONNECT_MESH
00074 #include "NanostackInterface.h"
00075 LoWPANNDInterface mesh;
00076 
00077 #elif MBED_CONF_APP_NETWORK_INTERFACE == MESH_THREAD
00078 #define EASY_CONNECT_MESH
00079 #include "NanostackInterface.h"
00080 ThreadInterface mesh;
00081 
00082 #elif MBED_CONF_APP_NETWORK_INTERFACE == CELLULAR_ONBOARD
00083 #include "OnboardCellularInterface.h"
00084 OnboardCellularInterface cellular;
00085 
00086 #elif MBED_CONF_APP_NETWORK_INTERFACE == CELLULAR
00087 #include "EasyCellularConnection.h"
00088 EasyCellularConnection cellular;
00089 
00090 #elif MBED_CONF_APP_NETWORK_INTERFACE == WIFI_WIZFI310
00091 #include "WizFi310Interface.h"
00092 #define EASY_CONNECT_WIFI_TYPE "WizFi310"
00093 
00094 #ifdef MBED_CONF_APP_WIZFI310_DEBUG
00095     WizFi310Interface wifi(MBED_CONF_EASY_CONNECT_WIFI_WIZFI310_TX, MBED_CONF_EASY_CONNECT_WIFI_WIZFI310_RX, MBED_CONF_EASY_CONNECT_WIFI_WIZFI310_DEBUG);
00096 #else
00097     WizFi310Interface wifi(MBED_CONF_EASY_CONNECT_WIFI_WIZFI310_TX, MBED_CONF_EASY_CONNECT_WIFI_WIZFI310_RX);
00098 #endif
00099 
00100 #elif MBED_CONF_APP_NETWORK_INTERFACE == CELLULAR_WNC14A2A
00101 #include "WNC14A2AInterface.h"
00102 
00103 #if MBED_CONF_APP_WNC_DEBUG == true
00104 #include "WNCDebug.h"
00105 WNCDebug dbgout(stderr);
00106 WNC14A2AInterface wnc(&dbgout);
00107 #else
00108 WNC14A2AInterface wnc;
00109 #endif
00110 
00111 
00112 #elif MBED_CONF_APP_NETWORK_INTERFACE == ETHERNET_W5500
00113 
00114 #include "W5500Interface/W5500Interface.h"
00115 W5500Interface eth(W5500_SPI_MOSI,W5500_SPI_MISO,W5500_SPI_SCLK, W5500_SPI_CS, W5500_SPI_RST); // mosi, miso, sclk, cs, reset
00116 
00117 #else
00118 #error "No connectivity method chosen. Please add 'config.network-interfaces.value' to your mbed_app.json (see README.md for more information)."
00119 #endif // MBED_CONF_APP_NETWORK_INTERFACE
00120 
00121 /*
00122  * In case of Mesh, instantiate the configured RF PHY.
00123  */
00124 #if defined (EASY_CONNECT_MESH)
00125 #if MBED_CONF_APP_MESH_RADIO_TYPE == ATMEL
00126 #include "NanostackRfPhyAtmel.h"
00127 #define EASY_CONNECT_MESH_TYPE "Atmel"
00128 NanostackRfPhyAtmel rf_phy(ATMEL_SPI_MOSI, ATMEL_SPI_MISO, ATMEL_SPI_SCLK, ATMEL_SPI_CS,
00129                            ATMEL_SPI_RST, ATMEL_SPI_SLP, ATMEL_SPI_IRQ, ATMEL_I2C_SDA, ATMEL_I2C_SCL);
00130 
00131 #elif MBED_CONF_APP_MESH_RADIO_TYPE == MCR20
00132 #include "NanostackRfPhyMcr20a.h"
00133 #define EASY_CONNECT_MESH_TYPE "Mcr20A"
00134 NanostackRfPhyMcr20a rf_phy(MCR20A_SPI_MOSI, MCR20A_SPI_MISO, MCR20A_SPI_SCLK, MCR20A_SPI_CS, MCR20A_SPI_RST, MCR20A_SPI_IRQ);
00135 
00136 #elif MBED_CONF_APP_MESH_RADIO_TYPE == SPIRIT1
00137 #include "NanostackRfPhySpirit1.h"
00138 #define EASY_CONNECT_MESH_TYPE "Spirit1"
00139 NanostackRfPhySpirit1 rf_phy(SPIRIT1_SPI_MOSI, SPIRIT1_SPI_MISO, SPIRIT1_SPI_SCLK,
00140                              SPIRIT1_DEV_IRQ, SPIRIT1_DEV_CS, SPIRIT1_DEV_SDN, SPIRIT1_BRD_LED);
00141 
00142 #elif MBED_CONF_APP_MESH_RADIO_TYPE == EFR32
00143 #include "NanostackRfPhyEfr32.h"
00144 #define EASY_CONNECT_MESH_TYPE "EFR32"
00145 NanostackRfPhyEfr32 rf_phy;
00146 
00147 #endif // MBED_CONF_APP_RADIO_TYPE
00148 #endif // EASY_CONNECT_MESH
00149 
00150 #if defined (EASY_CONNECT_WIFI)
00151 #define WIFI_SSID_MAX_LEN      32    // As per IEEE 802.11 chapter 7.3.2.1 (SSID element)
00152 #define WIFI_PASSWORD_MAX_LEN  64    // 
00153 
00154 char* _ssid = NULL;
00155 char* _password = NULL;
00156 #endif // EASY_CONNECT_WIFI
00157 
00158 /* \brief print_MAC - print_MAC  - helper function to print out MAC address
00159  * in: network_interface - pointer to network i/f
00160  *     bool log-messages   print out logs or not
00161  * MAC address is printed, if it can be acquired & log_messages is true.
00162  *
00163  */
00164 void print_MAC(NetworkInterface* network_interface, bool log_messages) {
00165 #if MBED_CONF_APP_NETWORK_INTERFACE != CELLULAR_ONBOARD && MBED_CONF_APP_NETWORK_INTERFACE != CELLULAR
00166     const char *mac_addr = network_interface->get_mac_address();
00167     if (mac_addr == NULL) {
00168         if (log_messages) {
00169             printf("[EasyConnect] ERROR - No MAC address\n");
00170         }
00171         return;
00172     }
00173     if (log_messages) {
00174         printf("[EasyConnect] MAC address %s\n", mac_addr);
00175     }
00176 #endif
00177 }
00178 
00179 
00180 
00181 /* \brief easy_connect     easy_connect() function to connect the pre-defined network bearer,
00182  *                         config done via mbed_app.json (see README.md for details).
00183  *
00184  * IN: bool  log_messages  print out diagnostics or not.
00185  */
00186 NetworkInterface* easy_connect(bool log_messages) {
00187     NetworkInterface* network_interface = NULL;
00188     int connect_success = -1;
00189 
00190 #if defined (EASY_CONNECT_WIFI)
00191     // We check if the _ssid and _password have already been set (via the easy_connect()
00192     // that takes thoses parameters or not.
00193     // If they have not been set, use the ones we can gain from mbed_app.json.
00194     if (_ssid == NULL) { 
00195         if(strlen(MBED_CONF_APP_WIFI_SSID) > WIFI_SSID_MAX_LEN) {
00196             printf("ERROR - MBED_CONF_APP_WIFI_SSID is too long %d vs. %d\n", 
00197                     strlen(MBED_CONF_APP_WIFI_SSID),
00198                     WIFI_SSID_MAX_LEN);
00199             return NULL;
00200         }
00201     }
00202 
00203     if (_password == NULL) {
00204         if(strlen(MBED_CONF_APP_WIFI_PASSWORD) > WIFI_PASSWORD_MAX_LEN) {
00205             printf("ERROR - MBED_CONF_APP_WIFI_PASSWORD is too long %d vs. %d\n", 
00206                     strlen(MBED_CONF_APP_WIFI_PASSWORD),
00207                     WIFI_PASSWORD_MAX_LEN);
00208             return NULL;
00209         }
00210     }
00211 #endif // EASY_CONNECT_WIFI
00212 
00213     /// This should be removed once mbedOS supports proper dual-stack
00214     if (log_messages) {
00215 #if defined (EASY_CONNECT_MESH) || (MBED_CONF_LWIP_IPV6_ENABLED==true)
00216         printf("[EasyConnect] IPv6 mode\n");
00217 #else
00218         printf("[EasyConnect] IPv4 mode\n");
00219 #endif
00220     }
00221 
00222 #if defined (EASY_CONNECT_WIFI)
00223     if (log_messages) {
00224         printf("[EasyConnect] Using WiFi (%s) \n", EASY_CONNECT_WIFI_TYPE);
00225         printf("[EasyConnect] Connecting to WiFi %s\n", 
00226                 ((_ssid == NULL) ? MBED_CONF_APP_WIFI_SSID : _ssid) );
00227     }
00228     network_interface = &wifi;
00229     if (_ssid == NULL) {
00230         connect_success = wifi.connect(MBED_CONF_APP_WIFI_SSID, MBED_CONF_APP_WIFI_PASSWORD,
00231                           (strlen(MBED_CONF_APP_WIFI_PASSWORD) > 1) ? NSAPI_SECURITY_WPA_WPA2 : NSAPI_SECURITY_NONE);
00232     }
00233     else {
00234         connect_success = wifi.connect(_ssid, _password, (strlen(_password) > 1) ? NSAPI_SECURITY_WPA_WPA2 : NSAPI_SECURITY_NONE);
00235     }
00236 #elif MBED_CONF_APP_NETWORK_INTERFACE == CELLULAR_ONBOARD || MBED_CONF_APP_NETWORK_INTERFACE == CELLULAR
00237 #  ifdef MBED_CONF_APP_CELLULAR_SIM_PIN
00238     cellular.set_sim_pin(MBED_CONF_APP_CELLULAR_SIM_PIN);
00239 #  endif
00240 #  ifdef MBED_CONF_APP_CELLULAR_APN
00241 #    ifndef MBED_CONF_APP_CELLULAR_USERNAME
00242 #      define MBED_CONF_APP_CELLULAR_USERNAME 0
00243 #    endif
00244 #    ifndef MBED_CONF_APP_CELLULAR_PASSWORD
00245 #      define MBED_CONF_APP_CELLULAR_PASSWORD 0
00246 #    endif
00247     cellular.set_credentials(MBED_CONF_APP_CELLULAR_APN, MBED_CONF_APP_CELLULAR_USERNAME, MBED_CONF_APP_CELLULAR_PASSWORD);
00248     if (log_messages) {
00249         printf("[EasyConnect] Connecting using Cellular interface and APN %s\n", MBED_CONF_APP_CELLULAR_APN);
00250     }
00251 #  else
00252     if (log_messages) {
00253         printf("[EasyConnect] Connecting using Cellular interface and default APN\n");
00254     }
00255 #  endif
00256     connect_success = cellular.connect();
00257     network_interface = &cellular;
00258 
00259 #elif MBED_CONF_APP_NETWORK_INTERFACE == CELLULAR_WNC14A2A
00260     if (log_messages) {
00261         printf("[EasyConnect] Using WNC14A2A\n");
00262     }
00263 #   if MBED_CONF_APP_WNC_DEBUG == true
00264     printf("[EasyConnect] With WNC14A2A debug output set to 0x%02X\n",MBED_CONF_APP_WNC_DEBUG_SETTING);
00265     wnc.doDebug(MBED_CONF_APP_WNC_DEBUG_SETTING);
00266 #   endif
00267     network_interface = &wnc;
00268     connect_success = wnc.connect();
00269 
00270 #elif MBED_CONF_APP_NETWORK_INTERFACE == ETHERNET
00271     if (log_messages) {
00272         printf("[EasyConnect] Using Ethernet\n");
00273     }
00274     network_interface = ð
00275 #if MBED_CONF_EVENTS_SHARED_DISPATCH_FROM_APPLICATION
00276     eth.set_blocking(false);
00277 #endif
00278     connect_success = eth.connect();
00279 
00280 #elif MBED_CONF_APP_NETWORK_INTERFACE == ETHERNET_W5500
00281  
00282     if (log_messages) {
00283         printf("[EasyConnect] Using Ethernet W5500\n");
00284     }
00285     // wait during chip reset
00286     wait(1);
00287     
00288     network_interface = ð
00289 #if MBED_CONF_EVENTS_SHARED_DISPATCH_FROM_APPLICATION
00290     eth.set_blocking(false);
00291 #endif
00292     connect_success = eth.connect();
00293 
00294 #endif
00295 
00296 #ifdef EASY_CONNECT_MESH
00297     if (log_messages) {
00298         printf("[EasyConnect] Using Mesh (%s)\n", EASY_CONNECT_MESH_TYPE);
00299         printf("[EasyConnect] Connecting to Mesh...\n");
00300     }
00301     network_interface = &mesh;
00302 #if MBED_CONF_EVENTS_SHARED_DISPATCH_FROM_APPLICATION
00303     mesh.set_blocking(false);
00304 #endif
00305     mesh.initialize(&rf_phy);
00306     connect_success = mesh.connect();
00307 #endif
00308 
00309     if(connect_success == 0
00310 #if (MBED_CONF_EVENTS_SHARED_DISPATCH_FROM_APPLICATION && (MBED_CONF_APP_NETWORK_INTERFACE == ETHERNET || defined(EASY_CONNECT_MESH)))
00311             || connect_success == NSAPI_ERROR_IS_CONNECTED || connect_success == NSAPI_ERROR_ALREADY
00312 #endif
00313             ) {
00314 #if (MBED_CONF_EVENTS_SHARED_DISPATCH_FROM_APPLICATION && (MBED_CONF_APP_NETWORK_INTERFACE == ETHERNET || defined(EASY_CONNECT_MESH)))
00315         nsapi_connection_status_t connection_status;
00316 
00317         for (;;) {
00318 
00319             // Check current connection status.
00320             connection_status = network_interface->get_connection_status();
00321 
00322             if (connection_status == NSAPI_STATUS_GLOBAL_UP) {
00323 
00324                 // Connection ready.
00325                 break;
00326 
00327             } else if (connection_status == NSAPI_STATUS_ERROR_UNSUPPORTED) {
00328 
00329                 if (log_messages) {
00330                     print_MAC(network_interface, log_messages);
00331                     printf("[EasyConnect] Connection to Network Failed %d!\n", connection_status);
00332                 }
00333                 return NULL;
00334 
00335             }
00336 
00337             // Not ready yet, give some runtime to the network stack.
00338             mbed::mbed_event_queue()->dispatch(100);
00339 
00340         }
00341 #endif
00342 
00343         if (log_messages) {
00344             printf("[EasyConnect] Connected to Network successfully\n");
00345             print_MAC(network_interface, log_messages);
00346         }
00347     } else {
00348         if (log_messages) {
00349             print_MAC(network_interface, log_messages);
00350             printf("[EasyConnect] Connection to Network Failed %d!\n", connect_success);
00351         }
00352         return NULL;
00353     }
00354     const char *ip_addr  = network_interface->get_ip_address();
00355     if (ip_addr == NULL) {
00356         if (log_messages) {
00357             printf("[EasyConnect] ERROR - No IP address\n");
00358         }
00359         return NULL;
00360     }
00361 
00362     if (log_messages) {
00363         printf("[EasyConnect] IP address %s\n", ip_addr);
00364     }
00365     return network_interface;
00366 }
00367 
00368 /* \brief easy_connect - easy_connect function to connect the pre-defined network bearer,
00369  *                       config done via mbed_app.json (see README.md for details).
00370  *                       This version is just a helper version and uses the easy_connect() with
00371  *                       one parameters to do it's job.
00372  * IN: bool  log_messages  print out diagnostics or not.
00373  *     char* WiFiSSID      WiFi SSID - pointer to WiFi SSID, but if it is NULL  
00374  *                         then MBED_CONF_APP_WIFI_SSID will be used
00375  *     char* WiFiPassword  WiFi Password - pointer to WiFI password, but if it's NULL
00376  *                         then MBED_CONF_APP_WIFI_PASSWORD will be used
00377  */
00378 
00379 NetworkInterface* easy_connect(bool log_messages,
00380                                char* WiFiSSID,
00381                                char* WiFiPassword ) {
00382 
00383 // This functionality only makes sense when using WiFi
00384 #if defined (EASY_CONNECT_WIFI) 
00385     // We essentially want to populate the _ssid and _password and then call easy_connect() again. 
00386     if (WiFiSSID != NULL) {
00387         if(strlen(WiFiSSID) > WIFI_SSID_MAX_LEN) {
00388             printf("ERROR - WiFi SSID is too long - %d vs %d.\n", strlen(WiFiSSID), WIFI_SSID_MAX_LEN);
00389             return NULL;
00390         }
00391         _ssid = WiFiSSID;
00392     }
00393 
00394     if (WiFiPassword != NULL) {
00395         if(strlen(WiFiPassword) > WIFI_PASSWORD_MAX_LEN) {
00396             printf("ERROR - WiFi Password is too long - %d vs %d\n", strlen(WiFiPassword), WIFI_PASSWORD_MAX_LEN);
00397             return NULL;
00398         }
00399         _password = WiFiPassword;
00400     }
00401 #endif // EASY_CONNECT_WIFI
00402     return easy_connect(log_messages);
00403 }
00404 
00405 /* \brief easy_get_netif - easy_connect function to get pointer to network interface
00406  *                        without connecting to it.
00407  *
00408  * IN: bool  log_messages  print out diagnostics or not.
00409  */
00410 NetworkInterface* easy_get_netif(bool log_messages) {
00411 #if defined (EASY_CONNECT_WIFI)
00412     if (log_messages) {
00413         printf("[EasyConnect] WiFi: %s\n", EASY_CONNECT_WIFI_TYPE);
00414     }
00415     return &wifi;
00416 
00417 #elif MBED_CONF_APP_NETWORK_INTERFACE == ETHERNET
00418     if (log_messages) {
00419         printf("[EasyConnect] Ethernet\n");
00420     }
00421     return ð
00422 
00423 #elif defined (EASY_CONNECT_MESH)
00424     if (log_messages) {
00425         printf("[EasyConnect] Mesh : %s\n", EASY_CONNECT_MESH_TYPE);
00426     }
00427     return &mesh;
00428 
00429 #elif MBED_CONF_APP_NETWORK_INTERFACE == CELLULAR_ONBOARD || MBED_CONF_APP_NETWORK_INTERFACE == CELLULAR
00430     if (log_messages) {
00431         printf("[EasyConnect] Cellular\n");
00432     }
00433     return  &cellular;
00434 
00435 #elif MBED_CONF_APP_NETWORK_INTERFACE == CELLULAR_WNC14A2A
00436     if (log_messages) {
00437         printf("[EasyConnect] WNC14A2A\n");
00438     }
00439     return  &wnc;
00440 
00441 #elif MBED_CONF_APP_NETWORK_INTERFACE == ETHERNET_W5500
00442     if (log_messages) {
00443         printf("[EasyConnect] Ethernet W5500\n");
00444     }
00445     return ð
00446 
00447 #endif
00448 }
00449 
00450 /* \brief easy_get_wifi - easy_connect function to get pointer to Wifi interface 
00451  *                        without connecting to it. You would want this 1st so that
00452  *                        you can scan the APNs, choose the right one and then connect.
00453  *
00454  * IN: bool  log_messages  print out diagnostics or not.
00455  */
00456 WiFiInterface* easy_get_wifi(bool log_messages) {
00457 #if defined (EASY_CONNECT_WIFI)
00458     if (log_messages) {
00459         printf("[EasyConnect] WiFi: %s\n", EASY_CONNECT_WIFI_TYPE);
00460     }
00461     return &wifi;
00462 #else
00463     if (log_messages) {
00464         printf("[EasyConnect] ERROR - Wifi not in use, can not return WifiInterface.\n");
00465     }
00466     return NULL;
00467 #endif
00468 }