Merge remote-tracking branch 'origin/master' into ieee802154

This commit is contained in:
Gregory Nutt 2017-03-30 16:30:43 -06:00
commit 916bd80f9f
76 changed files with 5855 additions and 641 deletions

View File

@ -2810,36 +2810,25 @@ menu "Timer Configuration"
if SCHED_TICKLESS
config STM32_ONESHOT
bool
default y
config STM32_FREERUN
bool
default y
config STM32_TICKLESS_ONESHOT
int "Tickless one-shot timer channel"
config STM32_TICKLESS_TIMER
int "Tickless hardware timer"
default 2
range 1 14
depends on STM32_ONESHOT
---help---
If the Tickless OS feature is enabled, the one clock must be
assigned to provided the one-shot timer needed by the OS.
If the Tickless OS feature is enabled, then one clock must be
assigned to provided the timer needed by the OS.
config STM32_TICKLESS_FREERUN
int "Tickless free-running timer channel"
default 5
range 1 14
depends on STM32_FREERUN
config STM32_TICKLESS_CHANNEL
int "Tickless timer channel"
default 1
range 1 4
---help---
If the Tickless OS feature is enabled, the one clock must be
assigned to provided the free-running timer needed by the OS.
assigned to provided the free-running timer needed by the OS
and one channel on that clock is needed to handle intervals.
endif # SCHED_TICKLESS
if !SCHED_TICKLESS
config STM32_ONESHOT
bool "TIM one-shot wrapper"
default n
@ -2854,8 +2843,6 @@ config STM32_FREERUN
Enable a wrapper around the low level timer/counter functions to
support a free-running timer.
endif # !SCHED_TICKLESS
config STM32_ONESHOT_MAXTIMERS
int "Maximum number of oneshot timers"
default 1

View File

@ -2,7 +2,9 @@
* arch/arm/src/stm32/stm32_tickless.c
*
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
* Copyright (C) 2017 Ansync Labs. All rights reserved.
* Authors: Gregory Nutt <gnutt@nuttx.org>
* Konstantin Berezenko <kpberezenko@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -55,24 +57,19 @@
*
****************************************************************************/
/****************************************************************************
* SAM34 Timer Usage
* STM32 Timer Usage
*
* This current implementation uses two timers: A one-shot timer to provide
* the timed events and a free running timer to provide the current time.
* Since timers are a limited resource, that could be an issue on some
* systems.
*
* We could do the job with a single timer if we were to keep the single
* timer in a free-running at all times. The STM32 timer/counters have
* 16-bit/32-bit counters with the capability to generate a compare interrupt
* when the timer matches a compare value but also to continue counting
* without stopping (giving another, different interrupt when the timer
* rolls over from 0xffffffff to zero). So we could potentially just set
* the compare at the number of ticks you want PLUS the current value of
* timer. Then you could have both with a single timer: An interval timer
* and a free-running counter with the same timer!
*
* Patches are welcome!
* This implementation uses one timer: A free running timer to provide
* the current time and a capture/compare channel for timed-events.
* The STM32 has both 16-bit and 32-bit timers so to keep things consistent
* we limit the timer counters to a 16-bit range. BASIC timers that
* are found on some STM32 chips (timers 6 and 7) are incompatible with this
* implementation because they don't have capture/compare channels. There
* are two interrupts generated from our timer, the overflow interrupt which
* drives the timing handler and the capture/compare interrupt which drives
* the interval handler. There are some low level timer control functions
* implemented here because the API of stm32_tim.c does not provide adequate
* control over capture/compare interrupts.
*
****************************************************************************/
@ -84,12 +81,15 @@
#include <stdint.h>
#include <stdbool.h>
#include <errno.h>
#include <assert.h>
#include <nuttx/arch.h>
#include <debug.h>
#include "stm32_oneshot.h"
#include "stm32_freerun.h"
#include "up_arch.h"
#include "stm32_tim.h"
#ifdef CONFIG_SCHED_TICKLESS
@ -97,30 +97,24 @@
* Pre-processor Definitions
****************************************************************************/
#ifndef CONFIG_STM32_ONESHOT
# error CONFIG_STM32_ONESHOT must be selected for the Tickless OS option
#endif
#ifndef CONFIG_STM32_FREERUN
# error CONFIG_STM32_FREERUN must be selected for the Tickless OS option
#endif
#ifndef CONFIG_STM32_TICKLESS_FREERUN
# error CONFIG_STM32_TICKLESS_FREERUN must be selected for the Tickless OS option
#endif
#ifndef CONFIG_STM32_TICKLESS_ONESHOT
# error CONFIG_STM32_TICKLESS_ONESHOT must be selected for the Tickless OS option
#endif
/****************************************************************************
* Private Types
****************************************************************************/
struct stm32_tickless_s
{
struct stm32_oneshot_s oneshot;
struct stm32_freerun_s freerun;
uint8_t timer; /* The timer/counter in use */
uint8_t channel; /* The timer channel to use for intervals */
FAR struct stm32_tim_dev_s *tch; /* Handle returned by stm32_tim_init() */
uint32_t frequency;
#ifdef CONFIG_CLOCK_TIMEKEEPING
uint64_t counter_mask;
#else
uint32_t overflow; /* Timer counter overflow */
#endif
volatile bool pending; /* True: pending task */
uint32_t period; /* Interval period */
uint32_t base;
};
/****************************************************************************
@ -133,11 +127,159 @@ static struct stm32_tickless_s g_tickless;
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: stm32_oneshot_handler
/************************************************************************************
* Name: stm32_getreg16
*
* Description:
* Called when the one shot timer expires
* Get a 16-bit register value by offset
*
************************************************************************************/
static inline uint16_t stm32_getreg16(uint8_t offset)
{
return getreg16(g_tickless.base + offset);
}
/************************************************************************************
* Name: stm32_putreg16
*
* Description:
* Put a 16-bit register value by offset
*
************************************************************************************/
static inline void stm32_putreg16(uint8_t offset, uint16_t value)
{
putreg16(value, g_tickless.base + offset);
}
/************************************************************************************
* Name: stm32_modifyreg16
*
* Description:
* Modify a 16-bit register value by offset
*
************************************************************************************/
static inline void stm32_modifyreg16(uint8_t offset, uint16_t clearbits,
uint16_t setbits)
{
modifyreg16(g_tickless.base + offset, clearbits, setbits);
}
/************************************************************************************
* Name: stm32_tickless_enableint
************************************************************************************/
static inline void stm32_tickless_enableint(int channel)
{
stm32_modifyreg16(STM32_BTIM_DIER_OFFSET, 0, 1 << channel);
}
/************************************************************************************
* Name: stm32_tickless_disableint
************************************************************************************/
static inline void stm32_tickless_disableint(int channel)
{
stm32_modifyreg16(STM32_BTIM_DIER_OFFSET, 1 << channel, 0);
}
/************************************************************************************
* Name: stm32_tickless_ackint
************************************************************************************/
static inline void stm32_tickless_ackint(int channel)
{
stm32_putreg16(STM32_BTIM_SR_OFFSET, ~(1 << channel));
}
/************************************************************************************
* Name: stm32_tickless_getint
************************************************************************************/
static inline uint16_t stm32_tickless_getint(void)
{
return stm32_getreg16(STM32_BTIM_SR_OFFSET);
}
/************************************************************************************
* Name: stm32_tickless_setchannel
************************************************************************************/
static int stm32_tickless_setchannel(uint8_t channel)
{
uint16_t ccmr_orig = 0;
uint16_t ccmr_val = 0;
uint16_t ccmr_mask = 0xff;
uint16_t ccer_val = stm32_getreg16(STM32_GTIM_CCER_OFFSET);
uint8_t ccmr_offset = STM32_GTIM_CCMR1_OFFSET;
/* Further we use range as 0..3; if channel=0 it will also overflow here */
if (--channel > 4)
{
return -EINVAL;
}
/* Assume that channel is disabled and polarity is active high */
ccer_val &= ~(3 << (channel << 2));
/* This function is not supported on basic timers. To enable or
* disable it, simply set its clock to valid frequency or zero.
*/
#if STM32_NBTIM > 0
if (g_tickless.base == STM32_TIM6_BASE
#endif
#if STM32_NBTIM > 1
|| g_tickless.base == STM32_TIM7_BASE
#endif
#if STM32_NBTIM > 0
)
{
return -EINVAL;
}
#endif
/* Frozen mode because we don't want to change the GPIO, preload register
* disabled.
*/
ccmr_val = (ATIM_CCMR_MODE_FRZN << ATIM_CCMR1_OC1M_SHIFT);
/* Set polarity */
ccer_val |= ATIM_CCER_CC1P << (channel << 2);
/* Define its position (shift) and get register offset */
if ((channel & 1) != 0)
{
ccmr_val <<= 8;
ccmr_mask <<= 8;
}
if (channel > 1)
{
ccmr_offset = STM32_GTIM_CCMR2_OFFSET;
}
ccmr_orig = stm32_getreg16(ccmr_offset);
ccmr_orig &= ~ccmr_mask;
ccmr_orig |= ccmr_val;
stm32_putreg16(ccmr_offset, ccmr_orig);
stm32_putreg16(STM32_GTIM_CCER_OFFSET, ccer_val);
return OK;
}
/****************************************************************************
* Name: stm32_interval_handler
*
* Description:
* Called when the timer counter matches the compare register
*
* Input Parameters:
* None
@ -151,12 +293,78 @@ static struct stm32_tickless_s g_tickless;
*
****************************************************************************/
static void stm32_oneshot_handler(void *arg)
static void stm32_interval_handler(void)
{
tmrinfo("Expired...\n");
/* Disable the compare interrupt now. */
stm32_tickless_disableint(g_tickless.channel);
stm32_tickless_ackint(g_tickless.channel);
g_tickless.pending = false;
sched_timer_expiration();
}
/****************************************************************************
* Name: stm32_timing_handler
*
* Description:
* Timer interrupt callback. When the freerun timer counter overflows,
* this interrupt will occur. We will just increment an overflow count.
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
#ifndef CONFIG_CLOCK_TIMEKEEPING
static void stm32_timing_handler(void)
{
g_tickless.overflow++;
STM32_TIM_ACKINT(g_tickless.tch, 0);
}
#endif /* CONFIG_CLOCK_TIMEKEEPING */
/****************************************************************************
* Name: stm32_tickless_handler
*
* Description:
* Generic interrupt handler for this timer. It checks the source of the
* interrupt and fires the appropriate handler.
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
static int stm32_tickless_handler(int irq, void *context, void *arg)
{
int interrupt_flags = stm32_tickless_getint();
#ifndef CONFIG_CLOCK_TIMEKEEPING
if (interrupt_flags & ATIM_SR_UIF)
{
stm32_timing_handler();
}
#endif /* CONFIG_CLOCK_TIMEKEEPING */
if (interrupt_flags & (1 << g_tickless.channel))
{
stm32_interval_handler();
}
return OK;
}
/****************************************************************************
* Public Functions
****************************************************************************/
@ -188,55 +396,172 @@ static void stm32_oneshot_handler(void *arg)
void arm_timer_initialize(void)
{
#ifdef CONFIG_SCHED_TICKLESS_LIMIT_MAX_SLEEP
uint64_t max_delay;
#endif
int ret;
/* Initialize the one-shot timer */
ret = stm32_oneshot_initialize(&g_tickless.oneshot,
CONFIG_STM32_TICKLESS_ONESHOT,
CONFIG_USEC_PER_TICK);
if (ret < 0)
switch (CONFIG_STM32_TICKLESS_TIMER)
{
tmrerr("ERROR: stm32_oneshot_initialize failed\n");
PANIC();
}
#ifdef CONFIG_SCHED_TICKLESS_LIMIT_MAX_SLEEP
/* Get the maximum delay of the one-shot timer in microseconds */
ret = stm32_oneshot_max_delay(&g_tickless.oneshot, &max_delay);
if (ret < 0)
{
tmrerr("ERROR: stm32_oneshot_max_delay failed\n");
PANIC();
}
/* Convert this to configured clock ticks for use by the OS timer logic */
max_delay /= CONFIG_USEC_PER_TICK;
if (max_delay > UINT32_MAX)
{
g_oneshot_maxticks = UINT32_MAX;
}
else
{
g_oneshot_maxticks = max_delay;
}
#ifdef CONFIG_STM32_TIM1
case 1:
g_tickless.base = STM32_TIM1_BASE;
break;
#endif
/* Initialize the free-running timer */
#ifdef CONFIG_STM32_TIM2
case 2:
g_tickless.base = STM32_TIM2_BASE;
break;
#endif
ret = stm32_freerun_initialize(&g_tickless.freerun,
CONFIG_STM32_TICKLESS_FREERUN,
CONFIG_USEC_PER_TICK);
if (ret < 0)
{
tmrerr("ERROR: stm32_freerun_initialize failed\n");
PANIC();
#ifdef CONFIG_STM32_TIM3
case 3:
g_tickless.base = STM32_TIM3_BASE;
break;
#endif
#ifdef CONFIG_STM32_TIM4
case 4:
g_tickless.base = STM32_TIM4_BASE;
break;
#endif
#ifdef CONFIG_STM32_TIM5
case 5:
g_tickless.base = STM32_TIM5_BASE;
break;
#endif
#ifdef CONFIG_STM32_TIM6
case 6:
/* Basic timers not supported by this implementation */
ASSERT(0);
break;
#endif
#ifdef CONFIG_STM32_TIM7
case 7:
/* Basic timers not supported by this implementation */
ASSERT(0);
break;
#endif
#ifdef CONFIG_STM32_TIM8
case 8:
g_tickless.base = STM32_TIM8_BASE;
break;
#endif
#ifdef CONFIG_STM32_TIM9
case 9:
g_tickless.base = STM32_TIM9_BASE;
break;
#endif
#ifdef CONFIG_STM32_TIM10
case 10:
g_tickless.base = STM32_TIM10_BASE;
break;
#endif
#ifdef CONFIG_STM32_TIM11
case 11:
g_tickless.base = STM32_TIM11_BASE;
break;
#endif
#ifdef CONFIG_STM32_TIM12
case 12:
g_tickless.base = STM32_TIM12_BASE;
break;
#endif
#ifdef CONFIG_STM32_TIM13
case 13:
g_tickless.base = STM32_TIM13_BASE;
break;
#endif
#ifdef CONFIG_STM32_TIM14
case 14:
g_tickless.base = STM32_TIM14_BASE;
break;
#endif
#ifdef CONFIG_STM32_TIM15
case 15:
g_tickless.base = STM32_TIM15_BASE;
break;
#endif
#ifdef CONFIG_STM32_TIM16
case 16:
g_tickless.base = STM32_TIM16_BASE;
break;
#endif
#ifdef CONFIG_STM32_TIM17
case 17:
g_tickless.base = STM32_TIM17_BASE;
break;
#endif
default:
ASSERT(0);
}
/* Get the TC frequency that corresponds to the requested resolution */
g_tickless.frequency = USEC_PER_SEC / (uint32_t)CONFIG_USEC_PER_TICK;
g_tickless.timer = CONFIG_STM32_TICKLESS_TIMER;
g_tickless.channel = CONFIG_STM32_TICKLESS_CHANNEL;
g_tickless.pending = false;
g_tickless.period = 0;
tmrinfo("timer=%d channel=%d frequency=%d Hz\n",
g_tickless.timer, g_tickless.channel, g_tickless.frequency);
g_tickless.tch = stm32_tim_init(g_tickless.timer);
if (!g_tickless.tch)
{
tmrerr("ERROR: Failed to allocate TIM%d\n", g_tickless.timer);
ASSERT(0);
}
STM32_TIM_SETCLOCK(g_tickless.tch, g_tickless.frequency);
#ifdef CONFIG_CLOCK_TIMEKEEPING
/* Should this be changed to 0xffff because we use 16 bit timers? */
g_tickless.counter_mask = 0xffffffffull;
#else
g_tickless.overflow = 0;
/* Set up to receive the callback when the counter overflow occurs */
STM32_TIM_SETISR(g_tickless.tch, stm32_tickless_handler, NULL, 0);
#endif
/* Initialize interval to zero */
STM32_TIM_SETCOMPARE(g_tickless.tch, g_tickless.channel, 0);
/* Setup compare channel for the interval timing */
stm32_tickless_setchannel(g_tickless.channel);
/* Set timer period */
STM32_TIM_SETPERIOD(g_tickless.tch, UINT16_MAX);
/* Initialize the counter */
STM32_TIM_SETMODE(g_tickless.tch, STM32_TIM_MODE_UP);
#ifdef CONFIG_SCHED_TICKLESS_LIMIT_MAX_SLEEP
g_oneshot_maxticks = UINT16_MAX;
#endif
/* Start the timer */
STM32_TIM_ACKINT(g_tickless.tch, 0);
STM32_TIM_ENABLEINT(g_tickless.tch, 0);
}
/****************************************************************************
@ -276,14 +601,84 @@ void arm_timer_initialize(void)
int up_timer_gettime(FAR struct timespec *ts)
{
return stm32_freerun_counter(&g_tickless.freerun, ts);
uint64_t usec;
uint32_t counter;
uint32_t verify;
uint32_t overflow;
uint32_t sec;
int pending;
irqstate_t flags;
DEBUGASSERT(g_tickless.tch && ts);
/* Temporarily disable the overflow counter. NOTE that we have to be
* careful here because stm32_tc_getpending() will reset the pending
* interrupt status. If we do not handle the overflow here then, it will
* be lost.
*/
flags = enter_critical_section();
overflow = g_tickless.overflow;
counter = STM32_TIM_GETCOUNTER(g_tickless.tch);
pending = STM32_TIM_CHECKINT(g_tickless.tch, 0);
verify = STM32_TIM_GETCOUNTER(g_tickless.tch);
/* If an interrupt was pending before we re-enabled interrupts,
* then the overflow needs to be incremented.
*/
if (pending)
{
STM32_TIM_ACKINT(g_tickless.tch, 0);
/* Increment the overflow count and use the value of the
* guaranteed to be AFTER the overflow occurred.
*/
overflow++;
counter = verify;
/* Update tickless overflow counter. */
g_tickless.overflow = overflow;
}
leave_critical_section(flags);
tmrinfo("counter=%lu (%lu) overflow=%lu, pending=%i\n",
(unsigned long)counter, (unsigned long)verify,
(unsigned long)overflow, pending);
tmrinfo("frequency=%u\n", g_tickless.frequency);
/* Convert the whole thing to units of microseconds.
*
* frequency = ticks / second
* seconds = ticks * frequency
* usecs = (ticks * USEC_PER_SEC) / frequency;
*/
usec = ((((uint64_t)overflow << 16) + (uint64_t)counter) * USEC_PER_SEC) /
g_tickless.frequency;
/* And return the value of the timer */
sec = (uint32_t)(usec / USEC_PER_SEC);
ts->tv_sec = sec;
ts->tv_nsec = (usec - (sec * USEC_PER_SEC)) * NSEC_PER_USEC;
tmrinfo("usec=%llu ts=(%u, %lu)\n",
usec, (unsigned long)ts->tv_sec, (unsigned long)ts->tv_nsec);
return OK;
}
#else
int up_timer_getcounter(FAR uint64_t *cycles)
{
return stm32_freerun_counter(&g_tickless.freerun, cycles);
*cycles = (uint64_t)STM32_TIM_GETCOUNTER(g_tickless.tch);
return OK;
}
#endif /* CONFIG_CLOCK_TIMEKEEPING */
@ -306,7 +701,7 @@ int up_timer_getcounter(FAR uint64_t *cycles)
void up_timer_getmask(FAR uint64_t *mask)
{
DEBUGASSERT(mask != NULL);
*mask = g_tickless.freerun.counter_mask;
*mask = g_tickless.counter_mask;
}
#endif /* CONFIG_CLOCK_TIMEKEEPING */
@ -348,7 +743,101 @@ void up_timer_getmask(FAR uint64_t *mask)
int up_timer_cancel(FAR struct timespec *ts)
{
return stm32_oneshot_cancel(&g_tickless.oneshot, ts);
irqstate_t flags;
uint64_t usec;
uint64_t sec;
uint64_t nsec;
uint32_t count;
uint32_t period;
/* Was the timer running? */
flags = enter_critical_section();
if (!g_tickless.pending)
{
/* No.. Just return zero timer remaining and successful cancellation.
* This function may execute at a high rate with no timer running
* (as when pre-emption is enabled and disabled).
*/
if (ts)
{
ts->tv_sec = 0;
ts->tv_nsec = 0;
}
leave_critical_section(flags);
return OK;
}
/* Yes.. Get the timer counter and period registers and disable the compare interrupt.
*
*/
tmrinfo("Cancelling...\n");
/* Disable the interrupt. */
stm32_tickless_disableint(g_tickless.channel);
count = STM32_TIM_GETCOUNTER(g_tickless.tch);
period = g_tickless.period;
g_tickless.pending = false;
leave_critical_section(flags);
/* Did the caller provide us with a location to return the time
* remaining?
*/
if (ts != NULL)
{
/* Yes.. then calculate and return the time remaining on the
* oneshot timer.
*/
tmrinfo("period=%lu count=%lu\n",
(unsigned long)period, (unsigned long)count);
if (count > period)
{
/* Handle rollover */
period += UINT16_MAX;
}
else if (count == period)
{
/* No time remaining */
ts->tv_sec = 0;
ts->tv_nsec = 0;
return OK;
}
/* The total time remaining is the difference. Convert that
* to units of microseconds.
*
* frequency = ticks / second
* seconds = ticks * frequency
* usecs = (ticks * USEC_PER_SEC) / frequency;
*/
usec = (((uint64_t)(period - count)) * USEC_PER_SEC) /
g_tickless.frequency;
/* Return the time remaining in the correct form */
sec = usec / USEC_PER_SEC;
nsec = ((usec) - (sec * USEC_PER_SEC)) * NSEC_PER_USEC;
ts->tv_sec = (time_t)sec;
ts->tv_nsec = (unsigned long)nsec;
tmrinfo("remaining (%lu, %lu)\n",
(unsigned long)ts->tv_sec, (unsigned long)ts->tv_nsec);
}
return OK;
}
/****************************************************************************
@ -378,6 +867,65 @@ int up_timer_cancel(FAR struct timespec *ts)
int up_timer_start(FAR const struct timespec *ts)
{
return stm32_oneshot_start(&g_tickless.oneshot, stm32_oneshot_handler, NULL, ts);
uint64_t usec;
uint64_t period;
uint32_t count;
irqstate_t flags;
tmrinfo("handler=%p arg=%p, ts=(%lu, %lu)\n",
handler, arg, (unsigned long)ts->tv_sec, (unsigned long)ts->tv_nsec);
DEBUGASSERT(ts);
DEBUGASSERT(g_tickless.tch);
/* Was an interval already running? */
flags = enter_critical_section();
if (g_tickless.pending)
{
/* Yes.. then cancel it */
tmrinfo("Already running... cancelling\n");
(void)up_timer_cancel(NULL);
}
/* Express the delay in microseconds */
usec = (uint64_t)ts->tv_sec * USEC_PER_SEC +
(uint64_t)(ts->tv_nsec / NSEC_PER_USEC);
/* Get the timer counter frequency and determine the number of counts need
* to achieve the requested delay.
*
* frequency = ticks / second
* ticks = seconds * frequency
* = (usecs * frequency) / USEC_PER_SEC;
*/
period = (usec * (uint64_t)g_tickless.frequency) / USEC_PER_SEC;
count = STM32_TIM_GETCOUNTER(g_tickless.tch);
tmrinfo("usec=%llu period=%08llx\n", usec, period);
DEBUGASSERT(period <= UINT16_MAX);
/* Set interval compare value. Rollover is fine,
* channel will trigger on the next period. (uint16_t) cast
* handles the overflow.
*/
g_tickless.period = (uint16_t)(period + count);
STM32_TIM_SETCOMPARE(g_tickless.tch, g_tickless.channel,
g_tickless.period);
/* Enable interrupts. We should get the callback when the interrupt
* occurs.
*/
stm32_tickless_ackint(g_tickless.channel);
stm32_tickless_enableint(g_tickless.channel);
g_tickless.pending = true;
leave_critical_section(flags);
return OK;
}
#endif /* CONFIG_SCHED_TICKLESS */

