Merge remote-tracking branch 'origin/master' into ieee802154
This commit is contained in:
commit
916bd80f9f
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
--------------------
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
606
crypto/blake2s.c
Normal 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
561
crypto/random_pool.c
Normal 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);
|
||||
}
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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?
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -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
1131
drivers/sensors/hts221.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -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];
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -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? */
|
||||
|
@ -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? */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -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 */
|
||||
|
197
include/nuttx/crypto/blake2s.h
Normal file
197
include/nuttx/crypto/blake2s.h
Normal 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 */
|
@ -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
171
include/nuttx/random.h
Normal 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 */
|
158
include/nuttx/sensors/hts221.h
Normal file
158
include/nuttx/sensors/hts221.h
Normal 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 */
|
@ -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 */
|
||||
|
@ -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
77
include/sys/random.h
Normal 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 */
|
@ -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
|
||||
|
@ -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)
|
||||
|
55
libc/string/lib_explicit_bzero.c
Normal file
55
libc/string/lib_explicit_bzero.c
Normal 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);
|
||||
}
|
@ -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;
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
||||
|
577
net/sixlowpan/sixlowpan_framer.c
Normal file
577
net/sixlowpan/sixlowpan_framer.c
Normal 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(¶ms, 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 *)¶ms->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 *)¶ms->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, ¶ms, dest_panid);
|
||||
|
||||
/* Return the length of the header */
|
||||
|
||||
return sixlowpan_802154_hdrlen(¶ms);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* 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, ¶ms, dest_panid);
|
||||
|
||||
/* Get the length of the header */
|
||||
|
||||
len = sixlowpan_802154_hdrlen(¶ms);
|
||||
|
||||
/* 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(¶ms, 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 */
|
@ -41,7 +41,7 @@
|
||||
|
||||
#include "nuttx/net/sixlowpan.h"
|
||||
|
||||
#include "sixlowpan/sixlowpan.h"
|
||||
#include "sixlowpan/sixlowpan_internal.h"
|
||||
|
||||
#ifdef CONFIG_NET_6LOWPAN
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include "sixlowpan/sixlowpan.h"
|
||||
#include "sixlowpan/sixlowpan_internal.h"
|
||||
|
||||
#ifdef CONFIG_NET_6LOWPAN
|
||||
|
||||
|
@ -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
|
||||
****************************************************************************/
|
||||
|
485
net/sixlowpan/sixlowpan_internal.h
Normal file
485
net/sixlowpan/sixlowpan_internal.h
Normal 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 */
|
@ -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 */
|
||||
|
@ -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
|
||||
|
||||
|
180
net/sixlowpan/sixlowpan_tcpsend.c
Normal file
180
net/sixlowpan/sixlowpan_tcpsend.c
Normal 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 */
|
181
net/sixlowpan/sixlowpan_udpsend.c
Normal file
181
net/sixlowpan/sixlowpan_udpsend.c
Normal 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 */
|
100
net/sixlowpan/sixlowpan_utils.c
Normal file
100
net/sixlowpan/sixlowpan_utils.c
Normal 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 */
|
@ -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);
|
||||
|
@ -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.
|
@ -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
|
||||
****************************************************************************/
|
||||
|
@ -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
|
||||
****************************************************************************/
|
||||
|
Loading…
x
Reference in New Issue
Block a user