Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers LoWPANNDInterface.cpp Source File

LoWPANNDInterface.cpp

00001 /*
00002  * Copyright (c) 2018 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 "LoWPANNDInterface.h"
00018 #include "include/nd_tasklet.h"
00019 #include "callback_handler.h"
00020 #include "NanostackLockGuard.h"
00021 #include "mesh_system.h"
00022 #include "randLIB.h"
00023 
00024 #include "ns_trace.h"
00025 #define TRACE_GROUP "nslp"
00026 
00027 class Nanostack::LoWPANNDInterface : public Nanostack::MeshInterface {
00028 public:
00029     virtual nsapi_error_t bringup(bool dhcp, const char *ip,
00030                                   const char *netmask, const char *gw,
00031                                   nsapi_ip_stack_t stack = IPV6_STACK,
00032                                   bool blocking = true);
00033     virtual nsapi_error_t bringdown();
00034     virtual char *get_gateway(char *buf, nsapi_size_t buflen);
00035 
00036     friend class Nanostack;
00037     friend class ::LoWPANNDInterface;
00038 private:
00039     LoWPANNDInterface(NanostackRfPhy &phy) : MeshInterface(phy) { }
00040     mesh_error_t init();
00041     mesh_error_t mesh_connect();
00042     mesh_error_t mesh_disconnect();
00043 };
00044 
00045 Nanostack::LoWPANNDInterface *LoWPANNDInterface::get_interface() const
00046 {
00047     return static_cast<Nanostack::LoWPANNDInterface *>(_interface);
00048 }
00049 
00050 nsapi_error_t LoWPANNDInterface::do_initialize()
00051 {
00052     if (!_interface) {
00053         _interface = new (std::nothrow) Nanostack::LoWPANNDInterface(*_phy);
00054         if (!_interface) {
00055             return NSAPI_ERROR_NO_MEMORY ;
00056         }
00057         _interface->attach(_connection_status_cb);
00058     }
00059     return NSAPI_ERROR_OK ;
00060 }
00061 
00062 nsapi_error_t Nanostack::LoWPANNDInterface::bringup(bool dhcp, const char *ip,
00063                                                     const char *netmask, const char *gw,
00064                                                     nsapi_ip_stack_t stack, bool blocking)
00065 {
00066     nanostack_lock();
00067 
00068     if (register_phy() < 0) {
00069         nanostack_unlock();
00070         return NSAPI_ERROR_DEVICE_ERROR ;
00071     }
00072 
00073     _blocking = blocking;
00074 
00075     // After the RF is up, we can seed the random from it.
00076     randLIB_seed_random();
00077 
00078     mesh_error_t status = init();
00079     if (status != MESH_ERROR_NONE) {
00080         nanostack_unlock();
00081         return map_mesh_error(status);
00082     }
00083 
00084     status = mesh_connect();
00085     if (status != MESH_ERROR_NONE) {
00086         nanostack_unlock();
00087         return map_mesh_error(status);
00088     }
00089 
00090     // Release mutex before blocking
00091     nanostack_unlock();
00092 
00093     if (blocking) {
00094         // wait connection for ever
00095         connect_semaphore.acquire();
00096     }
00097     return 0;
00098 
00099 }
00100 
00101 nsapi_error_t Nanostack::LoWPANNDInterface::bringdown()
00102 {
00103     NanostackLockGuard lock;
00104 
00105     mesh_error_t status = mesh_disconnect();
00106 
00107     return map_mesh_error(status);
00108 }
00109 
00110 mesh_error_t Nanostack::LoWPANNDInterface::init()
00111 {
00112     nd_tasklet_init();
00113     __mesh_handler_set_callback(this);
00114     interface_id = nd_tasklet_network_init(_device_id);
00115 
00116     if (interface_id == -2) {
00117         return MESH_ERROR_PARAM;
00118     } else if (interface_id == -3) {
00119         return MESH_ERROR_MEMORY;
00120     } else if (interface_id < 0) {
00121         return MESH_ERROR_UNKNOWN;
00122     }
00123     return MESH_ERROR_NONE;
00124 }
00125 
00126 mesh_error_t Nanostack::LoWPANNDInterface::mesh_connect()
00127 {
00128     int8_t status = -9; // init to unknown error
00129     tr_debug("connect()");
00130 
00131     status = nd_tasklet_connect(&__mesh_handler_c_callback, interface_id);
00132 
00133     if (status >= 0) {
00134         return MESH_ERROR_NONE;
00135     } else if (status == -1) {
00136         return MESH_ERROR_PARAM;
00137     } else if (status == -2) {
00138         return MESH_ERROR_MEMORY;
00139     } else if (status == -3) {
00140         return MESH_ERROR_STATE;
00141     } else {
00142         return MESH_ERROR_UNKNOWN;
00143     }
00144 }
00145 
00146 mesh_error_t Nanostack::LoWPANNDInterface::mesh_disconnect()
00147 {
00148     int8_t status = -1;
00149 
00150     status = nd_tasklet_disconnect(true);
00151 
00152     if (status >= 0) {
00153         return MESH_ERROR_NONE;
00154     }
00155 
00156     return MESH_ERROR_UNKNOWN;
00157 }
00158 
00159 char *Nanostack::LoWPANNDInterface::get_gateway(char *buf, nsapi_size_t buflen)
00160 {
00161     NanostackLockGuard lock;
00162     if (nd_tasklet_get_router_ip_address(buf, buflen) == 0) {
00163         return buf;
00164     }
00165     return NULL;
00166 }
00167 
00168 bool LoWPANNDInterface::getRouterIpAddress(char *address, int8_t len)
00169 {
00170     SocketAddress sock_addr;
00171     if (_interface->get_gateway(&sock_addr) == NSAPI_ERROR_OK ) {
00172         strncpy(address, sock_addr.get_ip_address(), len);
00173         return true;
00174     }
00175     return false;
00176 }
00177 
00178 #define LOWPAN 0x2345
00179 #if MBED_CONF_NSAPI_DEFAULT_MESH_TYPE == LOWPAN && DEVICE_802_15_4_PHY
00180 MBED_WEAK MeshInterface *MeshInterface::get_target_default_instance()
00181 {
00182     static bool inited;
00183     static LoWPANNDInterface interface;
00184     singleton_lock();
00185     if (!inited) {
00186         nsapi_error_t result = interface.initialize(&NanostackRfPhy::get_default_instance());
00187         if (result != 0) {
00188             tr_error("LoWPANND initialize failed: %d", result);
00189             singleton_unlock();
00190             return NULL;
00191         }
00192         inited = true;
00193     }
00194     singleton_unlock();
00195     return &interface;
00196 }
00197 #endif