View File

@ -2015,6 +2015,27 @@ config BOARD_RESET_ON_CRASH
If selected the board_crashdump should reset the machine after
saveing the state of the machine
config BOARD_ENTROPY_POOL
bool "Enable Board level storing of entropy pool structure"
default n
depends on CRYPTO_RANDOM_POOL
---help---
Entropy pool structure can be provided by board source.
Use for this is, for example, to allocate entropy pool
from special area of RAM which content is kept over
system reset.
config BOARD_INITRNGSEED
bool "Enable Board level initial seeding of entropy pool RNG"
default n
depends on CRYPTO_RANDOM_POOL
---help---
If enabled, entropy pool random number generator will call
board_init_rndseed() upon initialization. This function
can then provide early entropy seed to the pool through
entropy injection APIs provided at 'nuttx/random.h'.
#endif
config LIB_BOARDCTL
bool "Enable boardctl() interface"
default n

View File

@ -749,6 +749,19 @@ Selecting the GMAC peripheral
CONFIG_NSH_NOMAC=n : We will get the IP address from EEPROM
: Defaults should be okay for other options
SAMV71 Versions
---------------
WARNING: The newer SAMV71 have 6 GMAC queues, not 3. All queues must be
configured for the GMAC to work correctly, even the queues that you are not
using (you can just configure these queues with a very small ring buffer.)
The older uses the Cortex-M7 core r0p1 and the newer r1p1 revisions. The
SAMV71 revisions are called "rev A" (or sometimes "MRLA") and "rev B"
("MRLB"). There should be a small "A" or "B" on the chip package just below
the reference and you can also differentiate them at runtime with the
VERSION field in the CHIPID CIDR register.
Cache-Related Issues
--------------------

View File

@ -50,4 +50,35 @@ config CRYPTO_SW_AES
implemenations. This needs to support up_aesinitialize() and
aes_cypher() per include/nuttx/crypto/crypto.h.
config CRYPTO_BLAKE2S
bool "BLAKE2s hash algorithm"
default n
---help---
Enable the BLAKE2s hash algorithm
config CRYPTO_RANDOM_POOL
bool "Entropy pool and strong randon number generator"
default n
select CRYPTO_BLAKE2S
---help---
Entropy pool gathers environmental noise from device drivers,
user-space, etc., and returns good random numbers, suitable
for cryptographic use. Based on entropy pool design from
*BSDs and uses BLAKE2Xs algorithm for CSPRNG output.
NOTE: May not actually be cyptographically secure, if
not enough entropy is made available to the entropy pool.
if CRYPTO_RANDOM_POOL
config CRYPTO_RANDOM_POOL_COLLECT_IRQ_RANDOMNESS
bool "Use interrupts to feed timing randomness to entropy pool"
default y
---help---
Feed entropy pool with interrupt randomness from interrupt
dispatch function 'irq_dispatch'. This adds some overhead
for every interrupt handled.
endif # CRYPTO_RANDOM_POOL
endif # CRYPTO

View File

@ -56,6 +56,18 @@ ifeq ($(CONFIG_CRYPTO_SW_AES),y)
CRYPTO_CSRCS += aes.c
endif
# BLAKE2s hash algorithm
ifeq ($(CONFIG_CRYPTO_BLAKE2S),y)
CRYPTO_CSRCS += blake2s.c
endif
# Entropy pool random number generator
ifeq ($(CONFIG_CRYPTO_RANDOM_POOL),y)
CRYPTO_CSRCS += random_pool.c
endif
endif # CONFIG_CRYPTO
ASRCS = $(CRYPTO_ASRCS)
@ -97,4 +109,4 @@ distclean: clean
$(call DELFILE, Make.dep)
$(call DELFILE, .depend)
-include Make.dep
-include Make.dep

606
crypto/blake2s.c Normal file
View File

@ -0,0 +1,606 @@
/****************************************************************************
* crypto/blake2s.c
*
* This code is based on public-domain/CC0 BLAKE2 reference implementation
* by Samual Neves, at https://github.com/BLAKE2/BLAKE2/tree/master/ref
* Copyright 2012, Samuel Neves <sneves@dei.uc.pt>
*
* Copyright (C) 2017 Haltian Ltd. All rights reserved.
* Authors: Jussi Kivilinna <jussi.kivilinna@haltian.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <debug.h>
#include <assert.h>
#include <errno.h>
#include <nuttx/crypto/blake2s.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
static const uint32_t blake2s_IV[8] =
{
0x6a09e667ul, 0xbb67ae85ul, 0x3c6ef372ul, 0xa54ff53aul, 0x510e527ful,
0x9b05688cul, 0x1f83d9abul, 0x5be0cd19ul
};
static const uint8_t blake2s_sigma[10][16] =
{
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
{ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
{ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
{ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
{ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
{ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 },
{ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
{ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },
{ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 }
};
/****************************************************************************
* Private Functions
****************************************************************************/
static inline uint32_t rotr32(const uint32_t w, const unsigned int c)
{
return (w >> (c & 31)) | (w << ((32 - c) & 31));
}
static void blake2_memcpy(FAR void *dst, FAR const void *src, size_t len)
{
#ifdef BLAKE2_UNALIGNED
FAR uint32_alias_t *idst = dst;
FAR const uint32_alias_t *isrc = src;
FAR uint8_t *bdst;
FAR const uint8_t *bsrc;
while (len >= sizeof(uint32_alias_t))
{
*idst = *isrc;
idst++;
isrc++;
len -= sizeof(uint32_alias_t);
}
bdst = (FAR uint8_t *)idst;
bsrc = (FAR const uint8_t *)isrc;
while (len)
{
*bdst = *bsrc;
bdst++;
bsrc++;
len--;
}
#else
memcpy(dst, set, len);
#endif
}
static void blake2_memset(FAR void *dst, int set, size_t len)
{
#ifdef BLAKE2_UNALIGNED
FAR uint32_alias_t *idst = dst;
FAR uint8_t *bdst;
uint32_t mset;
set &= 0xff;
mset = (uint32_t)set * 0x01010101UL;
while (len >= sizeof(uint32_alias_t))
{
*idst = mset;
idst++;
len -= sizeof(uint32_alias_t);
}
bdst = (FAR uint8_t *)idst;
set &= 0xff;
while (len)
{
*bdst = set;
bdst++;
len--;
}
#else
memset(dst, set, len);
#endif
}
static inline void secure_zero_memory(FAR void *v, size_t n)
{
explicit_bzero(v, n);
}
/* Some helper functions, not necessarily useful */
static int blake2s_is_lastblock(FAR const blake2s_state *S)
{
return S->f[0] != 0;
}
static void blake2s_set_lastblock(FAR blake2s_state *S)
{
S->f[0] = (uint32_t)-1;
}
static void blake2s_increment_counter(FAR blake2s_state *S, const uint32_t inc)
{
S->t[0] += inc;
S->t[1] += (S->t[0] < inc);
}
static void blake2s_init0(FAR blake2s_state *S)
{
size_t i;
blake2_memset(S, 0, sizeof(*S) - sizeof(S->buf));
for (i = 0; i < 8; ++i)
S->h[i] = blake2s_IV[i];
}
static void blake2s_compress(FAR blake2s_state *S,
const uint8_t in[BLAKE2S_BLOCKBYTES])
{
uint32_t m[16];
uint32_t v[16];
size_t i;
unsigned int round;
for (i = 0; i < 16; ++i)
{
m[i] = blake2_load32(in + i * sizeof(m[i]));
}
for (i = 0; i < 8; ++i)
{
v[i] = S->h[i];
}
v[8] = blake2s_IV[0];
v[9] = blake2s_IV[1];
v[10] = blake2s_IV[2];
v[11] = blake2s_IV[3];
v[12] = S->t[0] ^ blake2s_IV[4];
v[13] = S->t[1] ^ blake2s_IV[5];
v[14] = S->f[0] ^ blake2s_IV[6];
v[15] = S->f[1] ^ blake2s_IV[7];
#define G(r,i,a,b,c,d) \
do { \
a = a + b + m[blake2s_sigma[r][2*i+0]]; \
d = rotr32(d ^ a, 16); \
c = c + d; \
b = rotr32(b ^ c, 12); \
a = a + b + m[blake2s_sigma[r][2*i+1]]; \
d = rotr32(d ^ a, 8); \
c = c + d; \
b = rotr32(b ^ c, 7); \
} while(0)
#define ROUND(r) \
do { \
G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
G(r,2,v[ 2],v[ 6],v[10],v[14]); \
G(r,3,v[ 3],v[ 7],v[11],v[15]); \
G(r,4,v[ 0],v[ 5],v[10],v[15]); \
G(r,5,v[ 1],v[ 6],v[11],v[12]); \
G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
} while(0)
/* Size vs performance trade-off. With unrolling, on ARMv7-M function text
* is ~4 KiB and without ~1 KiB. Without unrolling we take ~25% performance
* hit. */
#if 1
/* Smaller, slightly slower. */
for (round = 0; round < 10; round++)
{
ROUND(round);
}
#else
/* Larger, slightly faster. */
(void)(round=0);
ROUND(0);
ROUND(1);
ROUND(2);
ROUND(3);
ROUND(4);
ROUND(5);
ROUND(6);
ROUND(7);
ROUND(8);
ROUND(9);
#endif
#undef G
#undef ROUND
for (i = 0; i < 8; ++i)
{
S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
}
}
#ifdef CONFIG_BLAKE2_SELFTEST
/* BLAKE2s self-test from RFC 7693 */
static void selftest_seq(FAR uint8_t *out, size_t len, uint32_t seed)
{
size_t i;
uint32_t t, a, b;
a = 0xDEAD4BAD * seed; /* prime */
b = 1;
/* fill the buf */
for (i = 0; i < len; i++)
{
t = a + b;
a = b;
b = t;
out[i] = (t >> 24) & 0xFF;
}
}
static int blake2s_selftest(void)
{
/* Grand hash of hash results. */
static const uint8_t blake2s_res[32] =
{
0x6a, 0x41, 0x1f, 0x08, 0xce, 0x25, 0xad, 0xcd, 0xfb, 0x02, 0xab, 0xa6,
0x41, 0x45, 0x1c, 0xec, 0x53, 0xc5, 0x98, 0xb2, 0x4f, 0x4f, 0xc7, 0x87,
0xfb, 0xdc, 0x88, 0x79, 0x7f, 0x4c, 0x1d, 0xfe
};
/* Parameter sets. */
static const size_t b2s_md_len[4] = { 16, 20, 28, 32 };
static const size_t b2s_in_len[6] = { 0, 3, 64, 65, 255, 1024 };
size_t i, j, outlen, inlen;
FAR uint8_t *in;
uint8_t md[32], key[32];
blake2s_state ctx;
int ret = -1;
in = malloc(1024);
if (!in)
{
goto out;
}
/* 256-bit hash for testing. */
if (blake2s_init(&ctx, 32))
{
goto out;
}
for (i = 0; i < 4; i++)
{
outlen = b2s_md_len[i];
for (j = 0; j < 6; j++)
{
inlen = b2s_in_len[j];
selftest_seq(in, inlen, inlen); /* unkeyed hash */
blake2s(md, outlen, in, inlen, NULL, 0);
blake2s_update(&ctx, md, outlen); /* hash the hash */
selftest_seq(key, outlen, outlen); /* keyed hash */
blake2s(md, outlen, in, inlen, key, outlen);
blake2s_update(&ctx, md, outlen); /* hash the hash */
}
}
/* Compute and compare the hash of hashes. */
blake2s_final(&ctx, md, 32);
for (i = 0; i < 32; i++)
{
if (md[i] != blake2s_res[i])
goto out;
}
ret = 0;
out:
free(in);
return ret;
}
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/* init2 xors IV with input parameter block */
int blake2s_init_param(FAR blake2s_state *S, FAR const blake2s_param *P)
{
FAR const unsigned char *p = (FAR const unsigned char *)(P);
size_t i;
#ifdef CONFIG_BLAKE2_SELFTEST
static bool selftest_done = false;
int ret;
if (!selftest_done)
{
selftest_done = true;
ret = blake2s_selftest();
DEBUGASSERT(ret == 0);
if (ret)
return -1;
}
#endif
blake2s_init0(S);
/* IV XOR ParamBlock */
for (i = 0; i < 8; ++i)
{
S->h[i] ^= blake2_load32(&p[i * 4]);
}
S->outlen = P->digest_length;
return 0;
}
/* Sequential blake2s initialization */
int blake2s_init(FAR blake2s_state *S, size_t outlen)
{
blake2s_param P[1];
/* Move interval verification here? */
if ((!outlen) || (outlen > BLAKE2S_OUTBYTES))
{
return -1;
}
P->digest_length = (uint8_t)outlen;
P->key_length = 0;
P->fanout = 1;
P->depth = 1;
blake2_store32(P->leaf_length, 0);
blake2_store32(P->node_offset, 0);
blake2_store16(P->xof_length, 0);
P->node_depth = 0;
P->inner_length = 0;
/* memset(P->reserved, 0, sizeof(P->reserved)); */
blake2_memset(P->salt, 0, sizeof(P->salt));
blake2_memset(P->personal, 0, sizeof(P->personal));
return blake2s_init_param(S, P);
}
int blake2s_init_key(FAR blake2s_state *S, size_t outlen, FAR const void *key,
size_t keylen)
{
blake2s_param P[1];
uint8_t block[BLAKE2S_BLOCKBYTES];
if ((!outlen) || (outlen > BLAKE2S_OUTBYTES))
{
return -1;
}
if (!key || !keylen || keylen > BLAKE2S_KEYBYTES)
{
return -1;
}
P->digest_length = (uint8_t) outlen;
P->key_length = (uint8_t) keylen;
P->fanout = 1;
P->depth = 1;
blake2_store32(P->leaf_length, 0);
blake2_store32(P->node_offset, 0);
blake2_store16(P->xof_length, 0);
P->node_depth = 0;
P->inner_length = 0;
/* memset(P->reserved, 0, sizeof(P->reserved)); */
blake2_memset(P->salt, 0, sizeof(P->salt));
blake2_memset(P->personal, 0, sizeof(P->personal));
blake2s_init_param(S, P);
blake2_memset(block, 0, BLAKE2S_BLOCKBYTES);
blake2_memcpy(block, key, keylen);
blake2s_update(S, block, BLAKE2S_BLOCKBYTES);
secure_zero_memory(block, BLAKE2S_BLOCKBYTES); /* Burn the key from stack */
return 0;
}
int blake2s_update(FAR blake2s_state *S, FAR const void *pin, size_t inlen)
{
FAR const unsigned char * in = FAR (const unsigned char *)pin;
size_t left, fill;
if (inlen <= 0)
{
return 0;
}
left = S->buflen;
fill = BLAKE2S_BLOCKBYTES - left;
if (inlen > fill)
{
S->buflen = 0;
if (fill)
{
blake2_memcpy(S->buf + left, in, fill); /* Fill buffer */
}
blake2s_increment_counter(S, BLAKE2S_BLOCKBYTES);
blake2s_compress(S, S->buf); /* Compress */
in += fill;
inlen -= fill;
while (inlen > BLAKE2S_BLOCKBYTES)
{
blake2s_increment_counter(S, BLAKE2S_BLOCKBYTES);
blake2s_compress(S, in);
in += BLAKE2S_BLOCKBYTES;
inlen -= BLAKE2S_BLOCKBYTES;
}
}
blake2_memcpy(S->buf + S->buflen, in, inlen);
S->buflen += inlen;
return 0;
}
int blake2s_final(FAR blake2s_state *S, FAR void *out, size_t outlen)
{
FAR uint8_t *outbuf = out;
uint32_t tmp = 0;
size_t outwords;
size_t padding;
size_t i;
if (out == NULL || outlen < S->outlen)
{
return -1;
}
if (blake2s_is_lastblock(S))
{
return -1;
}
blake2s_increment_counter(S, (uint32_t)S->buflen);
blake2s_set_lastblock(S);
padding = BLAKE2S_BLOCKBYTES - S->buflen;
if (padding)
{
blake2_memset(S->buf + S->buflen, 0, padding);
}
blake2s_compress(S, S->buf);
/* Output hash to out buffer */
outwords = outlen / sizeof(uint32_t);
outwords = (outwords < 8) ? outwords : 8;
for (i = 0; i < outwords; ++i)
{
/* Store full words */
blake2_store32(outbuf, S->h[i]);
outlen -= sizeof(uint32_t);
outbuf += sizeof(uint32_t);
}
if (outwords < 8 && outlen > 0 && outlen < sizeof(uint32_t))
{
/* Store partial word */
blake2_store32(&tmp, S->h[i]);
blake2_memcpy(outbuf, &tmp, outlen);
}
return 0;
}
int blake2s(FAR void *out, size_t outlen, FAR const void *in, size_t inlen,
FAR const void *key, size_t keylen)
{
blake2s_state S[1];
/* Verify parameters */
if (NULL == in && inlen > 0)
{
return -1;
}
if (NULL == out)
{
return -1;
}
if (NULL == key && keylen > 0)
{
return -1;
}
if (!outlen || outlen > BLAKE2S_OUTBYTES)
{
return -1;
}
if (keylen > BLAKE2S_KEYBYTES)
{
return -1;
}
if (keylen > 0)
{
if (blake2s_init_key(S, outlen, key, keylen) < 0)
{
return -1;
}
}
else
{
if (blake2s_init(S, outlen) < 0)
{
return -1;
}
}
blake2s_update(S, (const uint8_t *)in, inlen);
blake2s_final(S, out, outlen);
return 0;
}

561
crypto/random_pool.c Normal file
View File

