Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers WisunInterface.cpp Source File

WisunInterface.cpp

00001 /*
00002  * Copyright (c) 2018-2019 ARM Limited. All rights reserved.
00003  * SPDX-License-Identifier: Apache-2.0
00004  * Licensed under the Apache License, Version 2.0 (the License); you may
00005  * not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  * http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
00012  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #include "WisunInterface.h"
00018 #include "NanostackRfPhy.h"
00019 #include "include/wisun_tasklet.h"
00020 #include "callback_handler.h"
00021 #include "NanostackLockGuard.h"
00022 #include "mesh_system.h"
00023 #include "randLIB.h"
00024 
00025 #include "ns_trace.h"
00026 #define TRACE_GROUP "WSIn"
00027 
00028 class Nanostack::WisunInterface : public Nanostack::MeshInterface {
00029 public:
00030     virtual nsapi_error_t bringup(bool dhcp, const char *ip,
00031                                   const char *netmask, const char *gw,
00032                                   nsapi_ip_stack_t stack = IPV6_STACK,
00033                                   bool blocking = true);
00034     virtual nsapi_error_t bringdown();
00035     virtual char *get_gateway(char *buf, nsapi_size_t buflen);
00036 
00037     friend class Nanostack;
00038     friend class ::WisunInterface;
00039 private:
00040     WisunInterface(NanostackRfPhy &phy) : MeshInterface(phy) { }
00041     mesh_error_t init();
00042     mesh_error_t mesh_connect();
00043     mesh_error_t mesh_disconnect();
00044 };
00045 
00046 Nanostack::WisunInterface *WisunInterface::get_interface() const
00047 {
00048     return static_cast<Nanostack::WisunInterface *>(_interface);
00049 }
00050 
00051 nsapi_error_t WisunInterface::do_initialize()
00052 {
00053     if (!_interface) {
00054         _interface = new (std::nothrow) Nanostack::WisunInterface(*_phy);
00055         if (!_interface) {
00056             return NSAPI_ERROR_NO_MEMORY ;
00057         }
00058         _interface->attach(_connection_status_cb);
00059     }
00060     return NSAPI_ERROR_OK ;
00061 }
00062 
00063 nsapi_error_t Nanostack::WisunInterface::bringup(bool dhcp, const char *ip,
00064                                                  const char *netmask, const char *gw,
00065                                                  nsapi_ip_stack_t stack, bool blocking)
00066 {
00067     nanostack_lock();
00068 
00069     if (register_phy() < 0) {
00070         nanostack_unlock();
00071         return NSAPI_ERROR_DEVICE_ERROR ;
00072     }
00073 
00074     _blocking = blocking;
00075 
00076     // After the RF is up, we can seed the random from it.
00077     randLIB_seed_random();
00078 
00079     mesh_error_t status = init();
00080     if (status != MESH_ERROR_NONE) {
00081         nanostack_unlock();
00082         return map_mesh_error(status);
00083     }
00084 
00085     status = mesh_connect();
00086     if (status != MESH_ERROR_NONE) {
00087         nanostack_unlock();
00088         return map_mesh_error(status);
00089     }
00090 
00091     // Release mutex before blocking
00092     nanostack_unlock();
00093 
00094     if (blocking) {
00095         // wait connection for ever
00096         connect_semaphore.acquire();
00097     }
00098     return 0;
00099 
00100 }
00101 
00102 nsapi_error_t Nanostack::WisunInterface::bringdown()
00103 {
00104     NanostackLockGuard lock;
00105 
00106     mesh_error_t status = mesh_disconnect();
00107 
00108     return map_mesh_error(status);
00109 }
00110 
00111 mesh_error_t Nanostack::WisunInterface::init()
00112 {
00113     wisun_tasklet_init();
00114     __mesh_handler_set_callback(this);
00115     interface_id = wisun_tasklet_network_init(_device_id);
00116 
00117     if (interface_id == -2) {
00118         return MESH_ERROR_PARAM;
00119     } else if (interface_id == -3) {
00120         return MESH_ERROR_MEMORY;
00121     } else if (interface_id < 0) {
00122         return MESH_ERROR_UNKNOWN;
00123     }
00124     return MESH_ERROR_NONE;
00125 }
00126 
00127 mesh_error_t Nanostack::WisunInterface::mesh_connect()
00128 {
00129     int8_t status = -9; // init to unknown error
00130     tr_debug("connect()");
00131 
00132     status = wisun_tasklet_connect(&__mesh_handler_c_callback, interface_id);
00133 
00134     if (status >= 0) {
00135         return MESH_ERROR_NONE;
00136     } else if (status == -1) {
00137         return MESH_ERROR_PARAM;
00138     } else if (status == -2) {
00139         return MESH_ERROR_MEMORY;
00140     } else if (status == -3) {
00141         return MESH_ERROR_STATE;
00142     } else {
00143         return MESH_ERROR_UNKNOWN;
00144     }
00145 }
00146 
00147 mesh_error_t Nanostack::WisunInterface::mesh_disconnect()
00148 {
00149     int8_t status = -1;
00150 
00151     status = wisun_tasklet_disconnect(true);
00152 
00153     if (status >= 0) {
00154         return MESH_ERROR_NONE;
00155     }
00156 
00157     return MESH_ERROR_UNKNOWN;
00158 }
00159 
00160 char *Nanostack::WisunInterface::get_gateway(char *buf, nsapi_size_t buflen)
00161 {
00162     NanostackLockGuard lock;
00163     if (wisun_tasklet_get_router_ip_address(buf, buflen) == 0) {
00164         return buf;
00165     }
00166     return NULL;
00167 }
00168 
00169 bool WisunInterface::getRouterIpAddress(char *address, int8_t len)
00170 {
00171     SocketAddress sock_addr;
00172     if (_interface->get_gateway(&sock_addr) == NSAPI_ERROR_OK ) {
00173         strncpy(address, sock_addr.get_ip_address(), len);
00174         return true;
00175     }
00176     return false;
00177 }
00178 
00179 mesh_error_t WisunInterface::set_network_name(char *network_name)
00180 {
00181     mesh_error_t ret_val = MESH_ERROR_NONE;
00182 
00183     int status = wisun_tasklet_set_network_name(get_interface_id(), network_name);
00184     if (status != 0) {
00185         ret_val = MESH_ERROR_UNKNOWN;
00186     }
00187 
00188     return ret_val;
00189 }
00190 
00191 mesh_error_t WisunInterface::set_network_regulatory_domain(uint8_t regulatory_domain, uint8_t operating_class, uint8_t operating_mode)
00192 {
00193     mesh_error_t ret_val = MESH_ERROR_NONE;
00194 
00195     int status = wisun_tasklet_set_regulatory_domain(get_interface_id(), regulatory_domain, operating_class, operating_mode);
00196     if (status != 0) {
00197         ret_val = MESH_ERROR_UNKNOWN;
00198     }
00199 
00200     return ret_val;
00201 }
00202 
00203 mesh_error_t WisunInterface::set_own_certificate(uint8_t *cert, uint16_t cert_len, uint8_t *cert_key, uint16_t cert_key_len)
00204 {
00205     mesh_error_t ret_val = MESH_ERROR_NONE;
00206     int status =  wisun_tasklet_set_own_certificate(cert, cert_len, cert_key, cert_key_len);
00207     if (status == -1) {
00208         ret_val = MESH_ERROR_MEMORY;
00209     } else if (status == -2) {
00210         ret_val = MESH_ERROR_STATE;
00211     }
00212 
00213     return ret_val;
00214 }
00215 
00216 mesh_error_t WisunInterface::remove_own_certificates(void)
00217 {
00218     mesh_error_t ret_val = MESH_ERROR_NONE;
00219     int status =  wisun_tasklet_remove_own_certificates();
00220     if (status == -1) {
00221         ret_val = MESH_ERROR_MEMORY;
00222     } else if (status == -2) {
00223         ret_val = MESH_ERROR_STATE;
00224     }
00225 
00226     return ret_val;
00227 }
00228 
00229 mesh_error_t WisunInterface::set_trusted_certificate(uint8_t *cert, uint16_t cert_len)
00230 {
00231     mesh_error_t ret_val = MESH_ERROR_NONE;
00232     int status =  wisun_tasklet_set_trusted_certificate(cert, cert_len);
00233     if (status == -1) {
00234         ret_val = MESH_ERROR_MEMORY;
00235     } else if (status == -2) {
00236         ret_val = MESH_ERROR_STATE;
00237     }
00238 
00239     return ret_val;
00240 }
00241 
00242 mesh_error_t WisunInterface::remove_trusted_certificates(void)
00243 {
00244     mesh_error_t ret_val = MESH_ERROR_NONE;
00245     int status =  wisun_tasklet_remove_trusted_certificates();
00246     if (status == -1) {
00247         ret_val = MESH_ERROR_MEMORY;
00248     } else if (status == -2) {
00249         ret_val = MESH_ERROR_STATE;
00250     }
00251 
00252     return ret_val;
00253 }
00254 
00255 #define WISUN 0x2345
00256 #if MBED_CONF_NSAPI_DEFAULT_MESH_TYPE == WISUN && DEVICE_802_15_4_PHY
00257 MBED_WEAK MeshInterface *MeshInterface::get_target_default_instance()
00258 {
00259     static bool inited;
00260     static WisunInterface interface;
00261     singleton_lock();
00262     if (!inited) {
00263         nsapi_error_t result = interface.initialize(&NanostackRfPhy::get_default_instance());
00264         if (result != 0) {
00265             tr_error("Wi-SUN initialize failed: %d", result);
00266             singleton_unlock();
00267             return NULL;
00268         }
00269         inited = true;
00270     }
00271     singleton_unlock();
00272     return &interface;
00273 }
00274 #endif