1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #6314 from haukepetersen/add_uuid

sys: add uuid module for central ID/addr generation
This commit is contained in:
Martine Lenders 2017-01-19 14:12:09 +01:00 committed by GitHub
commit 7599a81fd6
14 changed files with 213 additions and 123 deletions

View File

@ -8,6 +8,7 @@ endif
ifneq (,$(filter at86rf2%,$(USEMODULE)))
USEMODULE += at86rf2xx
USEMODULE += xtimer
USEMODULE += uuid
USEMODULE += netif
USEMODULE += ieee802154
USEMODULE += netdev2_ieee802154
@ -30,6 +31,7 @@ endif
ifneq (,$(filter cc110x,$(USEMODULE)))
USEMODULE += ieee802154
USEMODULE += uuid
ifneq (,$(filter gnrc_netdev_default,$(USEMODULE)))
USEMODULE += gnrc_cc110x
# XXX: this can be modelled as a dependency for gnrc_netdev_default as soon
@ -40,6 +42,7 @@ endif
ifneq (,$(filter cc2420,$(USEMODULE)))
USEMODULE += xtimer
USEMODULE += uuid
USEMODULE += netif
USEMODULE += ieee802154
USEMODULE += netdev2_ieee802154
@ -60,6 +63,7 @@ endif
ifneq (,$(filter enc28j60,$(USEMODULE)))
USEMODULE += netdev2_eth
USEMODULE += xtimer
USEMODULE += uuid
endif
ifneq (,$(filter encx24j600,$(USEMODULE)))
@ -152,6 +156,7 @@ endif
ifneq (,$(filter w5100,$(USEMODULE)))
USEMODULE += netdev2_eth
USEMODULE += uuid
endif
ifneq (,$(filter xbee,$(USEMODULE)))

View File

@ -23,7 +23,8 @@
* @}
*/
#include "periph/cpuid.h"
#include "uuid.h"
#include "byteorder.h"
#include "net/ieee802154.h"
#include "net/gnrc.h"
@ -51,15 +52,7 @@ void at86rf2xx_setup(at86rf2xx_t *dev, const at86rf2xx_params_t *params)
void at86rf2xx_reset(at86rf2xx_t *dev)
{
#if CPUID_LEN
/* make sure that the buffer is always big enough to store a 64bit value */
# if CPUID_LEN < IEEE802154_LONG_ADDRESS_LEN
uint8_t cpuid[IEEE802154_LONG_ADDRESS_LEN];
# else
uint8_t cpuid[CPUID_LEN];
#endif
eui64_t addr_long;
#endif
at86rf2xx_hardware_reset(dev);
@ -69,30 +62,16 @@ void at86rf2xx_reset(at86rf2xx_t *dev)
/* reset options and sequence number */
dev->netdev.seq = 0;
dev->netdev.flags = 0;
/* set short and long address */
#if CPUID_LEN
/* in case CPUID_LEN < 8, fill missing bytes with zeros */
memset(cpuid, 0, CPUID_LEN);
cpuid_get(cpuid);
#if CPUID_LEN > IEEE802154_LONG_ADDRESS_LEN
for (unsigned int i = IEEE802154_LONG_ADDRESS_LEN; i < CPUID_LEN; i++) {
cpuid[i & 0x07] ^= cpuid[i];
}
#endif
/* get an 8-byte unique ID to use as hardware address */
uuid_get(addr_long.uint8, IEEE802154_LONG_ADDRESS_LEN);
/* make sure we mark the address as non-multicast and not globally unique */
cpuid[0] &= ~(0x01);
cpuid[0] |= 0x02;
/* copy and set long address */
memcpy(&addr_long, cpuid, IEEE802154_LONG_ADDRESS_LEN);
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));
#else
at86rf2xx_set_addr_long(dev, AT86RF2XX_DEFAULT_ADDR_LONG);
at86rf2xx_set_addr_short(dev, AT86RF2XX_DEFAULT_ADDR_SHORT);
#endif
/* set default PAN id */
at86rf2xx_set_pan(dev, AT86RF2XX_DEFAULT_PANID);
/* set default channel */

View File

@ -29,7 +29,6 @@
#include "cc110x-interface.h"
#include "net/eui64.h"
#include "periph/cpuid.h"
#include "periph/gpio.h"
#include "net/netdev2.h"
#include "net/gnrc/nettype.h"

View File

