Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
ThreadInterface.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 "ThreadInterface.h" 00018 #include "include/thread_tasklet.h" 00019 #include "callback_handler.h" 00020 #include "mesh_system.h" 00021 #include "randLIB.h" 00022 00023 #include "ns_trace.h" 00024 #define TRACE_GROUP "nsth" 00025 00026 class Nanostack::ThreadInterface : public Nanostack::MeshInterface { 00027 public: 00028 virtual nsapi_error_t bringup(bool dhcp, const char *ip, 00029 const char *netmask, const char *gw, 00030 nsapi_ip_stack_t stack = IPV6_STACK, 00031 bool blocking = true); 00032 virtual nsapi_error_t bringdown(); 00033 friend class Nanostack; 00034 friend class ::ThreadInterface; 00035 private: 00036 ThreadInterface(NanostackRfPhy &phy) : MeshInterface(phy), eui64_set(false) { } 00037 00038 /* 00039 * \brief Initialization of the interface. 00040 * \return MESH_ERROR_NONE on success. 00041 * \return MESH_ERROR_PARAM when input parameters are illegal (also in case when RF device is already associated to other interface) 00042 * \return MESH_ERROR_MEMORY in case of memory error 00043 * \return MESH_ERROR_UNKNOWN in other error cases 00044 */ 00045 mesh_error_t init(); 00046 /** 00047 * \brief Connect interface to the mesh network 00048 * \return MESH_ERROR_NONE on success. 00049 * \return MESH_ERROR_PARAM in case of illegal parameters. 00050 * \return MESH_ERROR_MEMORY in case of memory error. 00051 * \return MESH_ERROR_STATE if interface is already connected to network. 00052 * \return MESH_ERROR_UNKNOWN in case of unspecified error. 00053 * */ 00054 mesh_error_t mesh_connect(); 00055 00056 /** 00057 * \brief Disconnect interface from the mesh network 00058 * \return MESH_ERROR_NONE on success. 00059 * \return MESH_ERROR_UNKNOWN in case of error. 00060 * */ 00061 mesh_error_t mesh_disconnect(); 00062 00063 /** 00064 * \brief Sets the eui64 for the device configuration. 00065 * By default this value is read from the radio driver. 00066 * The value must be set before calling the connect function. 00067 * */ 00068 void device_eui64_set(const uint8_t *eui64); 00069 00070 /** 00071 * \brief Reads the eui64 from the device configuration. 00072 * */ 00073 void device_eui64_get(uint8_t *eui64); 00074 00075 /** 00076 * \brief sets the PSKd for the device configuration. 00077 * The default value is overwritten, which is defined in the mbed_lib.json file in the mesh-api 00078 * The value must be set before calling the connect function. 00079 * \return MESH_ERROR_NONE on success. 00080 * \return MESH_ERROR_PARAM in case of illegal parameters. 00081 * \return MESH_ERROR_MEMORY in case of memory error. 00082 * */ 00083 00084 mesh_error_t device_pskd_set(const char *pskd); 00085 00086 bool eui64_set; 00087 }; 00088 00089 Nanostack::ThreadInterface *ThreadInterface::get_interface() const 00090 { 00091 return static_cast<Nanostack::ThreadInterface *>(_interface); 00092 } 00093 00094 nsapi_error_t ThreadInterface::do_initialize() 00095 { 00096 if (!_interface) { 00097 _interface = new (std::nothrow) Nanostack::ThreadInterface(*_phy); 00098 if (!_interface) { 00099 return NSAPI_ERROR_NO_MEMORY ; 00100 } 00101 _interface->attach(_connection_status_cb); 00102 } 00103 return NSAPI_ERROR_OK ; 00104 } 00105 00106 nsapi_error_t Nanostack::ThreadInterface::bringup(bool dhcp, const char *ip, 00107 const char *netmask, const char *gw, 00108 nsapi_ip_stack_t stack, bool blocking) 00109 { 00110 if (_connect_status == NSAPI_STATUS_GLOBAL_UP || _connect_status == NSAPI_STATUS_LOCAL_UP ) { 00111 return NSAPI_ERROR_IS_CONNECTED ; 00112 } else if (_connect_status == NSAPI_STATUS_CONNECTING ) { 00113 return NSAPI_ERROR_ALREADY ; 00114 } 00115 00116 if (stack == IPV4_STACK) { 00117 return NSAPI_ERROR_UNSUPPORTED ; 00118 } 00119 00120 if (register_phy() < 0) { 00121 return NSAPI_ERROR_DEVICE_ERROR ; 00122 } 00123 nanostack_lock(); 00124 00125 _blocking = blocking; 00126 00127 // After the RF is up, we can seed the random from it. 00128 randLIB_seed_random(); 00129 00130 mesh_error_t status = init(); 00131 if (status != MESH_ERROR_NONE) { 00132 nanostack_unlock(); 00133 return map_mesh_error(status); 00134 } 00135 00136 status = mesh_connect(); 00137 if (status != MESH_ERROR_NONE) { 00138 nanostack_unlock(); 00139 return map_mesh_error(status); 00140 } 00141 00142 // Release mutex before blocking 00143 nanostack_unlock(); 00144 00145 // In Thread wait connection for ever: 00146 // -routers will create new network and get local connectivity 00147 // -end devices will get connectivity once attached to existing network 00148 // -devices without network settings gets connectivity once commissioned and attached to network 00149 _connect_status = NSAPI_STATUS_CONNECTING ; 00150 if (_blocking) { 00151 connect_semaphore.acquire(); 00152 } 00153 return 0; 00154 } 00155 00156 nsapi_error_t Nanostack::ThreadInterface::bringdown() 00157 { 00158 nanostack_lock(); 00159 00160 mesh_error_t status = mesh_disconnect(); 00161 00162 nanostack_unlock(); 00163 00164 return map_mesh_error(status); 00165 } 00166 00167 mesh_error_t Nanostack::ThreadInterface::init() 00168 { 00169 thread_tasklet_init(); 00170 __mesh_handler_set_callback(this); 00171 device_eui64_get(NULL); // Ensure we've selected the EUI-64 - this does it 00172 interface_id = thread_tasklet_network_init(_device_id); 00173 00174 if (interface_id == -2) { 00175 return MESH_ERROR_PARAM; 00176 } else if (interface_id == -3) { 00177 return MESH_ERROR_MEMORY; 00178 } else if (interface_id < 0) { 00179 return MESH_ERROR_UNKNOWN; 00180 } 00181 return MESH_ERROR_NONE; 00182 } 00183 00184 mesh_error_t Nanostack::ThreadInterface::mesh_connect() 00185 { 00186 int8_t status; 00187 tr_debug("connect()"); 00188 00189 status = thread_tasklet_connect(&__mesh_handler_c_callback, interface_id); 00190 00191 if (status >= 0) { 00192 return MESH_ERROR_NONE; 00193 } else if (status == -1) { 00194 return MESH_ERROR_PARAM; 00195 } else if (status == -2) { 00196 return MESH_ERROR_MEMORY; 00197 } else if (status == -3) { 00198 return MESH_ERROR_STATE; 00199 } else { 00200 return MESH_ERROR_UNKNOWN; 00201 } 00202 } 00203 00204 mesh_error_t Nanostack::ThreadInterface::mesh_disconnect() 00205 { 00206 int8_t status; 00207 00208 status = thread_tasklet_disconnect(true); 00209 00210 if (status >= 0) { 00211 return MESH_ERROR_NONE; 00212 } 00213 00214 return MESH_ERROR_UNKNOWN; 00215 } 00216 00217 void ThreadInterface::device_eui64_set(const uint8_t *eui64) 00218 { 00219 get_interface()->device_eui64_set(eui64); 00220 } 00221 00222 void ThreadInterface::device_eui64_get(uint8_t *eui64) 00223 { 00224 memset(eui64, 0, 8); 00225 if (!get_interface()) { 00226 return; 00227 } 00228 get_interface()->device_eui64_get(eui64); 00229 } 00230 00231 void Nanostack::ThreadInterface::device_eui64_set(const uint8_t *eui64) 00232 { 00233 eui64_set = true; 00234 thread_tasklet_device_eui64_set(eui64); 00235 } 00236 00237 void Nanostack::ThreadInterface::device_eui64_get(uint8_t *eui64) 00238 { 00239 if (!eui64_set) { 00240 uint8_t eui64_buf[8]; 00241 if (register_phy() < 0) { 00242 return; 00243 } 00244 get_phy().get_mac_address(eui64_buf); 00245 device_eui64_set(eui64_buf); 00246 } 00247 00248 if (eui64) { 00249 thread_tasklet_device_eui64_get(eui64); 00250 } 00251 } 00252 00253 mesh_error_t ThreadInterface::device_pskd_set(const char *pskd) 00254 { 00255 return get_interface()->device_pskd_set(pskd); 00256 } 00257 00258 mesh_error_t Nanostack::ThreadInterface::device_pskd_set(const char *pskd) 00259 { 00260 return (mesh_error_t)thread_tasklet_device_pskd_set(pskd); 00261 } 00262 00263 #define THREAD 0x2345 00264 #if MBED_CONF_NSAPI_DEFAULT_MESH_TYPE == THREAD && DEVICE_802_15_4_PHY 00265 00266 MBED_WEAK MeshInterface *MeshInterface::get_target_default_instance() 00267 { 00268 static bool inited; 00269 static ThreadInterface interface; 00270 singleton_lock(); 00271 if (!inited) { 00272 nsapi_error_t result = interface.initialize(&NanostackRfPhy::get_default_instance()); 00273 if (result != 0) { 00274 tr_error("Thread initialize failed: %d", result); 00275 singleton_unlock(); 00276 return NULL; 00277 } 00278 inited = true; 00279 } 00280 singleton_unlock(); 00281 return &interface; 00282 } 00283 #endif
Generated on Tue Jul 12 2022 13:55:00 by