@ -0,0 +1,561 @@
/****************************************************************************
* crypto/random_pool.c
*
* Copyright (C) 2015-2017 Haltian Ltd. All rights reserved.
* Authors: Juha Niskanen <juha.niskanen@haltian.com>
* Jussi Kivilinna <jussi.kivilinna@haltian.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include <debug.h>
#include <assert.h>
#include <errno.h>
#include <nuttx/arch.h>
#include <nuttx/random.h>
#include <nuttx/board.h>
#include <nuttx/crypto/blake2s.h>
/****************************************************************************
* Definitions
****************************************************************************/
#ifndef MIN
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#endif
#define ROTL_32(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) )
#define ROTR_32(x,n) ( ((x) >> (n)) | ((x) << (32-(n))) )
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
struct blake2xs_rng_s
{
uint32_t out_node_offset;
blake2s_param param;
blake2s_state ctx;
char out_root[BLAKE2S_OUTBYTES];
};
struct rng_s
{
sem_t rd_sem; /* Threads can only exclusively access the RNG */
volatile uint32_t rd_addptr;
volatile uint32_t rd_newentr;
volatile uint8_t rd_rotate;
volatile uint8_t rd_prev_time;
volatile uint16_t rd_prev_irq;
bool output_initialized;
struct blake2xs_rng_s blake2xs;
};
enum
{
POOL_SIZE = ENTROPY_POOL_SIZE,
POOL_MASK = (POOL_SIZE - 1),
MIN_SEED_NEW_ENTROPY_WORDS = 128,
MAX_SEED_NEW_ENTROPY_WORDS = 1024
};
/****************************************************************************
* Private Data
****************************************************************************/
static struct rng_s g_rng;
#ifdef CONFIG_BOARD_ENTROPY_POOL
/* Entropy pool structure can be provided by board source. Use for this is,
* for example, allocate entropy pool from special area of RAM which content
* is kept over system reset. */
# define entropy_pool board_entropy_pool
#else
static struct entropy_pool_s entropy_pool;
#endif
/* Polynomial from paper "The Linux Pseudorandom Number Generator Revisited"
* x^POOL_SIZE + x^104 + x^76 + x^51 + x^25 + x + 1 */
static const uint32_t pool_stir[] = { POOL_SIZE, 104, 76, 51, 25, 1 };
/* Derived from IEEE 802.3 CRC-32 */
static const uint32_t pool_twist[8] =
{
0x00000000, 0x3b6e20c8, 0x76dc4190, 0x4db26158,
0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278
};
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Function: addentropy
*
* Description:
*
* This function adds a number of integers into the entropy pool.
* The pool is stirred with a polynomial of degree POOL_SIZE over GF(2).
*
* Code is inspired by add_entropy_words() function of OpenBSD kernel.
*
* Parameters:
* buf - Buffer of integers to be added
* n - Number of elements in buf
* inc_new - Count element as new entry
*
* Returned Value:
* None
*
****************************************************************************/
static void addentropy(FAR const uint32_t *buf, size_t n, bool inc_new)
{
/* Compile time check for that POOL_SIZE is power of two. */
static char pool_size_p2_check[1 - ((POOL_SIZE & (POOL_SIZE - 1)) * 2)];
UNUSED(pool_size_p2_check);
while (n-- > 0)
{
uint32_t rotate;
uint32_t w;
uint32_t i;
rotate = g_rng.rd_rotate;
w = ROTL_32(*buf, rotate);
i = g_rng.rd_addptr = (g_rng.rd_addptr - 1) & POOL_MASK;
/* Normal round, we add 7 bits of rotation to the pool.
* At the beginning of the pool, we add extra 7 bits
* rotation, in order for successive passes spread the
* input bits across the pool evenly.
*/
g_rng.rd_rotate = (rotate + (i ? 7 : 14)) & 31;
/* XOR pool contents corresponding to polynomial terms */
w ^= entropy_pool.pool[(i + pool_stir[1]) & POOL_MASK];
w ^= entropy_pool.pool[(i + pool_stir[2]) & POOL_MASK];
w ^= entropy_pool.pool[(i + pool_stir[3]) & POOL_MASK];
w ^= entropy_pool.pool[(i + pool_stir[4]) & POOL_MASK];
w ^= entropy_pool.pool[(i + pool_stir[5]) & POOL_MASK];
w ^= entropy_pool.pool[i]; /* 2^POOL_SIZE */
entropy_pool.pool[i] = (w >> 3) ^ pool_twist[w & 7];
buf++;
if (inc_new)
{
g_rng.rd_newentr += 1;
}
}
}
/****************************************************************************
* Function: getentropy
*
* Description:
* Hash entropy pool to BLAKE2s context. This is an internal interface for
* seeding out-facing BLAKE2Xs random bit generator from entropy pool.
*
* Code is inspired by extract_entropy() function of OpenBSD kernel.
*
* Note that this function cannot fail, other than by asserting.
*
* Warning: In protected kernel builds, this interface MUST NOT be
* exported to userspace. This interface MUST NOT be used as a
* general-purpose random bit generator!
*
* Parameters:
* S - BLAKE2s instance that will absorb entropy pool
*
* Returned Value:
* None
*
****************************************************************************/
static void getentropy(FAR blake2s_state *S)
{
#ifdef CONFIG_SCHED_CPULOAD
struct cpuload_s load;
#endif
uint32_t tmp;
add_sw_randomness(g_rng.rd_newentr);
/* Absorb the entropy pool */
blake2s_update(S, (FAR const uint32_t *)entropy_pool.pool,
sizeof(entropy_pool.pool));
/* Add something back so repeated calls to this function
* return different values.
*/
tmp = sizeof(entropy_pool.pool);
tmp <<= 27;
#ifdef CONFIG_SCHED_CPULOAD
clock_cpuload(0, &load);
tmp += load.total ^ ROTL_32(load.active, 23);
#endif
add_sw_randomness(tmp);
g_rng.rd_newentr = 0;
}
/* The BLAKE2Xs based random number generator algorithm.
*
* BLAKE2X is a extensible-output function (XOF) variant of BLAKE2 hash
* function. One application of XOFs is use as deterministic random bit
* number generator (DRBG) as used here. BLAKE2 specification is available
* at https://blake2.net/
*
* BLAKE2Xs here implementation is based on public-domain/CC0 BLAKE2 reference
* implementation by Samual Neves, at
* https://github.com/BLAKE2/BLAKE2/tree/master/ref
* Copyright 2012, Samuel Neves <sneves@dei.uc.pt>
*/
static void rng_reseed(void)
{
blake2s_param P = {};
/* Reset output node counter. */
g_rng.blake2xs.out_node_offset = 0;
/* Initialize parameter block */
P.digest_length = BLAKE2S_OUTBYTES;
P.key_length = 0;
P.fanout = 1;
P.depth = 1;
blake2_store32(P.leaf_length, 0);
blake2_store32(P.node_offset, 0);
blake2_store16(P.xof_length, 0xffff);
P.node_depth = 0;
P.inner_length = 0;
g_rng.blake2xs.param = P;
blake2s_init_param(&g_rng.blake2xs.ctx, &g_rng.blake2xs.param);
/* Initialize with randomness from entropy pool */
getentropy(&g_rng.blake2xs.ctx);
/* Absorb also the previous root */
blake2s_update(&g_rng.blake2xs.ctx, g_rng.blake2xs.out_root,
sizeof(g_rng.blake2xs.out_root));
/* Finalize the new root hash */
blake2s_final(&g_rng.blake2xs.ctx, g_rng.blake2xs.out_root,
BLAKE2S_OUTBYTES);
explicit_bzero(&g_rng.blake2xs.ctx, sizeof(g_rng.blake2xs.ctx));
/* Setup parameters for output phase. */
g_rng.blake2xs.param.key_length = 0;
g_rng.blake2xs.param.fanout = 0;
blake2_store32(g_rng.blake2xs.param.leaf_length, BLAKE2S_OUTBYTES);
g_rng.blake2xs.param.inner_length = BLAKE2S_OUTBYTES;
g_rng.blake2xs.param.node_depth = 0;
g_rng.output_initialized = true;
}
static void rng_buf_internal(FAR void *bytes, size_t nbytes)
{
if (!g_rng.output_initialized)
{
if (g_rng.rd_newentr < MIN_SEED_NEW_ENTROPY_WORDS)
{
cryptwarn("Entropy pool RNG initialized with very low entropy. "
" Consider implementing CONFIG_BOARD_INITRNGSEED!\n");
}
rng_reseed();
}
else if (g_rng.rd_newentr >= MAX_SEED_NEW_ENTROPY_WORDS)
{
/* Initial entropy is low. Reseed when we have accumulated more. */
rng_reseed();
}
else if (g_rng.blake2xs.out_node_offset == UINT32_MAX)
{
/* Maximum BLAKE2Xs output reached (2^32-1 output blocks, maximum 128 GiB
* bytes), reseed. */
rng_reseed();
}
/* Output phase for BLAKE2Xs. */
for (; nbytes > 0; ++g_rng.blake2xs.out_node_offset)
{
size_t block_size = MIN(nbytes, BLAKE2S_OUTBYTES);
/* Initialize state */
g_rng.blake2xs.param.digest_length = block_size;
blake2_store32(g_rng.blake2xs.param.node_offset,
g_rng.blake2xs.out_node_offset);
blake2s_init_param(&g_rng.blake2xs.ctx, &g_rng.blake2xs.param);
/* Process state and output random bytes */
blake2s_update(&g_rng.blake2xs.ctx, g_rng.blake2xs.out_root,
sizeof(g_rng.blake2xs.out_root));
blake2s_final(&g_rng.blake2xs.ctx, bytes, block_size);
bytes += block_size;
nbytes -= block_size;
}
}
static void rng_init(void)
{
crypinfo("Initializing RNG\n");
memset(&g_rng, 0, sizeof(struct rng_s));
sem_init(&g_rng.rd_sem, 0, 1);
/* We do not initialize output here because this is called
* quite early in boot and there may not be enough entropy.
*
* Board level may define CONFIG_BOARD_INITRNGSEED if it implements
* early random seeding.
*/
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Function: up_rngaddint
*
* Description:
* Add one integer to entropy pool, contributing a specific kind
* of entropy to pool.
*
* Parameters:
* kindof - Enumeration constant telling where val came from
* val - Integer to be added
*
* Returned Value:
* None
*
****************************************************************************/
void up_rngaddint(enum rnd_source_t kindof, int val)
{
uint32_t buf[1];
buf[0] = val;
up_rngaddentropy(kindof, buf, 1);
}
/****************************************************************************
* Function: up_rngaddentropy
*
* Description:
* Add buffer of integers to entropy pool.
*
* Parameters:
* kindof - Enumeration constant telling where val came from
* buf - Buffer of integers to be added
* n - Number of elements in buf
*
* Returned Value:
* None
*
****************************************************************************/
void up_rngaddentropy(enum rnd_source_t kindof, FAR const uint32_t *buf,
size_t n)
{
uint32_t tbuf[1];
struct timespec ts;
bool new_inc = true;
if (kindof == RND_SRC_IRQ && n > 0)
{
/* Ignore interrupt randomness if previous interrupt was from same
* source. */
if (buf[0] == g_rng.rd_prev_irq)
{
return;
}
g_rng.rd_prev_irq = buf[0];
}
/* We don't actually track what kind of entropy we receive,
* just add it all to pool. One exception is interrupt
* and timer randomness, where we limit rate of new pool entry
* counting to prevent high interrupt rate triggering RNG
* reseeding too fast.
*/
(void)clock_gettime(CLOCK_REALTIME, &ts);
tbuf[0] = ROTL_32(ts.tv_nsec, 17) ^ ROTL_32(ts.tv_sec, 3);
tbuf[0] += ROTL_32(kindof, 27);
tbuf[0] += ROTL_32((uintptr_t)&tbuf[0], 11);
if (kindof == RND_SRC_TIME || kindof == RND_SRC_IRQ)
{
uint8_t curr_time = ts.tv_sec * 8 + ts.tv_nsec / (NSEC_PER_SEC / 8);
/* Allow interrupts/timers increase entropy counter at max rate
* of 8 Hz. */
if (g_rng.rd_prev_time == curr_time)
{
new_inc = false;
}
else
{
g_rng.rd_prev_time = curr_time;
}
}
if (n > 0)
{
tbuf[0] ^= buf[0];
buf++;
n--;
}
addentropy(tbuf, 1, new_inc);
if (n > 0)
{
addentropy(buf, n, new_inc);
}
}
/****************************************************************************
* Function: up_rngreseed
*
* Description:
* Force reseeding random number generator from entropy pool
*
****************************************************************************/
void up_rngreseed(void)
{
while (sem_wait(&g_rng.rd_sem) != 0)
{
assert(errno == EINTR);
}
if (g_rng.rd_newentr >= MIN_SEED_NEW_ENTROPY_WORDS)
{
rng_reseed();
}
sem_post(&g_rng.rd_sem);
}
/****************************************************************************
* Function: up_randompool_initialize
*
* Description:
* Initialize entropy pool and random number generator
*
****************************************************************************/
void up_randompool_initialize(void)
{
rng_init();
#ifdef CONFIG_BOARD_INITRNGSEED
board_init_rngseed();
#endif
}
/****************************************************************************
* Function: getrandom
*
* Description:
* Fill a buffer of arbitrary length with randomness. This is the
* preferred interface for getting random numbers. The traditional
* /dev/random approach is susceptible for things like the attacker
* exhausting file descriptors on purpose.
*
* Note that this function cannot fail, other than by asserting.
*
* Parameters:
* bytes - Buffer for returned random bytes
* nbytes - Number of bytes requested.
*
* Returned Value:
* None
*
****************************************************************************/
void getrandom(FAR void *bytes, size_t nbytes)
{
while (sem_wait(&g_rng.rd_sem) != 0)
{
assert(errno == EINTR);
}
rng_buf_internal(bytes, nbytes);
sem_post(&g_rng.rd_sem);
}

View File

@ -69,6 +69,15 @@ config DEV_URANDOM_CONGRUENTIAL
NOTE: Not cyptographically secure
config DEV_URANDOM_RANDOM_POOL
bool "Entropy pool"
depends on CRYPTO_RANDOM_POOL
---help---
Use the entropy pool CPRNG output for urandom algorithm.
NOTE: May or may not be cyptographically secure, depending upon the
quality entropy available to entropy pool.
config DEV_URANDOM_ARCH
bool "Architecture-specific"
depends on ARCH_HAVE_RNG

View File

@ -60,6 +60,7 @@
#include <nuttx/arch.h>
#include <nuttx/semaphore.h>
#include <nuttx/analog/adc.h>
#include <nuttx/random.h>
#include <nuttx/irq.h>
@ -296,6 +297,10 @@ static ssize_t adc_read(FAR struct file *filep, FAR char *buffer, size_t buflen)
break;
}
/* Feed ADC data to entropy pool */
add_sensor_randomness(msg->am_data);
/* Copy the message to the user buffer */
if (msglen == 1)

View File

