takashi kadono / Mbed OS Nucleo_446

Dependencies:   ssd1331

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers LoWPANNDInterface.cpp Source File

LoWPANNDInterface.cpp

00001 #include "LoWPANNDInterface.h"
00002 #include "include/nd_tasklet.h"
00003 #include "callback_handler.h"
00004 #include "NanostackLockGuard.h"
00005 #include "mesh_system.h"
00006 #include "randLIB.h"
00007 
00008 #include "ns_trace.h"
00009 #define TRACE_GROUP "nslp"
00010 
00011 class Nanostack::LoWPANNDInterface : public Nanostack::MeshInterface
00012 {
00013 public:
00014     virtual nsapi_error_t bringup(bool dhcp, const char *ip,
00015                                   const char *netmask, const char *gw,
00016                                   nsapi_ip_stack_t stack = IPV6_STACK,
00017                                   bool blocking = true);
00018     virtual nsapi_error_t bringdown();
00019     virtual char *get_gateway(char *buf, nsapi_size_t buflen);
00020 
00021     friend Nanostack;
00022     friend class ::LoWPANNDInterface;
00023 private:
00024     LoWPANNDInterface(NanostackRfPhy &phy) : MeshInterface(phy) { }
00025     mesh_error_t init();
00026     mesh_error_t mesh_connect();
00027     mesh_error_t mesh_disconnect();
00028 };
00029 
00030 Nanostack::LoWPANNDInterface *LoWPANNDInterface::get_interface() const
00031 {
00032     return static_cast<Nanostack::LoWPANNDInterface*>(_interface);
00033 }
00034 
00035 nsapi_error_t LoWPANNDInterface::do_initialize()
00036 {
00037     if (!_interface) {
00038         _interface = new (nothrow) Nanostack::LoWPANNDInterface(*_phy);
00039         if (!_interface) {
00040             return NSAPI_ERROR_NO_MEMORY ;
00041         }
00042         _interface->attach(_connection_status_cb);
00043     }
00044     return NSAPI_ERROR_OK ;
00045 }
00046 
00047 nsapi_error_t Nanostack::LoWPANNDInterface::bringup(bool dhcp, const char *ip,
00048                                                     const char *netmask, const char *gw,
00049                                                     nsapi_ip_stack_t stack, bool blocking)
00050 {
00051     nanostack_lock();
00052 
00053     if (register_phy() < 0) {
00054         nanostack_unlock();
00055         return NSAPI_ERROR_DEVICE_ERROR ;
00056     }
00057 
00058     _blocking = blocking;
00059 
00060     // After the RF is up, we can seed the random from it.
00061     randLIB_seed_random();
00062 
00063     mesh_error_t status = init();
00064     if (status != MESH_ERROR_NONE) {
00065         nanostack_unlock();
00066         return map_mesh_error(status);
00067     }
00068 
00069     status = mesh_connect();
00070     if (status != MESH_ERROR_NONE) {
00071         nanostack_unlock();
00072         return map_mesh_error(status);
00073     }
00074 
00075     // Release mutex before blocking
00076     nanostack_unlock();
00077 
00078     if (blocking) {
00079         // wait connection for ever
00080         int32_t count = connect_semaphore.wait(osWaitForever);
00081 
00082         if (count <= 0) {
00083             return NSAPI_ERROR_DHCP_FAILURE ; // sort of...
00084         }
00085     }
00086     return 0;
00087 
00088 }
00089 
00090 nsapi_error_t Nanostack::LoWPANNDInterface::bringdown()
00091 {
00092     NanostackLockGuard lock;
00093 
00094     mesh_error_t status = mesh_disconnect();
00095 
00096     return map_mesh_error(status);
00097 }
00098 
00099 mesh_error_t Nanostack::LoWPANNDInterface::init()
00100 {
00101     nd_tasklet_init();
00102     __mesh_handler_set_callback(this);
00103     interface_id = nd_tasklet_network_init(_device_id);
00104 
00105     if (interface_id == -2) {
00106         return MESH_ERROR_PARAM;
00107     } else if (interface_id == -3) {
00108         return MESH_ERROR_MEMORY;
00109     } else if (interface_id < 0) {
00110         return MESH_ERROR_UNKNOWN;
00111     }
00112     return MESH_ERROR_NONE;
00113 }
00114 
00115 mesh_error_t Nanostack::LoWPANNDInterface::mesh_connect()
00116 {
00117     int8_t status = -9; // init to unknown error
00118     tr_debug("connect()");
00119 
00120     status = nd_tasklet_connect(&__mesh_handler_c_callback, interface_id);
00121 
00122     if (status >= 0) {
00123         return MESH_ERROR_NONE;
00124     } else if (status == -1) {
00125         return MESH_ERROR_PARAM;
00126     } else if (status == -2) {
00127         return MESH_ERROR_MEMORY;
00128     } else if (status == -3) {
00129         return MESH_ERROR_STATE;
00130     } else {
00131         return MESH_ERROR_UNKNOWN;
00132     }
00133 }
00134 
00135 mesh_error_t Nanostack::LoWPANNDInterface::mesh_disconnect()
00136 {
00137     int8_t status = -1;
00138 
00139     status = nd_tasklet_disconnect(true);
00140 
00141     if (status >= 0) {
00142         return MESH_ERROR_NONE;
00143     }
00144 
00145     return MESH_ERROR_UNKNOWN;
00146 }
00147 
00148 char *Nanostack::LoWPANNDInterface::get_gateway(char *buf, nsapi_size_t buflen)
00149 {
00150     NanostackLockGuard lock;
00151     if (nd_tasklet_get_router_ip_address(buf, buflen) == 0) {
00152         return buf;
00153     }
00154     return NULL;
00155 }
00156 
00157 bool LoWPANNDInterface::getRouterIpAddress(char *address, int8_t len)
00158 {
00159     return _interface->get_gateway(address, len);
00160 }
00161 
00162 #define LOWPAN 0x2345
00163 #if MBED_CONF_NSAPI_DEFAULT_MESH_TYPE == LOWPAN && DEVICE_802_15_4_PHY
00164 MBED_WEAK MeshInterface *MeshInterface::get_target_default_instance()
00165 {
00166     static LoWPANNDInterface lowpan(&NanostackRfPhy::get_default_instance());
00167 
00168     return &lowpan;
00169 }
00170 #endif