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