mirror of https://github.com/ARMmbed/mbed-os.git
Nanostack EMAC implementation
Make Nanostack an OnboardNetworkInterface, implementing add_ethernet_interface so it can use EMAC drivers. Can now be used via EthernetInterface, and be the system's default network stack. Legacy support for NanostackEthernetInterface retained. Some restructuring of mesh interface code to fit into the OnboardNetworkStack:::Interface system.pull/6847/head
parent
a0d374ef00
commit
3c83c62ff7
|
@ -30,22 +30,16 @@ public:
|
|||
*
|
||||
* Must initialize to initialize the mesh on a phy.
|
||||
*/
|
||||
LoWPANNDInterface() : MeshInterfaceNanostack() { }
|
||||
LoWPANNDInterface() { }
|
||||
|
||||
/** Create an initialized MeshInterface
|
||||
/** Create an initialized LoWPANNDInterface
|
||||
*
|
||||
*/
|
||||
LoWPANNDInterface(NanostackRfPhy *phy) : MeshInterfaceNanostack(phy) { }
|
||||
|
||||
nsapi_error_t initialize(NanostackRfPhy *phy);
|
||||
virtual int connect();
|
||||
virtual int disconnect();
|
||||
virtual bool getOwnIpAddress(char *address, int8_t len);
|
||||
bool getRouterIpAddress(char *address, int8_t len);
|
||||
private:
|
||||
mesh_error_t init();
|
||||
mesh_error_t mesh_connect();
|
||||
mesh_error_t mesh_disconnect();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -20,36 +20,53 @@
|
|||
|
||||
#include "MeshInterface.h"
|
||||
#include "NanostackRfPhy.h"
|
||||
#include "Nanostack.h"
|
||||
#include "mesh_interface_types.h"
|
||||
|
||||
/** Nanostack's network interface class.
|
||||
*
|
||||
* Common class that is shared between mesh interface classes
|
||||
*/
|
||||
class MeshInterfaceNanostack : public MeshInterface {
|
||||
class Nanostack::Interface : public OnboardNetworkStack::Interface, private mbed::NonCopyable<Nanostack::Interface> {
|
||||
public:
|
||||
virtual char *get_ip_address(char *buf, nsapi_size_t buflen);
|
||||
virtual char *get_mac_address(char *buf, nsapi_size_t buflen);
|
||||
virtual char *get_netmask(char *buf, nsapi_size_t buflen);
|
||||
virtual char *get_gateway(char *buf, nsapi_size_t buflen);
|
||||
virtual void attach(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb);
|
||||
virtual nsapi_connection_status_t get_connection_status() const;
|
||||
|
||||
/** Attach phy and initialize the mesh
|
||||
*
|
||||
* Initializes a mesh interface on the given phy. Not needed if
|
||||
* the phy is passed to the mesh's constructor.
|
||||
*
|
||||
* @return 0 on success, negative on failure
|
||||
*/
|
||||
nsapi_error_t initialize(NanostackPhy *phy);
|
||||
void get_mac_address(uint8_t *buf) const { interface_phy.get_mac_address(buf); }
|
||||
|
||||
/** Start the interface
|
||||
*
|
||||
* @return 0 on success, negative on failure
|
||||
*/
|
||||
virtual nsapi_error_t connect() = 0;
|
||||
/**
|
||||
* \brief Callback from C-layer
|
||||
* \param status state of the network
|
||||
* */
|
||||
void network_handler(mesh_connection_status_t status);
|
||||
|
||||
/** Stop the interface
|
||||
*
|
||||
* @return 0 on success, negative on failure
|
||||
*/
|
||||
virtual nsapi_error_t disconnect() = 0;
|
||||
int8_t get_interface_id() const { return interface_id; }
|
||||
int8_t get_driver_id() const { return _device_id; }
|
||||
|
||||
private:
|
||||
NanostackPhy &interface_phy;
|
||||
protected:
|
||||
Interface(NanostackPhy &phy);
|
||||
virtual nsapi_error_t register_phy();
|
||||
NanostackPhy &get_phy() const { return interface_phy; }
|
||||
int8_t interface_id;
|
||||
int8_t _device_id;
|
||||
Semaphore connect_semaphore;
|
||||
|
||||
Callback<void(nsapi_event_t, intptr_t)> _connection_status_cb;
|
||||
nsapi_connection_status_t _connect_status;
|
||||
bool _blocking;
|
||||
};
|
||||
|
||||
class Nanostack::MeshInterface : public Nanostack::Interface {
|
||||
protected:
|
||||
MeshInterface(NanostackRfPhy &phy) : Interface(phy) { }
|
||||
NanostackRfPhy &get_phy() const { return static_cast<NanostackRfPhy &>(Interface::get_phy()); }
|
||||
};
|
||||
|
||||
|
||||
class InterfaceNanostack : public virtual NetworkInterface {
|
||||
public:
|
||||
/** Get the internally stored IP address
|
||||
/return IP address of the interface or null if not yet connected
|
||||
*/
|
||||
|
@ -60,18 +77,11 @@ public:
|
|||
*/
|
||||
virtual const char *get_mac_address();
|
||||
|
||||
/** Get the interface ID
|
||||
/return Interface identifier
|
||||
*/
|
||||
int8_t get_interface_id() const { return _network_interface_id; }
|
||||
|
||||
/**
|
||||
* \brief Callback from C-layer
|
||||
* \param status state of the network
|
||||
* */
|
||||
void mesh_network_handler(mesh_connection_status_t status);
|
||||
|
||||
/** Register callback for status reporting
|
||||
*
|
||||
* The specified status callback function will be called on status changes
|
||||
* on the network. The parameters on the callback are the event type and
|
||||
* event-type dependent reason parameter.
|
||||
*
|
||||
* @param status_cb The callback for status changes
|
||||
*/
|
||||
|
@ -90,34 +100,41 @@ public:
|
|||
*/
|
||||
virtual nsapi_error_t set_blocking(bool blocking);
|
||||
|
||||
/** Get the interface ID
|
||||
/return Interface identifier
|
||||
*/
|
||||
int8_t get_interface_id() const { return _interface->get_interface_id(); }
|
||||
|
||||
protected:
|
||||
MeshInterfaceNanostack();
|
||||
MeshInterfaceNanostack(NanostackPhy *phy);
|
||||
nsapi_error_t register_phy();
|
||||
virtual NetworkStack * get_stack(void);
|
||||
InterfaceNanostack();
|
||||
virtual Nanostack *get_stack(void);
|
||||
Nanostack::Interface *get_interface() const { return _interface; }
|
||||
|
||||
/**
|
||||
* \brief Read own global IP address
|
||||
*
|
||||
* \param address is where the IP address will be copied
|
||||
* \param len is the length of the address buffer, must be at least 40 bytes
|
||||
* \return true if address is read successfully, false otherwise
|
||||
*/
|
||||
virtual bool getOwnIpAddress(char *address, int8_t len) = 0;
|
||||
Nanostack::Interface *_interface;
|
||||
|
||||
NanostackPhy *phy;
|
||||
/** Network interface ID */
|
||||
int8_t _network_interface_id;
|
||||
/** Registered device ID */
|
||||
int8_t _device_id;
|
||||
uint8_t _eui64[8];
|
||||
char ip_addr_str[40];
|
||||
char mac_addr_str[24];
|
||||
Semaphore connect_semaphore;
|
||||
|
||||
Callback<void(nsapi_event_t, intptr_t)> _connection_status_cb;
|
||||
nsapi_connection_status_t _connect_status;
|
||||
mbed::Callback<void(nsapi_event_t, intptr_t)> _connection_status_cb;
|
||||
bool _blocking;
|
||||
};
|
||||
|
||||
class MeshInterfaceNanostack : public InterfaceNanostack, public MeshInterface, private mbed::NonCopyable<MeshInterfaceNanostack> {
|
||||
public:
|
||||
|
||||
/** Attach phy and initialize the mesh
|
||||
*
|
||||
* Initializes a mesh interface on the given phy. Not needed if
|
||||
* the phy is passed to the mesh's constructor.
|
||||
*
|
||||
* @return 0 on success, negative on failure
|
||||
*/
|
||||
nsapi_error_t initialize(NanostackRfPhy *phy);
|
||||
|
||||
protected:
|
||||
MeshInterfaceNanostack() : _phy(NULL) { }
|
||||
MeshInterfaceNanostack(NanostackRfPhy *phy) : _phy(phy) { }
|
||||
Nanostack::MeshInterface *get_interface() const { return static_cast<Nanostack::MeshInterface *>(_interface); }
|
||||
NanostackRfPhy *_phy;
|
||||
};
|
||||
|
||||
#endif /* MESHINTERFACENANOSTACK_H */
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (c) 2016 ARM Limited. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef NANOSTACKEMACINTERFACE_H
|
||||
#define NANOSTACKEMACINTERFACE_H
|
||||
|
||||
#include "MeshInterfaceNanostack.h"
|
||||
#include "NanostackEthernetPhy.h"
|
||||
|
||||
class NanostackEMACInterface : public Nanostack::Interface {
|
||||
public:
|
||||
|
||||
NanostackEMACInterface(EMAC &emac);
|
||||
};
|
||||
|
||||
#endif // NANOSTACKEMACINTERFACE_H
|
|
@ -17,24 +17,53 @@
|
|||
#ifndef NANOSTACKETHERNETINTERFACE_H
|
||||
#define NANOSTACKETHERNETINTERFACE_H
|
||||
|
||||
#include "EthInterface.h"
|
||||
#include "MeshInterfaceNanostack.h"
|
||||
#include "NanostackEthernetPhy.h"
|
||||
|
||||
class Nanostack::EthernetInterface : public Nanostack::Interface {
|
||||
public:
|
||||
virtual nsapi_error_t bringup(bool dhcp, const char *ip,
|
||||
const char *netmask, const char *gw,
|
||||
nsapi_ip_stack_t stack = DEFAULT_STACK,
|
||||
bool blocking = true);
|
||||
virtual nsapi_error_t bringdown();
|
||||
|
||||
private:
|
||||
friend Nanostack;
|
||||
friend class NanostackEthernetInterface;
|
||||
EthernetInterface(NanostackEthernetPhy &phy) : Interface(phy) {}
|
||||
nsapi_error_t initialize();
|
||||
protected:
|
||||
NanostackEthernetPhy &get_phy() const { return static_cast<NanostackEthernetPhy &>(Interface::get_phy()); }
|
||||
};
|
||||
|
||||
/** Ethernet interface for Nanostack.
|
||||
*
|
||||
* Configure Nanostack to use Ethernet connectivity.
|
||||
*/
|
||||
class NanostackEthernetInterface : public MeshInterfaceNanostack {
|
||||
class NanostackEthernetInterface : public InterfaceNanostack, public EthInterface, private mbed::NonCopyable<NanostackEthernetInterface> {
|
||||
public:
|
||||
|
||||
NanostackEthernetInterface() : MeshInterfaceNanostack() { }
|
||||
NanostackEthernetInterface(NanostackEthernetPhy *phy) : MeshInterfaceNanostack(phy) { }
|
||||
NanostackEthernetInterface() { }
|
||||
//NanostackEthernetInterface(NanostackEthernetPhy *phy);
|
||||
|
||||
nsapi_error_t initialize(NanostackEthernetPhy *phy);
|
||||
virtual int connect();
|
||||
virtual int disconnect();
|
||||
virtual bool getOwnIpAddress(char *address, int8_t len);
|
||||
bool getRouterIpAddress(char *address, int8_t len);
|
||||
|
||||
/** Start the interface
|
||||
*
|
||||
* @return 0 on success, negative on failure
|
||||
*/
|
||||
virtual nsapi_error_t connect();
|
||||
|
||||
/** Stop the interface
|
||||
*
|
||||
* @return 0 on success, negative on failure
|
||||
*/
|
||||
virtual nsapi_error_t disconnect();
|
||||
|
||||
protected:
|
||||
Nanostack::EthernetInterface *get_interface() const { return static_cast<Nanostack::EthernetInterface *>(_interface); }
|
||||
|
||||
};
|
||||
|
||||
#endif // NANOSTACKETHERNETINTERFACE_H
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (c) 2016 ARM Limited. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef NANOSTACKRFINTERFACE_H
|
||||
#define NANOSTACKRFINTERFACE_H
|
||||
|
||||
#include "MeshInterfaceNanostack.h"
|
||||
#include "NanostackRfPhy.h"
|
||||
|
||||
class NanostackRfInterface : public Nanostack::Interface {
|
||||
public:
|
||||
|
||||
NanostackRfInterface(NanostackRfPhy &phy);
|
||||
};
|
||||
|
||||
#endif // NANOSTACKRFINTERFACE_H
|
|
@ -26,18 +26,16 @@
|
|||
class ThreadInterface : public MeshInterfaceNanostack {
|
||||
public:
|
||||
|
||||
/** Create an uninitialized LoWPANNDInterface
|
||||
/** Create an uninitialized ThreadInterface
|
||||
*
|
||||
* Must initialize to initialize the mesh on a phy.
|
||||
*/
|
||||
ThreadInterface() : MeshInterfaceNanostack() { }
|
||||
ThreadInterface() : user_set_eui64(false) { }
|
||||
|
||||
/** Create an initialized MeshInterface
|
||||
/** Create an initialized ThreadInterface
|
||||
*
|
||||
*/
|
||||
ThreadInterface(NanostackRfPhy *phy) : MeshInterfaceNanostack(phy) { }
|
||||
|
||||
nsapi_error_t initialize(NanostackRfPhy *phy);
|
||||
ThreadInterface(NanostackRfPhy *phy) : MeshInterfaceNanostack(phy), user_set_eui64(false) { }
|
||||
|
||||
/**
|
||||
* \brief Sets the eui64 for the device configuration.
|
||||
|
@ -59,40 +57,11 @@ public:
|
|||
|
||||
virtual int connect();
|
||||
virtual int disconnect();
|
||||
protected:
|
||||
Nanostack::ThreadInterface *get_interface() const;
|
||||
|
||||
private:
|
||||
/*
|
||||
* \brief Initialization of the interface.
|
||||
* \return MESH_ERROR_NONE on success.
|
||||
* \return MESH_ERROR_PARAM when input parameters are illegal (also in case when RF device is already associated to other interface)
|
||||
* \return MESH_ERROR_MEMORY in case of memory error
|
||||
* \return MESH_ERROR_UNKNOWN in other error cases
|
||||
*/
|
||||
mesh_error_t init();
|
||||
/**
|
||||
* \brief Connect interface to the mesh network
|
||||
* \return MESH_ERROR_NONE on success.
|
||||
* \return MESH_ERROR_PARAM in case of illegal parameters.
|
||||
* \return MESH_ERROR_MEMORY in case of memory error.
|
||||
* \return MESH_ERROR_STATE if interface is already connected to network.
|
||||
* \return MESH_ERROR_UNKNOWN in case of unspecified error.
|
||||
* */
|
||||
mesh_error_t mesh_connect();
|
||||
|
||||
/**
|
||||
* \brief Disconnect interface from the mesh network
|
||||
* \return MESH_ERROR_NONE on success.
|
||||
* \return MESH_ERROR_UNKNOWN in case of error.
|
||||
* */
|
||||
mesh_error_t mesh_disconnect();
|
||||
|
||||
/**
|
||||
* \brief Read own global IP address
|
||||
*
|
||||
* \param address is where the IP address will be copied
|
||||
* \param len is the length of the address buffer, must be at least 40 bytes
|
||||
* \return true if address is read successfully, false otherwise
|
||||
*/
|
||||
virtual bool getOwnIpAddress(char *address, int8_t len);
|
||||
bool user_set_eui64;
|
||||
};
|
||||
|
||||
#endif // THREADINTERFACE_H
|
||||
|
|
|
@ -14,20 +14,21 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "MeshInterfaceNanostack.h"
|
||||
|
||||
#include "include/callback_handler.h"
|
||||
|
||||
|
||||
static MeshInterfaceNanostack *_handler = NULL;
|
||||
static Nanostack::Interface *_handler = NULL;
|
||||
|
||||
void __mesh_handler_c_callback(mesh_connection_status_t state)
|
||||
{
|
||||
|
||||
if (_handler) {
|
||||
_handler->mesh_network_handler(state);
|
||||
_handler->network_handler(state);
|
||||
}
|
||||
}
|
||||
|
||||
void __mesh_handler_set_callback(MeshInterfaceNanostack *handler)
|
||||
void __mesh_handler_set_callback(Nanostack::Interface *handler)
|
||||
{
|
||||
_handler = handler;
|
||||
}
|
||||
|
|
|
@ -1,18 +1,49 @@
|
|||
#include "LoWPANNDInterface.h"
|
||||
#include "include/nd_tasklet.h"
|
||||
#include "callback_handler.h"
|
||||
#include "NanostackLockGuard.h"
|
||||
#include "mesh_system.h"
|
||||
#include "randLIB.h"
|
||||
|
||||
#include "ns_trace.h"
|
||||
#define TRACE_GROUP "nslp"
|
||||
|
||||
nsapi_error_t LoWPANNDInterface::initialize(NanostackRfPhy *phy)
|
||||
class Nanostack::LoWPANNDInterface : public Nanostack::MeshInterface
|
||||
{
|
||||
return MeshInterfaceNanostack::initialize(phy);
|
||||
}
|
||||
public:
|
||||
virtual nsapi_error_t bringup(bool dhcp, const char *ip,
|
||||
const char *netmask, const char *gw,
|
||||
nsapi_ip_stack_t stack = IPV6_STACK,
|
||||
bool blocking = true);
|
||||
virtual nsapi_error_t bringdown();
|
||||
virtual char *get_gateway(char *buf, nsapi_size_t buflen);
|
||||
|
||||
friend Nanostack;
|
||||
friend class ::LoWPANNDInterface;
|
||||
private:
|
||||
LoWPANNDInterface(NanostackRfPhy &phy) : MeshInterface(phy) { }
|
||||
mesh_error_t init();
|
||||
mesh_error_t mesh_connect();
|
||||
mesh_error_t mesh_disconnect();
|
||||
};
|
||||
|
||||
int LoWPANNDInterface::connect()
|
||||
{
|
||||
if (!_interface) {
|
||||
_interface = new (nothrow) Nanostack::LoWPANNDInterface(*_phy);
|
||||
if (!_interface) {
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
_interface->attach(_connection_status_cb);
|
||||
}
|
||||
|
||||
return _interface->bringup(false, NULL, NULL, NULL, IPV6_STACK, _blocking);
|
||||
|
||||
}
|
||||
|
||||
nsapi_error_t Nanostack::LoWPANNDInterface::bringup(bool dhcp, const char *ip,
|
||||
const char *netmask, const char *gw,
|
||||
nsapi_ip_stack_t stack, bool blocking)
|
||||
{
|
||||
nanostack_lock();
|
||||
|
||||
|
@ -21,6 +52,8 @@ int LoWPANNDInterface::connect()
|
|||
return NSAPI_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
_blocking = blocking;
|
||||
|
||||
// After the RF is up, we can seed the random from it.
|
||||
randLIB_seed_random();
|
||||
|
||||
|
@ -39,11 +72,13 @@ int LoWPANNDInterface::connect()
|
|||
// Release mutex before blocking
|
||||
nanostack_unlock();
|
||||
|
||||
// wait connection for ever
|
||||
int32_t count = connect_semaphore.wait(osWaitForever);
|
||||
if (blocking) {
|
||||
// wait connection for ever
|
||||
int32_t count = connect_semaphore.wait(osWaitForever);
|
||||
|
||||
if (count <= 0) {
|
||||
return NSAPI_ERROR_DHCP_FAILURE; // sort of...
|
||||
if (count <= 0) {
|
||||
return NSAPI_ERROR_DHCP_FAILURE; // sort of...
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
|
@ -51,37 +86,40 @@ int LoWPANNDInterface::connect()
|
|||
|
||||
int LoWPANNDInterface::disconnect()
|
||||
{
|
||||
nanostack_lock();
|
||||
return _interface->bringdown();
|
||||
}
|
||||
|
||||
nsapi_error_t Nanostack::LoWPANNDInterface::bringdown()
|
||||
{
|
||||
NanostackLockGuard lock;
|
||||
|
||||
mesh_error_t status = mesh_disconnect();
|
||||
|
||||
nanostack_unlock();
|
||||
|
||||
return map_mesh_error(status);
|
||||
}
|
||||
|
||||
mesh_error_t LoWPANNDInterface::init()
|
||||
mesh_error_t Nanostack::LoWPANNDInterface::init()
|
||||
{
|
||||
nd_tasklet_init();
|
||||
__mesh_handler_set_callback(this);
|
||||
_network_interface_id = nd_tasklet_network_init(_device_id);
|
||||
interface_id = nd_tasklet_network_init(_device_id);
|
||||
|
||||
if (_network_interface_id == -2) {
|
||||
if (interface_id == -2) {
|
||||
return MESH_ERROR_PARAM;
|
||||
} else if (_network_interface_id == -3) {
|
||||
} else if (interface_id == -3) {
|
||||
return MESH_ERROR_MEMORY;
|
||||
} else if (_network_interface_id < 0) {
|
||||
} else if (interface_id < 0) {
|
||||
return MESH_ERROR_UNKNOWN;
|
||||
}
|
||||
return MESH_ERROR_NONE;
|
||||
}
|
||||
|
||||
mesh_error_t LoWPANNDInterface::mesh_connect()
|
||||
mesh_error_t Nanostack::LoWPANNDInterface::mesh_connect()
|
||||
{
|
||||
int8_t status = -9; // init to unknown error
|
||||
tr_debug("connect()");
|
||||
|
||||
status = nd_tasklet_connect(&__mesh_handler_c_callback, _network_interface_id);
|
||||
status = nd_tasklet_connect(&__mesh_handler_c_callback, interface_id);
|
||||
|
||||
if (status >= 0) {
|
||||
return MESH_ERROR_NONE;
|
||||
|
@ -96,7 +134,7 @@ mesh_error_t LoWPANNDInterface::mesh_connect()
|
|||
}
|
||||
}
|
||||
|
||||
mesh_error_t LoWPANNDInterface::mesh_disconnect()
|
||||
mesh_error_t Nanostack::LoWPANNDInterface::mesh_disconnect()
|
||||
{
|
||||
int8_t status = -1;
|
||||
|
||||
|
@ -109,20 +147,16 @@ mesh_error_t LoWPANNDInterface::mesh_disconnect()
|
|||
return MESH_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
bool LoWPANNDInterface::getOwnIpAddress(char *address, int8_t len)
|
||||
char *Nanostack::LoWPANNDInterface::get_gateway(char *buf, nsapi_size_t buflen)
|
||||
{
|
||||
tr_debug("getOwnIpAddress()");
|
||||
if (nd_tasklet_get_ip_address(address, len) == 0) {
|
||||
return true;
|
||||
NanostackLockGuard lock;
|
||||
if (nd_tasklet_get_router_ip_address(buf, buflen) == 0) {
|
||||
return buf;
|
||||
}
|
||||
return false;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool LoWPANNDInterface::getRouterIpAddress(char *address, int8_t len)
|
||||
{
|
||||
tr_debug("getRouterIpAddress()");
|
||||
if (nd_tasklet_get_router_ip_address(address, len) == 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return _interface->get_gateway(address, len);
|
||||
}
|
||||
|
|
|
@ -15,56 +15,99 @@
|
|||
*/
|
||||
|
||||
#include "MeshInterfaceNanostack.h"
|
||||
#include "NanostackInterface.h"
|
||||
#include "Nanostack.h"
|
||||
#include "NanostackLockGuard.h"
|
||||
#include "mesh_system.h"
|
||||
#include "net_interface.h"
|
||||
#include "nanostack/net_interface.h"
|
||||
#include "thread_management_if.h"
|
||||
#include "ip6string.h"
|
||||
|
||||
|
||||
MeshInterfaceNanostack::MeshInterfaceNanostack()
|
||||
: phy(NULL), _network_interface_id(-1), _device_id(-1), _eui64(),
|
||||
ip_addr_str(), mac_addr_str(), connect_semaphore(0),
|
||||
_connection_status_cb(NULL), _connect_status(NSAPI_STATUS_DISCONNECTED),
|
||||
_blocking(true)
|
||||
char *Nanostack::Interface::get_ip_address(char *buf, nsapi_size_t buflen)
|
||||
{
|
||||
// Nothing to do
|
||||
NanostackLockGuard lock;
|
||||
uint8_t binary_ipv6[16];
|
||||
|
||||
if (buflen >= 40 && arm_net_address_get(interface_id, ADDR_IPV6_GP, binary_ipv6) == 0) {
|
||||
ip6tos(binary_ipv6, buf);
|
||||
return buf;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
MeshInterfaceNanostack::MeshInterfaceNanostack(NanostackPhy *phy)
|
||||
: phy(phy), _network_interface_id(-1), _device_id(-1), connect_semaphore(0)
|
||||
char *Nanostack::Interface::get_mac_address(char *buf, nsapi_size_t buflen)
|
||||
{
|
||||
// Nothing to do
|
||||
NanostackLockGuard lock;
|
||||
link_layer_address_s addr;
|
||||
if (buflen >= 24 && arm_nwk_mac_address_read(interface_id, &addr) == 0) {
|
||||
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]);
|
||||
return buf;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
nsapi_error_t MeshInterfaceNanostack::initialize(NanostackPhy *phy)
|
||||
char *Nanostack::Interface::get_netmask(char *, nsapi_size_t)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *Nanostack::Interface::get_gateway(char *, nsapi_size_t)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nsapi_connection_status_t Nanostack::Interface::get_connection_status() const
|
||||
{
|
||||
return _connect_status;
|
||||
}
|
||||
|
||||
void Nanostack::Interface::attach(
|
||||
mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb)
|
||||
{
|
||||
_connection_status_cb = status_cb;
|
||||
}
|
||||
|
||||
Nanostack::Interface::Interface(NanostackPhy &phy) : interface_phy(phy), interface_id(-1), _device_id(-1),
|
||||
_connect_status(NSAPI_STATUS_DISCONNECTED), _blocking(true)
|
||||
{
|
||||
mesh_system_init();
|
||||
if (this->phy != NULL) {
|
||||
error("Phy already set");
|
||||
}
|
||||
this->phy = phy;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MeshInterfaceNanostack::mesh_network_handler(mesh_connection_status_t status)
|
||||
{
|
||||
nanostack_lock();
|
||||
|
||||
InterfaceNanostack::InterfaceNanostack()
|
||||
: _interface(NULL),
|
||||
ip_addr_str(), mac_addr_str(), _blocking(true)
|
||||
{
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
nsapi_error_t MeshInterfaceNanostack::initialize(NanostackRfPhy *phy)
|
||||
{
|
||||
if (_phy) {
|
||||
error("Phy already set");
|
||||
return NSAPI_ERROR_IS_CONNECTED;
|
||||
}
|
||||
_phy = phy;
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
|
||||
void Nanostack::Interface::network_handler(mesh_connection_status_t status)
|
||||
{
|
||||
if ((status == MESH_CONNECTED || status == MESH_CONNECTED_LOCAL ||
|
||||
status == MESH_CONNECTED_GLOBAL) && _blocking) {
|
||||
connect_semaphore.release();
|
||||
}
|
||||
|
||||
nanostack_unlock();
|
||||
|
||||
|
||||
if (status == MESH_CONNECTED) {
|
||||
uint8_t temp_ipv6_global[16];
|
||||
uint8_t temp_ipv6_local[16];
|
||||
if (arm_net_address_get(_network_interface_id, ADDR_IPV6_LL, temp_ipv6_local) == 0) {
|
||||
if (arm_net_address_get(interface_id, ADDR_IPV6_LL, temp_ipv6_local) == 0) {
|
||||
_connect_status = NSAPI_STATUS_LOCAL_UP;
|
||||
}
|
||||
if (arm_net_address_get(_network_interface_id, ADDR_IPV6_GP, temp_ipv6_global) == 0
|
||||
if (arm_net_address_get(interface_id, ADDR_IPV6_GP, temp_ipv6_global) == 0
|
||||
&& (memcmp(temp_ipv6_global, temp_ipv6_local, 16) != 0)) {
|
||||
_connect_status = NSAPI_STATUS_GLOBAL_UP;
|
||||
}
|
||||
|
@ -83,65 +126,58 @@ void MeshInterfaceNanostack::mesh_network_handler(mesh_connection_status_t statu
|
|||
}
|
||||
}
|
||||
|
||||
nsapi_error_t MeshInterfaceNanostack::register_phy()
|
||||
nsapi_error_t Nanostack::Interface::register_phy()
|
||||
{
|
||||
nanostack_lock();
|
||||
NanostackLockGuard lock;
|
||||
|
||||
_device_id = phy->phy_register();
|
||||
_device_id = interface_phy.phy_register();
|
||||
if (_device_id < 0) {
|
||||
nanostack_unlock();
|
||||
return -1;
|
||||
}
|
||||
// Read mac address after registering the device.
|
||||
const uint8_t empty_eui64[8] = {0,0,0,0,0,0,0,0};
|
||||
// if not set by application then read from rf driver
|
||||
if(!memcmp(_eui64, empty_eui64,8)) {
|
||||
phy->get_mac_address(_eui64);
|
||||
return NSAPI_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
sprintf(mac_addr_str, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", _eui64[0], _eui64[1], _eui64[2], _eui64[3], _eui64[4], _eui64[5], _eui64[6], _eui64[7]);
|
||||
|
||||
nanostack_unlock();
|
||||
|
||||
return 0;
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
NetworkStack * MeshInterfaceNanostack::get_stack()
|
||||
Nanostack *InterfaceNanostack::get_stack()
|
||||
{
|
||||
return NanostackInterface::get_stack();
|
||||
return &Nanostack::get_instance();
|
||||
}
|
||||
|
||||
const char *MeshInterfaceNanostack::get_ip_address()
|
||||
const char *InterfaceNanostack::get_ip_address()
|
||||
{
|
||||
nanostack_lock();
|
||||
|
||||
const char *ret = NULL;
|
||||
if (getOwnIpAddress(ip_addr_str, sizeof ip_addr_str)) {
|
||||
ret = ip_addr_str;
|
||||
if (_interface->get_ip_address(ip_addr_str, sizeof(ip_addr_str))) {
|
||||
return ip_addr_str;
|
||||
}
|
||||
|
||||
nanostack_unlock();
|
||||
|
||||
return ret;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *MeshInterfaceNanostack::get_mac_address()
|
||||
const char *InterfaceNanostack::get_mac_address()
|
||||
{
|
||||
return mac_addr_str;
|
||||
if (_interface->get_mac_address(mac_addr_str, sizeof(mac_addr_str))) {
|
||||
return mac_addr_str;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nsapi_connection_status_t MeshInterfaceNanostack::get_connection_status() const
|
||||
nsapi_connection_status_t InterfaceNanostack::get_connection_status() const
|
||||
{
|
||||
return _connect_status;
|
||||
if (_interface) {
|
||||
return _interface->get_connection_status();
|
||||
} else {
|
||||
return NSAPI_STATUS_DISCONNECTED;
|
||||
}
|
||||
}
|
||||
|
||||
void MeshInterfaceNanostack::attach(
|
||||
Callback<void(nsapi_event_t, intptr_t)> status_cb)
|
||||
void InterfaceNanostack::attach(
|
||||
mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb)
|
||||
{
|
||||
_connection_status_cb = status_cb;
|
||||
if (_interface) {
|
||||
_interface->attach(status_cb);
|
||||
}
|
||||
}
|
||||
|
||||
nsapi_error_t MeshInterfaceNanostack::set_blocking(bool blocking)
|
||||
nsapi_error_t InterfaceNanostack::set_blocking(bool blocking)
|
||||
{
|
||||
_blocking = blocking;
|
||||
return NSAPI_ERROR_OK;
|
||||
|
|
|
@ -0,0 +1,218 @@
|
|||
/*
|
||||
* Copyright (c) 2017 ARM Limited. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "Nanostack.h"
|
||||
#include "NanostackEthernetInterface.h"
|
||||
#include "NanostackEthernetPhy.h"
|
||||
#include "EMAC.h"
|
||||
#include "nsdynmemLIB.h"
|
||||
#include "arm_hal_phy.h"
|
||||
|
||||
class EMACPhy : public NanostackEthernetPhy
|
||||
{
|
||||
public:
|
||||
EMACPhy(NanostackMemoryManager &mem, EMAC &m);
|
||||
virtual int8_t phy_register();
|
||||
virtual void get_mac_address(uint8_t *mac);
|
||||
virtual void set_mac_address(uint8_t *mac);
|
||||
|
||||
int8_t address_write(phy_address_type_e , uint8_t *);
|
||||
int8_t tx(uint8_t *data_ptr, uint16_t data_len, uint8_t tx_handle,data_protocol_e data_flow);
|
||||
|
||||
void emac_phy_rx(emac_mem_buf_t *mem);
|
||||
|
||||
private:
|
||||
NanostackMemoryManager &memory_manager;
|
||||
EMAC &emac;
|
||||
uint8_t mac_addr[6];
|
||||
int8_t device_id;
|
||||
phy_device_driver_s phy;
|
||||
};
|
||||
|
||||
// GAH! no handles on the callback. Force a single interface
|
||||
static EMACPhy *single_phy;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
static int8_t emac_phy_address_write(phy_address_type_e address_type, uint8_t *address_ptr)
|
||||
{
|
||||
return single_phy->address_write(address_type, address_ptr);
|
||||
}
|
||||
|
||||
static int8_t emac_phy_interface_state_control(phy_interface_state_e, uint8_t)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int8_t emac_phy_tx(uint8_t *data_ptr, uint16_t data_len, uint8_t tx_handle,data_protocol_e data_flow)
|
||||
{
|
||||
return single_phy->tx(data_ptr, data_len, tx_handle, data_flow);
|
||||
}
|
||||
|
||||
EMACPhy::EMACPhy(NanostackMemoryManager &mem, EMAC &m) : memory_manager(mem), emac(m), device_id(-1)
|
||||
{
|
||||
/* Same default address logic as lwIP glue uses */
|
||||
#if (MBED_MAC_ADDRESS_SUM != MBED_MAC_ADDR_INTERFACE)
|
||||
mac_addr[0] = MBED_MAC_ADDR_0;
|
||||
mac_addr[1] = MBED_MAC_ADDR_1;
|
||||
mac_addr[2] = MBED_MAC_ADDR_2;
|
||||
mac_addr[3] = MBED_MAC_ADDR_3;
|
||||
mac_addr[4] = MBED_MAC_ADDR_4;
|
||||
mac_addr[5] = MBED_MAC_ADDR_5;
|
||||
#else
|
||||
mbed_mac_address((char *) mac_addr);
|
||||
#endif
|
||||
/* We have a default MAC address, so do don't force them to supply one */
|
||||
/* They may or may not update hwaddr with their address */
|
||||
emac.get_hwaddr(mac_addr);
|
||||
}
|
||||
|
||||
|
||||
void EMACPhy::emac_phy_rx(emac_mem_buf_t *mem)
|
||||
{
|
||||
const uint8_t *ptr = NULL;
|
||||
uint8_t *tmpbuf = NULL;
|
||||
uint32_t total_len;
|
||||
|
||||
if (memory_manager.get_next(mem) == NULL) {
|
||||
// Easy contiguous case
|
||||
ptr = static_cast<const uint8_t*>(memory_manager.get_ptr(mem));
|
||||
total_len = memory_manager.get_len(mem);
|
||||
} else {
|
||||
// Nanostack can't accept chunked data - make temporary contiguous copy
|
||||
total_len = memory_manager.get_total_len(mem);
|
||||
ptr = tmpbuf = static_cast<uint8_t *>(ns_dyn_mem_temporary_alloc(total_len));
|
||||
if (tmpbuf) {
|
||||
memory_manager.copy_from_buf(tmpbuf, total_len, mem);
|
||||
}
|
||||
}
|
||||
|
||||
if (ptr) {
|
||||
phy.phy_rx_cb(ptr, total_len, 0xff, 0, device_id);
|
||||
}
|
||||
ns_dyn_mem_free(tmpbuf);
|
||||
memory_manager.free(mem);
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
int8_t EMACPhy::address_write(phy_address_type_e address_type, uint8_t *address_ptr)
|
||||
{
|
||||
if (address_type != PHY_MAC_48BIT) {
|
||||
return -1;
|
||||
}
|
||||
memcpy(mac_addr, address_ptr, 6);
|
||||
emac.set_hwaddr(address_ptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int8_t EMACPhy::tx(uint8_t *data_ptr, uint16_t data_len, uint8_t tx_handle,data_protocol_e data_flow)
|
||||
{
|
||||
emac_mem_buf_t *mem = memory_manager.alloc_pool(data_len, 0);
|
||||
if (!mem) {
|
||||
return -1;
|
||||
}
|
||||
memory_manager.copy_to_buf(mem, data_ptr, data_len);
|
||||
|
||||
// They take ownership - their responsibility to free
|
||||
emac.link_out(mem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int8_t EMACPhy::phy_register()
|
||||
{
|
||||
if (device_id < 0) {
|
||||
|
||||
emac.set_memory_manager(memory_manager);
|
||||
emac.set_link_input_cb(callback(this, &EMACPhy::emac_phy_rx));
|
||||
|
||||
if (!emac.power_up()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
phy.phy_MTU = emac.get_mtu_size();
|
||||
/* Set the address - this could be either board default, what they
|
||||
* told us with EMAC::get_mac_address, or something manually specified
|
||||
* with EMACPhy::set_mac_address
|
||||
*/
|
||||
emac.set_hwaddr(mac_addr);
|
||||
|
||||
emac.set_all_multicast(true);
|
||||
|
||||
phy.PHY_MAC = mac_addr;
|
||||
phy.address_write = emac_phy_address_write;
|
||||
phy.driver_description = const_cast<char*>("ETH");
|
||||
phy.link_type = PHY_LINK_ETHERNET_TYPE;
|
||||
phy.phy_MTU = 0;
|
||||
phy.phy_header_length = 0;
|
||||
phy.phy_tail_length = 0;
|
||||
phy.state_control = emac_phy_interface_state_control;
|
||||
phy.tx = emac_phy_tx;
|
||||
phy.phy_rx_cb = NULL;
|
||||
phy.phy_tx_done_cb = NULL;
|
||||
device_id = arm_net_phy_register(&phy);
|
||||
// driver_readiness_status_callback = driver_status_cb;
|
||||
|
||||
if (device_id < 0){
|
||||
//tr_error("Ethernet Driver failed to register with Stack. RetCode=%i", eth_driver_enabled);
|
||||
//driver_readiness_status_callback(0, eth_interface_id);
|
||||
emac.power_down();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return device_id;
|
||||
}
|
||||
|
||||
void EMACPhy::get_mac_address(uint8_t *mac)
|
||||
{
|
||||
memcpy(mac, mac_addr, sizeof mac_addr);
|
||||
}
|
||||
|
||||
void EMACPhy::set_mac_address(uint8_t *mac)
|
||||
{
|
||||
memcpy(mac_addr, mac, sizeof mac_addr);
|
||||
}
|
||||
|
||||
nsapi_error_t Nanostack::add_ethernet_interface(EMAC &emac, bool default_if, Nanostack::EthernetInterface **interface_out, const uint8_t *mac_addr)
|
||||
{
|
||||
if (single_phy) {
|
||||
return NSAPI_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
single_phy = new (nothrow) EMACPhy(this->memory_manager, emac);
|
||||
if (!single_phy) {
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
|
||||
if (mac_addr) {
|
||||
single_phy->set_mac_address(const_cast<uint8_t*>(mac_addr));
|
||||
}
|
||||
|
||||
Nanostack::EthernetInterface *interface;
|
||||
|
||||
interface = new (nothrow) Nanostack::EthernetInterface(*single_phy);
|
||||
if (!interface) {
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
|
||||
nsapi_error_t err = interface->initialize();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
*interface_out = interface;
|
||||
|
||||
return NSAPI_ERROR_OK;
|
||||
|
||||
}
|
||||
|
||||
nsapi_error_t Nanostack::add_ethernet_interface(EMAC &emac, bool default_if, OnboardNetworkStack::Interface **interface_out)
|
||||
{
|
||||
Nanostack::EthernetInterface *interface;
|
||||
nsapi_error_t err = add_ethernet_interface(emac, default_if, &interface);
|
||||
*interface_out = interface;
|
||||
return err;
|
||||
}
|
|
@ -18,12 +18,8 @@
|
|||
#include "callback_handler.h"
|
||||
#include "enet_tasklet.h"
|
||||
|
||||
nsapi_error_t NanostackEthernetInterface::initialize(NanostackEthernetPhy *phy)
|
||||
nsapi_error_t Nanostack::EthernetInterface::initialize()
|
||||
{
|
||||
nsapi_error_t err = MeshInterfaceNanostack::initialize(phy);
|
||||
if (err != NSAPI_ERROR_OK)
|
||||
return err;
|
||||
|
||||
nanostack_lock();
|
||||
|
||||
if (register_phy() < 0) {
|
||||
|
@ -31,54 +27,85 @@ nsapi_error_t NanostackEthernetInterface::initialize(NanostackEthernetPhy *phy)
|
|||
return NSAPI_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
enet_tasklet_init();
|
||||
__mesh_handler_set_callback(this);
|
||||
_network_interface_id = enet_tasklet_network_init(_device_id);
|
||||
|
||||
nanostack_unlock();
|
||||
|
||||
if (_network_interface_id < 0)
|
||||
return MESH_ERROR_UNKNOWN;
|
||||
else
|
||||
return MESH_ERROR_NONE;
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
int NanostackEthernetInterface::connect()
|
||||
nsapi_error_t NanostackEthernetInterface::initialize(NanostackEthernetPhy *phy)
|
||||
{
|
||||
if (_interface) {
|
||||
return NSAPI_ERROR_PARAMETER;
|
||||
}
|
||||
|
||||
_interface = new (nothrow) Nanostack::EthernetInterface(*phy);
|
||||
if (!_interface) {
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
|
||||
return get_interface()->initialize();
|
||||
}
|
||||
|
||||
nsapi_error_t Nanostack::EthernetInterface::bringup(bool dhcp, const char *ip,
|
||||
const char *netmask, const char *gw,
|
||||
nsapi_ip_stack_t stack, bool blocking)
|
||||
{
|
||||
if (stack == IPV4_STACK) {
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
nanostack_lock();
|
||||
int8_t status = enet_tasklet_connect(&__mesh_handler_c_callback, _network_interface_id);
|
||||
_blocking = blocking;
|
||||
if (interface_id < 0) {
|
||||
enet_tasklet_init();
|
||||
__mesh_handler_set_callback(this);
|
||||
interface_id = enet_tasklet_network_init(_device_id);
|
||||
}
|
||||
int8_t status = -1;
|
||||
if (interface_id >= 0) {
|
||||
status = enet_tasklet_connect(&__mesh_handler_c_callback, interface_id);
|
||||
}
|
||||
nanostack_unlock();
|
||||
|
||||
if (status == -1) {
|
||||
return MESH_ERROR_PARAM;
|
||||
return NSAPI_ERROR_DEVICE_ERROR;
|
||||
} else if (status == -2) {
|
||||
return MESH_ERROR_MEMORY;
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
} else if (status == -3) {
|
||||
return MESH_ERROR_STATE;
|
||||
return NSAPI_ERROR_ALREADY;
|
||||
} else if (status != 0) {
|
||||
return MESH_ERROR_UNKNOWN;
|
||||
return NSAPI_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
int32_t count = connect_semaphore.wait(30000);
|
||||
if (blocking) {
|
||||
int32_t count = connect_semaphore.wait(30000);
|
||||
|
||||
if (count <= 0) {
|
||||
return NSAPI_ERROR_DHCP_FAILURE; // sort of...
|
||||
if (count <= 0) {
|
||||
return NSAPI_ERROR_DHCP_FAILURE; // sort of...
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int NanostackEthernetInterface::disconnect()
|
||||
int NanostackEthernetInterface::connect()
|
||||
{
|
||||
if (!_interface) {
|
||||
return NSAPI_ERROR_PARAMETER;
|
||||
}
|
||||
return _interface->bringup(false, NULL, NULL, NULL, IPV6_STACK, _blocking);
|
||||
}
|
||||
|
||||
nsapi_error_t Nanostack::EthernetInterface::bringdown()
|
||||
{
|
||||
enet_tasklet_disconnect();
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool NanostackEthernetInterface::getOwnIpAddress(char *address, int8_t len)
|
||||
{
|
||||
return enet_tasklet_get_ip_address(address, len)?false:true;
|
||||
}
|
||||
|
||||
bool NanostackEthernetInterface::getRouterIpAddress(char *address, int8_t len)
|
||||
int NanostackEthernetInterface::disconnect()
|
||||
{
|
||||
return false;
|
||||
if (!_interface) {
|
||||
return NSAPI_ERROR_NO_CONNECTION;
|
||||
}
|
||||
return _interface->bringdown();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,143 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2016 ARM Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "nsdynmemLIB.h"
|
||||
#include <string.h>
|
||||
#include "mbed_assert.h"
|
||||
#include "NanostackMemoryManager.h"
|
||||
|
||||
struct ns_stack_mem_t
|
||||
{
|
||||
ns_stack_mem_t *next;
|
||||
void *payload;
|
||||
uint32_t len;
|
||||
uint8_t mem[];
|
||||
};
|
||||
|
||||
emac_mem_buf_t *NanostackMemoryManager::alloc_heap(uint32_t size, uint32_t align)
|
||||
{
|
||||
ns_stack_mem_t *buf = static_cast<ns_stack_mem_t *>(ns_dyn_mem_temporary_alloc(sizeof(ns_stack_mem_t) + size + align));
|
||||
if (buf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buf->next = NULL;
|
||||
buf->payload = buf->mem;
|
||||
buf->len = size;
|
||||
|
||||
if (align) {
|
||||
uint32_t remainder = reinterpret_cast<uint32_t>(buf->payload) % align;
|
||||
if (remainder) {
|
||||
uint32_t offset = align - remainder;
|
||||
if (offset >= align) {
|
||||
offset = align;
|
||||
}
|
||||
|
||||
buf->payload = static_cast<char *>(buf->payload) + offset;
|
||||
}
|
||||
}
|
||||
|
||||
return static_cast<emac_mem_buf_t *>(buf);
|
||||
}
|
||||
|
||||
emac_mem_buf_t *NanostackMemoryManager::alloc_pool(uint32_t size, uint32_t align)
|
||||
{
|
||||
return alloc_heap(size, align);
|
||||
}
|
||||
|
||||
uint32_t NanostackMemoryManager::get_pool_alloc_unit(uint32_t align) const
|
||||
{
|
||||
return 1536; // arbitrary nicely-aligned number big enough for Ethernet
|
||||
}
|
||||
|
||||
void NanostackMemoryManager::free(emac_mem_buf_t *mem)
|
||||
{
|
||||
ns_dyn_mem_free(mem);
|
||||
}
|
||||
|
||||
uint32_t NanostackMemoryManager::get_total_len(const emac_mem_buf_t *buf) const
|
||||
{
|
||||
const ns_stack_mem_t *mem = static_cast<const ns_stack_mem_t *>(buf);
|
||||
uint32_t total = 0;
|
||||
|
||||
while (mem) {
|
||||
total += mem->len;
|
||||
mem = mem->next;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
void NanostackMemoryManager::copy(emac_mem_buf_t *to, const emac_mem_buf_t *from)
|
||||
{
|
||||
ns_stack_mem_t *to_mem = static_cast<ns_stack_mem_t *>(to);
|
||||
const ns_stack_mem_t *from_mem = static_cast<const ns_stack_mem_t *>(from);
|
||||
MBED_ASSERT(get_total_len(to) >= get_total_len(from));
|
||||
|
||||
uint32_t to_offset = 0;
|
||||
uint32_t from_offset = 0;
|
||||
while (from_mem) {
|
||||
uint32_t to_avail = to_mem->len - to_offset;
|
||||
uint32_t from_avail = from_mem->len - from_offset;
|
||||
uint32_t chunk = to_avail < from_avail ? to_avail : from_avail;
|
||||
uint8_t *to_ptr = static_cast<uint8_t *>(to_mem->payload) + to_offset;
|
||||
const uint8_t *from_ptr = static_cast<const uint8_t *>(from_mem->payload) + from_offset;
|
||||
memcpy(to_ptr, from_ptr, chunk);
|
||||
to_offset += chunk;
|
||||
if (to_offset == to_mem->len) {
|
||||
to_mem = to_mem->next;
|
||||
to_offset = 0;
|
||||
}
|
||||
from_offset += chunk;
|
||||
if (from_offset == from_mem->len) {
|
||||
from_mem = from_mem->next;
|
||||
from_offset = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NanostackMemoryManager::cat(emac_mem_buf_t *to_buf, emac_mem_buf_t *cat_buf)
|
||||
{
|
||||
ns_stack_mem_t *to_mem = static_cast<ns_stack_mem_t *>(to_buf);
|
||||
ns_stack_mem_t *cat_mem = static_cast<ns_stack_mem_t *>(cat_buf);
|
||||
|
||||
while (to_mem->next) {
|
||||
to_mem = to_mem->next;
|
||||
}
|
||||
|
||||
to_mem->next = cat_mem;
|
||||
}
|
||||
|
||||
emac_mem_buf_t *NanostackMemoryManager::get_next(const emac_mem_buf_t *buf) const
|
||||
{
|
||||
return static_cast<const ns_stack_mem_t *>(buf)->next;
|
||||
}
|
||||
|
||||
void *NanostackMemoryManager::get_ptr(const emac_mem_buf_t *buf) const
|
||||
{
|
||||
return static_cast<const ns_stack_mem_t *>(buf)->payload;
|
||||
}
|
||||
|
||||
uint32_t NanostackMemoryManager::get_len(const emac_mem_buf_t *buf) const
|
||||
{
|
||||
return static_cast<const ns_stack_mem_t *>(buf)->len;
|
||||
}
|
||||
|
||||
void NanostackMemoryManager::set_len(emac_mem_buf_t *buf, uint32_t len)
|
||||
{
|
||||
ns_stack_mem_t *mem = static_cast<ns_stack_mem_t *>(buf);
|
||||
|
||||
mem->len = len;
|
||||
}
|
|
@ -7,12 +7,86 @@
|
|||
#include "ns_trace.h"
|
||||
#define TRACE_GROUP "nsth"
|
||||
|
||||
nsapi_error_t ThreadInterface::initialize(NanostackRfPhy *phy)
|
||||
class Nanostack::ThreadInterface : public Nanostack::MeshInterface
|
||||
{
|
||||
return MeshInterfaceNanostack::initialize(phy);
|
||||
public:
|
||||
virtual nsapi_error_t bringup(bool dhcp, const char *ip,
|
||||
const char *netmask, const char *gw,
|
||||
nsapi_ip_stack_t stack = IPV6_STACK,
|
||||
bool blocking = true);
|
||||
virtual nsapi_error_t bringdown();
|
||||
friend Nanostack;
|
||||
friend class ::ThreadInterface;
|
||||
private:
|
||||
ThreadInterface(NanostackRfPhy &phy) : MeshInterface(phy), user_eui64_set(false) { }
|
||||
|
||||
/*
|
||||
* \brief Initialization of the interface.
|
||||
* \return MESH_ERROR_NONE on success.
|
||||
* \return MESH_ERROR_PARAM when input parameters are illegal (also in case when RF device is already associated to other interface)
|
||||
* \return MESH_ERROR_MEMORY in case of memory error
|
||||
* \return MESH_ERROR_UNKNOWN in other error cases
|
||||
*/
|
||||
mesh_error_t init();
|
||||
/**
|
||||
* \brief Connect interface to the mesh network
|
||||
* \return MESH_ERROR_NONE on success.
|
||||
* \return MESH_ERROR_PARAM in case of illegal parameters.
|
||||
* \return MESH_ERROR_MEMORY in case of memory error.
|
||||
* \return MESH_ERROR_STATE if interface is already connected to network.
|
||||
* \return MESH_ERROR_UNKNOWN in case of unspecified error.
|
||||
* */
|
||||
mesh_error_t mesh_connect();
|
||||
|
||||
/**
|
||||
* \brief Disconnect interface from the mesh network
|
||||
* \return MESH_ERROR_NONE on success.
|
||||
* \return MESH_ERROR_UNKNOWN in case of error.
|
||||
* */
|
||||
mesh_error_t mesh_disconnect();
|
||||
|
||||
/**
|
||||
* \brief Sets the eui64 for the device configuration.
|
||||
* By default this value is read from the radio driver.
|
||||
* The value must be set before calling the connect function.
|
||||
* */
|
||||
void device_eui64_set(const uint8_t *eui64);
|
||||
|
||||
/**
|
||||
* \brief sets the PSKd for the device configuration.
|
||||
* The default value is overwritten, which is defined in the mbed_lib.json file in the mesh-api
|
||||
* The value must be set before calling the connect function.
|
||||
* \return MESH_ERROR_NONE on success.
|
||||
* \return MESH_ERROR_PARAM in case of illegal parameters.
|
||||
* \return MESH_ERROR_MEMORY in case of memory error.
|
||||
* */
|
||||
|
||||
mesh_error_t device_pskd_set(const char *pskd);
|
||||
|
||||
bool user_eui64_set;
|
||||
};
|
||||
|
||||
Nanostack::ThreadInterface *ThreadInterface::get_interface() const
|
||||
{
|
||||
return static_cast<Nanostack::ThreadInterface*>(_interface);
|
||||
}
|
||||
|
||||
int ThreadInterface::connect()
|
||||
{
|
||||
if (!_interface) {
|
||||
_interface = new (nothrow) Nanostack::ThreadInterface(*_phy);
|
||||
if (!_interface) {
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
_interface->attach(_connection_status_cb);
|
||||
}
|
||||
|
||||
return _interface->bringup(false, NULL, NULL, NULL, IPV6_STACK, _blocking);
|
||||
}
|
||||
|
||||
nsapi_error_t Nanostack::ThreadInterface::bringup(bool dhcp, const char *ip,
|
||||
const char *netmask, const char *gw,
|
||||
nsapi_ip_stack_t stack, bool blocking)
|
||||
{
|
||||
if (_connect_status == NSAPI_STATUS_GLOBAL_UP || _connect_status == NSAPI_STATUS_LOCAL_UP) {
|
||||
return NSAPI_ERROR_IS_CONNECTED;
|
||||
|
@ -20,12 +94,17 @@ int ThreadInterface::connect()
|
|||
return NSAPI_ERROR_ALREADY;
|
||||
}
|
||||
|
||||
nanostack_lock();
|
||||
if (stack == IPV4_STACK) {
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (register_phy() < 0) {
|
||||
nanostack_unlock();
|
||||
return NSAPI_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
nanostack_lock();
|
||||
|
||||
_blocking = blocking;
|
||||
|
||||
// After the RF is up, we can seed the random from it.
|
||||
randLIB_seed_random();
|
||||
|
||||
|
@ -63,6 +142,11 @@ int ThreadInterface::connect()
|
|||
}
|
||||
|
||||
int ThreadInterface::disconnect()
|
||||
{
|
||||
return _interface->bringdown();
|
||||
}
|
||||
|
||||
nsapi_error_t Nanostack::ThreadInterface::bringdown()
|
||||
{
|
||||
nanostack_lock();
|
||||
|
||||
|
@ -73,38 +157,33 @@ int ThreadInterface::disconnect()
|
|||
return map_mesh_error(status);
|
||||
}
|
||||
|
||||
mesh_error_t ThreadInterface::init()
|
||||
mesh_error_t Nanostack::ThreadInterface::init()
|
||||
{
|
||||
thread_tasklet_init();
|
||||
__mesh_handler_set_callback(this);
|
||||
thread_tasklet_device_eui64_set(_eui64);
|
||||
_network_interface_id = thread_tasklet_network_init(_device_id);
|
||||
if (!user_eui64_set) {
|
||||
uint8_t eui64[8];
|
||||
get_phy().get_mac_address(eui64);
|
||||
thread_tasklet_device_eui64_set(eui64);
|
||||
}
|
||||
interface_id = thread_tasklet_network_init(_device_id);
|
||||
|
||||
if (_network_interface_id == -2) {
|
||||
if (interface_id == -2) {
|
||||
return MESH_ERROR_PARAM;
|
||||
} else if (_network_interface_id == -3) {
|
||||
} else if (interface_id == -3) {
|
||||
return MESH_ERROR_MEMORY;
|
||||
} else if (_network_interface_id < 0) {
|
||||
} else if (interface_id < 0) {
|
||||
return MESH_ERROR_UNKNOWN;
|
||||
}
|
||||
return MESH_ERROR_NONE;
|
||||
}
|
||||
|
||||
bool ThreadInterface::getOwnIpAddress(char *address, int8_t len)
|
||||
{
|
||||
tr_debug("getOwnIpAddress()");
|
||||
if (thread_tasklet_get_ip_address(address, len) == 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
mesh_error_t ThreadInterface::mesh_connect()
|
||||
mesh_error_t Nanostack::ThreadInterface::mesh_connect()
|
||||
{
|
||||
int8_t status;
|
||||
tr_debug("connect()");
|
||||
|
||||
status = thread_tasklet_connect(&__mesh_handler_c_callback, _network_interface_id);
|
||||
status = thread_tasklet_connect(&__mesh_handler_c_callback, interface_id);
|
||||
|
||||
if (status >= 0) {
|
||||
return MESH_ERROR_NONE;
|
||||
|
@ -119,17 +198,7 @@ mesh_error_t ThreadInterface::mesh_connect()
|
|||
}
|
||||
}
|
||||
|
||||
void ThreadInterface::device_eui64_set(const uint8_t *eui64)
|
||||
{
|
||||
memcpy(_eui64, eui64, 8);
|
||||
}
|
||||
|
||||
mesh_error_t ThreadInterface::device_pskd_set(const char *pskd)
|
||||
{
|
||||
return (mesh_error_t)thread_tasklet_device_pskd_set(pskd);
|
||||
}
|
||||
|
||||
mesh_error_t ThreadInterface::mesh_disconnect()
|
||||
mesh_error_t Nanostack::ThreadInterface::mesh_disconnect()
|
||||
{
|
||||
int8_t status;
|
||||
|
||||
|
@ -141,3 +210,24 @@ mesh_error_t ThreadInterface::mesh_disconnect()
|
|||
|
||||
return MESH_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
void ThreadInterface::device_eui64_set(const uint8_t *eui64)
|
||||
{
|
||||
get_interface()->device_eui64_set(eui64);
|
||||
}
|
||||
|
||||
void Nanostack::ThreadInterface::device_eui64_set(const uint8_t *eui64)
|
||||
{
|
||||
user_eui64_set = true;
|
||||
thread_tasklet_device_eui64_set(eui64);
|
||||
}
|
||||
|
||||
mesh_error_t ThreadInterface::device_pskd_set(const char *pskd)
|
||||
{
|
||||
return get_interface()->device_pskd_set(pskd);
|
||||
}
|
||||
|
||||
mesh_error_t Nanostack::ThreadInterface::device_pskd_set(const char *pskd)
|
||||
{
|
||||
return (mesh_error_t)thread_tasklet_device_pskd_set(pskd);
|
||||
}
|
||||
|
|
|
@ -224,20 +224,6 @@ void enet_tasklet_network_state_changed(mesh_connection_status_t status)
|
|||
}
|
||||
|
||||
/* Public functions */
|
||||
int8_t enet_tasklet_get_ip_address(char *address, int8_t len)
|
||||
{
|
||||
uint8_t binary_ipv6[16];
|
||||
|
||||
if ((len >= 40) && (0 == arm_net_address_get(
|
||||
tasklet_data_ptr->network_interface_id, ADDR_IPV6_GP, binary_ipv6))) {
|
||||
ip6tos(binary_ipv6, address);
|
||||
//tr_debug("IP address: %s", address);
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int8_t enet_tasklet_connect(mesh_interface_cb callback, int8_t nwk_interface_id)
|
||||
{
|
||||
int8_t re_connecting = true;
|
||||
|
|
|
@ -0,0 +1,143 @@
|
|||
/* Copyright (c) 2017 ARM Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef NANOSTACK_MEMORY_MANAGER_H
|
||||
#define NANOSTACK_MEMORY_MANAGER_H
|
||||
|
||||
#include "EMACMemoryManager.h"
|
||||
|
||||
class NanostackMemoryManager : public EMACMemoryManager {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Allocates memory buffer from the heap
|
||||
*
|
||||
* Memory buffer allocated from heap is always contiguous and can be arbitrary size.
|
||||
*
|
||||
* @param size Size of the memory to allocate in bytes
|
||||
* @param align Memory alignment requirement in bytes
|
||||
* @return Allocated memory buffer, or NULL in case of error
|
||||
*/
|
||||
virtual emac_mem_buf_t *alloc_heap(uint32_t size, uint32_t align);
|
||||
|
||||
/**
|
||||
* Allocates memory buffer chain from a pool
|
||||
*
|
||||
* Memory allocated from pool is contiguous if size is equal or less than
|
||||
* (aligned) allocation unit, otherwise may be chained. Will typically come from
|
||||
* fixed-size packet pool memory.
|
||||
*
|
||||
* @param size Total size of the memory to allocate in bytes
|
||||
* @param align Memory alignment requirement for each buffer in bytes
|
||||
* @return Allocated memory buffer chain, or NULL in case of error
|
||||
*/
|
||||
virtual emac_mem_buf_t *alloc_pool(uint32_t size, uint32_t align);
|
||||
|
||||
/**
|
||||
* Get memory buffer pool allocation unit
|
||||
*
|
||||
* Returns the maximum size of contiguous memory that can be allocated from a pool.
|
||||
*
|
||||
* @param align Memory alignment requirement in bytes
|
||||
* @return Contiguous memory size
|
||||
*/
|
||||
virtual uint32_t get_pool_alloc_unit(uint32_t align) const;
|
||||
|
||||
/**
|
||||
* Free memory buffer chain
|
||||
*
|
||||
* If memory buffer is chained must point to the start of the chain. Frees all buffers
|
||||
* from the chained list.
|
||||
*
|
||||
* @param buf Memory buffer chain to be freed.
|
||||
*/
|
||||
virtual void free(emac_mem_buf_t *buf);
|
||||
|
||||
/**
|
||||
* Return total length of a memory buffer chain
|
||||
*
|
||||
* Returns a total length of this buffer and any following buffers in the chain.
|
||||
*
|
||||
* @param buf Memory buffer chain
|
||||
* @return Total length in bytes
|
||||
*/
|
||||
virtual uint32_t get_total_len(const emac_mem_buf_t *buf) const;
|
||||
|
||||
virtual void set_align_preference(uint32_t align) { }
|
||||
|
||||
/**
|
||||
* Copy a memory buffer chain
|
||||
*
|
||||
* Copies data from one buffer chain to another. Copy operation does not adjust the lengths
|
||||
* of the copied-to memory buffer chain, so chain total lengths must be the same.
|
||||
*
|
||||
* @param to_buf Memory buffer chain to copy to
|
||||
* @param from_buf Memory buffer chain to copy from
|
||||
*/
|
||||
virtual void copy(emac_mem_buf_t *to_buf, const emac_mem_buf_t *from_buf);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Concatenate two memory buffer chains
|
||||
*
|
||||
* Concatenates buffer chain to end of the other buffer chain. Concatenated-to buffer total length
|
||||
* is adjusted accordingly. cat_buf must point to the start of a the chain. After concatenation
|
||||
* to_buf's chain now owns those buffers, and they will be freed when the to_buf chain is freed.
|
||||
*
|
||||
* @param to_buf Memory buffer chain to concatenate to
|
||||
* @param cat_buf Memory buffer chain to concatenate
|
||||
*/
|
||||
virtual void cat(emac_mem_buf_t *to_buf, emac_mem_buf_t *cat_buf);
|
||||
|
||||
/**
|
||||
* Returns the next buffer
|
||||
*
|
||||
* Returns the next buffer from the memory buffer chain.
|
||||
*
|
||||
* @param buf Memory buffer
|
||||
* @return The next memory buffer, or NULL if last
|
||||
*/
|
||||
virtual emac_mem_buf_t *get_next(const emac_mem_buf_t *buf) const;
|
||||
|
||||
/**
|
||||
* Return pointer to the payload of the buffer
|
||||
*
|
||||
* @param buf Memory buffer
|
||||
* @return Pointer to the payload
|
||||
*/
|
||||
virtual void *get_ptr(const emac_mem_buf_t *buf) const;
|
||||
|
||||
/**
|
||||
* Return payload size of the buffer
|
||||
*
|
||||
* @param buf Memory buffer
|
||||
* @return Size in bytes
|
||||
*/
|
||||
virtual uint32_t get_len(const emac_mem_buf_t *buf) const;
|
||||
|
||||
/**
|
||||
* Sets the payload size of the buffer
|
||||
*
|
||||
* The allocated payload size will not change. It is not permitted
|
||||
* to change the length of a buffer that is not the first (or only) in a chain.
|
||||
*
|
||||
* @param buf Memory buffer
|
||||
* @param len Payload size, must be less or equal allocated size
|
||||
*/
|
||||
virtual void set_len(emac_mem_buf_t *buf, uint32_t len);
|
||||
};
|
||||
|
||||
#endif /* NANOSTACK_MEMORY_MANAGER_H */
|
|
@ -21,6 +21,7 @@
|
|||
#include "mesh_interface_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include "MeshInterfaceNanostack.h"
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
@ -31,8 +32,7 @@ void __mesh_handler_c_callback(mesh_connection_status_t state);
|
|||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include "NanostackInterface.h"
|
||||
void __mesh_handler_set_callback(MeshInterfaceNanostack *handler);
|
||||
void __mesh_handler_set_callback(Nanostack::Interface *handler);
|
||||
#endif
|
||||
|
||||
#endif /* __INCLUDE_CALLBACK_HANDLER_H__ */
|
||||
|
|
|
@ -26,7 +26,6 @@ void enet_tasklet_init(void);
|
|||
uint8_t enet_tasklet_network_init(int8_t);
|
||||
int8_t enet_tasklet_connect(void (*)(mesh_connection_status_t mesh_status), int8_t nwk_interface_id);
|
||||
void enet_tasklet_disconnect();
|
||||
int8_t enet_tasklet_get_ip_address(char *address, int8_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -29,17 +29,6 @@ extern "C" {
|
|||
*/
|
||||
typedef void (*mesh_interface_cb)(mesh_connection_status_t mesh_status);
|
||||
|
||||
/*
|
||||
* \brief Read own global IP address
|
||||
*
|
||||
* \param address where own IP address will be written
|
||||
* \param len length of provided address buffer
|
||||
*
|
||||
* \return 0 on success
|
||||
* \return -1 if address reading fails
|
||||
*/
|
||||
int8_t nd_tasklet_get_ip_address(char *address, int8_t len);
|
||||
|
||||
/*
|
||||
* \brief Read border router IP address
|
||||
*
|
||||
|
|
|
@ -29,17 +29,6 @@ extern "C" {
|
|||
*/
|
||||
typedef void (*mesh_interface_cb)(mesh_connection_status_t mesh_status);
|
||||
|
||||
/*
|
||||
* \brief Read own global IP address
|
||||
*
|
||||
* \param address where own IP address will be written
|
||||
* \param len length of provided address buffer
|
||||
*
|
||||
* \return 0 on success
|
||||
* \return -1 if address reading fails
|
||||
*/
|
||||
int8_t thread_tasklet_get_ip_address(char *address, int8_t len);
|
||||
|
||||
/*
|
||||
* \brief Connect to mesh network
|
||||
*
|
||||
|
|
|
@ -340,20 +340,6 @@ void nd_tasklet_trace_bootstrap_info()
|
|||
#endif /* #define TRACE_ND_TASKLET */
|
||||
|
||||
/* Public functions */
|
||||
int8_t nd_tasklet_get_ip_address(char *address, int8_t len)
|
||||
{
|
||||
uint8_t binary_ipv6[16];
|
||||
|
||||
if ((len >= 40) && (0 == arm_net_address_get(
|
||||
tasklet_data_ptr->network_interface_id, ADDR_IPV6_GP, binary_ipv6))) {
|
||||
ip6tos(binary_ipv6, address);
|
||||
//tr_debug("IP address: %s", address);
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int8_t nd_tasklet_get_router_ip_address(char *address, int8_t len)
|
||||
{
|
||||
network_layer_address_s nd_address;
|
||||
|
|
|
@ -390,20 +390,6 @@ void thread_tasklet_trace_bootstrap_info()
|
|||
}
|
||||
#endif /* #define TRACE_THREAD_TASKLET */
|
||||
|
||||
int8_t thread_tasklet_get_ip_address(char *address, int8_t len)
|
||||
{
|
||||
uint8_t binary_ipv6[16];
|
||||
|
||||
if ((len >= 40) && (0 == arm_net_address_get(
|
||||
thread_tasklet_data_ptr->nwk_if_id, ADDR_IPV6_GP, binary_ipv6))) {
|
||||
ip6tos(binary_ipv6, address);
|
||||
//tr_debug("IP address: %s", address);
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int8_t thread_tasklet_connect(mesh_interface_cb callback, int8_t nwk_interface_id)
|
||||
{
|
||||
int8_t re_connecting = true;
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#include "mbed.h"
|
||||
#include "rtos.h"
|
||||
#include "NanostackInterface.h"
|
||||
#include "Nanostack.h"
|
||||
#include "NanostackLockGuard.h"
|
||||
|
||||
#include "ns_address.h"
|
||||
|
@ -444,20 +444,7 @@ void NanostackSocket::event_connection_reset(socket_callback_t *sock_cb)
|
|||
close();
|
||||
}
|
||||
|
||||
NanostackInterface *NanostackInterface::_ns_interface;
|
||||
|
||||
NanostackInterface *NanostackInterface::get_stack()
|
||||
{
|
||||
NanostackLockGuard lock;
|
||||
|
||||
if (NULL == _ns_interface) {
|
||||
_ns_interface = new NanostackInterface();
|
||||
}
|
||||
|
||||
return _ns_interface;
|
||||
}
|
||||
|
||||
const char * NanostackInterface::get_ip_address()
|
||||
const char * Nanostack::get_ip_address()
|
||||
{
|
||||
NanostackLockGuard lock;
|
||||
|
||||
|
@ -474,7 +461,7 @@ const char * NanostackInterface::get_ip_address()
|
|||
return "::";
|
||||
}
|
||||
|
||||
nsapi_error_t NanostackInterface::socket_open(void **handle, nsapi_protocol_t protocol)
|
||||
nsapi_error_t Nanostack::socket_open(void **handle, nsapi_protocol_t protocol)
|
||||
{
|
||||
// Validate parameters
|
||||
if (NULL == handle) {
|
||||
|
@ -511,7 +498,7 @@ nsapi_error_t NanostackInterface::socket_open(void **handle, nsapi_protocol_t pr
|
|||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t NanostackInterface::socket_close(void *handle)
|
||||
nsapi_error_t Nanostack::socket_close(void *handle)
|
||||
{
|
||||
NanostackLockGuard lock;
|
||||
// Validate parameters
|
||||
|
@ -528,7 +515,7 @@ nsapi_error_t NanostackInterface::socket_close(void *handle)
|
|||
|
||||
}
|
||||
|
||||
nsapi_size_or_error_t NanostackInterface::do_sendto(void *handle, const ns_address_t *address, const void *data, nsapi_size_t size)
|
||||
nsapi_size_or_error_t Nanostack::do_sendto(void *handle, const ns_address_t *address, const void *data, nsapi_size_t size)
|
||||
{
|
||||
// Validate parameters
|
||||
NanostackSocket * socket = static_cast<NanostackSocket *>(handle);
|
||||
|
@ -601,7 +588,7 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
nsapi_size_or_error_t NanostackInterface::socket_sendto(void *handle, const SocketAddress &address, const void *data, nsapi_size_t size)
|
||||
nsapi_size_or_error_t Nanostack::socket_sendto(void *handle, const SocketAddress &address, const void *data, nsapi_size_t size)
|
||||
{
|
||||
if (address.get_ip_version() != NSAPI_IPv6) {
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
|
@ -613,7 +600,7 @@ nsapi_size_or_error_t NanostackInterface::socket_sendto(void *handle, const Sock
|
|||
return do_sendto(handle, &ns_address, data, size);
|
||||
}
|
||||
|
||||
nsapi_size_or_error_t NanostackInterface::socket_recvfrom(void *handle, SocketAddress *address, void *buffer, nsapi_size_t size)
|
||||
nsapi_size_or_error_t Nanostack::socket_recvfrom(void *handle, SocketAddress *address, void *buffer, nsapi_size_t size)
|
||||
{
|
||||
// Validate parameters
|
||||
NanostackSocket *socket = static_cast<NanostackSocket *>(handle);
|
||||
|
@ -658,7 +645,7 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
nsapi_error_t NanostackInterface::socket_bind(void *handle, const SocketAddress &address)
|
||||
nsapi_error_t Nanostack::socket_bind(void *handle, const SocketAddress &address)
|
||||
{
|
||||
// Validate parameters
|
||||
NanostackSocket *socket = static_cast<NanostackSocket *>(handle);
|
||||
|
@ -699,7 +686,7 @@ nsapi_error_t NanostackInterface::socket_bind(void *handle, const SocketAddress
|
|||
return ret;
|
||||
}
|
||||
|
||||
nsapi_error_t NanostackInterface::setsockopt(void *handle, int level, int optname, const void *optval, unsigned optlen)
|
||||
nsapi_error_t Nanostack::setsockopt(void *handle, int level, int optname, const void *optval, unsigned optlen)
|
||||
{
|
||||
NanostackSocket *socket = static_cast<NanostackSocket *>(handle);
|
||||
if (handle == NULL) {
|
||||
|
@ -753,7 +740,7 @@ nsapi_error_t NanostackInterface::setsockopt(void *handle, int level, int optnam
|
|||
}
|
||||
}
|
||||
|
||||
nsapi_error_t NanostackInterface::getsockopt(void *handle, int level, int optname, void *optval, unsigned *optlen)
|
||||
nsapi_error_t Nanostack::getsockopt(void *handle, int level, int optname, void *optval, unsigned *optlen)
|
||||
{
|
||||
NanostackSocket *socket = static_cast<NanostackSocket *>(handle);
|
||||
if (handle == NULL) {
|
||||
|
@ -776,7 +763,7 @@ nsapi_error_t NanostackInterface::getsockopt(void *handle, int level, int optnam
|
|||
return ret;
|
||||
}
|
||||
|
||||
nsapi_error_t NanostackInterface::socket_listen(void *handle, int backlog)
|
||||
nsapi_error_t Nanostack::socket_listen(void *handle, int backlog)
|
||||
{
|
||||
//Check if socket exists
|
||||
NanostackSocket *socket = static_cast<NanostackSocket *>(handle);
|
||||
|
@ -798,7 +785,7 @@ nsapi_error_t NanostackInterface::socket_listen(void *handle, int backlog)
|
|||
return ret;
|
||||
}
|
||||
|
||||
nsapi_error_t NanostackInterface::socket_connect(void *handle, const SocketAddress &addr)
|
||||
nsapi_error_t Nanostack::socket_connect(void *handle, const SocketAddress &addr)
|
||||
{
|
||||
// Validate parameters
|
||||
NanostackSocket *socket = static_cast<NanostackSocket *>(handle);
|
||||
|
@ -850,7 +837,7 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
nsapi_error_t NanostackInterface::socket_accept(void *server, void **handle, SocketAddress *address)
|
||||
nsapi_error_t Nanostack::socket_accept(void *server, void **handle, SocketAddress *address)
|
||||
{
|
||||
NanostackSocket * socket = static_cast<NanostackSocket *>(server);
|
||||
NanostackSocket *accepted_sock = NULL;
|
||||
|
@ -900,17 +887,17 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
nsapi_size_or_error_t NanostackInterface::socket_send(void *handle, const void *data, nsapi_size_t size)
|
||||
nsapi_size_or_error_t Nanostack::socket_send(void *handle, const void *data, nsapi_size_t size)
|
||||
{
|
||||
return do_sendto(handle, NULL, data, size);
|
||||
}
|
||||
|
||||
nsapi_size_or_error_t NanostackInterface::socket_recv(void *handle, void *data, nsapi_size_t size)
|
||||
nsapi_size_or_error_t Nanostack::socket_recv(void *handle, void *data, nsapi_size_t size)
|
||||
{
|
||||
return socket_recvfrom(handle, NULL, data, size);
|
||||
}
|
||||
|
||||
void NanostackInterface::socket_attach(void *handle, void (*callback)(void *), void *id)
|
||||
void Nanostack::socket_attach(void *handle, void (*callback)(void *), void *id)
|
||||
{
|
||||
// Validate parameters
|
||||
NanostackSocket * socket = static_cast<NanostackSocket *>(handle);
|
||||
|
@ -926,3 +913,18 @@ void NanostackInterface::socket_attach(void *handle, void (*callback)(void *), v
|
|||
|
||||
tr_debug("socket_attach(socket=%p) sock_id=%d", socket, socket->socket_id);
|
||||
}
|
||||
|
||||
Nanostack &Nanostack::get_instance() {
|
||||
static Nanostack nanostack;
|
||||
return nanostack;
|
||||
}
|
||||
|
||||
// This works as long as it's not ever set to something which corresponds to
|
||||
// a macro defined as a non-integer. Eg `#define Nanostack "Foo"`
|
||||
#define NANOSTACK 0x99119911
|
||||
#if MBED_CONF_NSAPI_DEFAULT_STACK == NANOSTACK
|
||||
#undef NANOSTACK
|
||||
OnboardNetworkStack &OnboardNetworkStack::get_default_instance() {
|
||||
return Nanostack::get_instance();
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,252 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2017, Arm Limited and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef NANOSTACK_H_
|
||||
#define NANOSTACK_H_
|
||||
|
||||
#include "mbed.h"
|
||||
#include "OnboardNetworkStack.h"
|
||||
#include "NanostackMemoryManager.h"
|
||||
#include "MeshInterface.h"
|
||||
#include "mesh_interface_types.h"
|
||||
|
||||
struct ns_address;
|
||||
|
||||
class Nanostack : public OnboardNetworkStack, private mbed::NonCopyable<Nanostack> {
|
||||
public:
|
||||
static Nanostack &get_instance();
|
||||
|
||||
// Our Nanostack::Interface etc are defined by mbed_mesh_api
|
||||
class Interface;
|
||||
class EthernetInterface;
|
||||
class MeshInterface;
|
||||
class LoWPANNDInterface;
|
||||
class ThreadInterface;
|
||||
|
||||
/* Implement OnboardNetworkStack method */
|
||||
virtual nsapi_error_t add_ethernet_interface(EMAC &emac, bool default_if, OnboardNetworkStack::Interface **interface_out);
|
||||
|
||||
/* Local variant with stronger typing and manual address specification */
|
||||
nsapi_error_t add_ethernet_interface(EMAC &emac, bool default_if, Nanostack::EthernetInterface **interface_out, const uint8_t *mac_addr = NULL);
|
||||
|
||||
protected:
|
||||
|
||||
/** Get the local IP address
|
||||
*
|
||||
* @return Null-terminated representation of the local IP address
|
||||
* or null if not yet connected
|
||||
*/
|
||||
virtual const char *get_ip_address();
|
||||
|
||||
/** Opens a socket
|
||||
*
|
||||
* Creates a network socket and stores it in the specified handle.
|
||||
* The handle must be passed to following calls on the socket.
|
||||
*
|
||||
* A stack may have a finite number of sockets, in this case
|
||||
* NSAPI_ERROR_NO_SOCKET is returned if no socket is available.
|
||||
*
|
||||
* @param handle Destination for the handle to a newly created socket
|
||||
* @param proto Protocol of socket to open, NSAPI_TCP or NSAPI_UDP
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
virtual nsapi_error_t socket_open(void **handle, nsapi_protocol_t proto);
|
||||
|
||||
/** Close the socket
|
||||
*
|
||||
* Closes any open connection and deallocates any memory associated
|
||||
* with the socket.
|
||||
*
|
||||
* @param handle Socket handle
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
virtual nsapi_error_t socket_close(void *handle);
|
||||
|
||||
/** Bind a specific address to a socket
|
||||
*
|
||||
* Binding a socket specifies the address and port on which to recieve
|
||||
* data. If the IP address is zeroed, only the port is bound.
|
||||
*
|
||||
* @param handle Socket handle
|
||||
* @param address Local address to bind
|
||||
* @return 0 on success, negative error code on failure.
|
||||
*/
|
||||
virtual nsapi_error_t socket_bind(void *handle, const SocketAddress &address);
|
||||
|
||||
/** Listen for connections on a TCP socket
|
||||
*
|
||||
* Marks the socket as a passive socket that can be used to accept
|
||||
* incoming connections.
|
||||
*
|
||||
* @param handle Socket handle
|
||||
* @param backlog Number of pending connections that can be queued
|
||||
* simultaneously
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
virtual nsapi_error_t socket_listen(void *handle, int backlog);
|
||||
|
||||
/** Connects TCP socket to a remote host
|
||||
*
|
||||
* Initiates a connection to a remote server specified by the
|
||||
* indicated address.
|
||||
*
|
||||
* @param handle Socket handle
|
||||
* @param address The SocketAddress of the remote host
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
virtual nsapi_error_t socket_connect(void *handle, const SocketAddress &address);
|
||||
|
||||
/** Accepts a connection on a TCP socket
|
||||
*
|
||||
* The server socket must be bound and set to listen for connections.
|
||||
* On a new connection, creates a network socket and stores it in the
|
||||
* specified handle. The handle must be passed to following calls on
|
||||
* the socket.
|
||||
*
|
||||
* A stack may have a finite number of sockets, in this case
|
||||
* NSAPI_ERROR_NO_SOCKET is returned if no socket is available.
|
||||
*
|
||||
* This call is non-blocking. If accept would block,
|
||||
* NSAPI_ERROR_WOULD_BLOCK is returned immediately.
|
||||
*
|
||||
* @param server Socket handle to server to accept from
|
||||
* @param handle Destination for a handle to the newly created socket
|
||||
* @param address Destination for the remote address or NULL
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
virtual nsapi_error_t socket_accept(void *handle, void **server, SocketAddress *address);
|
||||
|
||||
/** Send data over a TCP socket
|
||||
*
|
||||
* The socket must be connected to a remote host. Returns the number of
|
||||
* bytes sent from the buffer.
|
||||
*
|
||||
* This call is non-blocking. If send would block,
|
||||
* NSAPI_ERROR_WOULD_BLOCK is returned immediately.
|
||||
*
|
||||
* @param handle Socket handle
|
||||
* @param data Buffer of data to send to the host
|
||||
* @param size Size of the buffer in bytes
|
||||
* @return Number of sent bytes on success, negative error
|
||||
* code on failure
|
||||
*/
|
||||
virtual nsapi_size_or_error_t socket_send(void *handle, const void *data, nsapi_size_t size);
|
||||
|
||||
/** Receive data over a TCP socket
|
||||
*
|
||||
* The socket must be connected to a remote host. Returns the number of
|
||||
* bytes received into the buffer.
|
||||
*
|
||||
* This call is non-blocking. If recv would block,
|
||||
* NSAPI_ERROR_WOULD_BLOCK is returned immediately.
|
||||
*
|
||||
* @param handle Socket handle
|
||||
* @param data Destination buffer for data received from the host
|
||||
* @param size Size of the buffer in bytes
|
||||
* @return Number of received bytes on success, negative error
|
||||
* code on failure
|
||||
*/
|
||||
virtual nsapi_size_or_error_t socket_recv(void *handle, void *data, nsapi_size_t size);
|
||||
|
||||
/** Send a packet over a UDP socket
|
||||
*
|
||||
* Sends data to the specified address. Returns the number of bytes
|
||||
* sent from the buffer.
|
||||
*
|
||||
* This call is non-blocking. If sendto would block,
|
||||
* NSAPI_ERROR_WOULD_BLOCK is returned immediately.
|
||||
*
|
||||
* @param handle Socket handle
|
||||
* @param address The SocketAddress of the remote host
|
||||
* @param data Buffer of data to send to the host
|
||||
* @param size Size of the buffer in bytes
|
||||
* @return Number of sent bytes on success, negative error
|
||||
* code on failure
|
||||
*/
|
||||
virtual nsapi_size_or_error_t socket_sendto(void *handle, const SocketAddress &address, const void *data, nsapi_size_t size);
|
||||
|
||||
/** Receive a packet over a UDP socket
|
||||
*
|
||||
* Receives data and stores the source address in address if address
|
||||
* is not NULL. Returns the number of bytes received into the buffer.
|
||||
*
|
||||
* This call is non-blocking. If recvfrom would block,
|
||||
* NSAPI_ERROR_WOULD_BLOCK is returned immediately.
|
||||
*
|
||||
* @param handle Socket handle
|
||||
* @param address Destination for the source address or NULL
|
||||
* @param buffer Destination buffer for data received from the host
|
||||
* @param size Size of the buffer in bytes
|
||||
* @return Number of received bytes on success, negative error
|
||||
* code on failure
|
||||
*/
|
||||
virtual nsapi_size_or_error_t socket_recvfrom(void *handle, SocketAddress *address, void *buffer, nsapi_size_t size);
|
||||
|
||||
/** Register a callback on state change of the socket
|
||||
*
|
||||
* The specified callback will be called on state changes such as when
|
||||
* the socket can recv/send/accept successfully and on when an error
|
||||
* occurs. The callback may also be called spuriously without reason.
|
||||
*
|
||||
* The callback may be called in an interrupt context and should not
|
||||
* perform expensive operations such as recv/send calls.
|
||||
*
|
||||
* @param handle Socket handle
|
||||
* @param callback Function to call on state change
|
||||
* @param data Argument to pass to callback
|
||||
*/
|
||||
virtual void socket_attach(void *handle, void (*callback)(void *), void *data);
|
||||
|
||||
/* Set stack-specific socket options
|
||||
*
|
||||
* The setsockopt allow an application to pass stack-specific hints
|
||||
* to the underlying stack. For unsupported options,
|
||||
* NSAPI_ERROR_UNSUPPORTED is returned and the socket is unmodified.
|
||||
*
|
||||
* @param handle Socket handle
|
||||
* @param level Stack-specific protocol level
|
||||
* @param optname Stack-specific option identifier
|
||||
* @param optval Option value
|
||||
* @param optlen Length of the option value
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
virtual nsapi_error_t setsockopt(void *handle, int level, int optname, const void *optval, unsigned optlen);
|
||||
|
||||
/* Get stack-specific socket options
|
||||
*
|
||||
* The getstackopt allow an application to retrieve stack-specific hints
|
||||
* from the underlying stack. For unsupported options,
|
||||
* NSAPI_ERROR_UNSUPPORTED is returned and optval is unmodified.
|
||||
*
|
||||
* @param handle Socket handle
|
||||
* @param level Stack-specific protocol level
|
||||
* @param optname Stack-specific option identifier
|
||||
* @param optval Destination for option value
|
||||
* @param optlen Length of the option value
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
virtual nsapi_error_t getsockopt(void *handle, int level, int optname, void *optval, unsigned *optlen);
|
||||
|
||||
private:
|
||||
nsapi_size_or_error_t do_sendto(void *handle, const struct ns_address *address, const void *data, nsapi_size_t size);
|
||||
char text_ip_address[40];
|
||||
NanostackMemoryManager memory_manager;
|
||||
};
|
||||
|
||||
nsapi_error_t map_mesh_error(mesh_error_t err);
|
||||
|
||||
#endif /* NANOSTACK_H_ */
|
|
@ -19,7 +19,6 @@
|
|||
#define NANOSTACK_INTERFACE_H_
|
||||
|
||||
#include "mbed.h"
|
||||
#include "NetworkStack.h"
|
||||
#include "MeshInterface.h"
|
||||
// Include here for backward compatibility
|
||||
#include "LoWPANNDInterface.h"
|
||||
|
@ -27,217 +26,4 @@
|
|||
#include "NanostackEthernetInterface.h"
|
||||
#include "MeshInterfaceNanostack.h"
|
||||
|
||||
struct ns_address;
|
||||
|
||||
/** Network interface class for Nanostack */
|
||||
class NanostackInterface : public NetworkStack {
|
||||
public:
|
||||
static NanostackInterface *get_stack();
|
||||
|
||||
protected:
|
||||
|
||||
/** Get the local IP address
|
||||
*
|
||||
* @return Null-terminated representation of the local IP address
|
||||
* or null if not yet connected
|
||||
*/
|
||||
virtual const char *get_ip_address();
|
||||
|
||||
/** Opens a socket
|
||||
*
|
||||
* Creates a network socket and stores it in the specified handle.
|
||||
* The handle must be passed to following calls on the socket.
|
||||
*
|
||||
* A stack may have a finite number of sockets, in this case
|
||||
* NSAPI_ERROR_NO_SOCKET is returned if no socket is available.
|
||||
*
|
||||
* @param handle Destination for the handle to a newly created socket
|
||||
* @param proto Protocol of socket to open, NSAPI_TCP or NSAPI_UDP
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
virtual nsapi_error_t socket_open(void **handle, nsapi_protocol_t proto);
|
||||
|
||||
/** Close the socket
|
||||
*
|
||||
* Closes any open connection and deallocates any memory associated
|
||||
* with the socket.
|
||||
*
|
||||
* @param handle Socket handle
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
virtual nsapi_error_t socket_close(void *handle);
|
||||
|
||||
/** Bind a specific address to a socket
|
||||
*
|
||||
* Binding a socket specifies the address and port on which to recieve
|
||||
* data. If the IP address is zeroed, only the port is bound.
|
||||
*
|
||||
* @param handle Socket handle
|
||||
* @param address Local address to bind
|
||||
* @return 0 on success, negative error code on failure.
|
||||
*/
|
||||
virtual nsapi_error_t socket_bind(void *handle, const SocketAddress &address);
|
||||
|
||||
/** Listen for connections on a TCP socket
|
||||
*
|
||||
* Marks the socket as a passive socket that can be used to accept
|
||||
* incoming connections.
|
||||
*
|
||||
* @param handle Socket handle
|
||||
* @param backlog Number of pending connections that can be queued
|
||||
* simultaneously
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
virtual nsapi_error_t socket_listen(void *handle, int backlog);
|
||||
|
||||
/** Connects TCP socket to a remote host
|
||||
*
|
||||
* Initiates a connection to a remote server specified by the
|
||||
* indicated address.
|
||||
*
|
||||
* @param handle Socket handle
|
||||
* @param address The SocketAddress of the remote host
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
virtual nsapi_error_t socket_connect(void *handle, const SocketAddress &address);
|
||||
|
||||
/** Accepts a connection on a TCP socket
|
||||
*
|
||||
* The server socket must be bound and set to listen for connections.
|
||||
* On a new connection, creates a network socket and stores it in the
|
||||
* specified handle. The handle must be passed to following calls on
|
||||
* the socket.
|
||||
*
|
||||
* A stack may have a finite number of sockets, in this case
|
||||
* NSAPI_ERROR_NO_SOCKET is returned if no socket is available.
|
||||
*
|
||||
* This call is non-blocking. If accept would block,
|
||||
* NSAPI_ERROR_WOULD_BLOCK is returned immediately.
|
||||
*
|
||||
* @param server Socket handle to server to accept from
|
||||
* @param handle Destination for a handle to the newly created socket
|
||||
* @param address Destination for the remote address or NULL
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
virtual nsapi_error_t socket_accept(void *handle, void **server, SocketAddress *address);
|
||||
|
||||
/** Send data over a TCP socket
|
||||
*
|
||||
* The socket must be connected to a remote host. Returns the number of
|
||||
* bytes sent from the buffer.
|
||||
*
|
||||
* This call is non-blocking. If send would block,
|
||||
* NSAPI_ERROR_WOULD_BLOCK is returned immediately.
|
||||
*
|
||||
* @param handle Socket handle
|
||||
* @param data Buffer of data to send to the host
|
||||
* @param size Size of the buffer in bytes
|
||||
* @return Number of sent bytes on success, negative error
|
||||
* code on failure
|
||||
*/
|
||||
virtual nsapi_size_or_error_t socket_send(void *handle, const void *data, nsapi_size_t size);
|
||||
|
||||
/** Receive data over a TCP socket
|
||||
*
|
||||
* The socket must be connected to a remote host. Returns the number of
|
||||
* bytes received into the buffer.
|
||||
*
|
||||
* This call is non-blocking. If recv would block,
|
||||
* NSAPI_ERROR_WOULD_BLOCK is returned immediately.
|
||||
*
|
||||
* @param handle Socket handle
|
||||
* @param data Destination buffer for data received from the host
|
||||
* @param size Size of the buffer in bytes
|
||||
* @return Number of received bytes on success, negative error
|
||||
* code on failure
|
||||
*/
|
||||
virtual nsapi_size_or_error_t socket_recv(void *handle, void *data, nsapi_size_t size);
|
||||
|
||||
/** Send a packet over a UDP socket
|
||||
*
|
||||
* Sends data to the specified address. Returns the number of bytes
|
||||
* sent from the buffer.
|
||||
*
|
||||
* This call is non-blocking. If sendto would block,
|
||||
* NSAPI_ERROR_WOULD_BLOCK is returned immediately.
|
||||
*
|
||||
* @param handle Socket handle
|
||||
* @param address The SocketAddress of the remote host
|
||||
* @param data Buffer of data to send to the host
|
||||
* @param size Size of the buffer in bytes
|
||||
* @return Number of sent bytes on success, negative error
|
||||
* code on failure
|
||||
*/
|
||||
virtual nsapi_size_or_error_t socket_sendto(void *handle, const SocketAddress &address, const void *data, nsapi_size_t size);
|
||||
|
||||
/** Receive a packet over a UDP socket
|
||||
*
|
||||
* Receives data and stores the source address in address if address
|
||||
* is not NULL. Returns the number of bytes received into the buffer.
|
||||
*
|
||||
* This call is non-blocking. If recvfrom would block,
|
||||
* NSAPI_ERROR_WOULD_BLOCK is returned immediately.
|
||||
*
|
||||
* @param handle Socket handle
|
||||
* @param address Destination for the source address or NULL
|
||||
* @param buffer Destination buffer for data received from the host
|
||||
* @param size Size of the buffer in bytes
|
||||
* @return Number of received bytes on success, negative error
|
||||
* code on failure
|
||||
*/
|
||||
virtual nsapi_size_or_error_t socket_recvfrom(void *handle, SocketAddress *address, void *buffer, nsapi_size_t size);
|
||||
|
||||
/** Register a callback on state change of the socket
|
||||
*
|
||||
* The specified callback will be called on state changes such as when
|
||||
* the socket can recv/send/accept successfully and on when an error
|
||||
* occurs. The callback may also be called spuriously without reason.
|
||||
*
|
||||
* The callback may be called in an interrupt context and should not
|
||||
* perform expensive operations such as recv/send calls.
|
||||
*
|
||||
* @param handle Socket handle
|
||||
* @param callback Function to call on state change
|
||||
* @param data Argument to pass to callback
|
||||
*/
|
||||
virtual void socket_attach(void *handle, void (*callback)(void *), void *data);
|
||||
|
||||
/* Set stack-specific socket options
|
||||
*
|
||||
* The setsockopt allow an application to pass stack-specific hints
|
||||
* to the underlying stack. For unsupported options,
|
||||
* NSAPI_ERROR_UNSUPPORTED is returned and the socket is unmodified.
|
||||
*
|
||||
* @param handle Socket handle
|
||||
* @param level Stack-specific protocol level
|
||||
* @param optname Stack-specific option identifier
|
||||
* @param optval Option value
|
||||
* @param optlen Length of the option value
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
virtual nsapi_error_t setsockopt(void *handle, int level, int optname, const void *optval, unsigned optlen);
|
||||
|
||||
/* Get stack-specific socket options
|
||||
*
|
||||
* The getstackopt allow an application to retrieve stack-specific hints
|
||||
* from the underlying stack. For unsupported options,
|
||||
* NSAPI_ERROR_UNSUPPORTED is returned and optval is unmodified.
|
||||
*
|
||||
* @param handle Socket handle
|
||||
* @param level Stack-specific protocol level
|
||||
* @param optname Stack-specific option identifier
|
||||
* @param optval Destination for option value
|
||||
* @param optlen Length of the option value
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
virtual nsapi_error_t getsockopt(void *handle, int level, int optname, void *optval, unsigned *optlen);
|
||||
|
||||
private:
|
||||
nsapi_size_or_error_t do_sendto(void *handle, const struct ns_address *address, const void *data, nsapi_size_t size);
|
||||
char text_ip_address[40];
|
||||
static NanostackInterface * _ns_interface;
|
||||
};
|
||||
|
||||
nsapi_error_t map_mesh_error(mesh_error_t err);
|
||||
|
||||
#endif /* NANOSTACK_INTERFACE_H_ */
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
*
|
||||
* Common interface that is shared between mesh hardware
|
||||
*/
|
||||
class MeshInterface : public NetworkInterface
|
||||
class MeshInterface : public virtual NetworkInterface
|
||||
{
|
||||
virtual MeshInterface *meshInterface() {
|
||||
return this;
|
||||
|
|
Loading…
Reference in New Issue