Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

net/l2util: add eui_short/48/64_get() #12641

Closed
wants to merge 11 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions boards/samr21-xpro/Makefile.dep
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
ifneq (,$(filter gnrc_netdev_default netdev_default,$(USEMODULE)))
USEMODULE += at86rf233
USEMODULE += periph_i2c
endif

ifneq (,$(filter saul_default,$(USEMODULE)))
Expand Down
41 changes: 41 additions & 0 deletions boards/samr21-xpro/board.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,44 @@ void board_init(void)
/* initialize the CPU */
cpu_init();
}

#ifdef MODULE_PERIPH_I2C
#include "periph/i2c.h"
#include "net/l2util.h"
#include "net/netif_ids.h"

#define DEV_I2C I2C_DEV(0)
#define EDBG_ADDR (0x28)
#define TOKEN_EUI64 (0xD2)
#define TOKEN_EXT (0xE1)

/* EDBG provides an EUI-64 for the internal radio */
size_t board_get_eui64(netif_id_t driver, unsigned idx, eui64_t *addr)
{
if (driver != AT86RF2XX_DEVUID) {
return 0;
}

if (idx != 0) {
return 0;
}

i2c_acquire(DEV_I2C);

/* dummy read form another token */
if (i2c_read_regs(0, EDBG_ADDR, TOKEN_EXT, addr, 2, 0)) {
goto error;
}

if (i2c_read_regs(0, EDBG_ADDR, TOKEN_EUI64, addr, sizeof(*addr), 0)) {
goto error;
}

i2c_release(DEV_I2C);
return sizeof(eui64_t);

error:
i2c_release(DEV_I2C);
return 0;
}
#endif
20 changes: 8 additions & 12 deletions drivers/at86rf2xx/at86rf2xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,13 @@
#include "at86rf2xx_registers.h"
#include "at86rf2xx_internal.h"
#include "at86rf2xx_netdev.h"
#include "at86rf2xx_params.h"

#define ENABLE_DEBUG (0)
#include "debug.h"


void at86rf2xx_setup(at86rf2xx_t *dev, const at86rf2xx_params_t *params)
void at86rf2xx_setup(at86rf2xx_t *dev, unsigned idx)
{
netdev_t *netdev = (netdev_t *)dev;

Expand All @@ -49,13 +50,15 @@ void at86rf2xx_setup(at86rf2xx_t *dev, const at86rf2xx_params_t *params)
dev->pending_tx = 0;

#if defined(MODULE_AT86RFA1) || defined(MODULE_AT86RFR2)
(void) params;
/* set all interrupts off */
at86rf2xx_reg_write(dev, AT86RF2XX_REG__IRQ_MASK, 0x00);
#else
/* initialize device descriptor */
dev->params = *params;
dev->params = at86rf2xx_params[idx];
#endif

l2util_generate_short_addr(AT86RF2XX_DEVUID, idx, (network_uint16_t *)dev->netdev.short_addr);
l2util_generate_eui64(AT86RF2XX_DEVUID, idx, (eui64_t *)dev->netdev.long_addr);
}

static void at86rf2xx_disable_clock_output(at86rf2xx_t *dev)
Expand Down Expand Up @@ -89,8 +92,6 @@ static void at86rf2xx_enable_smart_idle(at86rf2xx_t *dev)

void at86rf2xx_reset(at86rf2xx_t *dev)
{
eui64_t addr_long;

at86rf2xx_hardware_reset(dev);

netdev_ieee802154_reset(&dev->netdev);
Expand All @@ -100,14 +101,9 @@ void at86rf2xx_reset(at86rf2xx_t *dev)
at86rf2xx_set_state(dev, AT86RF2XX_STATE_FORCE_TRX_OFF);
}