@ -49,11 +49,13 @@
#include <string.h>
#include <poll.h>
#include <errno.h>
#include <assert.h>
#include <nuttx/lib/lib.h>
#include <nuttx/lib/xorshift128.h>
#include <nuttx/fs/fs.h>
#include <nuttx/drivers/drivers.h>
#include <nuttx/random.h>
#if defined(CONFIG_DEV_URANDOM) && !defined(CONFIG_DEV_URANDOM_ARCH)
@ -62,13 +64,18 @@
****************************************************************************/
#if !defined(CONFIG_DEV_URANDOM_CONGRUENTIAL) && \
!defined(CONFIG_DEV_URANDOM_XORSHIFT128)
# define CONFIG_DEV_URANDOM_XORSHIFT128 1
!defined(CONFIG_DEV_URANDOM_XORSHIFT128) && \
!defined(CONFIG_DEV_URANDOM_RANDOM_POOL)
# ifdef CONFIG_CRYPTO_RANDOM_POOL
# define CONFIG_DEV_URANDOM_RANDOM_POOL 1
# else
# define CONFIG_DEV_URANDOM_XORSHIFT128 1
# endif
#endif
#ifdef CONFIG_DEV_URANDOM_XORSHIFT128
# define PRNG() do_xorshift128()
#else /* CONFIG_DEV_URANDOM_CONGRUENTIAL */
#elif defined(CONFIG_DEV_URANDOM_CONGRUENTIAL)
# define PRNG() do_congruential()
#endif
@ -158,6 +165,12 @@ static inline uint32_t do_congruential(void)
static ssize_t devurand_read(FAR struct file *filep, FAR char *buffer,
size_t len)
{
#ifdef CONFIG_DEV_URANDOM_RANDOM_POOL
if (len)
{
getrandom(buffer, len);
}
#else
size_t n;
uint32_t rnd;
@ -208,6 +221,7 @@ static ssize_t devurand_read(FAR struct file *filep, FAR char *buffer,
}
while (--n > 0);
}
#endif /* CONFIG_DEV_URANDOM_RANDOM_POOL */
return len;
}
@ -228,6 +242,56 @@ static ssize_t devurand_write(FAR struct file *filep, FAR const char *buffer,
memcpy(&seed, buffer, len);
srand(seed);
return len;
#elif defined(CONFIG_DEV_URANDOM_RANDOM_POOL)
const unsigned int alignmask = sizeof(uint32_t) - 1;
const size_t initlen = len;
uint32_t tmp = 0;
size_t currlen;
if (!len)
{
return 0;
}
/* Seed entropy pool with data from user. */
if ((uintptr_t)buffer & alignmask)
{
/* Make unaligned input aligned. */
currlen = min(sizeof(uint32_t) - ((uintptr_t)buffer & alignmask), len);
memcpy(&tmp, buffer, currlen);
up_rngaddint(RND_SRC_SW, tmp);
len -= currlen;
buffer += currlen;
}
if (len >= sizeof(uint32_t))
{
/* Handle bulk aligned, word-sized data. */
DEBUGASSERT(((uintptr_t)buffer & alignmask) == 0);
currlen = len / sizeof(uint32_t);
up_rngaddentropy(RND_SRC_SW, (FAR uint32_t *)buffer, currlen);
buffer += currlen * sizeof(uint32_t);
len %= sizeof(uint32_t);
}
if (len > 0)
{
/* Handle trailing bytes. */
DEBUGASSERT(len < sizeof(uint32_t));
memcpy(&tmp, buffer, len);
up_rngaddint(RND_SRC_SW, tmp);
}
/* Reseeding of random number generator from entropy pool. */
up_rngreseed();
return initlen;
#else
len = min(len, sizeof(g_prng.u));
memcpy(&g_prng.u, buffer, len);
@ -274,6 +338,8 @@ void devurandom_register(void)
#ifdef CONFIG_DEV_URANDOM_CONGRUENTIAL
srand(10197);
#elif defined(CONFIG_DEV_URANDOM_RANDOM_POOL)
up_randompool_initialize();
#else
g_prng.state.w = 97;
g_prng.state.x = 101;

View File

@ -70,6 +70,7 @@
#include <nuttx/fs/fs.h>
#include <nuttx/spi/spi.h>
#include <nuttx/wqueue.h>
#include <nuttx/random.h>
#include <nuttx/semaphore.h>
#include <nuttx/input/touchscreen.h>
@ -624,6 +625,8 @@ static void ads7843e_worker(FAR void *arg)
y = ads7843e_sendcmd(priv, ADS7843_CMD_YPOSITION);
#endif
add_ui_randomness((x << 16) | y);
/* Perform a thresholding operation so that the results will be more stable.
* If the difference from the last sample is small, then ignore the event.
* REVISIT: Should a large change in pressure also generate a event?

View File

@ -60,6 +60,7 @@
#include <nuttx/kmalloc.h>
#include <nuttx/fs/fs.h>
#include <nuttx/input/ajoystick.h>
#include <nuttx/random.h>
#include <nuttx/irq.h>
@ -321,6 +322,8 @@ static void ajoy_sample(FAR struct ajoy_upperhalf_s *priv)
DEBUGASSERT(lower->al_buttons);
sample = lower->al_buttons(lower);
add_ui_randomness(sample);
#if !defined(CONFIG_DISABLE_POLL) || !defined(CONFIG_DISABLE_SIGNALS)
/* Determine which buttons have been newly pressed and which have been
* newly released.

View File

@ -56,6 +56,7 @@
#include <nuttx/kmalloc.h>
#include <nuttx/fs/fs.h>
#include <nuttx/input/buttons.h>
#include <nuttx/random.h>
#include <nuttx/irq.h>
@ -317,6 +318,8 @@ static void btn_sample(FAR struct btn_upperhalf_s *priv)
DEBUGASSERT(lower->bl_buttons);
sample = lower->bl_buttons(lower);
add_ui_randomness(sample);
#if !defined(CONFIG_DISABLE_POLL) || !defined(CONFIG_DISABLE_SIGNALS)
/* Determine which buttons have been newly pressed and which have been
* newly released.

View File

@ -60,6 +60,7 @@
#include <nuttx/kmalloc.h>
#include <nuttx/fs/fs.h>
#include <nuttx/input/djoystick.h>
#include <nuttx/random.h>
#include <nuttx/irq.h>
@ -321,6 +322,8 @@ static void djoy_sample(FAR struct djoy_upperhalf_s *priv)
DEBUGASSERT(lower->dl_sample);
sample = lower->dl_sample(lower);
add_ui_randomness(sample);
#if !defined(CONFIG_DISABLE_POLL) || !defined(CONFIG_DISABLE_SIGNALS)
/* Determine which buttons have been newly pressed and which have been
* newly released.

View File

@ -64,6 +64,7 @@
#include <nuttx/wqueue.h>
#include <nuttx/fs/fs.h>
#include <nuttx/spi/spi.h>
#include <nuttx/random.h>
#include <nuttx/semaphore.h>
#include <nuttx/input/touchscreen.h>
@ -628,6 +629,8 @@ static void max11802_worker(FAR void *arg)
}
while (readycount < 2);
add_ui_randomness((x << 16) | y);
/* Continue to sample the position while the pen is down */
wd_start(priv->wdog, MAX11802_WDOG_DELAY, max11802_wdog, 1,

View File

@ -64,6 +64,7 @@
#include <nuttx/fs/fs.h>
#include <nuttx/i2c/i2c_master.h>
#include <nuttx/wqueue.h>
#include <nuttx/random.h>
#include <nuttx/semaphore.h>
#include <nuttx/input/touchscreen.h>
@ -889,6 +890,8 @@ static void mxt_touch_event(FAR struct mxt_dev_s *priv,
sample->pressure = pressure;
sample->valid = true;
add_ui_randomness((x << 16) ^ y ^ (area << 9) ^ (pressure << 1));
/* If this is not the first touch report, then report it as a move:
* Same contact, same ID, but with a new, updated position.
* The CONTACT_REPORT state means that a contacted has been detected,

View File

@ -48,6 +48,7 @@
#include <debug.h>
#include <nuttx/input/stmpe811.h>
#include <nuttx/random.h>
#include "stmpe811.h"
@ -139,6 +140,8 @@ uint16_t stmpe811_tempread(STMPE811_HANDLE handle)
temp1 = stmpe811_getreg8(priv, STMPE811_SYS_CTRL2);
temp2 = stmpe811_getreg8(priv, STMPE811_SYS_CTRL2+1);
add_sensor_randomness((temp1 << 8) | temp2);
/* Scale the temperature (where Vio is assumed to be .33) */
temp = ((uint32_t)(temp1 & 3) << 8) | temp2;

View File

@ -62,6 +62,7 @@
#include <nuttx/fs/fs.h>
#include <nuttx/i2c/i2c_master.h>
#include <nuttx/wqueue.h>
#include <nuttx/random.h>
#include <nuttx/arch.h>
#include <nuttx/input/touchscreen.h>
@ -534,6 +535,8 @@ static ssize_t stmpe811_read(FAR struct file *filep, FAR char *buffer, size_t le
report->point[0].y = sample.y;
report->point[0].pressure = sample.z;
add_ui_randomness((sample.x << 16) ^ (sample.y << 8) ^ sample.z);
/* Report the appropriate flags */
if (sample.contact == CONTACT_UP)

View File

@ -68,6 +68,7 @@
#include <nuttx/fs/fs.h>
#include <nuttx/i2c/i2c_master.h>
#include <nuttx/wqueue.h>
#include <nuttx/random.h>
#include <nuttx/input/touchscreen.h>
#include <nuttx/input/tsc2007.h>
@ -619,7 +620,7 @@ static void tsc2007_worker(FAR void *arg)
* vertical or horizontal resistive network. The A/D converter converts
* the voltage measured at the point where the panel is touched. A measurement
* of the Y position of the pointing device is made by connecting the X+
* input to a data converter chip, turning on the Y+ and Y drivers, and
* input to a data converter chip, turning on the Y+ and Y- drivers, and
* digitizing the voltage seen at the X+ input ..."
*
* "... it is recommended that whenever the host writes to the TSC2007, the
@ -698,6 +699,8 @@ static void tsc2007_worker(FAR void *arg)
priv->sample.y = y;
priv->sample.pressure = pressure;
priv->sample.valid = true;
add_ui_randomness((x << 16) ^ y ^ (pressure << 9));
}
/* Note the availability of new measurements */

View File

@ -32,6 +32,29 @@ config BMP180
---help---
Enable driver support for the Bosch BMP180 barometer sensor.
config HTS221
bool "ST HTS221 humidity sensor"
default n
select I2C
---help---
Enable driver support for the ST HTS221 humidity sensor.
if HTS221
config DEBUG_HTS221
bool "Debug support for the HTS221"
default n
---help---
Enables debug features for the HTS221
config HTS221_NPOLLWAITERS
int "Number of waiters to poll"
default 1
---help---
Number of waiters to poll
endif # HTS221
config SENSORS_L3GD20
bool "ST L3GD20 Gyroscope Sensor support"
default n

View File

@ -81,6 +81,10 @@ ifeq ($(CONFIG_BMP180),y)
CSRCS += bmp180.c
endif
ifeq ($(CONFIG_HTS221),y)
CSRCS += hts221.c
endif
ifeq ($(CONFIG_I2C_LM75),y)
CSRCS += lm75.c
endif

View File

@ -48,6 +48,7 @@
#include <nuttx/kmalloc.h>
#include <nuttx/sensors/adxl345.h>
#include <nuttx/random.h>
#include "adxl345.h"
@ -165,6 +166,9 @@ static ssize_t adxl345_read(FAR struct file *filep, FAR char *buffer, size_t len
sample.data_z = adxl345_getreg8(priv, ADXL345_DATAZ1);
sample.data_z = (sample.data_z << 8) | adxl345_getreg8(priv, ADXL345_DATAZ0);
add_sensor_randomness(sample.data_x);
add_sensor_randomness((sample.data_z << 16) | sample.data_y);
/* Return read sample */
buffer = (FAR char *) &sample;

View File

@ -51,6 +51,7 @@
#include <nuttx/fs/fs.h>
#include <nuttx/i2c/i2c_master.h>
#include <nuttx/sensors/bh1750fvi.h>
#include <nuttx/random.h>
#if defined(CONFIG_I2C) && defined(CONFIG_BH1750FVI)
@ -250,6 +251,8 @@ static ssize_t bh1750fvi_read(FAR struct file *filep, FAR char *buffer,
buffer[0] = lux & 0xFF;
buffer[1] = (lux & 0xFF00) >> 8;
add_sensor_randomness(lux);
return buflen;
}

View File

@ -51,6 +51,7 @@
#include <nuttx/fs/fs.h>
#include <nuttx/sensors/bmg160.h>
#include <nuttx/random.h>
#if defined(CONFIG_SPI) && defined(CONFIG_BMG160)
@ -243,6 +244,10 @@ static void bmg160_read_measurement_data(FAR struct bmg160_dev_s *dev)
/* Give back the semaphore */
sem_post(&dev->datasem);
/* Feed sensor data to entropy pool */
add_sensor_randomness((x_gyr << 16) ^ (y_gyr << 8) ^ z_gyr);
}
/****************************************************************************

View File

@ -53,6 +53,7 @@
#include <nuttx/fs/fs.h>
#include <nuttx/i2c/i2c_master.h>
#include <nuttx/sensors/bmp180.h>
#include <nuttx/random.h>
#if defined(CONFIG_I2C) && defined(CONFIG_BMP180)
@ -464,6 +465,10 @@ static int bmp180_getpressure(FAR struct bmp180_dev_s *priv)
bmp180_read_press_temp(priv);
/* Feed raw sensor data to entropy pool */
add_sensor_randomness((priv->bmp180_utemp << 16) ^ priv->bmp180_upress);
/* Calculate true temperature */
x1 = ((priv->bmp180_utemp - priv->bmp180_cal_ac6) * priv->bmp180_cal_ac5) >> 15;

1131
drivers/sensors/hts221.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -51,6 +51,7 @@
#include <nuttx/fs/fs.h>
#include <nuttx/i2c/i2c_master.h>
#include <nuttx/sensors/kxtj9.h>
#include <nuttx/random.h>
#if defined(CONFIG_I2C) && defined(CONFIG_SENSOR_KXTJ9)
@ -459,6 +460,12 @@ static int kxtj9_read_sensor_data(FAR struct kxtj9_dev_s *priv,
kxtj9_reg_read(priv, INT_REL, &data, 1);
sem_post(&priv->exclsem);
/* Feed sensor data to entropy pool */
add_sensor_randomness((acc_data[0] << 16) ^ (acc_data[1] << 8) ^
acc_data[2]);
return OK;
}

View File

@ -49,6 +49,7 @@
#include <nuttx/kmalloc.h>
#include <nuttx/wqueue.h>
#include <nuttx/random.h>
#include <nuttx/fs/fs.h>
@ -257,6 +258,10 @@ static void l3gd20_read_measurement_data(FAR struct l3gd20_dev_s *dev)
/* Give back the semaphore */
sem_post(&dev->datasem);
/* Feed sensor data to entropy pool */
add_sensor_randomness((x_gyr << 16) ^ (y_gyr << 8) ^ (z_gyr << 0));
}
/****************************************************************************

View File

@ -48,6 +48,7 @@
#include <nuttx/kmalloc.h>
#include <nuttx/i2c/i2c_master.h>
#include <nuttx/sensors/lis331dl.h>
#include <nuttx/random.h>
#if defined(CONFIG_I2C) && defined(CONFIG_LIS331DL)
@ -414,6 +415,11 @@ lis331dl_getreadings(FAR struct lis331dl_dev_s * dev)
return NULL;
}
/* Feed sensor data to entropy pool */
add_sensor_randomness((retval[2] << 16) ^ (retval[4] << 8) ^
(retval[6] << 0));
dev->a.x = retval[2];
dev->a.y = retval[4];
dev->a.z = retval[6];

View File

@ -48,6 +48,7 @@
#include <nuttx/kmalloc.h>
#include <nuttx/wqueue.h>
#include <nuttx/random.h>
#include <nuttx/fs/fs.h>
#include <nuttx/sensors/lis3dsh.h>
@ -245,6 +246,10 @@ static void lis3dsh_read_measurement_data(FAR struct lis3dsh_dev_s *dev)
/* Give back the semaphore */
sem_post(&dev->datasem);
/* Feed sensor data to entropy pool */
add_sensor_randomness((x_acc << 16) ^ (y_acc << 8) ^ (z_acc << 0));
}
/****************************************************************************

View File

@ -47,6 +47,7 @@
#include <nuttx/kmalloc.h>
#include <nuttx/wqueue.h>
#include <nuttx/random.h>
#include <nuttx/fs/fs.h>
#include <nuttx/sensors/lis3mdl.h>
@ -251,6 +252,11 @@ static void lis3mdl_read_measurement_data(FAR struct lis3mdl_dev_s *dev)
/* Give back the semaphore */
sem_post(&dev->datasem);
/* Feed sensor data to entropy pool */
add_sensor_randomness((x_mag << 16) ^ (y_mag << 10) ^ (z_mag << 2) ^
temperature);
}
/****************************************************************************

View File

@ -49,6 +49,7 @@
#include <nuttx/fs/fs.h>
#include <nuttx/i2c/i2c_master.h>
#include <nuttx/sensors/lm75.h>
#include <nuttx/random.h>
#if defined(CONFIG_I2C) && defined(CONFIG_I2C_LM75)
@ -269,6 +270,8 @@ static int lm75_readtemp(FAR struct lm75_dev_s *priv, FAR b16_t *temp)
return ret;
}
add_sensor_randomness(temp16);
sninfo("Centigrade: %08x\n", temp16);
/* Was fahrenheit requested? */

View File

@ -51,6 +51,7 @@
#include <nuttx/fs/fs.h>
#include <nuttx/i2c/i2c_master.h>
#include <nuttx/sensors/lm92.h>
#include <nuttx/random.h>
#if defined(CONFIG_I2C) && defined(CONFIG_LM92)
@ -272,6 +273,8 @@ static int lm92_readtemp(FAR struct lm92_dev_s *priv, FAR b16_t *temp)
return ret;
}
add_sensor_randomness(temp16);
sninfo("Centigrade: %08x\n", temp16);
/* Was Fahrenheit requested? */

View File

@ -50,6 +50,7 @@
#include <nuttx/fs/fs.h>
#include <nuttx/i2c/i2c_master.h>
#include <nuttx/sensors/lsm9ds1.h>
#include <nuttx/random.h>
#if defined(CONFIG_I2C) && defined(CONFIG_SN_LSM9DS1)
@ -1244,6 +1245,7 @@ static ssize_t lsm9ds1_read(FAR struct file *filep, FAR char *buffer,
uint8_t regaddr;
uint8_t lo;
uint8_t hi;
uint32_t merge = 0;
/* Sanity check */
@ -1301,6 +1303,10 @@ static ssize_t lsm9ds1_read(FAR struct file *filep, FAR char *buffer,
data = ((uint16_t)hi << 8) | (uint16_t)lo;
/* Collect entropy */
merge += data ^ (merge >> 16);
/* The value is positive */
if (data < 0x8000)
@ -1329,6 +1335,10 @@ static ssize_t lsm9ds1_read(FAR struct file *filep, FAR char *buffer,
}
}
/* Feed sensor data to entropy pool */
add_sensor_randomness(merge);
return nsamples * samplesize;
}

View File

@ -54,6 +54,7 @@
#include <nuttx/fs/fs.h>
#include <nuttx/spi/spi.h>
#include <nuttx/sensors/max31855.h>
#include <nuttx/random.h>
#if defined(CONFIG_SPI) && defined(CONFIG_MAX31855)
@ -220,6 +221,10 @@ static ssize_t max31855_read(FAR struct file *filep, FAR char *buffer, size_t bu
sninfo("Read from MAX31855 = 0x%08X\n", regval);
/* Feed sensor data to entropy pool */
add_sensor_randomness(regval);
/* If negative, fix signal bits */
if (regval & 0x80000000)

View File

@ -54,6 +54,7 @@
#include <nuttx/fs/fs.h>
#include <nuttx/spi/spi.h>
#include <nuttx/sensors/max6675.h>
#include <nuttx/random.h>
#if defined(CONFIG_SPI) && defined(CONFIG_MAX6675)
@ -230,6 +231,10 @@ static ssize_t max6675_read(FAR struct file *filep, FAR char *buffer, size_t buf
ret = -EINVAL;
}
/* Feed sensor data to entropy pool */
add_sensor_randomness(regval);
/* Get the temperature */
*temp = (regval & MAX6675_TEMP_COUPLE) >> 3;

View File

@ -51,6 +51,7 @@
#include <nuttx/fs/fs.h>
#include <nuttx/i2c/i2c_master.h>
#include <nuttx/sensors/mb7040.h>
#include <nuttx/random.h>
#if defined(CONFIG_I2C) && defined(CONFIG_MB7040)
@ -323,6 +324,10 @@ static int mb7040_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
if (ret == OK)
{
*ptr = (int32_t)range;
/* Feed sensor data to entropy pool */
add_sensor_randomness(range);
}
sninfo("range: %04x ret: %d\n", *ptr, ret);

View File

@ -50,6 +50,7 @@
#include <nuttx/fs/fs.h>
#include <nuttx/i2c/i2c_master.h>
#include <nuttx/sensors/mcp9844.h>
#include <nuttx/random.h>
#if defined(CONFIG_I2C) && defined(CONFIG_MCP9844)
@ -274,6 +275,10 @@ static int mcp9844_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
if (ret == OK)
{
/* Feed sensor data to entropy pool */
add_sensor_randomness(raw_temperature);
/* BIT15 - 13 contain information if preset temperature values
* have been exceeded or undercut. BIT12 is now not any longer
* needed since we do have the sign information retrieved.

View File

@ -50,6 +50,7 @@
#include <nuttx/fs/fs.h>
#include <nuttx/sensors/mlx90393.h>
#include <nuttx/random.h>
#if defined(CONFIG_SPI) && defined(CONFIG_MLX90393)
@ -232,6 +233,11 @@ static void mlx90393_read_measurement_data(FAR struct mlx90393_dev_s *dev)
/* Give back the semaphore */
sem_post(&dev->datasem);
/* Feed sensor data to entropy pool */
add_sensor_randomness((x_mag << 17) ^ (y_mag << 9) ^ (z_mag << 1) ^
temperature);
}
/****************************************************************************

View File

@ -50,6 +50,7 @@
#include <nuttx/fs/fs.h>
#include <nuttx/spi/spi.h>
#include <nuttx/sensors/mpl115a.h>
#include <nuttx/random.h>
#if defined(CONFIG_SPI) && defined(CONFIG_MPL115A)
@ -227,6 +228,11 @@ static void mpl115a_read_press_temp(FAR struct mpl115a_dev_s *priv)
priv->mpl115a_temperature >>= 6; /* Tadc is 10bit unsigned */
sninfo("Temperature = %d\n", priv->mpl115a_temperature);
/* Feed sensor data to entropy pool */
add_sensor_randomness((priv->mpl115a_pressure << 16) ^
priv->mpl115a_temperature);
}
/****************************************************************************

View File

@ -53,6 +53,7 @@
#include <nuttx/arch.h>
#include <nuttx/i2c/i2c_master.h>
#include <nuttx/sensors/ms58xx.h>
#include <nuttx/random.h>
#if defined(CONFIG_I2C) && defined(CONFIG_MS58XX)
@ -725,6 +726,8 @@ static int ms58xx_measure(FAR struct ms58xx_dev_s *priv)
return ret;
}
add_sensor_randomness(rawpress ^ rawtemp);
diff = (int32_t)rawtemp - (int32_t)priv->c5 * ((int32_t)1 << 8);
temp = (int32_t)((int64_t)2000 +
(int64_t)diff * (int64_t)priv->c6 / ((int64_t)1 << 23));

View File

@ -48,6 +48,7 @@
#include <nuttx/fs/fs.h>
#include <nuttx/i2c/i2c_master.h>
#include <nuttx/sensors/veml6070.h>
#include <nuttx/random.h>
#if defined(CONFIG_I2C) && defined(CONFIG_VEML6070)
@ -272,6 +273,10 @@ static ssize_t veml6070_read(FAR struct file *filep, FAR char *buffer,
buffer[0] = regdata;
/* Feed sensor data to entropy pool */
add_sensor_randomness((buffer[1] << 16) ^ buffer[0]);
return buflen;
}

View File

@ -49,6 +49,7 @@
#include <nuttx/kmalloc.h>
#include <nuttx/spi/spi.h>
#include <nuttx/sensors/xen1210.h>
#include <nuttx/random.h>
#include "xen1210.h"
@ -442,6 +443,12 @@ void xen1210_getdata(FAR struct xen1210_dev_s *priv)
#ifdef CONFIG_XEN1210_REGDEBUG
_err("%02x->%02x\n", regaddr, regval);
#endif
/* Feed sensor data to entropy pool */
add_sensor_randomness((priv->sample.data_x << 8) ^
(priv->sample.data_y << 4) ^
(priv->sample.data_z << 4));
}
/****************************************************************************

View File

@ -646,4 +646,20 @@ void board_crashdump(uintptr_t currentsp, FAR void *tcb,
int lineno);
#endif
/****************************************************************************
* Name: board_initrngseed
*
* Description:
* If CONFIG_BOARD_INITRNGSEED is selected then board_init_rngseed is
* called at up_randompool_initialize() to feed initial random seed
* to RNG. Implemenation of this functions should feed at least
* MIN_SEED_NEW_ENTROPY_WORDS 32-bit random words to entropy-pool using
* up_rngaddentropy() or up_rngaddint().
*
****************************************************************************/
#ifdef CONFIG_BOARD_INITRNGSEED
void board_init_rngseed(void);
#endif
#endif /* __INCLUDE_NUTTX_BOARD_H */

View File

@ -0,0 +1,197 @@
/****************************************************************************
* include/nuttx/crypto/blake2s.h
*
* This code is based on public-domain/CC0 BLAKE2 reference implementation
* by Samual Neves, at https://github.com/BLAKE2/BLAKE2/tree/master/ref
* Copyright 2012, Samuel Neves <sneves@dei.uc.pt>
*
* Copyright (C) 2017 Haltian Ltd. All rights reserved.
* Authors: Jussi Kivilinna <jussi.kivilinna@haltian.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
#ifndef __INCLUDE_NUTTX_CRYPTO_BLAKE2S_H
#define __INCLUDE_NUTTX_CRYPTO_BLAKE2S_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C"
{
#endif
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Public Types
****************************************************************************/
enum blake2s_constant
{
BLAKE2S_BLOCKBYTES = 64,
BLAKE2S_OUTBYTES = 32,
BLAKE2S_KEYBYTES = 32,
BLAKE2S_SALTBYTES = 8,
BLAKE2S_PERSONALBYTES = 8
};
typedef struct blake2s_state__
{
uint32_t h[8];
uint32_t t[2];
uint32_t f[2];
size_t buflen;
size_t outlen;
uint8_t buf[BLAKE2S_BLOCKBYTES];
} blake2s_state;
typedef struct blake2s_param__
{
uint8_t digest_length; /* 1 */
uint8_t key_length; /* 2 */
uint8_t fanout; /* 3 */
uint8_t depth; /* 4 */
uint8_t leaf_length[4]; /* 8 */
uint8_t node_offset[4]; /* 12 */
uint8_t xof_length[2]; /* 14 */
uint8_t node_depth; /* 15 */
uint8_t inner_length; /* 16 */
/* uint8_t reserved[0]; */
uint8_t salt[BLAKE2S_SALTBYTES]; /* 24 */
uint8_t personal[BLAKE2S_PERSONALBYTES]; /* 32 */
} blake2s_param;
#ifdef __GNUC__ > 3
#define BLAKE2_UNALIGNED 1
typedef uint32_t uint32_alias_t __attribute__((may_alias, aligned(1)));
typedef uint16_t uint16_alias_t __attribute__((may_alias, aligned(1)));
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/* Streaming API */
int blake2s_init(FAR blake2s_state *S, size_t outlen);
int blake2s_init_key(FAR blake2s_state *S, size_t outlen, FAR const void *key,
size_t keylen);
int blake2s_init_param(FAR blake2s_state *S, FAR const blake2s_param *P);
int blake2s_update(FAR blake2s_state *S, FAR const void *in, size_t inlen);
int blake2s_final(FAR blake2s_state *S, FAR void *out, size_t outlen);
/* Simple API */
int blake2s(FAR void *out, size_t outlen, FAR const void *in, size_t inlen,
FAR const void *key, size_t keylen);
/****************************************************************************
* Public Inline Functions
****************************************************************************/
static inline uint32_t blake2_load32(FAR const void *src)
{
#if defined(BLAKE2_UNALIGNED) && !defined(CONFIG_ENDIAN_BIG)
return *(FAR uint32_alias_t *)src;
#elif !defined(CONFIG_ENDIAN_BIG)
FAR const uint8_t *p = (FAR const uint8_t *)src;
return ((uint32_t)(p[0]) << 24) |
((uint32_t)(p[1]) << 16) |
((uint32_t)(p[2]) << 8) |
((uint32_t)(p[3]) << 0);
#else
FAR const uint8_t *p = (FAR const uint8_t *)src;
return ((uint32_t)(p[0]) << 0) |
((uint32_t)(p[1]) << 8) |
((uint32_t)(p[2]) << 16) |
((uint32_t)(p[3]) << 24);
#endif
}
static inline uint16_t blake2_load16(FAR const void *src)
{
#if defined(BLAKE2_UNALIGNED) && !defined(CONFIG_ENDIAN_BIG)
return *(FAR uint16_alias_t *)src;
#elif !defined(CONFIG_ENDIAN_BIG)
const uint8_t *p = (FAR const uint8_t *)src;
return ((uint16_t)(p[0]) << 8) | ((uint16_t)(p[1]) << 0);
#else
const uint8_t *p = (FAR const uint8_t *)src;
return ((uint16_t)(p[0]) << 0) | ((uint16_t)(p[1]) << 8);
#endif
}
static inline void blake2_store16(FAR void *dst, uint16_t w)
{
#if defined(BLAKE2_UNALIGNED) && !defined(CONFIG_ENDIAN_BIG)
*(FAR uint16_alias_t *)dst = w;
#elif !defined(CONFIG_ENDIAN_BIG)
FAR uint8_t *p = (FAR uint8_t *)dst;
p[1] = (uint8_t)w; w >>= 8;
p[0] = (uint8_t)w;
#else
FAR uint8_t *p = (FAR uint8_t *)dst;
p[0] = (uint8_t)w; w >>= 8;
p[1] = (uint8_t)w;
#endif
}
static inline void blake2_store32(FAR void *dst, uint32_t w)
{
#if defined(BLAKE2_UNALIGNED) && !defined(CONFIG_ENDIAN_BIG)
*(FAR uint32_alias_t *)dst = w;
#elif !defined(CONFIG_ENDIAN_BIG)
FAR uint8_t *p = (FAR uint8_t *) dst;
p[0] = (uint8_t)(w >> 24);
p[1] = (uint8_t)(w >> 16);
p[2] = (uint8_t)(w >> 8);
p[3] = (uint8_t)(w >> 0);
#else
FAR uint8_t *p = (FAR uint8_t *) dst;
p[0] = (uint8_t)(w >> 0);
p[1] = (uint8_t)(w >> 8);
p[2] = (uint8_t)(w >> 16);
p[3] = (uint8_t)(w >> 24);
#endif
}
#ifdef __cplusplus
}
#endif
#endif /* __INCLUDE_NUTTX_CRYPTO_BLAKE2S_H */