@ -20,8 +20,8 @@
* @}
*/
#include "uuid.h"
#include "board.h"
#include "periph/cpuid.h"
#include "periph/gpio.h"
#include "periph/spi.h"
#include "xtimer.h"
@ -87,14 +87,9 @@ int cc110x_setup(cc110x_t *dev, const cc110x_params_t *params)
cc110x_set_channel(dev, CC110X_DEFAULT_CHANNEL);
/* set default node id */
#if CPUID_LEN
char cpuid[CPUID_LEN];
cpuid_get(cpuid);
for (int i = 1; i < CPUID_LEN; i++) {
cpuid[0] ^= cpuid[i];
}
cc110x_set_address(dev, (uint8_t) cpuid[0]);
#endif
uint8_t addr;
uuid_get(&addr, 1);
cc110x_set_address(dev, addr);
LOG_INFO("cc110x: initialized with address=%u and channel=%i\n",
(unsigned)dev->radio_address,

View File

@ -20,7 +20,7 @@
* @}
*/
#include "periph/cpuid.h"
#include "uuid.h"
#include "byteorder.h"
#include "net/ieee802154.h"
#include "net/gnrc.h"
@ -32,36 +32,6 @@
#define ENABLE_DEBUG (0)
#include "debug.h"
/**
* @todo Move this function to a global module
*/
#if CPUID_ID_LEN
static void addr_from_cpuid(uint8_t *addr)
{
/* option 1: generate addresses from CPUID */
uint8_t cpuid[CPUID_ID_LEN];
cpuid_get(cpuid);
memcpy(addr, cpuid, 8);
#if CPUID_ID_LEN < 8
/* in case CPUID_ID_LEN < 8, fill missing bytes with zeros */
for (int i = CPUID_ID_LEN; i < 8; i++) {
addr_long[i] = 0;
}
#else
/* in case CPUID_ID_LEN > 8, XOR those bytes on top of the first 8 */
for (int i = 8; i < CPUID_ID_LEN; i++) {
addr_long[i & 0x07] ^= cpuid[i];
}
#endif
/* make sure we mark the address as non-multicast and not globally unique */
addr_long[0] &= ~(0x01);
addr_long[0] |= 0x02;
}
#endif
void cc2420_setup(cc2420_t * dev, const cc2420_params_t *params)
{
@ -78,16 +48,17 @@ void cc2420_setup(cc2420_t * dev, const cc2420_params_t *params)
int cc2420_init(cc2420_t *dev)
{
uint16_t reg;
uint8_t addr[8] = CC2420_ADDR_FALLBACK;
uint8_t addr[8];
/* reset options and sequence number */
dev->netdev.seq = 0;
dev->netdev.flags = 0;
/* set default address, channel, PAN ID, and TX power */
#if CPUID_ID_LEN
addr_from_cpuid(addr);
#endif
uuid_get(addr, sizeof(addr));
/* make sure we mark the address as non-multicast and not globally unique */
addr[0] &= ~(0x01);
addr[0] |= 0x02;
cc2420_set_addr_short(dev, &addr[6]);
cc2420_set_addr_long(dev, addr);
cc2420_set_pan(dev, CC2420_PANID_DEFAULT);

View File

@ -21,6 +21,7 @@
*/
#include <string.h>
#include <errno.h>
#include "cc2420.h"
#include "cc2420_internal.h"

View File

@ -21,6 +21,7 @@
#include <errno.h>
#include <string.h>
#include "uuid.h"
#include "mutex.h"
#include "xtimer.h"
#include "assert.h"
@ -30,10 +31,6 @@
#include "enc28j60.h"
#include "enc28j60_regs.h"
#if CPUID_LEN
#include "periph/cpuid.h"
#endif
#define ENABLE_DEBUG (0)
#include "debug.h"
@ -269,7 +266,7 @@ static int nd_recv(netdev2_t *netdev, void *buf, size_t max_len, void *info)
if (buf != NULL) {
#ifdef MODULE_NETSTATS_L2
netdev->stats.rx_count++;
netdev2->stats.rx_bytes += size;
netdev->stats.rx_bytes += size;
#endif
/* read packet content into the supplied buffer */
if (size <= max_len) {
@ -354,14 +351,10 @@ static int nd_init(netdev2_t *netdev)
/* set non-back-to-back inter packet gap -> 0x12 is default */
cmd_wcr(dev, REG_B2_MAIPGL, 2, MAIPGL_FD);
/* set default MAC address */
#if CPUID_LEN
uint8_t macbuf[CPUID_LEN];
cpuid_get(&macbuf); /* we get the full ID but use only parts of it */
uint8_t macbuf[ETHERNET_ADDR_LEN];
uuid_get(macbuf, ETHERNET_ADDR_LEN);
macbuf[0] |= 0x02; /* locally administered address */
macbuf[0] &= ~0x01; /* unicast address */
#else
uint8_t macbuf[] = ENC28J60_FALLBACK_MAC;
#endif
mac_set(dev, macbuf);
/* PHY configuration */

View File

@ -48,14 +48,6 @@ extern "C" {
*/
#define AT86RF2XX_MAX_PKT_LENGTH (IEEE802154_FRAME_LEN_MAX)
/**
* @brief Default addresses used if the CPUID module is not present
* @{
*/
#define AT86RF2XX_DEFAULT_ADDR_SHORT (0x0230)
#define AT86RF2XX_DEFAULT_ADDR_LONG (0x1222334455667788)
/** @} */
/**
* @brief Channel configuration
* @{

View File

@ -38,14 +38,6 @@ extern "C" {
*/
#define CC2420_PKT_MAXLEN (IEEE802154_FRAME_LEN_MAX)
/**
* @brief Default addresses used if the CPUID module is not present
*
* In case this address is used, that short address will be created by using the
* last two bytes of the long address.
*/
#define CC2420_ADDR_FALLBACK {0x12, 0x22, 0x33, 0x44, 0x55, 0x66, 0x08, 0x15}
/**
* @brief PAN ID configuration
*/

View File

@ -32,15 +32,6 @@
extern "C" {
#endif
/**
* @brief Fallback MAC address in case CPUID is not available
*
* The enc28j60 does not provide a globally unique, pre-set MAC address, so we
* need to create one. For this the CPUID module is used to create a locally
* administered MAC. If this is not available, we use the MAC address below.
*/
#define ENC28J60_FALLBACK_MAC {0x02, 0x22, 0x33, 0x44, 0x55, 0x66}
/**
* @brief Struct containing the needed peripheral configuration
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2016 Freie Universität Berlin
* Copyright (C) 2016-2017 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
@ -22,8 +22,8 @@
#include <string.h>
#include "log.h"
#include "uuid.h"
#include "assert.h"
#include "periph/cpuid.h"
#include "net/ethernet.h"
#include "net/netdev2/eth.h"
@ -37,7 +37,6 @@
#define SPI_CONF SPI_CONF_FIRST_RISING
#define RMSR_DEFAULT_VALUE (0x55)
#define MAC_SEED (0x23)
#define S0_MEMSIZE (0x2000)
#define S0_MASK (S0_MEMSIZE - 1)
@ -143,9 +142,6 @@ static int init(netdev2_t *netdev)
w5100_t *dev = (w5100_t *)netdev;
uint8_t tmp;
uint8_t hwaddr[ETHERNET_ADDR_LEN];
#if CPUID_LEN
uint8_t cpuid[CPUID_LEN];
#endif
/* test the SPI connection by reading the value of the RMSR register */
tmp = rreg(dev, REG_TMSR);
@ -159,13 +155,7 @@ static int init(netdev2_t *netdev)
while (rreg(dev, REG_MODE) & MODE_RESET) {};
/* initialize the device, start with writing the MAC address */
memset(hwaddr, MAC_SEED, ETHERNET_ADDR_LEN);
#if CPUID_LEN
cpuid_get(cpuid);
for (int i = 0; i < CPUID_LEN; i++) {
hwaddr[i % ETHERNET_ADDR_LEN] ^= cpuid[i];
}
#endif
uuid_get(hwaddr, ETHERNET_ADDR_LEN);
hwaddr[0] &= ~0x03; /* no group address and not globally unique */
wchunk(dev, REG_SHAR0, hwaddr, ETHERNET_ADDR_LEN);

119
sys/include/uuid.h Normal file
View File

@ -0,0 +1,119 @@
/*
* Copyright (C) 2017 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @defgroup sys_uuid (Locally) Unique ID Generator
* @ingroup sys
* @brief Generate system wide unique IDs
*
* This module generates system wide, variable length unique IDs based on on the
* cpuid module. If the cpuid module is not present, the module falls back to a
* pre-defined, constant seed for creating unique ids.
*
* The main purpose of this module is to have a unified way for e.g. creating
* hardware addresses and similar.
*
* The IDs generated by this module are base created from a constant base part
* and a dynamic portion, which is XORed into the base ID. If the cpuid module
* is present, the base ID is created from the CPU's unique ID. If not, the
* base ID is created by simple 'memsetting' the base ID with the defined
* backup seed value.
*
* Once the base ID is generated, a UUID is generated by (i) XORing a counter
* value with the LSB of the base ID, or (ii) by XORing the least significant
* byes with a value given by the user.
*
* Example: Calling `uuid_base(&buf, 8)` will always yield an identical value,
* independent how often the function is called. But calling
* `uuid_base(&buf, 2)` afterwards will results in a different value, if the
* cpuid module is present, and in the same (but shorter) value if not.
*
* Example: Calling `uuid_get(&buf, 8)` four times in a row, will yield four
* different IDs, differing in their LSB.
*
* Example: Calling `uuid_custom(&buf, 8, 123)` will always yield the same
* value, but calling `uuid_custom(&buf, 8, 124)` will differ.
*
* @note This module generates unique IDs without any guarantees on their
* structure. These UUIDs are not compatible nor conform to the
* UUIDs as defined in RFC4122.
*
* @{
* @file
* @brief Header of the unique ID generation module
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*/
#ifndef UUID_H_
#define UUID_H_
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Value used as based for the UUIDs in case the cpuid module is not
* present
*/
#ifndef UUID_BACKUP_SEED
#define UUID_BACKUP_SEED 0x23
#endif
/**
* @brief Get a unique ID
*
* The resulting ID is built from the base ID generated with uuid_base(), which
* isXORed with an 8-bit incrementing counter value into the most significant
* byte.
*
* @note The resulting UUID will repeat after 255 calls.
*
* @param[out] buf memory location to copy the UUID into. MUST be able to
* hold at least @p len bytes
* @param[in] len length of the UUID in bytes
*/
void uuid_get(void *buf, size_t len);
/**
* @brief Get a custom unique ID based on a user given generator value
*
* The resulting ID is built from the base ID XORed with @p gen in the base
* ID's most significant bytes.
*
* @note Calling this function with identical values for @p gen and @p len
* will always result in identical UUIDs.
*
* @param[out] buf memory location to copy the UUID into. MUST be able to
* hold at least @p len bytes
* @param[in] len length of the UUID in bytes
* @param[in] gen custom UUID generator value
*/
void uuid_custom(void *buf, size_t len, int gen);
/**
* @brief Get a UUID base value
*
* The uuid module creates the value dependent on the given @p len value using
* the cpuid module if present or a static seed value (@ref UUID_BACKUP_SEED) if
* not.
*
* @param[out] buf memory location to copy the UUID into. MUST be able to
* hold at least @p len bytes
* @param[in] len length of the UUID in bytes
*/
void uuid_base(void *buf, size_t len);
#ifdef __cplusplus
}
#endif
#endif /* UUID_H_ */
/** @} */

1
sys/uuid/Makefile Normal file
View File

@ -0,0 +1 @@
include $(RIOTBASE)/Makefile.base

62
sys/uuid/uuid.c Normal file
View File

@ -0,0 +1,62 @@
/*
* Copyright (C) 2017 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup sys_uuid
* @{
*
* @file
* @brief UUID module implementation
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*
* @}
*/
#include <stdint.h>
#include <string.h>
#include "assert.h"
#include "periph/cpuid.h"
#include "uuid.h"
static uint8_t lastused = 1;
void uuid_get(void *buf, size_t len)
{
uuid_base(buf, len);
((uint8_t *)buf)[0] ^= lastused++;
}
void uuid_custom(void *buf, size_t len, int gen)
{
uuid_base(buf, len);
for (int i = 0; i < sizeof(gen); i++) {
((uint8_t *)buf)[i % len] ^= ((gen >> (i * 8)) & 0xff);
}
}
void uuid_base(void *buf, size_t len)
{
assert(buf && (len > 0));
memset(buf, UUID_BACKUP_SEED, len);
#if CPUID_LEN
uint8_t *out = (uint8_t *)buf;
uint8_t cid[CPUID_LEN];
cpuid_get(cid);
for (size_t i = 0; i < CPUID_LEN; i++) {
out[i % len] ^= cid[i];
}
#endif
}