/* get an 8-byte unique ID to use as hardware address */
luid_get(addr_long.uint8, IEEE802154_LONG_ADDRESS_LEN);
/* make sure we mark the address as non-multicast and not globally unique */
addr_long.uint8[0] &= ~(0x01);
addr_long.uint8[0] |= (0x02);
/* set short and long address */
at86rf2xx_set_addr_long(dev, ntohll(addr_long.uint64.u64));
at86rf2xx_set_addr_short(dev, ntohs(addr_long.uint16[0].u16));
at86rf2xx_set_addr_long(dev, dev->netdev.long_addr);
at86rf2xx_set_addr_short(dev, dev->netdev.short_addr);

/* set default channel */
at86rf2xx_set_chan(dev, AT86RF2XX_DEFAULT_CHANNEL);
Expand Down
19 changes: 7 additions & 12 deletions drivers/at86rf2xx/at86rf2xx_getset.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,15 +135,11 @@ uint16_t at86rf2xx_get_addr_short(const at86rf2xx_t *dev)
return (dev->netdev.short_addr[0] << 8) | dev->netdev.short_addr[1];
}

void at86rf2xx_set_addr_short(at86rf2xx_t *dev, uint16_t addr)
void at86rf2xx_set_addr_short(at86rf2xx_t *dev, const uint8_t *addr)
{
dev->netdev.short_addr[0] = (uint8_t)(addr);
dev->netdev.short_addr[1] = (uint8_t)(addr >> 8);
#ifdef MODULE_SIXLOWPAN
/* https://tools.ietf.org/html/rfc4944#section-12 requires the first bit to
* 0 for unicast addresses */
dev->netdev.short_addr[0] &= 0x7F;
#endif
dev->netdev.short_addr[0] = addr[0];
dev->netdev.short_addr[1] = addr[1];

at86rf2xx_reg_write(dev, AT86RF2XX_REG__SHORT_ADDR_0,
dev->netdev.short_addr[1]);
at86rf2xx_reg_write(dev, AT86RF2XX_REG__SHORT_ADDR_1,
Expand All @@ -161,12 +157,11 @@ uint64_t at86rf2xx_get_addr_long(const at86rf2xx_t *dev)
return addr;
}

void at86rf2xx_set_addr_long(at86rf2xx_t *dev, uint64_t addr)
void at86rf2xx_set_addr_long(at86rf2xx_t *dev, const uint8_t *addr)
{
for (int i = 0; i < 8; i++) {
dev->netdev.long_addr[i] = (uint8_t)(addr >> (i * 8));
at86rf2xx_reg_write(dev, (AT86RF2XX_REG__IEEE_ADDR_0 + i),
(addr >> ((7 - i) * 8)));
dev->netdev.long_addr[i] = addr[i];
at86rf2xx_reg_write(dev, (AT86RF2XX_REG__IEEE_ADDR_0 + i), addr[7-i]);
}
}

Expand Down
4 changes: 2 additions & 2 deletions drivers/at86rf2xx/at86rf2xx_netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -470,12 +470,12 @@ static int _set(netdev_t *netdev, netopt_t opt, const void *val, size_t len)
switch (opt) {
case NETOPT_ADDRESS:
assert(len <= sizeof(uint16_t));
at86rf2xx_set_addr_short(dev, *((const uint16_t *)val));
at86rf2xx_set_addr_short(dev, val);
/* don't set res to set netdev_ieee802154_t::short_addr */
break;
case NETOPT_ADDRESS_LONG:
assert(len <= sizeof(uint64_t));
at86rf2xx_set_addr_long(dev, *((const uint64_t *)val));
at86rf2xx_set_addr_long(dev, val);
/* don't set res to set netdev_ieee802154_t::long_addr */
break;
case NETOPT_NID:
Expand Down
8 changes: 4 additions & 4 deletions drivers/include/at86rf2xx.h
Original file line number Diff line number Diff line change
Expand Up @@ -268,9 +268,9 @@ typedef struct {
* @brief Setup an AT86RF2xx based device state
*
* @param[out] dev device descriptor
* @param[in] params parameters for device initialization
* @param[in] idx index in the at86rf2xx_params struct.
*/
void at86rf2xx_setup(at86rf2xx_t *dev, const at86rf2xx_params_t *params);
void at86rf2xx_setup(at86rf2xx_t *dev, unsigned idx);

/**
* @brief Trigger a hardware reset and configure radio with default values
Expand All @@ -294,7 +294,7 @@ uint16_t at86rf2xx_get_addr_short(const at86rf2xx_t *dev);
* @param[in,out] dev device to write to
* @param[in] addr (2-byte) short address to set
*/
void at86rf2xx_set_addr_short(at86rf2xx_t *dev, uint16_t addr);
void at86rf2xx_set_addr_short(at86rf2xx_t *dev, const uint8_t *addr);

/**
* @brief Get the configured long address of the given device
Expand All @@ -311,7 +311,7 @@ uint64_t at86rf2xx_get_addr_long(const at86rf2xx_t *dev);
* @param[in,out] dev device to write to
* @param[in] addr (8-byte) long address to set
*/
void at86rf2xx_set_addr_long(at86rf2xx_t *dev, uint64_t addr);
void at86rf2xx_set_addr_long(at86rf2xx_t *dev, const uint8_t *addr);

/**
* @brief Get the configured channel number of the given device
Expand Down
2 changes: 1 addition & 1 deletion sys/auto_init/netif/auto_init_at86rf2xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ void auto_init_at86rf2xx(void)
for (unsigned i = 0; i < AT86RF2XX_NUM; i++) {
LOG_DEBUG("[auto_init_netif] initializing at86rf2xx #%u\n", i);

at86rf2xx_setup(&at86rf2xx_devs[i], &at86rf2xx_params[i]);
at86rf2xx_setup(&at86rf2xx_devs[i], i);
#if defined(MODULE_GNRC_GOMACH)
gnrc_netif_gomach_create(_at86rf2xx_stacks[i],
AT86RF2XX_MAC_STACKSIZE,
Expand Down
6 changes: 6 additions & 0 deletions sys/include/luid.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ void luid_get(void *buf, size_t len);
*
* @note The resulting address will repeat after 255 calls.
*
* @warning Don't call this function directly, use @ref l2util_generate_short_addr() instead.
*
* @param[out] addr memory location to copy the address into.
*/
void luid_get_short(network_uint16_t *addr);
Expand All @@ -106,6 +108,8 @@ void luid_get_short(network_uint16_t *addr);
*
* @note The resulting address will repeat after 255 calls.
*
* @warning Don't call this function directly, use @ref l2util_generate_eui48() instead.
*
* @param[out] addr memory location to copy the address into.
*/
void luid_get_eui48(eui48_t *addr);
Expand All @@ -118,6 +122,8 @@ void luid_get_eui48(eui48_t *addr);
*
* @note The resulting address will repeat after 255 calls.
*
* @warning Don't call this function directly, use @ref l2util_generate_eui64() instead.
*
* @param[out] addr memory location to copy the address into.
*/
void luid_get_eui64(eui64_t *addr);
Expand Down
1 change: 0 additions & 1 deletion sys/include/net/eui48.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,6 @@ static inline void eui48_clear_group(eui48_t *addr)
addr->uint8[0] &= ~EUI48_GROUP_FLAG;
}


#ifdef __cplusplus
}
#endif
Expand Down
121 changes: 121 additions & 0 deletions sys/include/net/l2util.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@

#include <stdint.h>

#include "luid.h"
#include "net/eui64.h"
#include "net/netif_ids.h"
#include "net/ndp.h"

#ifdef __cplusplus
Expand Down Expand Up @@ -133,6 +135,125 @@ int l2util_ipv6_iid_to_addr(int dev_type, const eui64_t *iid, uint8_t *addr);
int l2util_ndp_addr_len_from_l2ao(int dev_type,
const ndp_opt_t *opt);

/**
* @brief Board-specific function to supply a short address to a netdev.
*
* @note Implement this function in your board code if the board
* provides the means to supply a unique address to a netdev.
*
* @warning Don't call this function directly, use @ref l2util_generate_short_addr() instead.
*
* @param[in] driver The driver id of the netdev
* @param[in] idx The index in the <driver>_params_t struct
* @param[out] addr The dedicated address for the netdev
*
* @return The number of bytes copied. 0 if no address is available.
*/
size_t board_get_short_addr(netif_id_t driver, unsigned idx, network_uint16_t *addr);

/**
* @brief Generates an short address for the netdev interface.
*
* @note It is possible to supply a board-specific, constant addres
* by implementing @ref board_get_short_addr.
* If no such function is availiable, this will fall back to
* @ref luid_get_short.
*
* @param[in] driver The driver id of the netdev
* Will be passed on to @ref board_get_eui48.
* @param[in] idx The index in the <driver>_params_t struct
* Will be passed on to @ref board_get_eui48.
* @param[out] addr The generated short address
*
*/
static inline void l2util_generate_short_addr(netif_id_t driver, unsigned idx, network_uint16_t *addr)
{
if (board_get_short_addr(driver, idx, addr) == sizeof(*addr)) {
return;
}

luid_get_short(addr);
}

/**
* @brief Board-specific function to supply an EUI-48 to a netdev
*
* @note Implement this function in your board code if the board
* provides the means to supply a unique address to a netdev.
*
* @warning Don't call this function directly, use @ref l2util_generate_eui48() instead.
*
* @param[in] driver The driver id of the netdev
* @param[in] idx The index in the <driver>_params_t struct
* @param[out] addr The dedicated address for the netdev
*
* @return The number of bytes copied. 0 if no address is available.
*/
size_t board_get_eui48(netif_id_t driver, unsigned idx, eui48_t *addr);

/**
* @brief Generates an EUI-48 address for the netdev interface.
*
* @note It is possible to supply a board-specific, constant addres
* by implementing @ref board_get_eui48.
* If no such function is availiable, this will fall back to
* @ref luid_get_eui48.
*
* @param[in] driver The driver id of the netdev
* Will be passed on to @ref board_get_eui48.
* @param[in] idx The index in the <driver>_params_t struct
* Will be passed on to @ref board_get_eui48.
* @param[out] addr The generated EUI-48 address
*
*/
static inline void l2util_generate_eui48(netif_id_t driver, unsigned idx, eui48_t *addr)
{
if (board_get_eui48(driver, idx, addr) == sizeof(*addr)) {
return;
}

luid_get_eui48(addr);
}

/**
* @brief Board-specific function to supply an EUI-64 to a netdev
*
* @note Implement this function in your board code if the board
* provides the means to supply a unique address to a netdev.
*
* @warning Don't call this function directly, use @ref l2util_generate_eui64() instead.
*
* @param[in] driver The driver id of the netdev
* @param[in] idx The index in the <driver>_params_t struct
* @param[out] addr The dedicated address for the netdev
*
* @return The number of bytes copied. 0 if no address is available.
*/
size_t board_get_eui64(netif_id_t driver, unsigned idx, eui64_t *addr);

/**
* @brief Generates an EUI-64 address for the netdev interface.
*
* @note It is possible to supply a board-specific, constant addres
* by implementing @ref board_get_eui64.
* If no such function is availiable, this will fall back to
* @ref luid_get_eui64.
*
* @param[in] driver The driver id of the netdev
* Will be passed on to @ref board_get_eui64.
* @param[in] idx The index in the <driver>_params_t struct
* Will be passed on to @ref board_get_eui64.
* @param[out] addr The generated EUI-64 address
*
*/
static inline void l2util_generate_eui64(netif_id_t driver, unsigned idx, eui64_t *addr)
{
if (board_get_eui64(driver, idx, addr) == sizeof(*addr)) {
return;
}

luid_get_eui64(addr);
}

#ifdef __cplusplus
}
Expand Down
Loading