View File

@ -323,6 +323,38 @@ struct rimeaddr_s
* manage the fragmentation. 'struct ieee802154_driver_s' is cast
* compatible with 'struct net_driver_s' when CONFIG_NET_MULTINIC is not
* defined or when dev->d_lltype == NET_LL_IEEE802154.
*
* The IEEE802.15.4 MAC network driver has reponsibility for initializing
* this structure. In general, all fields must be set to NULL. In
* addtion:
*
* 1) i_panid must be set to identify the network. It may be set to 0xfff
* if the device is not associated.
* 2) i_dsn must be set to a random value. After that, it will be managed
* by the network.
* 3) i_nodeaddr must be set after the MAC is assigned an address.
* 4) On network TX poll operations, the IEEE802.15.4 MAC needs to provide
* the i_frame buffer with size greater than or equal to
* CONFIG_NET_6LOWPAN_FRAMELEN. No dev.d_buf need be provided in this
* case. The entire is TX is performed using only the i_frame buffer.
* 5) On network input RX oprations, both buffers must be provided. The size
* of the i_frame buffer is, again, greater than or equal to
* CONFIG_NET_6LOWPAN_FRAMELEN. The larger dev.d_buf must have a size
* of at least <tbd>. The dev.d_buf is used for de-compressing each
* frame and reassembling any fragmented packets to create the full input
* packet that is provided to the applicatino.
*
* Frame Organization:
*
* Content Offset
* +------------------+ 0
* | Frame Header |
* +------------------+ i_dataoffset
* | Procotol Headers |
* | Data Payload |
* +------------------+ i_framelen
* | Unused |
* +------------------+ CONFIG_NET_6LOWPAN_FRAMELEN
*/
struct ieee802154_driver_s
@ -344,7 +376,8 @@ struct ieee802154_driver_s
* requesting new framesusing break-off fram buffers. That frame buffer
* management must be controlled by the IEEE802.15.4 MAC driver.
*
* Driver provied frame buffers should be 16-bit aligned.
* Driver provided frame buffers should of size CONFIG_NET_6LOWPAN_FRAMELEN
* and should be 16-bit aligned.
*/
FAR uint8_t *i_frame;
@ -360,6 +393,31 @@ struct ieee802154_driver_s
uint16_t i_framelen;
/* i_panid. The PAN ID is 16-bit number that identifies the network. It
* must be unique to differentiate a network. All the nodes in the same
* network should have the same PAN ID. This value must be provided to
* the network from the IEEE802.15.4 MAC driver.
*
* If this value is 0xffff, the device is not associated.
*/
uint16_t i_panid;
/* i_node_addr. The address assigned to this node. */
struct rimeaddr_s i_nodeaddr;
/* i_dsn. The sequence number in the range 0x00-0xff added to the
* transmitted data or MAC command frame. The default is a random value
* within that range.
*
* This field must be initialized to a random number by the IEEE802.15.4
* MAC driver. It sill be subsequently incremented on each frame by the
* network logic.
*/
uint8_t i_dsn;
/* The following fields are device-specific metadata used by the 6loWPAN
* stack and should not be modified by the IEEE802.15.4 MAC network drvier.
*/
@ -385,9 +443,9 @@ struct ieee802154_driver_s
uint8_t i_rime_hdrlen;
/* Next available pointer into header */
/* Offset first available byte for the payload after header region. */
uint8_t i_hdrptr;
uint8_t i_dataoffset;
/* Packet buffer metadata: Attributes and addresses */

171
include/nuttx/random.h Normal file
View File

@ -0,0 +1,171 @@
/****************************************************************************
* include/nuttx/random.h
*
* Copyright (C) 2015-2017 Haltian Ltd. All rights reserved.
* Authors: Juha Niskanen <juha.niskanen@haltian.com>
* Jussi Kivilinna <jussi.kivilinna@haltian.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
#ifndef __INCLUDE_NUTTX_RANDOM_H
#define __INCLUDE_NUTTX_RANDOM_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stddef.h>
#include <sys/random.h> /* getrandom() */
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Size of entropy pool in 32-bit integers, must be power of two */
#define ENTROPY_POOL_SIZE 128
#define add_irq_randomness(x) up_rngaddint(RND_SRC_IRQ, (x))
#define add_sensor_randomness(x) up_rngaddint(RND_SRC_SENSOR, (x))
#define add_time_randomness(x) up_rngaddint(RND_SRC_TIME, (x))
#define add_hw_randomness(x) up_rngaddint(RND_SRC_HW, (x))
#define add_sw_randomness(x) up_rngaddint(RND_SRC_SW, (x))
#define add_ui_randomness(x) up_rngaddint(RND_SRC_UI, (x))
/* Allow above macros to always exist in source without ifdefs */
#ifndef CONFIG_CRYPTO_RANDOM_POOL
# define up_rngaddint(k, x) ((void)(k),(void)(x))
# define up_rngaddentropy(k, buf, x) ((void)(k),(void)(buf),(void)(x))
#endif
/****************************************************************************
* Public Type Definitions
****************************************************************************/
/* Entropy pool structure */
struct entropy_pool_s
{
volatile uint32_t pool[ENTROPY_POOL_SIZE];
};
/* Randomness sources */
enum rnd_source_t
{
RND_SRC_TIME = 0,
RND_SRC_IRQ,
RND_SRC_SENSOR,
RND_SRC_HW, /* unique per HW UID or coming from factory line. */
RND_SRC_SW, /* unique per SW version. */
RND_SRC_UI /* buttons etc. user-visible interface elements. */
};
/****************************************************************************
* Public Data
****************************************************************************/
#ifdef CONFIG_BOARD_ENTROPY_POOL
/* Entropy pool structure can be provided by board source. Use for this is,
* for example, allocate entropy pool from special area of RAM which content
* is kept over system reset. */
extern struct entropy_pool_s board_entropy_pool;
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#ifdef CONFIG_CRYPTO_RANDOM_POOL
/****************************************************************************
* Function: up_rngaddint
*
* Description:
* Add one integer to entropy pool, contributing a specific kind
* of entropy to pool.
*
* Parameters:
* kindof - Enumeration constant telling where val came from
* val - Integer to be added
*
* Returned Value:
* None
*
****************************************************************************/
void up_rngaddint(enum rnd_source_t kindof, int val);
/****************************************************************************
* Function: up_rngaddentropy
*
* Description:
* Add buffer of integers to entropy pool.
*
* Parameters:
* kindof - Enumeration constant telling where val came from
* buf - Buffer of integers to be added
* n - Number of elements in buf
*
* Returned Value:
* None
*
****************************************************************************/
void up_rngaddentropy(enum rnd_source_t kindof, FAR const uint32_t *buf,
size_t n);
/****************************************************************************
* Function: up_rngreseed
*
* Description:
* Force reseeding random number generator from entropy pool
*
****************************************************************************/
void up_rngreseed(void);
/****************************************************************************
* Function: up_randompool_initialize
*
* Description:
* Initialize entropy pool and random number generator
*
****************************************************************************/
void up_randompool_initialize(void);
#endif /* CONFIG_CRYPTO_RANDOM_POOL */
#endif /* __INCLUDE_NUTTX_RANDOM_H */

View File

@ -0,0 +1,158 @@
/****************************************************************************
* include/nuttx/sensors/hts221.h
*
* Copyright (C) 2014 Haltian Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
#ifndef __INCLUDE_NUTT_SENSORS_HTS221_H
#define __INCLUDE_NUTT_SENSORS_HTS221_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/sensors/ioctl.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define HTS221_TEMPERATURE_PRECISION 100
#define HTS221_HUMIDITY_PRECISION 10
/****************************************************************************
* Public Types
****************************************************************************/
/* Number of temperature samples */
typedef enum hts221_avrg_temp_e
{
HTS221_AVGT2 = 0,
HTS221_AVGT4,
HTS221_AVGT8,
HTS221_AVGT16, /* Default value */
HTS221_AVGT32,
HTS221_AVGT64,
HTS221_AVGT128,
HTS221_AVGT256
} hts221_avrg_temp_t;
/* Number of humidity samples */
typedef enum hts221_avrg_humid_e
{
HTS221_AVGH4 = 0,
HTS221_AVGH8,
HTS221_AVGH16,
HTS221_AVGH32, /* Default value */
HTS221_AVGH64,
HTS221_AVGH128,
HTS221_AVGH256,
HTS221_AVGH512
}hts221_avrg_humid_t;
/* Output data rate configuration */
typedef enum hts221_odr_e
{
HTS221_ODR_ONESHOT = 0,
HTS221_ODR_1HZ,
HTS221_ODR_7HZ,
HTS221_ODR_12_5HZ
} hts221_odr_t;
/* Configuration structure */
typedef struct hts221_settings_s
{
hts221_avrg_temp_t temp_resol; /* Temperature resolution. The more
* samples sensor takes, the more power
* it uses */
hts221_avrg_humid_t humid_resol; /* Humidity resolution. The more
* samples sensor takes, the more power
* it uses */
hts221_odr_t odr; /* Output data rate */
bool is_bdu; /* If read operation is not faster than output
* operation, then this variable must be set to true */
bool is_data_rdy; /* Must be set to true, if interrupt needed.
* Default is 0, disabled */
bool is_high_edge; /* High or low interrupt signal from device.
* Default is high, 0 */
bool is_open_drain; /* Open drain or push-pull on data-ready pin.
* Default is push-pull, 0 */
bool is_boot; /* Refresh the content of the internal registers */
} hts221_settings_t;
/* Interrupt configuration data structure */
typedef struct hts221_config_s
{
int irq;
CODE int (*irq_attach)(FAR struct hts221_config_s * state, xcpt_t isr);
CODE void (*irq_enable)(FAR const struct hts221_config_s * state,
bool enable);
CODE void (*irq_clear)(FAR const struct hts221_config_s * state);
CODE int (*set_power)(FAR const struct hts221_config_s *state, bool on);
} hts221_config_t;
/* Raw data structure */
typedef struct hts221_raw_data_s
{
uint8_t humid_low_bits;
uint8_t humid_high_bits;
uint8_t temp_low_bits;
uint8_t temp_high_bits;
} hts221_raw_data_t;
typedef struct hts221_conv_data_s
{
int temperature;
unsigned int humidity;
} hts221_conv_data_t;
/* Status register data */
typedef struct hts221_status_s
{
bool is_humid_ready;
bool is_temp_ready;
} hts221_status_t;
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
int hts221_register(FAR const char *devpath, FAR struct i2c_master_s *i2c,
uint8_t addr, hts221_config_t * config);
#endif /* __INCLUDE_NUTT_SENSORS_HTS221_H */

View File

@ -115,4 +115,14 @@
#define SNIOC_RESET _SNIOC(0x0028) /* Arg: None */
#define SNIOC_OVERSAMPLING _SNIOC(0x0029) /* Arg: uint16_t value */
/* IOCTL commands unique to the HTS221 */
#define SNIOC_GET_DEV_ID _SNIOC(0x002a)
#define SNIOC_CFGR _SNIOC(0x002b)
#define SNIOC_START_CONVERSION _SNIOC(0x002c)
#define SNIOC_CHECK_STATUS_REG _SNIOC(0x002d)
#define SNIOC_READ_RAW_DATA _SNIOC(0x002e)
#define SNIOC_READ_CONVERT_DATA _SNIOC(0x002f)
#define SNIOC_DUMP_REGS _SNIOC(0x0030)
#endif /* __INCLUDE_NUTTX_SENSORS_IOCTL_H */

View File

@ -93,6 +93,8 @@ FAR void *memcpy(FAR void *dest, FAR const void *src, size_t n);
FAR void *memmove(FAR void *dest, FAR const void *src, size_t count);
FAR void *memset(FAR void *s, int c, size_t n);
void explicit_bzero(FAR void *s, size_t n);
#undef EXTERN
#if defined(__cplusplus)
}

77
include/sys/random.h Normal file
View File

@ -0,0 +1,77 @@
/****************************************************************************
* include/sys/random.h
*
* Copyright (C) 2015-2017 Haltian Ltd. All rights reserved.
* Authors: Juha Niskanen <juha.niskanen@haltian.com>
* Jussi Kivilinna <jussi.kivilinna@haltian.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
#ifndef __INCLUDE_SYS_RANDOM_H
#define __INCLUDE_SYS_RANDOM_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stddef.h>
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#ifdef CONFIG_CRYPTO_RANDOM_POOL
/****************************************************************************
* Function: getrandom
*
* Description:
* Fill a buffer of arbitrary length with randomness. This is the
* preferred interface for getting random numbers. The traditional
* /dev/random approach is susceptible for things like the attacker
* exhausting file descriptors on purpose.
*
* Note that this function cannot fail, other than by asserting.
*
* Parameters:
* bytes - Buffer for returned random bytes
* nbytes - Number of bytes requested.
*
* Returned Value:
* None
*
****************************************************************************/
void getrandom(FAR void *bytes, size_t nbytes);
#endif /* CONFIG_CRYPTO_RANDOM_POOL */
#endif /* __INCLUDE_SYS_RANDOM_H */

View File

@ -524,10 +524,19 @@
/* The following is defined only if CONFIG_TASK_NAME_SIZE > 0 */
#if CONFIG_TASK_NAME_SIZE > 0
# define SYS_prctl (SYS_nnetsocket+0)
# define SYS_maxsyscall (SYS_nnetsocket+1)
# define SYS_prctl (SYS_nnetsocket+1)
#else
# define SYS_maxsyscall SYS_nnetsocket
# define SYS_prctl SYS_nnetsocket
#endif
/* The following is defined only if entropy pool random number generator
* is enabled. */
#ifdef CONFIG_CRYPTO_RANDOM_POOL
# define SYS_getrandom (SYS_prctl+1)
# define SYS_maxsyscall (SYS_prctl+2)
#else
# define SYS_maxsyscall SYS_prctl
#endif
/* Note that the reported number of system calls does *NOT* include the

View File

@ -44,6 +44,7 @@ CSRCS += lib_strerror.c lib_strlen.c lib_strnlen.c lib_strncasecmp.c
CSRCS += lib_strncat.c lib_strncmp.c lib_strncpy.c lib_strndup.c
CSRCS += lib_strcasestr.c lib_strpbrk.c lib_strrchr.c lib_strspn.c
CSRCS += lib_strstr.c lib_strtok.c lib_strtokr.c lib_strerrorr.c
CSRCS += lib_explicit_bzero.c
ifneq ($(CONFIG_LIBC_ARCH_MEMCPY),y)
ifeq ($(CONFIG_MEMCPY_VIK),y)

View File

@ -0,0 +1,55 @@
/****************************************************************************
* libc/string/lib_explicit_bzero.c
*
* Copyright (C) 2015,2017 Haltian Ltd. All rights reserved.
* Author: Juha Niskanen <juha.niskanen@haltian.com>
* Jussi Kivilinna <jussi.kivilinna@haltian.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <string.h>
/****************************************************************************
* Global Functions
****************************************************************************/
/* memset that must not be optimized away by compiler (not even with LTO). */
void explicit_bzero(FAR void *s, size_t n)
{
static FAR void *(*FAR const volatile memset_v)(FAR void *, int, size_t) =
&memset;
memset_v(s, 0, n);
}

View File

