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