Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MeshInterfaceNanostack.cpp Source File

MeshInterfaceNanostack.cpp

00001 /*
00002  * Copyright (c) 2016-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 "MeshInterfaceNanostack.h"
00018 #include "Nanostack.h"
00019 #include "NanostackLockGuard.h"
00020 #include "mesh_system.h"
00021 #include "nanostack/net_interface.h"
00022 #include "thread_management_if.h"
00023 #include "ip6string.h"
00024 #include "mbed_error.h"
00025 
00026 nsapi_error_t Nanostack::Interface::get_ip_address(SocketAddress *address)
00027 {
00028     NanostackLockGuard lock;
00029     uint8_t binary_ipv6[16];
00030 
00031     if (arm_net_address_get(interface_id, ADDR_IPV6_GP, binary_ipv6) == 0) {
00032         address->set_ip_bytes(binary_ipv6, NSAPI_IPv6 );
00033         return NSAPI_ERROR_OK ;
00034     } else {
00035         return NSAPI_ERROR_NO_ADDRESS ;
00036     }
00037 }
00038 
00039 char *Nanostack::Interface::get_ip_address(char *buf, nsapi_size_t buflen)
00040 {
00041     NanostackLockGuard lock;
00042     uint8_t binary_ipv6[16];
00043 
00044     if (buflen >= 40 && arm_net_address_get(interface_id, ADDR_IPV6_GP, binary_ipv6) == 0) {
00045         ip6tos(binary_ipv6, buf);
00046         return buf;
00047     } else {
00048         return NULL;
00049     }
00050 }
00051 
00052 char *Nanostack::Interface::get_mac_address(char *buf, nsapi_size_t buflen)
00053 {
00054     NanostackLockGuard lock;
00055     link_layer_address_s addr;
00056     if (buflen >= 24 && arm_nwk_mac_address_read(interface_id, &addr) == 0) {
00057         snprintf(buf, buflen, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", addr.mac_long[0], addr.mac_long[1], addr.mac_long[2], addr.mac_long[3], addr.mac_long[4], addr.mac_long[5], addr.mac_long[6], addr.mac_long[7]);
00058         return buf;
00059     } else {
00060         return NULL;
00061     }
00062 }
00063 
00064 nsapi_error_t Nanostack::Interface::get_netmask(SocketAddress *address)
00065 {
00066     return NSAPI_ERROR_UNSUPPORTED ;
00067 }
00068 
00069 nsapi_error_t Nanostack::Interface::get_gateway(SocketAddress *address)
00070 {
00071     return NSAPI_ERROR_UNSUPPORTED ;
00072 }
00073 
00074 char *Nanostack::Interface::get_netmask(char *, nsapi_size_t)
00075 {
00076     return NULL;
00077 }
00078 
00079 char *Nanostack::Interface::get_gateway(char *, nsapi_size_t)
00080 {
00081     return NULL;
00082 }
00083 
00084 nsapi_connection_status_t Nanostack::Interface::get_connection_status() const
00085 {
00086     return _connect_status;
00087 }
00088 
00089 void Nanostack::Interface::attach(
00090     mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb)
00091 {
00092     _connection_status_cb = status_cb;
00093 }
00094 
00095 Nanostack::Interface::Interface(NanostackPhy &phy) : interface_phy(phy), interface_id(-1), _device_id(-1),
00096     _connect_status(NSAPI_STATUS_DISCONNECTED ), _previous_connection_status(NSAPI_STATUS_DISCONNECTED ), _blocking(true)
00097 {
00098     mesh_system_init();
00099 }
00100 
00101 
00102 InterfaceNanostack::InterfaceNanostack()
00103     : _interface(NULL),
00104       ip_addr(), mac_addr_str(), _blocking(true)
00105 {
00106     // Nothing to do
00107 }
00108 
00109 int InterfaceNanostack::connect()
00110 {
00111     nsapi_error_t error = do_initialize();
00112     if (error) {
00113         return error;
00114     }
00115 
00116     return _interface->bringup(false, NULL, NULL, NULL, IPV6_STACK, _blocking);
00117 }
00118 
00119 int InterfaceNanostack::disconnect()
00120 {
00121     if (!_interface) {
00122         return NSAPI_ERROR_NO_CONNECTION ;
00123     }
00124     return _interface->bringdown();
00125 }
00126 
00127 nsapi_error_t MeshInterfaceNanostack::initialize(NanostackRfPhy *phy)
00128 {
00129     if (_phy && phy && _phy != phy) {
00130         error("Phy already set");
00131         return NSAPI_ERROR_IS_CONNECTED ;
00132     }
00133     if (phy) {
00134         _phy = phy;
00135     }
00136     if (_phy) {
00137         return do_initialize();
00138     } else {
00139         return NSAPI_ERROR_PARAMETER ;
00140     }
00141 }
00142 
00143 void Nanostack::Interface::network_handler(mesh_connection_status_t status)
00144 {
00145     if (_blocking) {
00146         if (_connect_status == NSAPI_STATUS_CONNECTING 
00147                 && (status == MESH_CONNECTED || status == MESH_CONNECTED_LOCAL
00148                     || status == MESH_CONNECTED_GLOBAL)) {
00149             connect_semaphore.release();
00150         } else if (status == MESH_DISCONNECTED) {
00151             disconnect_semaphore.release();
00152         }
00153     }
00154 
00155 
00156     if (status == MESH_CONNECTED) {
00157         uint8_t temp_ipv6_global[16];
00158         uint8_t temp_ipv6_local[16];
00159         if (arm_net_address_get(interface_id, ADDR_IPV6_LL, temp_ipv6_local) == 0) {
00160             _connect_status = NSAPI_STATUS_LOCAL_UP ;
00161         }
00162         if (arm_net_address_get(interface_id, ADDR_IPV6_GP, temp_ipv6_global) == 0
00163                 && (memcmp(temp_ipv6_global, temp_ipv6_local, 16) != 0)) {
00164             _connect_status = NSAPI_STATUS_GLOBAL_UP ;
00165         }
00166     } else if (status == MESH_CONNECTED_LOCAL) {
00167         _connect_status = NSAPI_STATUS_LOCAL_UP ;
00168     } else if (status == MESH_CONNECTED_GLOBAL) {
00169         _connect_status = NSAPI_STATUS_GLOBAL_UP ;
00170     } else if (status == MESH_BOOTSTRAP_STARTED || status == MESH_BOOTSTRAP_FAILED) {
00171         _connect_status = NSAPI_STATUS_CONNECTING ;
00172     } else {
00173         _connect_status = NSAPI_STATUS_DISCONNECTED ;
00174     }
00175 
00176     if (_connection_status_cb && _previous_connection_status != _connect_status
00177             && (_previous_connection_status != NSAPI_STATUS_GLOBAL_UP  || status != MESH_BOOTSTRAP_STARTED)
00178             && (_previous_connection_status != NSAPI_STATUS_CONNECTING  || status != MESH_BOOTSTRAP_START_FAILED)) {
00179         _connection_status_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE , _connect_status);
00180     }
00181     _previous_connection_status = _connect_status;
00182 }
00183 
00184 nsapi_error_t Nanostack::Interface::register_phy()
00185 {
00186     NanostackLockGuard lock;
00187 
00188     if (_device_id < 0) {
00189         _device_id = interface_phy.phy_register();
00190     }
00191     if (_device_id < 0) {
00192         return NSAPI_ERROR_DEVICE_ERROR ;
00193     }
00194 
00195     return NSAPI_ERROR_OK ;
00196 }
00197 
00198 Nanostack *InterfaceNanostack::get_stack()
00199 {
00200     return &Nanostack::get_instance();
00201 }
00202 
00203 nsapi_error_t InterfaceNanostack::get_ip_address(SocketAddress *address)
00204 {
00205     if (_interface->get_ip_address(address) == NSAPI_ERROR_OK ) {
00206         ip_addr = address->get_ip_address();
00207         return NSAPI_ERROR_OK ;
00208     }
00209 
00210     return NSAPI_ERROR_NO_ADDRESS ;
00211 }
00212 
00213 const char *InterfaceNanostack::get_ip_address()
00214 {
00215     if (_interface->get_ip_address(&ip_addr) == NSAPI_ERROR_OK ) {
00216         return ip_addr.get_ip_address();
00217     }
00218     return NULL;
00219 }
00220 
00221 const char *InterfaceNanostack::get_mac_address()
00222 {
00223     if (_interface->get_mac_address(mac_addr_str, sizeof(mac_addr_str))) {
00224         return mac_addr_str;
00225     }
00226     return NULL;
00227 }
00228 
00229 nsapi_connection_status_t InterfaceNanostack::get_connection_status() const
00230 {
00231     if (_interface) {
00232         return _interface->get_connection_status();
00233     } else {
00234         return NSAPI_STATUS_DISCONNECTED ;
00235     }
00236 }
00237 
00238 void InterfaceNanostack::attach(
00239     mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb)
00240 {
00241     _connection_status_cb = status_cb;
00242     if (_interface) {
00243         _interface->attach(status_cb);
00244     }
00245 }
00246 
00247 nsapi_error_t InterfaceNanostack::set_blocking(bool blocking)
00248 {
00249     _blocking = blocking;
00250     return NSAPI_ERROR_OK ;
00251 }
00252 
00253 nsapi_error_t InterfaceNanostack::set_file_system_root_path(const char *root_path)
00254 {
00255     int status = mesh_system_set_file_system_root_path(root_path);
00256 
00257     if (status == 0) {
00258         return MESH_ERROR_NONE;
00259     } else if (status == -2) {
00260         return MESH_ERROR_MEMORY;
00261     }
00262 
00263     return MESH_ERROR_UNKNOWN;
00264 }
00265 
00266 #if !DEVICE_802_15_4_PHY
00267 MBED_WEAK MeshInterface *MeshInterface::get_target_default_instance()
00268 {
00269     return NULL;
00270 }
00271 #endif