@ -121,9 +121,9 @@ static inline void _local_semtake(sem_t *sem)
*
****************************************************************************/
int inline local_stream_connect(FAR struct local_conn_s *client,
FAR struct local_conn_s *server,
bool nonblock)
static int inline local_stream_connect(FAR struct local_conn_s *client,
FAR struct local_conn_s *server,
bool nonblock)
{
int ret;

View File

@ -136,7 +136,7 @@ config NET_6LOWPAN_RIMEADDR_SIZE
---help---
Only the values 2 and 8 are supported
config NET_SIXLOWPAN_MAXAGE
config NET_6LOWPAN_MAXAGE
int "Packet reassembly timeout"
default 20
---help---
@ -150,11 +150,11 @@ config NET_6LOWPAN_MAX_MACTRANSMITS
layer should resend packets if no link-layer ACK wasreceived. This
only makes sense with the csma_driver.
config NET_SIXLOWPAN_MAXPAYLOAD
config NET_6LOWPAN_MAXPAYLOAD
int "Max packet size"
default 102
---help---
CONFIG_NET_SIXLOWPAN_MAXPAYLOAD specifies the maximum size of packets
NET_6LOWPAN_MAXPAYLOAD specifies the maximum size of packets
before they get fragmented. The default is 127 bytes (the maximum size
of a 802.15.4 frame) - 25 bytes (for the 802.15.4 MAClayer header). This
can be increased for systems with larger packet sizes.

View File

@ -40,9 +40,17 @@ ifeq ($(CONFIG_NET_6LOWPAN),y)
# Include IEEE 802.15.4 file in the build
NET_CSRCS += sixlowpan_initialize.c sixlowpan_globals.c sixlowpan_utils.c
NET_CSRCS += sixlowpan_input.c sixlowpan_send.c
NET_CSRCS += sixlowpan_input.c sixlowpan_send.c sixlowpan_framer.c
NET_CSRCS += sixlowpan_compressor.c
ifeq ($(CONFIG_NET_TCP),y)
NET_CSRCS += sixlowpan_tcpsend.c
endif
ifeq ($(CONFIG_NET_UDP),y)
NET_CSRCS += sixlowpan_udpsend.c
endif
ifeq ($(CONFIG_NET_6LOWPAN_COMPRESSION_HC1),y)
NET_CSRCS += sixlowpan_hc1.c
endif

View File

@ -1,7 +1,7 @@
/****************************************************************************
* net/sixlowpan/sixlowpan.h
*
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -45,42 +45,6 @@
#ifdef CONFIG_NET_6LOWPAN
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Rime addres macros */
#define rimeaddr_copy(dest,src) \
memcpy(dest, src, CONFIG_NET_6LOWPAN_RIMEADDR_SIZE)
#define rimeaddr_cmp(addr1,addr2) \
(memcmp(addr1, addr2, CONFIG_NET_6LOWPAN_RIMEADDR_SIZE) == 0)
/****************************************************************************
* Public Types
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
/* A pointer to the optional, architecture-specific compressor */
struct sixlowpan_nhcompressor_s; /* Foward reference */
extern FAR struct sixlowpan_nhcompressor_s *g_sixlowpan_compressor;
#ifdef CONFIG_NET_6LOWPAN_SNIFFER
/* Rime Sniffer support for one single listener to enable trace of IP */
struct sixlowpan_rime_sniffer_s; /* Foward reference */
extern FAR struct sixlowpan_rime_sniffer_s *g_sixlowpan_sniffer;
#endif
/* All zero rime address */
extern const struct rimeaddr_s g_rimeaddr_null;
/****************************************************************************
* Public Types
****************************************************************************/
@ -89,10 +53,7 @@ extern const struct rimeaddr_s g_rimeaddr_null;
* Public Function Prototypes
****************************************************************************/
struct net_driver_s; /* Forward reference */
struct ieee802154_driver_s; /* Forward reference */
struct rimeaddr_s; /* Forward reference */
struct socket; /* Forward reference */
struct socket; /* Forward reference */
/****************************************************************************
* Name: sixlowpan_initialize
@ -171,171 +132,5 @@ ssize_t psock_6lowpan_udp_send(FAR struct socket *psock, FAR const void *buf,
size_t len);
#endif
/****************************************************************************
* Name: sixlowpan_output
*
* Description:
* Process an outgoing UDP or TCP packet. Called from UDP/TCP logic to
* determine if the the packet should be formatted for 6loWPAN output.
*
* Input Parameters:
* dev - The IEEE802.15.4 MAC network driver interface.
*
* Returned Value:
* Ok is returned on success; Othewise a negated errno value is returned.
* This function is expected to fail if the driver is not an IEEE802.15.4
* MAC network driver. In that case, the UDP/TCP will fall back to normal
* IPv4/IPv6 formatting.
*
****************************************************************************/
int sixlowpan_output(FAR struct net_driver_s *dev);
/****************************************************************************
* Name: sixlowpan_hc06_initialize
*
* Description:
* sixlowpan_hc06_initialize() is called during OS initialization at power-up
* reset. It is called from the common sixlowpan_initialize() function.
* sixlowpan_hc06_initialize() configures HC06 networking data structures.
* It is called prior to platform-specific driver initialization so that
* the 6loWPAN networking subsystem is prepared to deal with network
* driver initialization actions.
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC06
void sixlowpan_hc06_initialize(void);
#endif
/****************************************************************************
* Name: sixlowpan_hc06_initialize
*
* Description:
* Compress IP/UDP header
*
* This function is called by the 6lowpan code to create a compressed
* 6lowpan packet in the packetbuf buffer from a full IPv6 packet in the
* uip_buf buffer.
*
* HC-06 (draft-ietf-6lowpan-hc, version 6)
* http://tools.ietf.org/html/draft-ietf-6lowpan-hc-06
*
* NOTE: sixlowpan_compresshdr_hc06() does not support ISA100_UDP header
* compression
*
* Input Parameters:
* dev - A reference to the IEE802.15.4 network device state
* destaddr - L2 destination address, needed to compress IP dest
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC06
void sixlowpan_compresshdr_hc06(FAR struct net_driver_s *dev,
FAR struct rimeaddr_s *destaddr);
#endif
/****************************************************************************
* Name: sixlowpan_hc06_initialize
*
* Description:
* Uncompress HC06 (i.e., IPHC and LOWPAN_UDP) headers and put them in
* sixlowpan_buf
*
* This function is called by the input function when the dispatch is HC06.
* We process the packet in the rime buffer, uncompress the header fields,
* and copy the result in the sixlowpan buffer. At the end of the
* decompression, g_rime_hdrlen and g_uncompressed_hdrlen are set to the
* appropriate values
*
* Input Parmeters:
* dev - A reference to the IEE802.15.4 network device state
* iplen - Equal to 0 if the packet is not a fragment (IP length is then
* inferred from the L2 length), non 0 if the packet is a 1st
* fragment.
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC06
void sixlowpan_uncompresshdr_hc06(FAR struct net_driver_s *dev,
uint16_t iplen);
#endif
/****************************************************************************
* Name: sixlowpan_compresshdr_hc1
*
* Description:
* Compress IP/UDP header using HC1 and HC_UDP
*
* This function is called by the 6lowpan code to create a compressed
* 6lowpan packet in the packetbuf buffer from a full IPv6 packet in the
* uip_buf buffer.
*
* Input Parmeters:
* dev - A reference to the IEE802.15.4 network device state
* destaddr - L2 destination address, needed to compress the IP
* destination field
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC1
void sixlowpan_compresshdr_hc1(FAR struct net_driver_s *dev,
FAR struct rimeaddr_s *destaddr);
#endif
/****************************************************************************
* Name: sixlowpan_uncompresshdr_hc1
*
* Description:
* Uncompress HC1 (and HC_UDP) headers and put them in sixlowpan_buf
*
* This function is called by the input function when the dispatch is
* HC1. It processes the packet in the rime buffer, uncompresses the
* header fields, and copies the result in the sixlowpan buffer. At the
* end of the decompression, g_rime_hdrlen and uncompressed_hdr_len
* are set to the appropriate values
*
* Input Parameters:
* dev - A reference to the IEE802.15.4 network device state
* iplen - Equal to 0 if the packet is not a fragment (IP length is then
* inferred from the L2 length), non 0 if the packet is a 1st
* fragment.
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC1
void sixlowpan_uncompresshdr_hc1(FAR struct net_driver_s *dev,
uint16_t ip_len);
#endif
/****************************************************************************
* Name: sixlowpan_pktbuf_reset
*
* Description:
* Reset all attributes and addresses in the packet buffer metadata in the
* provided IEEE802.15.4 MAC driver structure.
*
****************************************************************************/
void sixlowpan_pktbuf_reset(FAR struct ieee802154_driver_s *ieee);
#endif /* CONFIG_NET_6LOWPAN */
#endif /* _NET_SIXLOWPAN_SIXLOWPAN_H */

View File

@ -42,7 +42,7 @@
#include "nuttx/net/net.h"
#include "nuttx/net/sixlowpan.h"
#include "sixlowpan/sixlowpan.h"
#include "sixlowpan/sixlowpan_internal.h"
#ifdef CONFIG_NET_6LOWPAN

View File

@ -0,0 +1,577 @@
/****************************************************************************
* net/sixlowpan/sixlowpan_framer.c
*
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Derives from Contiki:
*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
* Authors: Adam Dunkels <adam@sics.se>
* Nicolas Tsiftes <nvt@sics.se>
* Niclas Finne <nfi@sics.se>
* Mathilde Durvy <mdurvy@cisco.com>
* Julien Abeille <jabeille@cisco.com>
* Joakim Eriksson <joakime@sics.se>
* Joel Hoglund <joel@sics.se>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdbool.h>
#include <string.h>
#include <assert.h>
#include <debug.h>
#include "nuttx/net/net.h"
#include "nuttx/net/sixlowpan.h"
#include "sixlowpan/sixlowpan_internal.h"
#ifdef CONFIG_NET_6LOWPAN
/****************************************************************************
* Private Types
****************************************************************************/
/* Structure that contains the lengths of the various addressing and
* security fields in the 802.15.4 header.
*/
struct field_length_s
{
uint8_t dest_pid_len; /**< Length (in bytes) of destination PAN ID field */
uint8_t dest_addr_len; /**< Length (in bytes) of destination address field */
uint8_t src_pid_len; /**< Length (in bytes) of source PAN ID field */
uint8_t src_addr_len; /**< Length (in bytes) of source address field */
uint8_t aux_sec_len; /**< Length (in bytes) of aux security header field */
};
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Function: sixlowpan_addrlen
*
* Description:
* Return the address length associated with a 2-bit address mode
*
* Input parameters:
* addrmode - The address mode
*
* Returned Value:
* The address length associated with the address mode.
*
****************************************************************************/
static inline uint8_t sixlowpan_addrlen(uint8_t addrmode)
{
switch (addrmode)
{
case FRAME802154_SHORTADDRMODE: /* 16-bit address */
return 2;
case FRAME802154_LONGADDRMODE: /* 64-bit address */
return 8;
default:
return 0;
}
}
/****************************************************************************
* Function: sixlowpan_addrnull
*
* Description:
* If the output address is NULL in the Rime buf, then it is broadcast
* on the 802.15.4 network.
*
* Input parameters:
* addrmode - The address mode
*
* Returned Value:
* The address length associated with the address mode.
*
****************************************************************************/
static bool sixlowpan_addrnull(FAR uint8_t *addr)
{
#if CONFIG_NET_6LOWPAN_RIMEADDR_SIZE == 2
int i = 2;
#else
int i = 8;
#endif
while (i-- > 0)
{
if (addr[i] != 0x00)
{
return false;
}
}
return true;
}
/****************************************************************************
* Function: sixlowpan_fieldlengths
*
* Description:
* Return the lengths associated fields of the IEEE802.15.4 header.
*
* Input parameters:
* finfo - IEEE802.15.4 header info (input)
* flen - Field length info (output)
*
* Returned Value:
* None
*
****************************************************************************/
static void sixlowpan_fieldlengths(FAR struct frame802154_s *finfo,
FAR struct field_length_s *flen)
{
/* Initialize to all zero */
memset(flen, 0, sizeof(struct field_length_s));
/* Determine lengths of each field based on fcf and other args */
if ((finfo->fcf.dest_addr_mode & 3) != 0)
{
flen->dest_pid_len = 2;
}
if ((finfo->fcf.src_addr_mode & 3) != 0)
{
flen->src_pid_len = 2;
}
/* Set PAN ID compression bit if src pan id matches dest pan id. */
if ((finfo->fcf.dest_addr_mode & 3) != 0 &&
(finfo->fcf.src_addr_mode & 3) != 0 &&
finfo->src_pid == finfo->dest_pid)
{
finfo->fcf.panid_compression = 1;
/* Compressed header, only do dest pid */
/* flen->src_pid_len = 0; */
}
/* Determine address lengths */
flen->dest_addr_len = sixlowpan_addrlen(finfo->fcf.dest_addr_mode & 3);
flen->src_addr_len = sixlowpan_addrlen(finfo->fcf.src_addr_mode & 3);
/* Aux security header */
#if 0 /* TODO Aux security header not yet implemented */
if ((finfo->fcf.security_enabled & 1) != 0)
{
switch(finfo->aux_hdr.security_control.key_id_mode)
{
case 0:
flen->aux_sec_len = 5; /* Minimum value */
break;
case 1:
flen->aux_sec_len = 6;
break;
case 2:
flen->aux_sec_len = 10;
break;
case 3:
flen->aux_sec_len = 14;
break;
default:
break;
}
}
#endif
}
/****************************************************************************
* Function: sixlowpan_fieldlengths
*
* Description:
* Return the lengths associated fields of the IEEE802.15.4 header.
*
* Input parameters:
* finfo - IEEE802.15.4 header info (input)
* flen - Field length info (output)
*
* Returned Value:
* None
*
****************************************************************************/
static int sixlowpan_flen_hdrlen(FAR const struct field_length_s *flen)
{
return 3 + flen->dest_pid_len + flen->dest_addr_len +
flen->src_pid_len + flen->src_addr_len + flen->aux_sec_len;
}
/****************************************************************************
* Function: sixlowpan_802154_hdrlen
*
* Description:
* Calculates the length of the frame header. This function is meant to
* be called by a higher level function, that interfaces to a MAC.
*
* Input parameters:
* finfo - IEEE802.15.4 header info that specifies the frame to send.
*
* Returned Value:
* The length of the frame header.
*
****************************************************************************/
static int sixlowpan_802154_hdrlen(FAR struct frame802154_s *finfo)
{
struct field_length_s flen;
sixlowpan_fieldlengths(finfo, &flen);
return sixlowpan_flen_hdrlen(&flen);
}
/****************************************************************************
* Function: sixlowpan_setup_params
*
* Description:
* Configure frame parmeters structure.
*
* Input parameters:
* ieee - A reference IEEE802.15.4 MAC network device structure.
* params - Where to put the parmeters
* dest_panid - PAN ID of the destination. May be 0xffff if the destination
* is not associated.
*
* Returned Value:
* None.
*
****************************************************************************/
static void sixlowpan_setup_params(FAR struct ieee802154_driver_s *ieee,
FAR struct frame802154_s *params,
uint16_t dest_panid)
{
bool rcvrnull;
/* Initialize all prameters to all zero */
memset(&params, 0, sizeof(params));
/* Reset to an empty frame */
ieee->i_framelen = 0;
ieee->i_dataoffset = 0;
/* Build the FCF (Only non-zero elements need to be initialized). */
params->fcf.frame_type = FRAME802154_DATAFRAME;
params->fcf.frame_pending = ieee->i_pktattrs[PACKETBUF_ATTR_PENDING];
/* If the output address is NULL in the Rime buf, then it is broadcast
* on the 802.15.4 network.
*/
rcvrnull = sixlowpan_addrnull(ieee->i_pktaddrs[PACKETBUF_ADDR_RECEIVER].u8);
if (rcvrnull)
{
params->fcf.ack_required = ieee->i_pktattrs[PACKETBUF_ATTR_MAC_ACK];
}
/* Insert IEEE 802.15.4 (2003) version bit. */
params->fcf.frame_version = FRAME802154_IEEE802154_2003;
/* Increment and set the data sequence number. */
if (ieee->i_pktattrs[PACKETBUF_ATTR_MAC_SEQNO] != 0)
{
params->seq = ieee->i_pktattrs[PACKETBUF_ATTR_MAC_SEQNO];
}
else
{
params->seq = ieee->i_dsn++;
ieee->i_pktattrs[PACKETBUF_ATTR_MAC_SEQNO] = params->seq;
}
/* Complete the addressing fields. */
/* Set the source and destination PAN ID. */
params->src_pid = ieee->i_panid;
params->dest_pid = dest_panid;
/* If the output address is NULL in the Rime buf, then it is broadcast
* on the 802.15.4 network.
*/
if (rcvrnull)
{
/* Broadcast requires short address mode. */
params->fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE;
params->dest_addr[0] = 0xff;
params->dest_addr[1] = 0xff;
}
else
{
/* Copy the destination address */
rimeaddr_copy((struct rimeaddr_s *)&params->dest_addr,
ieee->i_pktaddrs[PACKETBUF_ADDR_RECEIVER].u8);
/* Use short address mode if so configured */
#if CONFIG_NET_6LOWPAN_RIMEADDR_SIZE == 2
params->fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE;
#else
params->fcf.dest_addr_mode = FRAME802154_LONGADDRMODE;
#endif
}
/* Set the source address to the node address assigned to the device */
rimeaddr_copy((struct rimeaddr_s *)&params->src_addr, &ieee->i_nodeaddr.u8);
/* Configure the payload address and length */
params->payload = FRAME_DATA_START(ieee);
params->payload_len = FRAME_DATA_SIZE(ieee);
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Function: sixlowpan_hdrlen
*
* Description:
* This function is before the first frame has been sent in order to
* determine what the size of the IEEE802.15.4 header will be. No frame
* buffer is required to make this determination.
*
* Input parameters:
* ieee - A reference IEEE802.15.4 MAC network device structure.
* dest_panid - PAN ID of the destination. May be 0xffff if the destination
* is not associated.
*
* Returned Value:
* The frame header length is returnd on success; otherwise, a negated
* errno value is return on failure.
*
****************************************************************************/
int sixlowpan_hdrlen(FAR struct ieee802154_driver_s *ieee,
uint16_t dest_panid)
{
struct frame802154_s params;
/* Set up the frame parameters */
sixlowpan_setup_params(ieee, &params, dest_panid);
/* Return the length of the header */
return sixlowpan_802154_hdrlen(&params);
}
/****************************************************************************
* Function: sixlowpan_802154_framecreate
*
* Description:
* Creates a frame for transmission over the air. This function is meant
* to be called by a higher level function, that interfaces to a MAC.
*
* Input parameters:
* finfo - Pointer to struct EEE802.15.4 header structure that specifies
* the frame to send.
* buf - Pointer to the buffer to use for the frame.
* buflen - The length of the buffer to use for the frame.
* finfo - I that specifies the frame to send.
*
* Returned Value:
* The length of the frame header or 0 if there was insufficient space in
* the buffer for the frame headers.
*
****************************************************************************/
int sixlowpan_802154_framecreate(FAR struct frame802154_s *finfo,
FAR uint8_t *buf, int buflen)
{
struct field_length_s flen;
uint8_t pos;
int hdrlen;
int i;
sixlowpan_fieldlengths(finfo, &flen);
hdrlen = sixlowpan_flen_hdrlen(&flen);
if (hdrlen > buflen)
{
/* Too little space for headers. */
return 0;
}
/* OK, now we have field lengths. Time to actually construct
* the outgoing frame, and store it in the provided buffer
*/
buf[0] = (finfo->fcf.frame_type & 7) |
((finfo->fcf.security_enabled & 1) << 3) |
((finfo->fcf.frame_pending & 1) << 4) |
((finfo->fcf.ack_required & 1) << 5) |
((finfo->fcf.panid_compression & 1) << 6);
buf[1] = ((finfo->fcf.dest_addr_mode & 3) << 2) |
((finfo->fcf.frame_version & 3) << 4) |
((finfo->fcf.src_addr_mode & 3) << 6);
/* Sequence number */
buf[2] = finfo->seq;
pos = 3;
/* Destination PAN ID */
if (flen.dest_pid_len == 2)
{
buf[pos++] = finfo->dest_pid & 0xff;
buf[pos++] = (finfo->dest_pid >> 8) & 0xff;
}
/* Destination address */
for (i = flen.dest_addr_len; i > 0; i--)
{
buf[pos++] = finfo->dest_addr[i - 1];
}
/* Source PAN ID */
if (flen.src_pid_len == 2)
{
buf[pos++] = finfo->src_pid & 0xff;
buf[pos++] = (finfo->src_pid >> 8) & 0xff;
}
/* Source address */
for (i = flen.src_addr_len; i > 0; i--)
{
buf[pos++] = finfo->src_addr[i - 1];
}
/* Aux header */
#if 0 /* TODO Aux security header not yet implemented */
if (flen.aux_sec_len)
{
pos += flen.aux_sec_len;
}
#endif
DEBUGASSERT(pos == hdrlen);
return (int)pos;
}
/****************************************************************************
* Function: sixlowpan_framecreate
*
* Description:
* This function is called after the IEEE802.15.4 MAC driver polls for
* TX data. It creates the IEEE802.15.4 header in the frame buffer.
*
* Input parameters:
* ieee - A reference IEEE802.15.4 MAC network device structure.
* dest_panid - PAN ID of the destination. May be 0xffff if the destination
* is not associated.
*
* Returned Value:
* The frame header length is returnd on success; otherwise, a negated
* errno value is return on failure.
*
****************************************************************************/
int sixlowpan_framecreate(FAR struct ieee802154_driver_s *ieee,
uint16_t dest_panid)
{
struct frame802154_s params;
int len;
int ret;
/* Set up the frame parameters */
sixlowpan_setup_params(ieee, &params, dest_panid);
/* Get the length of the header */
len = sixlowpan_802154_hdrlen(&params);
/* Allocate space for the header in the frame buffer */
ret = sixlowpan_frame_hdralloc(ieee, len);
if (ret < 0)
{
wlerr("ERROR: Header too large: %u\n", len);
return ret;
}
/* Then create the frame */
sixlowpan_802154_framecreate(&params, FRAME_HDR_START(ieee), len);
wlinfo("Frame type: %02x Data len: %d %u (%u)\n",
params.fcf.frame_type, len, FRAME_DATA_SIZE(ieee),
FRAME_SIZE(ieee));
#if CONFIG_NET_6LOWPAN_RIMEADDR_SIZE == 2
wlinfo("Dest address: %02x:%02x\n",
params.dest_addr[0], params.dest_addr[1]);
#else
wlinfo("Dest address: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
params.dest_addr[0], params.dest_addr[1], params.dest_addr[2],
params.dest_addr[3], params.dest_addr[4], params.dest_addr[5],
params.dest_addr[6], params.dest_addr[7]);
#endif
return len;
}
#endif /* CONFIG_NET_6LOWPAN */

View File

@ -41,7 +41,7 @@
#include "nuttx/net/sixlowpan.h"
#include "sixlowpan/sixlowpan.h"
#include "sixlowpan/sixlowpan_internal.h"
#ifdef CONFIG_NET_6LOWPAN

View File

@ -20,6 +20,7 @@
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
@ -44,7 +45,7 @@
****************************************************************************/
/* FOR HC-06 COMPLIANCE TODO:
*
*
* -Add compression options to UDP, currently only supports
* both ports compressed or both ports elided
* -Verify TC/FL compression works
@ -60,7 +61,7 @@
#include <nuttx/net/netdev.h>
#include <nuttx/net/sixlowpan.h>
#include "sixlowpan/sixlowpan.h"
#include "sixlowpan/sixlowpan_internal.h"
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC06

View File

@ -49,7 +49,7 @@
#include <nuttx/config.h>
#include <nuttx/net/netdev.h>
#include "sixlowpan/sixlowpan.h"
#include "sixlowpan/sixlowpan_internal.h"
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC1

View File

@ -40,6 +40,7 @@
#include <nuttx/config.h>
#include "sixlowpan/sixlowpan.h"
#include "sixlowpan/sixlowpan_internal.h"
#ifdef CONFIG_NET_6LOWPAN

View File

@ -42,10 +42,43 @@
#include <errno.h>
#include "nuttx/net/netdev.h"
#include "sixlowpan/sixlowpan.h"
#include "sixlowpan/sixlowpan_internal.h"
#ifdef CONFIG_NET_6LOWPAN
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Function: sixlowpan_isbroadcast
*
* Description:
* Return the address length associated with a 2-bit address mode
*
* Input parameters:
* addrmode - The address mode
*
* Returned Value:
* The address length associated with the address mode.
*
****************************************************************************/
static bool sixlowpan_isbroadcast(uint8_t mode, FAR uint8_t *addr)
{
int i = ((mode == FRAME802154_SHORTADDRMODE) ? 2 : 8);
while (i-- > 0)
{
if (addr[i] != 0xff)
{
return false;
}
}
return true;
}
/****************************************************************************
* Public Functions
****************************************************************************/

View File

@ -0,0 +1,485 @@
/****************************************************************************
* net/sixlowpan/sixlowpan_internal.h
*
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Parts of this file derive from Contiki:
*
* Copyright (c) 2008, Swedish Institute of Computer Science
* All rights reserved.
*
* Additional fixes for AVR contributed by:
* Colin O'Flynn coflynn@newae.com
* Eric Gnoske egnoske@gmail.com
* Blake Leverett bleverett@gmail.com
* Mike Vidales mavida404@gmail.com
* Kevin Brown kbrown3@uccs.edu
* Nate Bohlmann nate@elfwerks.com
*
* Additional fixes for MSP430 contributed by:
* Joakim Eriksson
* Niclas Finne
* Nicolas Tsiftes
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name of the copyright holders nor the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
****************************************************************************/
#ifndef _NET_SIXLOWPAN_SIXLOWPAN_INTERNAL_H
#define _NET_SIXLOWPAN_SIXLOWPAN_INTERNAL_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <nuttx/net/tcp.h>
#include <nuttx/net/udp.h>
#include <nuttx/net/icmpv6.h>
#ifdef CONFIG_NET_6LOWPAN
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Rime addres macros */
/* Copy a Rime address */
#define rimeaddr_copy(dest,src) \
memcpy(dest, src, CONFIG_NET_6LOWPAN_RIMEADDR_SIZE)
/* Compare two Rime addresses */
#define rimeaddr_cmp(addr1,addr2) \
(memcmp(addr1, addr2, CONFIG_NET_6LOWPAN_RIMEADDR_SIZE) == 0)
/* Frame buffer helpers */
#define FRAME_RESET(ieee) \
do \
{ \
(ieee)->i_dataoffset = 0; \
(ieee)->i_framelen = 0; \
} \
while (0)
#define FRAME_HDR_START(ieee) \
((ieee)->i_frame)
#define FRAME_HDR_SIZE(ieee) \
((ieee)->i_dataoffset)
#define FRAME_DATA_START(ieee) \
((FAR uint8_t *)((ieee)->i_frame) + (ieee)->i_dataoffset)
#define FRAME_DATA_SIZE(ieee) \
((ieee)->i_framelen - (ieee)->i_dataoffset)
#define FRAME_REMAINING(ieee) \
(CONFIG_NET_6LOWPAN_FRAMELEN - (ieee)->i_framelen)
#define FRAME_SIZE(ieee) \
((ieee)->i_framelen)
/* These are some definitions of element values used in the FCF. See the
* IEEE802.15.4 spec for details.
*/
#define FRAME802154_BEACONFRAME 0x00
#define FRAME802154_DATAFRAME 0x01
#define FRAME802154_ACKFRAME 0x02
#define FRAME802154_CMDFRAME 0x03
#define FRAME802154_BEACONREQ 0x07
#define FRAME802154_IEEERESERVED 0x00
#define FRAME802154_NOADDR 0x00 /* Only valid for ACK or Beacon frames */
#define FRAME802154_SHORTADDRMODE 0x02
#define FRAME802154_LONGADDRMODE 0x03
#define FRAME802154_NOBEACONS 0x0f
#define FRAME802154_BROADCASTADDR 0xffff
#define FRAME802154_BROADCASTPANDID 0xffff
#define FRAME802154_IEEE802154_2003 0x00
#define FRAME802154_IEEE802154_2006 0x01
#define FRAME802154_SECURITY_LEVEL_NONE 0
#define FRAME802154_SECURITY_LEVEL_128 3
/****************************************************************************
* Public Types
****************************************************************************/
/* IPv^ TCP/UDP Definitions *************************************************/
/* IPv6 + TCP header. Cast compatible based on IPv6 protocol field. */
struct ipv6tcp_hdr_s
{
struct ipv6_hdr_s ipv6;
struct tcp_hdr_s tcp;
};
/* IPv6 + UDP header */
struct ipv6udp_hdr_s
{
struct ipv6_hdr_s ipv6;
struct udp_hdr_s udp;
};
/* IPv6 + ICMPv6 header */
struct ipv6icmp_hdr_s
{
struct ipv6_hdr_s ipv6;
struct icmpv6_iphdr_s icmp;
};
/* IEEE802.15.4 Frame Definitions *******************************************/
/* The IEEE 802.15.4 frame has a number of constant/fixed fields that can be
* counted to make frame construction and max payload calculations easier.
* These include:
*
* 1. FCF - 2 bytes - Fixed
* 2. Sequence number - 1 byte - Fixed
* 3. Addressing fields - 4 - 20 bytes - Variable
* 4. Aux security header - 0 - 14 bytes - Variable
* 5. CRC - 2 bytes - Fixed
*/
/* Defines the bitfields of the frame control field (FCF). */
struct frame802154_fcf_s
{
uint8_t frame_type; /* 3 bit. Frame type field, see 802.15.4 */
uint8_t security_enabled; /* 1 bit. True if security is used in this frame */
uint8_t frame_pending; /* 1 bit. True if sender has more data to send */
uint8_t ack_required; /* 1 bit. Is an ack frame required? */
uint8_t panid_compression; /* 1 bit. Is this a compressed header? */
/* 3 bit. Unused bits */
uint8_t dest_addr_mode; /* 2 bit. Destination address mode, see 802.15.4 */
uint8_t frame_version; /* 2 bit. 802.15.4 frame version */
uint8_t src_addr_mode; /* 2 bit. Source address mode, see 802.15.4 */
};
/* 802.15.4 security control bitfield. See section 7.6.2.2.1 in 802.15.4
* specification.
*/
struct frame802154_scf_s
{
uint8_t security_level; /* 3 bit. security level */
uint8_t key_id_mode; /* 2 bit. Key identifier mode */
uint8_t reserved; /* 3 bit. Reserved bits */
};
/* 802.15.4 Aux security header */
struct frame802154_aux_hdr_s
{
struct frame802154_scf_s security_control; /* Security control bitfield */
uint32_t frame_counter; /* Frame counter, used for security */
uint8_t key[9]; /* The key itself, or an index to the key */
};
/* Parameters used by the frame802154_create() function. These parameters
* are used in the 802.15.4 frame header. See the 802.15.4 specification
* for details.
*/
struct frame802154_s
{
struct frame802154_fcf_s fcf; /* Frame control field */
uint8_t seq; /* Sequence number */
uint16_t dest_pid; /* Destination PAN ID */
uint8_t dest_addr[8]; /* Destination address */
uint16_t src_pid; /* Source PAN ID */
uint8_t src_addr[8]; /* Source address */
struct frame802154_aux_hdr_s aux_hdr; /* Aux security header */
uint8_t *payload; /* Pointer to 802.15.4 frame payload */
uint8_t payload_len; /* Length of payload field */
};
/****************************************************************************
* Public Data
****************************************************************************/
/* A pointer to the optional, architecture-specific compressor */
struct sixlowpan_nhcompressor_s; /* Foward reference */
extern FAR struct sixlowpan_nhcompressor_s *g_sixlowpan_compressor;
#ifdef CONFIG_NET_6LOWPAN_SNIFFER
/* Rime Sniffer support for one single listener to enable trace of IP */
struct sixlowpan_rime_sniffer_s; /* Foward reference */
extern FAR struct sixlowpan_rime_sniffer_s *g_sixlowpan_sniffer;
#endif
/****************************************************************************
* Public Types
****************************************************************************/
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
struct net_driver_s; /* Forward reference */
struct ieee802154_driver_s; /* Forward reference */
struct rimeaddr_s; /* Forward reference */
/****************************************************************************
* Name: sixlowpan_send
*
* Description:
* Process an outgoing UDP or TCP packet. Takes an IP packet and formats
* it to be sent on an 802.15.4 network using 6lowpan. Called from common
* UDP/TCP send logic.
*
* The payload data is in the caller 'buf' and is of length 'len'.
* Compressed headers will be added and if necessary the packet is
* fragmented. The resulting packet/fragments are put in dev->d_buf and
* the first frame will be delivered to the 802.15.4 MAC. via ieee->i_frame.
*
* Input Parmeters:
*
* Input Parameters:
* dev - The IEEE802.15.4 MAC network driver interface.
* ipv6 - IPv6 plus TCP or UDP headers.
* buf - Data to send
* len - Length of data to send
* raddr - The MAC address of the destination
*
* Returned Value:
* Ok is returned on success; Othewise a negated errno value is returned.
* This function is expected to fail if the driver is not an IEEE802.15.4
* MAC network driver. In that case, the UDP/TCP will fall back to normal
* IPv4/IPv6 formatting.
*
* Assumptions:
* Called with the network locked.
*
****************************************************************************/
int sixlowpan_send(FAR struct net_driver_s *dev,
FAR const struct ipv6_hdr_s *ipv6, FAR const void *buf,
size_t len, FAR const struct rimeaddr_s *raddr);
/****************************************************************************
* Function: sixlowpan_hdrlen
*
* Description:
* This function is before the first frame has been sent in order to
* determine what the size of the IEEE802.15.4 header will be. No frame
* buffer is required to make this determination.
*
* Input parameters:
* ieee - A reference IEEE802.15.4 MAC network device structure.
* dest_panid - PAN ID of the destination. May be 0xffff if the destination
* is not associated.
*
* Returned Value:
* The frame header length is returnd on success; otherwise, a negated
* errno value is return on failure.
*
****************************************************************************/
int sixlowpan_hdrlen(FAR struct ieee802154_driver_s *ieee,
uint16_t dest_panid);
/****************************************************************************
* Function: sixlowpan_framecreate
*
* Description:
* This function is called after the IEEE802.15.4 MAC driver polls for
* TX data. It creates the IEEE802.15.4 header in the frame buffer.
*
* Input parameters:
* ieee - A reference IEEE802.15.4 MAC network device structure.
* dest_panid - PAN ID of the destination. May be 0xffff if the destination
* is not associated.
*
* Returned Value:
* The frame header length is returnd on success; otherwise, a negated
* errno value is return on failure.
*
****************************************************************************/
int sixlowpan_framecreate(FAR struct ieee802154_driver_s *ieee,
uint16_t dest_panid);
/****************************************************************************
* Name: sixlowpan_hc06_initialize
*
* Description:
* sixlowpan_hc06_initialize() is called during OS initialization at power-up
* reset. It is called from the common sixlowpan_initialize() function.
* sixlowpan_hc06_initialize() configures HC06 networking data structures.
* It is called prior to platform-specific driver initialization so that
* the 6loWPAN networking subsystem is prepared to deal with network
* driver initialization actions.
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC06
void sixlowpan_hc06_initialize(void);
#endif
/****************************************************************************
* Name: sixlowpan_hc06_initialize
*
* Description:
* Compress IP/UDP header
*
* This function is called by the 6lowpan code to create a compressed
* 6lowpan packet in the packetbuf buffer from a full IPv6 packet in the
* uip_buf buffer.
*
* HC-06 (draft-ietf-6lowpan-hc, version 6)
* http://tools.ietf.org/html/draft-ietf-6lowpan-hc-06
*
* NOTE: sixlowpan_compresshdr_hc06() does not support ISA100_UDP header
* compression
*
* Input Parameters:
* dev - A reference to the IEE802.15.4 network device state
* destaddr - L2 destination address, needed to compress IP dest
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC06
void sixlowpan_compresshdr_hc06(FAR struct net_driver_s *dev,
FAR struct rimeaddr_s *destaddr);
#endif
/****************************************************************************
* Name: sixlowpan_hc06_initialize
*
* Description:
* Uncompress HC06 (i.e., IPHC and LOWPAN_UDP) headers and put them in
* sixlowpan_buf
*
* This function is called by the input function when the dispatch is HC06.
* We process the packet in the rime buffer, uncompress the header fields,
* and copy the result in the sixlowpan buffer. At the end of the
* decompression, g_rime_hdrlen and g_uncompressed_hdrlen are set to the
* appropriate values
*
* Input Parmeters:
* dev - A reference to the IEE802.15.4 network device state
* iplen - Equal to 0 if the packet is not a fragment (IP length is then
* inferred from the L2 length), non 0 if the packet is a 1st
* fragment.
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC06
void sixlowpan_uncompresshdr_hc06(FAR struct net_driver_s *dev,
uint16_t iplen);
#endif
/****************************************************************************
* Name: sixlowpan_compresshdr_hc1
*
* Description:
* Compress IP/UDP header using HC1 and HC_UDP
*
* This function is called by the 6lowpan code to create a compressed
* 6lowpan packet in the packetbuf buffer from a full IPv6 packet in the
* uip_buf buffer.
*
* Input Parmeters:
* dev - A reference to the IEE802.15.4 network device state
* destaddr - L2 destination address, needed to compress the IP
* destination field
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC1
void sixlowpan_compresshdr_hc1(FAR struct net_driver_s *dev,
FAR struct rimeaddr_s *destaddr);
#endif
/****************************************************************************
* Name: sixlowpan_uncompresshdr_hc1
*
* Description:
* Uncompress HC1 (and HC_UDP) headers and put them in sixlowpan_buf
*
* This function is called by the input function when the dispatch is
* HC1. It processes the packet in the rime buffer, uncompresses the
* header fields, and copies the result in the sixlowpan buffer. At the
* end of the decompression, g_rime_hdrlen and uncompressed_hdr_len
* are set to the appropriate values
*
* Input Parameters:
* dev - A reference to the IEE802.15.4 network device state
* iplen - Equal to 0 if the packet is not a fragment (IP length is then
* inferred from the L2 length), non 0 if the packet is a 1st
* fragment.
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC1
void sixlowpan_uncompresshdr_hc1(FAR struct net_driver_s *dev,
uint16_t ip_len);
#endif
/****************************************************************************
* Name: sixlowpan_frame_hdralloc
*
* Description:
* Allocate space for a header within the frame buffer (i_frame).
*
****************************************************************************/
int sixlowpan_frame_hdralloc(FAR struct ieee802154_driver_s *ieee,
int size);
#endif /* CONFIG_NET_6LOWPAN */
#endif /* _NET_SIXLOWPAN_SIXLOWPAN_INTERNAL_H */

View File

@ -4,6 +4,18 @@
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Parts of this file derive from Contiki:
*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
* Authors: Adam Dunkels <adam@sics.se>
* Nicolas Tsiftes <nvt@sics.se>
* Niclas Finne <nfi@sics.se>
* Mathilde Durvy <mdurvy@cisco.com>
* Julien Abeille <jabeille@cisco.com>
* Joakim Eriksson <joakime@sics.se>
* Joel Hoglund <joel@sics.se>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@ -11,25 +23,23 @@
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
****************************************************************************/
@ -55,38 +65,10 @@
#include "socket/socket.h"
#include "tcp/tcp.h"
#include "udp/udp.h"
#include "sixlowpan/sixlowpan.h"
#include "sixlowpan/sixlowpan_internal.h"
#ifdef CONFIG_NET_6LOWPAN
/****************************************************************************
* Private Types
****************************************************************************/
/* IPv6 + TCP header */
struct ipv6tcp_hdr_s
{
struct ipv6_hdr_s ipv6;
struct tcp_hdr_s tcp;
};
/* IPv6 + UDP header */
struct ipv6udp_hdr_s
{
struct ipv6_hdr_s ipv6;
struct udp_hdr_s udp;
};
/* IPv6 + ICMPv6 header */
struct ipv6icmp_hdr_s
{
struct ipv6_hdr_s ipv6;
struct icmpv6_iphdr_s icmp;
};
/****************************************************************************
* Private Functions
****************************************************************************/
@ -96,6 +78,7 @@ struct ipv6icmp_hdr_s
*
* Description:
* Setup some packet buffer attributes
*
* Input Parameters:
* ieee - Pointer to IEEE802.15.4 MAC driver structure.
* ipv6 - Pointer to the IPv6 header to "compress"
@ -186,6 +169,46 @@ static void sixlowpan_compress_ipv6hdr(FAR struct ieee802154_driver_s *ieee,
ieee->i_uncomp_hdrlen += IPv6_HDRLEN;
}
/****************************************************************************
* Name: sixlowpan_send_frame
*
* Description:
* Send one frame when the IEEE802.15.4 MAC device next polls.
*
* Input Parameters:
* ieee - Pointer to IEEE802.15.4 MAC driver structure.
* ipv6 - Pointer to the IPv6 header to "compress"
*
* Returned Value:
* None
*
****************************************************************************/
static int sixlowpan_send_frame(FAR struct ieee802154_driver_s *ieee)
{
/* Prepare the frame */
#warning Missing logic
/* Set up for the TX poll */
/* When polled, then we need to call sixlowpan_framecreate() to create the
* frame and copy the payload data into the frame.
*/
#if 0 /* Just some notes of what needs to be done in interrupt handler */
framer_hdrlen = sixlowpan_createframe(ieee, ieee->i_panid);
memcpy(ieee->i_rimeptr + ieee->i_rime_hdrlen, (uint8_t *)ipv6 + ieee->i_uncomp_hdrlen, len - ieee->i_uncomp_hdrlen);
dev->i_framelen = len - ieee->i_uncomp_hdrlen + ieee->i_rime_hdrlen;
#endif
#warning Missing logic
/* Notify the IEEE802.14.5 MAC driver that we have data to be sent */
#warning Missing logic
/* Wait for the transfer to complete */
#warning Missing logic
return -ENOSYS;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: sixlowpan_send
*
@ -204,7 +227,9 @@ static void sixlowpan_compress_ipv6hdr(FAR struct ieee802154_driver_s *ieee,
* Input Parameters:
* dev - The IEEE802.15.4 MAC network driver interface.
* ipv6 - IPv6 plus TCP or UDP headers.
* raddr - The MAC address of the destination
* buf - Data to send
* len - Length of data to send
* raddr - The IEEE802.15.4 MAC address of the destination
*
* Returned Value:
* Ok is returned on success; Othewise a negated errno value is returned.
@ -218,37 +243,56 @@ static void sixlowpan_compress_ipv6hdr(FAR struct ieee802154_driver_s *ieee,
****************************************************************************/
int sixlowpan_send(FAR struct net_driver_s *dev,
FAR const struct ipv6_hdr_s *ipv6, net_ipv6addr_t raddr)
FAR const struct ipv6_hdr_s *ipv6, FAR const void *buf,
size_t len, FAR const struct rimeaddr_s *raddr)
{
FAR struct ieee802154_driver_s *ieee = (FAR struct ieee802154_driver_s *)dev;
int framer_hdrlen; /* Framer header length */
struct rimeaddr_s dest; /* The MAC address of the destination of the packet */
uint16_t outlen; /* Number of bytes processed. */
uint16_t outlen = 0; /* Number of bytes processed. */
/* Initialize device-specific data */
FRAME_RESET(ieee);
ieee->i_uncomp_hdrlen = 0;
ieee->i_rime_hdrlen = 0;
/* REVISIT: Do I need this rimeptr? */
ieee->i_rimeptr = &dev->d_buf[PACKETBUF_HDR_SIZE];
/* Reset rime buffer, packet buffer metatadata */
dev->d_len = 0;
memset(ieee->i_pktattrs, 0, PACKETBUF_NUM_ATTRS * sizeof(uint16_t));
memset(ieee->i_pktaddrs, 0, PACKETBUF_NUM_ADDRS * sizeof(struct rimeaddr_s));
sixlowpan_pktbuf_reset(ieee);
ieee->i_rimeptr = &dev->d_buf[PACKETBUF_HDR_SIZE];
ieee->i_pktattrs[PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS] = CONFIG_NET_6LOWPAN_MAX_MACTRANSMITS;
ieee->i_pktattrs[PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS] =
CONFIG_NET_6LOWPAN_MAX_MACTRANSMITS;
#ifdef CONFIG_NET_6LOWPAN_SNIFFER
if (g_sixlowpan_sniffer != NULL)
{
/* Reset rime buffer, packet buffer metatadata */
memset(ieee->i_pktattrs, 0, PACKETBUF_NUM_ATTRS * sizeof(uint16_t));
memset(ieee->i_pktaddrs, 0, PACKETBUF_NUM_ADDRS * sizeof(struct rimeaddr_s));
ieee->i_pktattrs[PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS] =
CONFIG_NET_6LOWPAN_MAX_MACTRANSMITS;
/* Call the attribution when the callback comes, but set attributes here */
sixlowpan_set_pktattrs(ieee, ipv6);
}
#endif
/* Reset rime buffer, packet buffer metatadata */
memset(ieee->i_pktattrs, 0, PACKETBUF_NUM_ATTRS * sizeof(uint16_t));
memset(ieee->i_pktaddrs, 0, PACKETBUF_NUM_ADDRS * sizeof(struct rimeaddr_s));
ieee->i_pktattrs[PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS] =
CONFIG_NET_6LOWPAN_MAX_MACTRANSMITS;
/* Set stream mode for all TCP packets, except FIN packets. */
if (ipv6->proto == IP_PROTO_TCP)
@ -270,247 +314,129 @@ int sixlowpan_send(FAR struct net_driver_s *dev,
* argument raddr is NULL, we are sending a broadcast packet.
*/
#warning Missing logic
if (raddr == NULL)
{
memset(&dest, 0, sizeof(struct rimeaddr_s));
}
else
{
rimeaddr_copy(&dest, (FAR const struct rimeaddr_s *)raddr);
}
ninfo("Sending packet len %d\n", len);
#ifndef CONFIG_NET_6LOWPAN_COMPRESSION_IPv6
if (len >= CONFIG_NET_6LOWPAN_COMPRESSION_THRESHOLD)
{
/* Try to compress the headers */
#if defined(CONFIG_NET_6LOWPAN_COMPRESSION_HC1)
sixlowpan_compresshdr_hc1(dev, &dest);
#elif defined(CONFIG_NET_6LOWPAN_COMPRESSION_HC06)
sixlowpan_compresshdr_hc06(dev, &dest);
#else
# error No compression specified
#endif
}
else
#endif /* !CONFIG_NET_6LOWPAN_COMPRESSION_IPv6 */
{
/* Small.. use IPv6 dispatch (no compression) */
sixlowpan_compress_ipv6hdr(ieee, ipv6);
}
ninfo("Header of len %d\n", ieee->i_rime_hdrlen);
rimeaddr_copy(&ieee->i_pktaddrs[PACKETBUF_ADDR_RECEIVER], &dest);
/* Pre-calculate frame header length. */
framer_hdrlen = sixlowpan_hdrlen(ieee, ieee->i_panid);
if (framer_hdrlen < 0)
{
/* Failed to determine the size of the header failed. */
nerr("ERROR: sixlowpan_framecreate() failed: %d\n", framer_hdrlen);
return framer_hdrlen;
}
/* Check if we need to fragment the packet into several frames */
if ((int)len - (int)ieee->i_uncomp_hdrlen >
(int)CONFIG_NET_6LOWPAN_MAXPAYLOAD - framer_hdrlen -
(int)ieee->i_rime_hdrlen)
{
#if CONFIG_NET_6LOWPAN_FRAG
/* The outbound IPv6 packet is too large to fit into a single 15.4
* packet, so we fragment it into multiple packets and send them.
* The first fragment contains frag1 dispatch, then
* IPv6/HC1/HC06/HC_UDP dispatchs/headers.
* The following fragments contain only the fragn dispatch.
*/
ninfo("Fragmentation sending packet len %d\n", len);
/* Create 1st Fragment */
# warning Missing logic
/* Move HC1/HC06/IPv6 header */
# warning Missing logic
/* FRAG1 dispatch + header
* Note that the length is in units of 8 bytes
*/
# warning Missing logic
/* Copy payload and send */
# warning Missing logic
/* Check TX result. */
# warning Missing logic
/* Set outlen to what we already sent from the IP payload */
# warning Missing logic
/* Create following fragments
* Datagram tag is already in the buffer, we need to set the
* FRAGN dispatch and for each fragment, the offset
*/
# warning Missing logic
while (outlen < len)
{
/* Copy payload and send */
# warning Missing logic
ninfo("sixlowpan output: fragment offset %d, len %d, tag %d\n",
outlen >> 3, g_rime_payloadlen, g_mytag);
# warning Missing logic
sixlowpan_send_frame(ieee);
/* Check tx result. */
# warning Missing logic
}
return -ENOSYS;
#else
nerr("ERROR: Packet too large: %d\n", len);
nerr(" Cannot to be sent without fragmentation support\n");
nerr(" dropping packet\n");
return -E2BIG;
#endif
}
else
{
/* The packet does not need to be fragmented just copy the "payload"
* and send in one frame.
*/
return sixlowpan_send_frame(ieee);
}
return -ENOSYS;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Function: psock_6lowpan_tcp_send
*
* Description:
* psock_6lowpan_tcp_send() call may be used only when the TCP socket is in a
* connected state (so that the intended recipient is known).
*
* Parameters:
* psock - An instance of the internal socket structure.
* buf - Data to send
* len - Length of data to send
*
* Returned Value:
* On success, returns the number of characters sent. On error,
* -1 is returned, and errno is set appropriately. Returned error numbers
* must be consistent with definition of errors reported by send() or
* sendto().
*
* Assumptions:
* Called with the network locked.
*
****************************************************************************/
#ifdef CONFIG_NET_TCP
ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf,
size_t len)
{
FAR struct tcp_conn_s *conn;
FAR struct net_driver_s *dev;
struct ipv6tcp_hdr_s ipv6tcp;
int ret;
DEBUGASSERT(psock != NULL && psock->s_crefs > 0);
DEBUGASSERT(psock->s_type == SOCK_STREAM);
/* Make sure that this is a valid socket */
if (psock != NULL || psock->s_crefs <= 0)
{
nerr("ERROR: Invalid socket\n");
return (ssize_t)-EBADF;
}
/* Make sure that this is a connected TCP socket */
if (psock->s_type != SOCK_STREAM || !_SS_ISCONNECTED(psock->s_flags))
{
nerr("ERROR: Not connected\n");
return (ssize_t)-ENOTCONN;
}
/* Get the underlying TCP connection structure */
conn = (FAR struct tcp_conn_s *)psock->s_conn;
DEBUGASSERT(conn != NULL);
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
/* Ignore if not IPv6 domain */
if (conn->domain != PF_INET6)
{
nwarn("WARNING: Not IPv6\n");
return (ssize_t)-EPROTOTYPE;
}
#endif
/* Route outgoing message to the correct device */
#ifdef CONFIG_NETDEV_MULTINIC
dev = netdev_findby_ipv6addr(conn->u.ipv6.laddr, conn->u.ipv6.raddr);
if (dev == NULL || dev->d_lltype != NET_LL_IEEE805154)
{
nwarn("WARNING: Not routable or not IEEE802.15.4 MAC\n");
return (ssize_t)-ENETUNREACH;
}
#else
dev = netdev_findby_ipv6addr(conn->u.ipv6.raddr);
if (dev == NULL)
{
nwarn("WARNING: Not routable\n");
return (ssize_t)-ENETUNREACH;
}
#endif
#ifdef CONFIG_NET_ICMPv6_NEIGHBOR
/* Make sure that the IP address mapping is in the Neighbor Table */
ret = icmpv6_neighbor(conn->u.ipv6.raddr);
if (ret < 0)
{
nerr("ERROR: Not reachable\n");
return (ssize_t)-ENETUNREACH;
}
#endif
/* Initialize the IPv6/TCP headers */
#warning Missing logic
/* Set the socket state to sending */
psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_SEND);
/* If routable, then call sixlowpan_send() to format and send the 6loWPAN
* packet.
*/
ret = sixlowpan_send(dev, (FAR const struct ipv6_hdr_s *)&ipv6tcp,
conn->u.ipv6.raddr);
if (ret < 0)
{
nerr("ERROR: sixlowpan_send() failed: %d\n", ret);
}
return ret;
}
#endif
/****************************************************************************
* Function: psock_6lowpan_udp_send
*
* Description:
* psock_6lowpan_udp_send() call may be used with connectionlesss UDP
* sockets.
*
* Parameters:
* psock - An instance of the internal socket structure.
* buf - Data to send
* len - Length of data to send
*
* Returned Value:
* On success, returns the number of characters sent. On error,
* -1 is returned, and errno is set appropriately. Returned error numbers
* must be consistent with definition of errors reported by send() or
* sendto().
*
* Assumptions:
* Called with the network locked.
*
****************************************************************************/
#ifdef CONFIG_NET_UDP
ssize_t psock_6lowpan_udp_send(FAR struct socket *psock, FAR const void *buf,
size_t len)
{
FAR struct udp_conn_s *conn;
FAR struct net_driver_s *dev;
struct ipv6udp_hdr_s ipv6udp;
int ret;
DEBUGASSERT(psock != NULL && psock->s_crefs > 0);
DEBUGASSERT(psock->s_type == SOCK_DGRAM);
/* Make sure that this is a valid socket */
if (psock != NULL || psock->s_crefs <= 0)
{
nerr("ERROR: Invalid socket\n");
return (ssize_t)-EBADF;
}
/* Was the UDP socket connected via connect()? */
if (psock->s_type != SOCK_DGRAM || !_SS_ISCONNECTED(psock->s_flags))
{
/* No, then it is not legal to call send() with this socket. */
return -ENOTCONN;
}
/* Get the underlying UDP "connection" structure */
conn = (FAR struct udp_conn_s *)psock->s_conn;
DEBUGASSERT(conn != NULL);
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
/* Ignore if not IPv6 domain */
if (conn->domain != PF_INET6)
{
nwarn("WARNING: Not IPv6\n");
return (ssize_t)-EPROTOTYPE;
}
#endif
/* Route outgoing message to the correct device */
#ifdef CONFIG_NETDEV_MULTINIC
dev = netdev_findby_ipv6addr(conn->u.ipv6.laddr, conn->u.ipv6.raddr);
if (dev == NULL || dev->d_lltype != NET_LL_IEEE805154)
{
nwarn("WARNING: Not routable or not IEEE802.15.4 MAC\n");
return (ssize_t)-ENETUNREACH;
}
#else
dev = netdev_findby_ipv6addr(conn->u.ipv6.raddr);
if (dev == NULL)
{
nwarn("WARNING: Not routable\n");
return (ssize_t)-ENETUNREACH;
}
#endif
#ifdef CONFIG_NET_ICMPv6_NEIGHBOR
/* Make sure that the IP address mapping is in the Neighbor Table */
ret = icmpv6_neighbor(conn->u.ipv6.raddr);
if (ret < 0)
{
nerr("ERROR: Not reachable\n");
return (ssize_t)-ENETUNREACH;
}
#endif
/* Initialize the IPv6/UDP headers */
#warning Missing logic
/* Set the socket state to sending */
psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_SEND);
/* If routable, then call sixlowpan_send() to format and send the 6loWPAN
* packet.
*/
ret = sixlowpan_send(dev, (FAR const struct ipv6_hdr_s *)&ipv6udp,
conn->u.ipv6.raddr);
if (ret < 0)
{
nerr("ERROR: sixlowpan_send() failed: %d\n", ret);
}
return ret;
}
#endif
#endif /* CONFIG_NET_6LOWPAN */

View File

@ -42,7 +42,7 @@
#include "nuttx/net/net.h"
#include "nuttx/net/sixlowpan.h"
#include "sixlowpan/sixlowpan.h"
#include "sixlowpan/sixlowpan_internal.h"
#ifdef CONFIG_NET_6LOWPAN_SNIFFER

View File

@ -0,0 +1,180 @@
/****************************************************************************
* net/sixlowpan/sixlowpan_tcpsend.c
*
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include "nuttx/net/netdev.h"
#include "nuttx/net/tcp.h"
#include "nuttx/net/sixlowpan.h"
#include "netdev/netdev.h"
#include "socket/socket.h"
#include "tcp/tcp.h"
#include "sixlowpan/sixlowpan_internal.h"
#if defined(CONFIG_NET_6LOWPAN) && defined(CONFIG_NET_TCP)
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Function: psock_6lowpan_tcp_send
*
* Description:
* psock_6lowpan_tcp_send() call may be used only when the TCP socket is in a
* connected state (so that the intended recipient is known).
*
* Parameters:
* psock - An instance of the internal socket structure.
* buf - Data to send
* len - Length of data to send
*
* Returned Value:
* On success, returns the number of characters sent. On error,
* -1 is returned, and errno is set appropriately. Returned error numbers
* must be consistent with definition of errors reported by send() or
* sendto().
*
* Assumptions:
* Called with the network locked.
*
****************************************************************************/
ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf,
size_t len)
{
FAR struct tcp_conn_s *conn;
FAR struct net_driver_s *dev;
struct ipv6tcp_hdr_s ipv6tcp;
struct rimeaddr_s dest;
int ret;
DEBUGASSERT(psock != NULL && psock->s_crefs > 0);
DEBUGASSERT(psock->s_type == SOCK_STREAM);
/* Make sure that this is a valid socket */
if (psock != NULL || psock->s_crefs <= 0)
{
nerr("ERROR: Invalid socket\n");
return (ssize_t)-EBADF;
}
/* Make sure that this is a connected TCP socket */
if (psock->s_type != SOCK_STREAM || !_SS_ISCONNECTED(psock->s_flags))
{
nerr("ERROR: Not connected\n");
return (ssize_t)-ENOTCONN;
}
/* Get the underlying TCP connection structure */
conn = (FAR struct tcp_conn_s *)psock->s_conn;
DEBUGASSERT(conn != NULL);
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
/* Ignore if not IPv6 domain */
if (conn->domain != PF_INET6)
{
nwarn("WARNING: Not IPv6\n");
return (ssize_t)-EPROTOTYPE;
}
#endif
/* Route outgoing message to the correct device */
#ifdef CONFIG_NETDEV_MULTINIC
dev = netdev_findby_ipv6addr(conn->u.ipv6.laddr, conn->u.ipv6.raddr);
if (dev == NULL || dev->d_lltype != NET_LL_IEEE805154)
{
nwarn("WARNING: Not routable or not IEEE802.15.4 MAC\n");
return (ssize_t)-ENETUNREACH;
}
#else
dev = netdev_findby_ipv6addr(conn->u.ipv6.raddr);
if (dev == NULL)
{
nwarn("WARNING: Not routable\n");
return (ssize_t)-ENETUNREACH;
}
#endif
#ifdef CONFIG_NET_ICMPv6_NEIGHBOR
/* Make sure that the IP address mapping is in the Neighbor Table */
ret = icmpv6_neighbor(conn->u.ipv6.raddr);
if (ret < 0)
{
nerr("ERROR: Not reachable\n");
return (ssize_t)-ENETUNREACH;
}
#endif
/* Initialize the IPv6/TCP headers */
#warning Missing logic
/* Set the socket state to sending */
psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_SEND);
/* Get the Rime MAC address of the destination */
#warning Missing logic
/* If routable, then call sixlowpan_send() to format and send the 6loWPAN
* packet.
*/
ret = sixlowpan_send(dev, (FAR const struct ipv6_hdr_s *)&ipv6tcp,
buf, len, &dest);
if (ret < 0)
{
nerr("ERROR: sixlowpan_send() failed: %d\n", ret);
}
return ret;
}
#endif /* CONFIG_NET_6LOWPAN && CONFIG_NET_TCP */

View File

@ -0,0 +1,181 @@
/****************************************************************************
* net/sixlowpan/sixlowpan_udpsend.c
*
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include "nuttx/net/netdev.h"
#include "nuttx/net/udp.h"
#include "nuttx/net/sixlowpan.h"
#include "netdev/netdev.h"
#include "socket/socket.h"
#include "udp/udp.h"
#include "sixlowpan/sixlowpan_internal.h"
#if defined(CONFIG_NET_6LOWPAN) && defined(CONFIG_NET_UDP)
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Function: psock_6lowpan_udp_send
*
* Description:
* psock_6lowpan_udp_send() call may be used with connectionlesss UDP
* sockets.
*
* Parameters:
* psock - An instance of the internal socket structure.
* buf - Data to send
* len - Length of data to send
*
* Returned Value:
* On success, returns the number of characters sent. On error,
* -1 is returned, and errno is set appropriately. Returned error numbers
* must be consistent with definition of errors reported by send() or
* sendto().
*
* Assumptions:
* Called with the network locked.
*
****************************************************************************/
ssize_t psock_6lowpan_udp_send(FAR struct socket *psock, FAR const void *buf,
size_t len)
{
FAR struct udp_conn_s *conn;
FAR struct net_driver_s *dev;
struct ipv6udp_hdr_s ipv6udp;
struct rimeaddr_s dest;
int ret;
DEBUGASSERT(psock != NULL && psock->s_crefs > 0);
DEBUGASSERT(psock->s_type == SOCK_DGRAM);
/* Make sure that this is a valid socket */
if (psock != NULL || psock->s_crefs <= 0)
{
nerr("ERROR: Invalid socket\n");
return (ssize_t)-EBADF;
}
/* Was the UDP socket connected via connect()? */
if (psock->s_type != SOCK_DGRAM || !_SS_ISCONNECTED(psock->s_flags))
{
/* No, then it is not legal to call send() with this socket. */
return -ENOTCONN;
}
/* Get the underlying UDP "connection" structure */
conn = (FAR struct udp_conn_s *)psock->s_conn;
DEBUGASSERT(conn != NULL);
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
/* Ignore if not IPv6 domain */
if (conn->domain != PF_INET6)
{
nwarn("WARNING: Not IPv6\n");
return (ssize_t)-EPROTOTYPE;
}
#endif
/* Route outgoing message to the correct device */
#ifdef CONFIG_NETDEV_MULTINIC
dev = netdev_findby_ipv6addr(conn->u.ipv6.laddr, conn->u.ipv6.raddr);
if (dev == NULL || dev->d_lltype != NET_LL_IEEE805154)
{
nwarn("WARNING: Not routable or not IEEE802.15.4 MAC\n");
return (ssize_t)-ENETUNREACH;
}
#else
dev = netdev_findby_ipv6addr(conn->u.ipv6.raddr);
if (dev == NULL)
{
nwarn("WARNING: Not routable\n");
return (ssize_t)-ENETUNREACH;
}
#endif
#ifdef CONFIG_NET_ICMPv6_NEIGHBOR
/* Make sure that the IP address mapping is in the Neighbor Table */
ret = icmpv6_neighbor(conn->u.ipv6.raddr);
if (ret < 0)
{
nerr("ERROR: Not reachable\n");
return (ssize_t)-ENETUNREACH;
}
#endif
/* Initialize the IPv6/UDP headers */
#warning Missing logic
/* Set the socket state to sending */
psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_SEND);
/* Get the Rime MAC address of the destination */
#warning Missing logic
/* If routable, then call sixlowpan_send() to format and send the 6loWPAN
* packet.
*/
ret = sixlowpan_send(dev, (FAR const struct ipv6_hdr_s *)&ipv6udp,
buf, len, &dest);
if (ret < 0)
{
nerr("ERROR: sixlowpan_send() failed: %d\n", ret);
}
return ret;
}
#endif /* CONFIG_NET_6LOWPAN && CONFIG_NET_UDP */

View File

@ -0,0 +1,100 @@
/****************************************************************************
* net/sixlowpan/sixlowpan_utils.c
*
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Copyright (C) 2017, Gregory Nutt, all rights reserved
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Derives from logic in Contiki:
*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
* Authors: Adam Dunkels <adam@sics.se>
* Nicolas Tsiftes <nvt@sics.se>
* Niclas Finne <nfi@sics.se>
* Mathilde Durvy <mdurvy@cisco.com>
* Julien Abeille <jabeille@cisco.com>
* Joakim Eriksson <joakime@sics.se>
* Joel Hoglund <joel@sics.se>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
****************************************************************************/
/* Frame Organization:
*
* Content Offset
* +------------------+ 0
* | Frame Header |
* +------------------+ i_dataoffset
* | Procotol Headers |
* | Data Payload |
* +------------------+ i_framelen
* | Unused |
* +------------------+ CONFIG_NET_6LOWPAN_FRAMELEN
*/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <string.h>
#include <errno.h>
#include "nuttx/net/sixlowpan.h"
#include "sixlowpan/sixlowpan_internal.h"
#ifdef CONFIG_NET_6LOWPAN
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: sixlowpan_frame_hdralloc
*
* Description:
* Allocate space for a header within the packet buffer (dev->d_buf).
*
****************************************************************************/
int sixlowpan_frame_hdralloc(FAR struct ieee802154_driver_s *ieee,
int size)
{
if (size <= FRAME_REMAINING(ieee))
{
ieee->i_dataoffset += size;
ieee->i_framelen += size;
return OK;
}
return -ENOMEM;
}
#endif /* CONFIG_NET_6LOWPAN */

View File

@ -42,6 +42,7 @@
#include <debug.h>
#include <nuttx/arch.h>
#include <nuttx/irq.h>
#include <nuttx/random.h>
#include "irq/irq.h"
@ -53,7 +54,7 @@
* Name: irq_dispatch
*
* Description:
* This function must be called from the achitecture-specific logic in
* This function must be called from the architecture-specific logic in
* order to dispatch an interrupt to the appropriate, registered handling
* logic.
*
@ -97,6 +98,12 @@ void irq_dispatch(int irq, FAR void *context)
arg = NULL;
#endif
#ifdef CONFIG_CRYPTO_RANDOM_POOL_COLLECT_IRQ_RANDOMNESS
/* Add interrupt timing randomness to entropy pool */
add_irq_randomness(irq);
#endif
/* Then dispatch to the interrupt handler */
vector(irq, context, arg);

View File

@ -30,6 +30,7 @@
"get_errno_ptr","errno.h","defined(__DIRECT_ERRNO_ACCESS)","FAR int*"
"getenv","stdlib.h","!defined(CONFIG_DISABLE_ENVIRON)","FAR char*","FAR const char*"
"getpid","unistd.h","","pid_t"
"getrandom","sys/random.h","defined(CONFIG_CRYPTO_RANDOM_POOL)","void","FAR void*","size_t"
"getsockopt","sys/socket.h","CONFIG_NSOCKET_DESCRIPTORS > 0 && defined(CONFIG_NET)","int","int","int","int","FAR void*","FAR socklen_t*"
"insmod","nuttx/module.h","defined(CONFIG_MODULE)","FAR void *","FAR const char *","FAR const char *"
"ioctl","sys/ioctl.h","!defined(CONFIG_LIBC_IOCTL_VARIADIC) && (CONFIG_NSOCKET_DESCRIPTORS > 0 || CONFIG_NFILE_DESCRIPTORS > 0)","int","int","int","unsigned long"

Can't render this file because it has a wrong number of fields in line 2.

View File

@ -379,6 +379,13 @@ SYSCALL_LOOKUP(up_assert, 2, STUB_up_assert)
SYSCALL_LOOKUP(prctl, 5, STUB_prctl)
#endif
/* The following is defined only if entropy pool random number generator
* is enabled. */
#ifdef CONFIG_CRYPTO_RANDOM_POOL
SYSCALL_LOOKUP(getrandom, 2, STUB_getrandom)
#endif
/****************************************************************************
* Private Functions
****************************************************************************/

View File

@ -391,6 +391,11 @@ uintptr_t STUB_socket(int nbr, uintptr_t parm1, uintptr_t parm2,
uintptr_t STUB_prctl(int nbr, uintptr_t parm1, uintptr_t parm2,
uintptr_t parm3, uintptr_t parm4, uintptr_t parm5);
/* The following is defined only if entropy pool random number generator
* is enabled. */
uintptr_t STUB_getrandom(int nbr, uintptr_t parm1, uintptr_t parm2);
/****************************************************************************
* Public Data
****************************************************************************/