mirror of https://github.com/ARMmbed/mbed-os.git
commit
71d253c86d
|
@ -0,0 +1,5 @@
|
|||
SRCS := $(wildcard source/*)
|
||||
LIB := librand.a
|
||||
EXPORT_HEADERS := mbed-client-randlib
|
||||
|
||||
include ../exported_rules.mk
|
|
@ -1,168 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2014-2015 ARM Limited. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include "randLIB.h"
|
||||
|
||||
/**
|
||||
* \brief Init seed for Pseudo Random.
|
||||
* On a Linux, this does nothing.
|
||||
*
|
||||
* \return None
|
||||
*
|
||||
*/
|
||||
void randLIB_seed_random(void)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Generate 8-bit random number.
|
||||
*
|
||||
* \param None
|
||||
* \return 8-bit random number
|
||||
*
|
||||
*/
|
||||
uint8_t randLIB_get_8bit(void)
|
||||
{
|
||||
uint8_t ret_val;
|
||||
randLIB_get_n_bytes_random(&ret_val, 1);
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Generate 16-bit random number.
|
||||
*
|
||||
* \param None
|
||||
* \return 16-bit random number
|
||||
*
|
||||
*/
|
||||
uint16_t randLIB_get_16bit(void)
|
||||
{
|
||||
uint16_t ret_val;
|
||||
|
||||
randLIB_get_n_bytes_random((uint8_t*)&ret_val, 2);
|
||||
return ret_val;
|
||||
}
|
||||
/**
|
||||
* \brief Generate 32-bit random number.
|
||||
*
|
||||
* \param None
|
||||
* \return 32-bit random number
|
||||
*
|
||||
*/
|
||||
uint32_t randLIB_get_32bit(void)
|
||||
{
|
||||
uint32_t ret_val;
|
||||
randLIB_get_n_bytes_random((uint8_t*)&ret_val, 4);
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Generate n-bytes random numbers.
|
||||
*
|
||||
* \param data_ptr pointer where random will be stored
|
||||
* \param eight_bit_boundary how many bytes need random
|
||||
* \return 0 process valid
|
||||
* \return -1 Unsupported Parameters or failed to get random data.
|
||||
*
|
||||
*/
|
||||
int8_t randLIB_get_n_bytes_random(uint8_t *data_ptr, uint8_t eight_bit_boundary)
|
||||
{
|
||||
if ((data_ptr == 0) || (eight_bit_boundary == 0)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int fd = open("/dev/urandom", O_RDONLY);
|
||||
if (fd != -1) {
|
||||
size_t len = read(fd, data_ptr, eight_bit_boundary);
|
||||
close(fd);
|
||||
if (len == eight_bit_boundary)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Generate a random number within a range.
|
||||
*
|
||||
* The result is linearly distributed in the range [min..max], inclusive.
|
||||
*
|
||||
* \param min minimum value that can be generated
|
||||
* \param max maximum value that can be generated
|
||||
*/
|
||||
uint16_t randLIB_get_random_in_range(uint16_t min, uint16_t max)
|
||||
{
|
||||
/* This special case is potentially common, particularly in this routine's
|
||||
* first user (Trickle), so worth catching immediately */
|
||||
if (min == max) {
|
||||
return min;
|
||||
}
|
||||
|
||||
/* 16-bit arithmetic below fails in this extreme case; we can optimise it */
|
||||
if (max - min == 0xFFFF) {
|
||||
return randLIB_get_16bit();
|
||||
}
|
||||
|
||||
unsigned int values_needed = max + 1 - min;
|
||||
unsigned int band_size = 0x10000u / values_needed;
|
||||
unsigned int top_of_bands = band_size * values_needed;
|
||||
unsigned int result;
|
||||
do {
|
||||
result = randLIB_get_16bit();
|
||||
} while (result >= top_of_bands);
|
||||
|
||||
return min + (uint16_t)(result / band_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Randomise a base 32-bit number by a jitter factor
|
||||
*
|
||||
* The result is linearly distributed in the jitter range, which is expressed
|
||||
* as fixed-point unsigned 1.15 values. For example, to produce a number in the
|
||||
* range [0.75 * base, 1.25 * base], set min_factor to 0x6000 and max_factor to
|
||||
* 0xA000.
|
||||
*
|
||||
* Result is clamped to 0xFFFFFFFF if it overflows.
|
||||
*
|
||||
* \param base The base 32-bit value
|
||||
* \param min_factor The minimum value for the random factor
|
||||
* \param max_factor The maximum value for the random factor
|
||||
*/
|
||||
uint32_t randLIB_randomise_base(uint32_t base, uint16_t min_factor, uint16_t max_factor)
|
||||
{
|
||||
uint16_t random_factor = randLIB_get_random_in_range(min_factor, max_factor);
|
||||
|
||||
/* 32x16-bit long multiplication, to get 48-bit result */
|
||||
uint32_t hi = (base >> 16) * random_factor;
|
||||
uint32_t lo = (base & 0xFFFF) * random_factor;
|
||||
/* Add halves, and take top 32 bits of 48-bit result */
|
||||
uint32_t res = hi + (lo >> 16);
|
||||
|
||||
/* Randomisation factor is *2^15, so need to shift up 1 more bit, avoiding overflow */
|
||||
if (res & 0x80000000) {
|
||||
res = 0xFFFFFFFF;
|
||||
} else {
|
||||
res = (res << 1) | ((lo >> 15) & 1);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
|
@ -25,6 +25,10 @@ extern "C" {
|
|||
extern void arm_random_module_init(void);
|
||||
/**
|
||||
* \brief Get random library seed value.
|
||||
*
|
||||
* This function should return as random a value as possible, using
|
||||
* hardware sources. Repeated calls should return different values if
|
||||
* at all possible.
|
||||
*/
|
||||
extern uint32_t arm_random_seed_get(void);
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -48,11 +48,23 @@ extern "C" {
|
|||
/**
|
||||
* \brief Init seed for Pseudo Random.
|
||||
*
|
||||
* Makes call(s) to the platform's arm_random_seed_get() to seed the
|
||||
* pseudo-random generator.
|
||||
*
|
||||
* \return None
|
||||
*
|
||||
*/
|
||||
extern void randLIB_seed_random(void);
|
||||
|
||||
/**
|
||||
* \brief Update seed for pseudo-random generator
|
||||
*
|
||||
* Adds seed information to existing generator, to perturb the
|
||||
* sequence.
|
||||
* \param seed 64 bits of data to add to the seed.
|
||||
*/
|
||||
extern void randLIB_add_seed(uint64_t seed);
|
||||
|
||||
/**
|
||||
* \brief Generate 8-bit random number.
|
||||
*
|
||||
|
@ -75,21 +87,29 @@ extern uint16_t randLIB_get_16bit(void);
|
|||
* \brief Generate 32-bit random number.
|
||||
*
|
||||
* \param None
|
||||
* \return 16-bit random number
|
||||
* \return 32-bit random number
|
||||
*
|
||||
*/
|
||||
extern uint32_t randLIB_get_32bit(void);
|
||||
|
||||
/**
|
||||
* \brief Generate 64-bit random number.
|
||||
*
|
||||
* \param None
|
||||
* \return 64-bit random number
|
||||
*
|
||||
*/
|
||||
extern uint64_t randLIB_get_64bit(void);
|
||||
|
||||
/**
|
||||
* \brief Generate n-bytes random numbers.
|
||||
*
|
||||
* \param data_ptr pointer where random will be stored
|
||||
* \param eight_bit_boundary how many bytes need random
|
||||
* \return 0 process valid
|
||||
* \return -1 Unsupported Parameters
|
||||
* \param count how many bytes need random
|
||||
*
|
||||
* \return data_ptr
|
||||
*/
|
||||
extern int8_t randLIB_get_n_bytes_random(uint8_t *data_ptr, uint8_t eight_bit_boundary);
|
||||
extern void *randLIB_get_n_bytes_random(void *data_ptr, uint8_t count);
|
||||
|
||||
/**
|
||||
* \brief Generate a random number within a range.
|
||||
|
@ -117,6 +137,12 @@ uint16_t randLIB_get_random_in_range(uint16_t min, uint16_t max);
|
|||
*/
|
||||
uint32_t randLIB_randomise_base(uint32_t base, uint16_t min_factor, uint16_t max_factor);
|
||||
|
||||
#ifdef RANDLIB_PRNG
|
||||
/* \internal Reset the PRNG state to zero (invalid) */
|
||||
void randLIB_reset(void);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "nanostack-randlib",
|
||||
"version": "1.1.0",
|
||||
"version": "1.2.0",
|
||||
"description": "Pseudo random library used by mbed-client and 6LoWPAN stack.",
|
||||
"keywords": [],
|
||||
"homepage": "https://github.com/ARMmbed/mbed-client-randlib",
|
||||
|
|
|
@ -14,125 +14,175 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <limits.h>
|
||||
#include "randLIB.h"
|
||||
#include "platform/arm_hal_random.h"
|
||||
|
||||
#if ((RAND_MAX+1) & RAND_MAX) != 0
|
||||
#error "RAND_MAX isn't 2^n-1 :("
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This library is made for getting random numbers for Timing needs in protocols.
|
||||
* This library is made for getting random numbers for timing needs in
|
||||
* protocols, plus to generate dynamic ports, random IDs etc.
|
||||
*
|
||||
* **not safe to use for security or cryptographic operations.**
|
||||
*
|
||||
* Base implementation is a pseudo-RNG, but may also use a system RNG.
|
||||
* Replay of sequence by reseeding is not possible.
|
||||
*
|
||||
* Base pseudo-RNG is the xoroshiro128+ generator by Marsaglia, Blackman and
|
||||
* Vigna:
|
||||
*
|
||||
* http://xoroshiro.di.unimi.it/
|
||||
*
|
||||
* Certainly not the fastest for 32-bit or smaller platforms, but speed
|
||||
* is not critical. None of the long operations in the core are actually hard,
|
||||
* unlike the divisions and multiplies in the utility functions below, where we
|
||||
* do try to keep the operations narrow.
|
||||
*/
|
||||
|
||||
/* On some platforms, read from a system RNG, rather than use our own */
|
||||
/* RANDLIB_PRNG disables this and forces use of the PRNG (useful for test only?) */
|
||||
#ifndef RANDLIB_PRNG
|
||||
#ifdef __linux
|
||||
#define RANDOM_DEVICE "/dev/urandom"
|
||||
#endif
|
||||
#endif // RANDLIB_PRNG
|
||||
|
||||
/**
|
||||
* \brief Init seed for Pseudo Random.
|
||||
*
|
||||
* \return None
|
||||
*
|
||||
/* RAM usage - 16 bytes of state (or a FILE * pointer and underlying FILE, which
|
||||
* will include a buffer) */
|
||||
#ifdef RANDOM_DEVICE
|
||||
#include <stdio.h>
|
||||
static FILE *random_file;
|
||||
#else
|
||||
static uint64_t state[2];
|
||||
#endif
|
||||
|
||||
#ifdef RANDLIB_PRNG
|
||||
void randLIB_reset(void)
|
||||
{
|
||||
state[0] = 0;
|
||||
state[1] = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef RANDOM_DEVICE
|
||||
static inline uint64_t rol(uint64_t n, int bits)
|
||||
{
|
||||
return (n << bits) | (n >> (64 - bits));
|
||||
}
|
||||
|
||||
/* Lower-quality generator used only for initial seeding, if platform
|
||||
* isn't returning multiple seeds itself. Multiplies are rather heavy
|
||||
* for lower-end platforms, but this is initialisation only.
|
||||
*/
|
||||
static uint64_t splitmix64(uint64_t *seed)
|
||||
{
|
||||
uint64_t z = (*seed += UINT64_C(0x9E3779B97F4A7C15));
|
||||
z = (z ^ (z >> 30)) * UINT64_C(0xBF58476D1CE4E5B9);
|
||||
z = (z ^ (z >> 27)) * UINT64_C(0x94D049BB133111EB);
|
||||
return z ^ (z >> 31);
|
||||
}
|
||||
#endif // RANDOM_DEVICE
|
||||
|
||||
void randLIB_seed_random(void)
|
||||
{
|
||||
uint32_t rand_seed;
|
||||
#ifdef RANDOM_DEVICE
|
||||
if (!random_file) {
|
||||
random_file = fopen(RANDOM_DEVICE, "rb");
|
||||
}
|
||||
#else
|
||||
arm_random_module_init();
|
||||
rand_seed = arm_random_seed_get();
|
||||
srand(rand_seed);
|
||||
|
||||
/* We exclusive-OR with the current state, in case they make this call
|
||||
* multiple times,or in case someone has called randLIB_add_seed before
|
||||
* this. We don't want to potentially lose entropy.
|
||||
*/
|
||||
|
||||
/* Spell out expressions so we get known ordering of 4 seed calls */
|
||||
uint64_t s = (uint64_t) arm_random_seed_get() << 32;
|
||||
state[0] ^= ( s | arm_random_seed_get());
|
||||
|
||||
s = (uint64_t) arm_random_seed_get() << 32;
|
||||
state[1] ^= s | arm_random_seed_get();
|
||||
|
||||
/* This check serves to both to stir the state if the platform is returning
|
||||
* constant seeding values, and to avoid the illegal all-zero state.
|
||||
*/
|
||||
if (state[0] == state[1]) {
|
||||
randLIB_add_seed(state[0]);
|
||||
}
|
||||
#endif // RANDOM_DEVICE
|
||||
}
|
||||
|
||||
void randLIB_add_seed(uint64_t seed)
|
||||
{
|
||||
#ifndef RANDOM_DEVICE
|
||||
state[0] ^= splitmix64(&seed);
|
||||
state[1] ^= splitmix64(&seed);
|
||||
/* This is absolutely necessary, but I challenge you to add it to line coverage */
|
||||
if (state[1] == 0 && state[0] == 0) {
|
||||
state[0] = 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Generate 8-bit random number.
|
||||
*
|
||||
* \param None
|
||||
* \return 8-bit random number
|
||||
*
|
||||
*/
|
||||
uint8_t randLIB_get_8bit(void)
|
||||
{
|
||||
return rand();
|
||||
uint64_t r = randLIB_get_64bit();
|
||||
return (uint8_t) (r >> 56);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Generate 16-bit random number.
|
||||
*
|
||||
* \param None
|
||||
* \return 16-bit random number
|
||||
*
|
||||
*/
|
||||
uint16_t randLIB_get_16bit(void)
|
||||
{
|
||||
uint16_t ret_val;
|
||||
|
||||
ret_val = rand();
|
||||
#if RAND_MAX == 0x7FFF
|
||||
ret_val |= (uint16_t) rand() << 15;
|
||||
#endif
|
||||
|
||||
return ret_val;
|
||||
uint64_t r = randLIB_get_64bit();
|
||||
return (uint16_t) (r >> 48);
|
||||
}
|
||||
/**
|
||||
* \brief Generate 32-bit random number.
|
||||
*
|
||||
* \param None
|
||||
* \return 32-bit random number
|
||||
*
|
||||
*/
|
||||
|
||||
uint32_t randLIB_get_32bit(void)
|
||||
{
|
||||
uint32_t ret_val;
|
||||
|
||||
ret_val = rand();
|
||||
#if RAND_MAX == 0x7FFF
|
||||
ret_val |= (uint32_t) rand() << 15;
|
||||
ret_val |= (uint32_t) rand() << 30;
|
||||
#elif RAND_MAX == 0x3FFFFFFF /* IAR */
|
||||
ret_val |= (uint32_t) rand() << 30;
|
||||
#elif RAND_MAX == 0x7FFFFFFF
|
||||
ret_val |= (uint32_t) rand() << 31;
|
||||
#else
|
||||
#error "randLIB_get_32bit - odd RAND_MAX"
|
||||
#endif
|
||||
|
||||
return ret_val;
|
||||
uint64_t r = randLIB_get_64bit();
|
||||
return (uint32_t) (r >> 32);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Generate n-bytes random numbers.
|
||||
*
|
||||
* \param data_ptr pointer where random will be stored
|
||||
* \param eight_bit_boundary how many bytes need random
|
||||
* \return 0 process valid
|
||||
* \return -1 Unsupported Parameters
|
||||
*
|
||||
*/
|
||||
int8_t randLIB_get_n_bytes_random(uint8_t *data_ptr, uint8_t eight_bit_boundary)
|
||||
uint64_t randLIB_get_64bit(void)
|
||||
{
|
||||
if ((data_ptr == 0) || (eight_bit_boundary == 0)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (eight_bit_boundary) {
|
||||
*data_ptr++ = randLIB_get_8bit();
|
||||
eight_bit_boundary--;
|
||||
}
|
||||
#ifdef RANDOM_DEVICE
|
||||
if (!random_file) {
|
||||
return 0;
|
||||
}
|
||||
uint64_t result;
|
||||
if (fread(&result, sizeof result, 1, random_file) != 1) {
|
||||
result = 0;
|
||||
}
|
||||
return result;
|
||||
#else
|
||||
const uint64_t s0 = state[0];
|
||||
uint64_t s1 = state[1];
|
||||
const uint64_t result = s0 + s1;
|
||||
|
||||
s1 ^= s0;
|
||||
state[0] = rol(s0, 55) ^ s1 ^ (s1 << 14);
|
||||
state[1] = rol(s1, 36);
|
||||
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
void *randLIB_get_n_bytes_random(void *ptr, uint8_t count)
|
||||
{
|
||||
uint8_t *data_ptr = ptr;
|
||||
uint64_t r = 0;
|
||||
for (uint_fast8_t i = 0; i < count; i++) {
|
||||
/* Take 8 bytes at a time */
|
||||
if (i % 8 == 0) {
|
||||
r = randLIB_get_64bit();
|
||||
} else {
|
||||
r >>= 8;
|
||||
}
|
||||
data_ptr[i] = (uint8_t) r;
|
||||
}
|
||||
return data_ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Generate a random number within a range.
|
||||
*
|
||||
* The result is linearly distributed in the range [min..max], inclusive.
|
||||
*
|
||||
* \param min minimum value that can be generated
|
||||
* \param max maximum value that can be generated
|
||||
*/
|
||||
uint16_t randLIB_get_random_in_range(uint16_t min, uint16_t max)
|
||||
{
|
||||
/* This special case is potentially common, particularly in this routine's
|
||||
|
@ -141,46 +191,52 @@ uint16_t randLIB_get_random_in_range(uint16_t min, uint16_t max)
|
|||
return min;
|
||||
}
|
||||
|
||||
#if UINT_MAX >= 0xFFFFFFFF
|
||||
const unsigned int rand_max = 0xFFFFFFFFu; // will use rand32
|
||||
#else
|
||||
const unsigned int rand_max = 0xFFFFu; // will use rand16
|
||||
|
||||
/* 16-bit arithmetic below fails in this extreme case; we can optimise it */
|
||||
if (max - min == 0xFFFF) {
|
||||
return randLIB_get_16bit();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* We get RAND_MAX+1 values from rand() in the range [0..RAND_MAX], and
|
||||
/* We get rand_max values from rand16 or 32() in the range [0..rand_max-1], and
|
||||
* need to divvy them up into the number of values we need. And reroll any
|
||||
* odd values off the end as we insist every value having equal chance.
|
||||
*
|
||||
* Special handling for systems where RAND_MAX is 0x7FFF; we use our
|
||||
* randLIB_get_16bit() and have to be a bit more careful about
|
||||
* unsigned integer overflow. (On other systems rand() returns int,
|
||||
* so we can't overflow if we use unsigned int).
|
||||
* Using the range [0..rand_max-1] saves long division on the band
|
||||
* calculation - it means rand_max ends up always being rerolled.
|
||||
*
|
||||
* Eg, range(1,3), RAND_MAX = 0x7FFFFFFF:
|
||||
* We have 3 bands of size 0x2AAAAAAA (0x80000000/3).
|
||||
* Eg, range(1,2), rand_max = 0xFFFF:
|
||||
* We have 2 bands of size 0x7FFF (0xFFFF/2).
|
||||
*
|
||||
* We roll: 0x00000000..0x2AAAAAAA9 -> 1
|
||||
* 0x2AAAAAAA..0x555555553 -> 2
|
||||
* 0x55555554..0x7FFFFFFFD -> 3
|
||||
* 0x7FFFFFFE..0x7FFFFFFFF -> reroll
|
||||
* We roll: 0x0000..0x7FFE -> 1
|
||||
* 0x7FFF..0xFFFD -> 2
|
||||
* 0xFFFE..0xFFFF -> reroll
|
||||
* (calculating band size as 0x10000/2 would have avoided the reroll cases)
|
||||
*
|
||||
* Eg, range(1,3), rand_max = 0xFFFFFFFF:
|
||||
* We have 3 bands of size 0x55555555 (0xFFFFFFFF/3).
|
||||
*
|
||||
* We roll: 0x00000000..0x555555554 -> 1
|
||||
* 0x55555555..0xAAAAAAAA9 -> 2
|
||||
* 0xAAAAAAAA..0xFFFFFFFFE -> 3
|
||||
* 0xFFFFFFFF -> reroll
|
||||
*
|
||||
* (Bias problem clearly pretty insignificant there, but gets worse as
|
||||
* range increases).
|
||||
*/
|
||||
unsigned int values_needed = max + 1 - min;
|
||||
#if RAND_MAX > 0xFFFF
|
||||
unsigned int band_size = (RAND_MAX + 1u) / values_needed;
|
||||
#elif UINT_MAX > 0xFFFF
|
||||
unsigned int band_size = 0x10000u / values_needed;
|
||||
#else
|
||||
const unsigned int values_needed = max + 1 - min;
|
||||
/* Avoid the need for long division, at the expense of fractionally
|
||||
* increasing reroll chance. */
|
||||
unsigned int band_size = 0xFFFFu / values_needed;
|
||||
#endif
|
||||
unsigned int top_of_bands = band_size * values_needed;
|
||||
const unsigned int band_size = rand_max / values_needed;
|
||||
const unsigned int top_of_bands = band_size * values_needed;
|
||||
unsigned int result;
|
||||
do {
|
||||
#if RAND_MAX > 0xFFFF
|
||||
result = rand();
|
||||
#if UINT_MAX > 0xFFFF
|
||||
result = randLIB_get_32bit();
|
||||
#else
|
||||
result = randLIB_get_16bit();
|
||||
#endif
|
||||
|
@ -189,20 +245,6 @@ uint16_t randLIB_get_random_in_range(uint16_t min, uint16_t max)
|
|||
return min + (uint16_t)(result / band_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Randomise a base 32-bit number by a jitter factor
|
||||
*
|
||||
* The result is linearly distributed in the jitter range, which is expressed
|
||||
* as fixed-point unsigned 1.15 values. For example, to produce a number in the
|
||||
* range [0.75 * base, 1.25 * base], set min_factor to 0x6000 and max_factor to
|
||||
* 0xA000.
|
||||
*
|
||||
* Result is clamped to 0xFFFFFFFF if it overflows.
|
||||
*
|
||||
* \param base The base 32-bit value
|
||||
* \param min_factor The minimum value for the random factor
|
||||
* \param max_factor The maximum value for the random factor
|
||||
*/
|
||||
uint32_t randLIB_randomise_base(uint32_t base, uint16_t min_factor, uint16_t max_factor)
|
||||
{
|
||||
uint16_t random_factor = randLIB_get_random_in_range(min_factor, max_factor);
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
#scan for folders having "Makefile" in them and remove 'this' to prevent loop
|
||||
ifeq ($(OS),Windows_NT)
|
||||
all:
|
||||
clean:
|
||||
else
|
||||
DIRS := $(filter-out ./, $(sort $(dir $(shell find . -name 'Makefile'))))
|
||||
|
||||
all:
|
||||
for dir in $(DIRS); do \
|
||||
cd $$dir; make gcov; cd ..;\
|
||||
done
|
||||
|
||||
clean:
|
||||
for dir in $(DIRS); do \
|
||||
cd $$dir; make clean; cd ..;\
|
||||
done
|
||||
rm -rf ../source/*gcov ../source/*gcda ../source/*o
|
||||
rm -rf stubs/*gcov stubs/*gcda stubs/*o
|
||||
rm -rf results/*
|
||||
rm -rf coverages/*
|
||||
rm -rf results
|
||||
rm -rf coverages
|
||||
endif
|
|
@ -0,0 +1,18 @@
|
|||
include ../makefile_defines.txt
|
||||
|
||||
COMPONENT_NAME = randLIB_unit
|
||||
|
||||
#This must be changed manually
|
||||
SRC_FILES = \
|
||||
../../../../source/randLIB.c
|
||||
|
||||
TEST_SRC_FILES = \
|
||||
main.cpp \
|
||||
randlibtest.cpp \
|
||||
test_randlib.c \
|
||||
../stubs/random_stub.c \
|
||||
|
||||
include ../MakefileWorker.mk
|
||||
|
||||
CPPUTESTFLAGS += -DFEA_TRACE_SUPPORT -DRANDLIB_PRNG
|
||||
|
|
@ -35,6 +35,11 @@ TEST(randLIB, test_randLIB_get_32bit)
|
|||
CHECK(test_randLIB_get_32bit());
|
||||
}
|
||||
|
||||
TEST(randLIB, test_randLIB_get_64bit)
|
||||
{
|
||||
CHECK(test_randLIB_get_64bit());
|
||||
}
|
||||
|
||||
TEST(randLIB, test_randLIB_get_n_bytes_random)
|
||||
{
|
||||
CHECK(test_randLIB_get_n_bytes_random());
|
||||
|
|
|
@ -8,12 +8,14 @@
|
|||
|
||||
bool test_randLIB_seed_random()
|
||||
{
|
||||
randLIB_reset();
|
||||
randLIB_seed_random();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_randLIB_get_8bit()
|
||||
{
|
||||
randLIB_reset();
|
||||
randLIB_seed_random();
|
||||
uint8_t test = randLIB_get_8bit();
|
||||
if( test == 0 ) {
|
||||
|
@ -27,6 +29,7 @@ bool test_randLIB_get_8bit()
|
|||
|
||||
bool test_randLIB_get_16bit()
|
||||
{
|
||||
randLIB_reset();
|
||||
randLIB_seed_random();
|
||||
uint16_t test = randLIB_get_16bit();
|
||||
if( test == 0 ) {
|
||||
|
@ -40,6 +43,7 @@ bool test_randLIB_get_16bit()
|
|||
|
||||
bool test_randLIB_get_32bit()
|
||||
{
|
||||
randLIB_reset();
|
||||
randLIB_seed_random();
|
||||
uint32_t test = randLIB_get_32bit();
|
||||
if( test == 0 ) {
|
||||
|
@ -51,23 +55,114 @@ bool test_randLIB_get_32bit()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool test_randLIB_get_n_bytes_random()
|
||||
static bool test_output(uint32_t seed, bool seed_inc, const uint64_t expected[8])
|
||||
{
|
||||
int8_t ret = randLIB_get_n_bytes_random(NULL, 0);
|
||||
if( ret != -1){
|
||||
random_stub_set_seed(seed, seed_inc);
|
||||
randLIB_reset();
|
||||
randLIB_seed_random();
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (randLIB_get_64bit() != expected[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_randLIB_get_64bit()
|
||||
{
|
||||
/* Initial 8 xoroshiro128+ values with initial seed of
|
||||
* (0x0000000100000002, 0x00000003000000004).
|
||||
*/
|
||||
static const uint64_t expected1234[] = {
|
||||
UINT64_C(0x0000000400000006),
|
||||
UINT64_C(0x0100806200818026),
|
||||
UINT64_C(0x2a30826271904706),
|
||||
UINT64_C(0x918d7ea50109290d),
|
||||
UINT64_C(0x5dcbd701c1e1c64c),
|
||||
UINT64_C(0xaa129b152055f299),
|
||||
UINT64_C(0x4c95c2b1e1038a4d),
|
||||
UINT64_C(0x6479e7a3a75d865a)
|
||||
};
|
||||
|
||||
if (!test_output(1, true, expected1234)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* If passed all zero seeds, seeding should detect this
|
||||
* and use splitmix64 to create the actual seed
|
||||
* (0xe220a8397b1dcdaf, 0x6e789e6aa1b965f4),
|
||||
* and produce this output:
|
||||
*/
|
||||
static const uint64_t expected0000[] = {
|
||||
UINT64_C(0x509946a41cd733a3),
|
||||
UINT64_C(0x00885667b1934bfa),
|
||||
UINT64_C(0x1061f9ad258fd5d5),
|
||||
UINT64_C(0x3f8be44897a4317c),
|
||||
UINT64_C(0x60da683bea50e6ab),
|
||||
UINT64_C(0xd6b52f5379de1de0),
|
||||
UINT64_C(0x2608bc9fedc5b750),
|
||||
UINT64_C(0xb9fac9c7ec9de02a)
|
||||
};
|
||||
|
||||
if (!test_output(0, false, expected0000)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* If passed all "4" seeds, seeding should detect this
|
||||
* and use splitmix64 to create the actual seed
|
||||
* (0x03910b0eab9b37e1, 0x0b309ab53d42b2a2),
|
||||
* and produce this output:
|
||||
*/
|
||||
static const uint64_t expected4444[] = {
|
||||
UINT64_C(0x0ec1a5c3e8ddea83),
|
||||
UINT64_C(0x09e710b8faf5a491),
|
||||
UINT64_C(0xd4102776f79448b4),
|
||||
UINT64_C(0x5d61988b60091900),
|
||||
UINT64_C(0xf6c8a72a9c72cb4b),
|
||||
UINT64_C(0xb06923e0cf0f2fb1),
|
||||
UINT64_C(0x24bbed475153f573),
|
||||
UINT64_C(0xfff0b4bd08c5581f),
|
||||
};
|
||||
|
||||
if (!test_output(4, false, expected4444)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Last test used constant seed of 4, which is the default */
|
||||
return true;
|
||||
|
||||
fail:
|
||||
/* Put back the default seed of 4 (other tests might rely on it) */
|
||||
random_stub_set_seed(4, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool test_randLIB_get_n_bytes_random()
|
||||
{
|
||||
randLIB_reset();
|
||||
randLIB_seed_random();
|
||||
|
||||
uint8_t dat[5];
|
||||
ret = randLIB_get_n_bytes_random(&dat, 5);
|
||||
if( ret != 0){
|
||||
void *ret = randLIB_get_n_bytes_random(dat, 5);
|
||||
if(ret != dat){
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t dat2[5];
|
||||
randLIB_get_n_bytes_random(dat2, 5);
|
||||
if (memcmp(dat, dat2, 5) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_randLIB_get_random_in_range()
|
||||
{
|
||||
randLIB_reset();
|
||||
randLIB_seed_random();
|
||||
|
||||
uint16_t ret = randLIB_get_random_in_range(2, 2);
|
||||
if( ret != 2 ){
|
||||
return false;
|
||||
|
@ -85,6 +180,9 @@ bool test_randLIB_get_random_in_range()
|
|||
|
||||
bool test_randLIB_randomise_base()
|
||||
{
|
||||
randLIB_reset();
|
||||
randLIB_seed_random();
|
||||
|
||||
uint32_t ret = randLIB_randomise_base(0,0,0);
|
||||
if( ret ){
|
||||
return false;
|
||||
|
|
|
@ -18,6 +18,8 @@ bool test_randLIB_get_16bit();
|
|||
|
||||
bool test_randLIB_get_32bit();
|
||||
|
||||
bool test_randLIB_get_64bit();
|
||||
|
||||
bool test_randLIB_get_n_bytes_random();
|
||||
|
||||
bool test_randLIB_get_random_in_range();
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015 ARM. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "CppUTest/CommandLineTestRunner.h"
|
||||
#include "CppUTest/TestPlugin.h"
|
||||
#include "CppUTest/TestRegistry.h"
|
||||
#include "CppUTestExt/MockSupportPlugin.h"
|
||||
int main(int ac, char** av)
|
||||
{
|
||||
return CommandLineTestRunner::RunAllTests(ac, av);
|
||||
}
|
||||
|
||||
IMPORT_TEST_GROUP(randLIB_linux);
|
|
@ -1,69 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016 ARM. All rights reserved.
|
||||
*/
|
||||
#include "CppUTest/TestHarness.h"
|
||||
#include "../randlib/test_randlib.h"
|
||||
#include "randLIB.h"
|
||||
|
||||
TEST_GROUP(randLIB_linux)
|
||||
{
|
||||
void setup()
|
||||
{
|
||||
}
|
||||
|
||||
void teardown()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
extern bool allow_open;
|
||||
|
||||
TEST(randLIB_linux, test_randLIB_seed_random)
|
||||
{
|
||||
allow_open = true;
|
||||
CHECK(test_randLIB_seed_random());
|
||||
}
|
||||
|
||||
TEST(randLIB_linux, test_randLIB_get_8bit)
|
||||
{
|
||||
allow_open = true;
|
||||
CHECK(test_randLIB_get_8bit());
|
||||
}
|
||||
|
||||
TEST(randLIB_linux, test_randLIB_get_16bit)
|
||||
{
|
||||
allow_open = true;
|
||||
CHECK(test_randLIB_get_16bit());
|
||||
}
|
||||
|
||||
TEST(randLIB_linux, test_randLIB_get_32bit)
|
||||
{
|
||||
allow_open = true;
|
||||
CHECK(test_randLIB_get_32bit());
|
||||
}
|
||||
|
||||
TEST(randLIB_linux, test_randLIB_get_n_bytes_random)
|
||||
{
|
||||
allow_open = true;
|
||||
CHECK(test_randLIB_get_n_bytes_random());
|
||||
}
|
||||
|
||||
TEST(randLIB_linux, test_randLIB_get_random_in_range)
|
||||
{
|
||||
allow_open = true;
|
||||
CHECK(test_randLIB_get_random_in_range());
|
||||
}
|
||||
|
||||
TEST(randLIB_linux, test_randLIB_randomise_base)
|
||||
{
|
||||
allow_open = true;
|
||||
CHECK(test_randLIB_randomise_base());
|
||||
}
|
||||
|
||||
TEST(randLIB_linux, test_fail_to_open)
|
||||
{
|
||||
uint8_t buf[4];
|
||||
allow_open = false;
|
||||
CHECK(-1 == randLIB_get_n_bytes_random(buf, 4));
|
||||
allow_open = true;
|
||||
}
|
0
features/FEATURE_COMMON_PAL/mbed-client-randlib/test/mbed-client-randlib/unittest/run_tests
Normal file → Executable file
0
features/FEATURE_COMMON_PAL/mbed-client-randlib/test/mbed-client-randlib/unittest/run_tests
Normal file → Executable file
|
@ -1,8 +1,10 @@
|
|||
/*
|
||||
* Copyright (c) 2016, ARM Limited, All Rights Reserved
|
||||
*/
|
||||
#include "inttypes.h"
|
||||
#include "random_stub.h"
|
||||
|
||||
static uint32_t seed_value = 4;
|
||||
static bool seed_inc = false;
|
||||
|
||||
void arm_random_module_init(void)
|
||||
{
|
||||
|
@ -11,5 +13,15 @@ void arm_random_module_init(void)
|
|||
|
||||
uint32_t arm_random_seed_get(void)
|
||||
{
|
||||
return 4;
|
||||
uint32_t result = seed_value;
|
||||
if (seed_inc) {
|
||||
++seed_value;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void random_stub_set_seed(uint32_t value, bool increment)
|
||||
{
|
||||
seed_value = value;
|
||||
seed_inc = increment;
|
||||
}
|
||||
|
|
BIN
features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_lowpan_border_router.ar
Normal file → Executable file
BIN
features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_lowpan_border_router.ar
Normal file → Executable file
Binary file not shown.
BIN
features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_M3/libnanostack_armcc_Cortex-M3_lowpan_border_router.ar
Normal file → Executable file
BIN
features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_M3/libnanostack_armcc_Cortex-M3_lowpan_border_router.ar
Normal file → Executable file
Binary file not shown.
BIN
features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_lowpan_border_router.ar
Normal file → Executable file
BIN
features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_lowpan_border_router.ar
Normal file → Executable file
Binary file not shown.
Binary file not shown.
BIN
features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_border_router.a
Normal file → Executable file
BIN
features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_border_router.a
Normal file → Executable file
Binary file not shown.
Binary file not shown.
BIN
features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_lowpan_border_router.a
Normal file → Executable file
BIN
features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_lowpan_border_router.a
Normal file → Executable file
Binary file not shown.
BIN
features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_M3/libnanostack_iccarm_Cortex-M3_lowpan_border_router.a
Normal file → Executable file
BIN
features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_M3/libnanostack_iccarm_Cortex-M3_lowpan_border_router.a
Normal file → Executable file
Binary file not shown.
BIN
features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_lowpan_border_router.a
Normal file → Executable file
BIN
features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_lowpan_border_router.a
Normal file → Executable file
Binary file not shown.
BIN
features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_lowpan_host.ar
Normal file → Executable file
BIN
features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_lowpan_host.ar
Normal file → Executable file
Binary file not shown.
BIN
features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_ARM/TARGET_M3/libnanostack_armcc_Cortex-M3_lowpan_host.ar
Normal file → Executable file
BIN
features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_ARM/TARGET_M3/libnanostack_armcc_Cortex-M3_lowpan_host.ar
Normal file → Executable file
Binary file not shown.
BIN
features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_lowpan_host.ar
Normal file → Executable file
BIN
features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_lowpan_host.ar
Normal file → Executable file
Binary file not shown.
BIN
features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_lowpan_host.a
Normal file → Executable file
BIN
features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_lowpan_host.a
Normal file → Executable file
Binary file not shown.
BIN
features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_GCC/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_host.a
Normal file → Executable file
BIN
features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_GCC/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_host.a
Normal file → Executable file
Binary file not shown.
BIN
features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_host.a
Normal file → Executable file
BIN
features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_host.a
Normal file → Executable file
Binary file not shown.
BIN
features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_lowpan_host.a
Normal file → Executable file
BIN
features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_lowpan_host.a
Normal file → Executable file
Binary file not shown.
BIN
features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_IAR/TARGET_M3/libnanostack_iccarm_Cortex-M3_lowpan_host.a
Normal file → Executable file
BIN
features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_IAR/TARGET_M3/libnanostack_iccarm_Cortex-M3_lowpan_host.a
Normal file → Executable file
Binary file not shown.
BIN
features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_lowpan_host.a
Normal file → Executable file
BIN
features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_lowpan_host.a
Normal file → Executable file
Binary file not shown.
BIN
features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_lowpan_router.ar
Normal file → Executable file
BIN
features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_lowpan_router.ar
Normal file → Executable file
Binary file not shown.
BIN
features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_ARM/TARGET_M3/libnanostack_armcc_Cortex-M3_lowpan_router.ar
Normal file → Executable file
BIN
features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_ARM/TARGET_M3/libnanostack_armcc_Cortex-M3_lowpan_router.ar
Normal file → Executable file
Binary file not shown.
BIN
features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_lowpan_router.ar
Normal file → Executable file
BIN
features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_lowpan_router.ar
Normal file → Executable file
Binary file not shown.
BIN
features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_lowpan_router.a
Normal file → Executable file
BIN
features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_lowpan_router.a
Normal file → Executable file
Binary file not shown.
BIN
features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_GCC/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_router.a
Normal file → Executable file
BIN
features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_GCC/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_router.a
Normal file → Executable file
Binary file not shown.
BIN
features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_router.a
Normal file → Executable file
BIN
features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_router.a
Normal file → Executable file
Binary file not shown.
BIN
features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_lowpan_router.a
Normal file → Executable file
BIN
features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_lowpan_router.a
Normal file → Executable file
Binary file not shown.
BIN
features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_IAR/TARGET_M3/libnanostack_iccarm_Cortex-M3_lowpan_router.a
Normal file → Executable file
BIN
features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_IAR/TARGET_M3/libnanostack_iccarm_Cortex-M3_lowpan_router.a
Normal file → Executable file
Binary file not shown.
BIN
features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_lowpan_router.a
Normal file → Executable file
BIN
features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_lowpan_router.a
Normal file → Executable file
Binary file not shown.
|
@ -28,23 +28,17 @@
|
|||
# * Same order. Each line should have maching pair in same index at other array
|
||||
REPOSITORIES=(
|
||||
git@github.com:ARMmbed/sal-stack-nanostack.git
|
||||
git@github.com:ARMmbed/coap-service.git
|
||||
)
|
||||
|
||||
DIRECTORIES=(
|
||||
sal-stack-nanostack
|
||||
coap-service
|
||||
)
|
||||
|
||||
# Exit immediately on fail, thread unset variables as error
|
||||
set -eu
|
||||
|
||||
# Count number of repositories
|
||||
# Count number of repositories (minus one)
|
||||
N=0
|
||||
for repo in ${REPOSITORIES[*]}; do
|
||||
let N=N+1
|
||||
done
|
||||
let N=N-1 # Substract one, because indexes start from 0
|
||||
|
||||
print_usage() {
|
||||
echo -e "Usage: $0 [clean | clone | export ]"
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
#
|
||||
# Makefile for combined CoAP Service library
|
||||
#
|
||||
|
||||
# Define compiler toolchain with CC or PLATFORM variables
|
||||
# Example (GCC toolchains, default $CC and $AR are used)
|
||||
# make
|
||||
#
|
||||
# OR (Cross-compile GCC toolchain)
|
||||
# make PLATFORM=arm-linux-gnueabi-
|
||||
#
|
||||
# OR (armcc/Keil)
|
||||
# make CC=armcc AR=ArmAR
|
||||
#
|
||||
# OR (IAR-ARM)
|
||||
# make CC=iccarm
|
||||
|
||||
#
|
||||
# External sources from libService
|
||||
#
|
||||
SERVLIB_DIR := ../libService
|
||||
override CFLAGS += -I$(SERVLIB_DIR)/libService/
|
||||
|
||||
NANOSTACK_DIR := ../nanostack
|
||||
override CFLAGS += -I$(NANOSTACK_DIR)/nanostack/
|
||||
|
||||
NSDLC_DIR := ../nsdl-c
|
||||
override CFLAGS += -I$(NSDLC_DIR)/nsdl-c
|
||||
|
||||
EVENTLOOP_DIR := ../event-loop
|
||||
override CFLAGS += -I$(EVENTLOOP_DIR)/nanostack-event-loop/
|
||||
|
||||
COAPSERVICE_DIR := ../coap-service
|
||||
override CFLAGS += -I$(COAPSERVICE_DIR)/coap-service/
|
||||
override CFLAGS += -I$(COAPSERVICE_DIR)/source/include/
|
||||
|
||||
LIB = libcoap-service.a
|
||||
|
||||
SRCS := \
|
||||
source/coap_connection_handler.c \
|
||||
source/coap_message_handler.c \
|
||||
source/coap_security_handler.c \
|
||||
source/coap_service_api.c \
|
||||
|
||||
override CFLAGS += -DVERSION='"$(VERSION)"'
|
||||
|
||||
include ../libService/toolchain_rules.mk
|
||||
|
||||
$(eval $(call generate_rules,$(LIB),$(SRCS)))
|
||||
|
||||
.PHONY: release
|
||||
release:
|
||||
7z a coap-service_$(VERSION).zip *.a *.lib include
|
||||
|
||||
.PHONY: deploy_to
|
||||
deploy_to: all
|
||||
tar --transform 's,^,coap-service/,' --append -f $(TO) *.a
|
|
@ -17,7 +17,5 @@ echo
|
|||
echo "Build coap service unit tests"
|
||||
echo
|
||||
|
||||
yt target x86-linux-native
|
||||
yt up
|
||||
make -f Makefile.test test
|
||||
make -f Makefile.test test clean
|
||||
|
|
|
@ -27,13 +27,12 @@ typedef struct internal_socket_s {
|
|||
uint32_t timeout_min;
|
||||
uint32_t timeout_max;
|
||||
|
||||
uint16_t listen_port;
|
||||
int8_t listen_socket;
|
||||
uint16_t listen_port; // 0 for ephemeral-port sockets
|
||||
|
||||
ns_address_t dest_addr;
|
||||
size_t data_len;
|
||||
int16_t data_len;
|
||||
uint8_t *data;
|
||||
|
||||
int8_t socket;
|
||||
bool real_socket;
|
||||
uint8_t usage_counter;
|
||||
bool is_secure;
|
||||
|
@ -64,6 +63,10 @@ typedef struct secure_session {
|
|||
coap_security_t *sec_handler; //owned
|
||||
internal_socket_t *parent; //not owned
|
||||
|
||||
ns_address_t remote_host;
|
||||
uint8_t local_address[16];
|
||||
// local port is fixed by socket
|
||||
|
||||
secure_timer_t timer;
|
||||
|
||||
session_state_t session_state;
|
||||
|
@ -72,8 +75,8 @@ typedef struct secure_session {
|
|||
} secure_session_t;
|
||||
|
||||
static NS_LIST_DEFINE(secure_session_list, secure_session_t, link);
|
||||
static int send_to_socket(int8_t socket_id, uint8_t *address_ptr, uint16_t port, const unsigned char *buf, size_t len);
|
||||
static int receive_from_socket(int8_t socket_id, unsigned char *buf, size_t len);
|
||||
static int secure_session_sendto(int8_t socket_id, void *handle, const void *buf, size_t len);
|
||||
static int secure_session_recvfrom(int8_t socket_id, unsigned char *buf, size_t len);
|
||||
static void start_timer(int8_t timer_id, uint32_t int_ms, uint32_t fin_ms);
|
||||
static int timer_status(int8_t timer_id);
|
||||
|
||||
|
@ -93,6 +96,7 @@ static void secure_session_delete(secure_session_t *this)
|
|||
{
|
||||
if (this) {
|
||||
ns_list_remove(&secure_session_list, this);
|
||||
transactions_delete_all(this->remote_host.address, this->remote_host.identifier);
|
||||
if( this->sec_handler ){
|
||||
coap_security_destroy(this->sec_handler);
|
||||
this->sec_handler = NULL;
|
||||
|
@ -107,7 +111,7 @@ static void secure_session_delete(secure_session_t *this)
|
|||
return;
|
||||
}
|
||||
|
||||
static secure_session_t *secure_session_create(internal_socket_t *parent, uint8_t *address_ptr, uint16_t port)
|
||||
static secure_session_t *secure_session_create(internal_socket_t *parent, const uint8_t *address_ptr, uint16_t port)
|
||||
{
|
||||
if(!address_ptr){
|
||||
return NULL;
|
||||
|
@ -146,9 +150,12 @@ static secure_session_t *secure_session_create(internal_socket_t *parent, uint8_
|
|||
timer_id++;
|
||||
}
|
||||
this->timer.id = timer_id;
|
||||
this->remote_host.type = ADDRESS_IPV6;
|
||||
memcpy(this->remote_host.address, address_ptr, 16);
|
||||
this->remote_host.identifier = port;
|
||||
|
||||
this->sec_handler = coap_security_create(parent->listen_socket, this->timer.id, address_ptr, port, ECJPAKE,
|
||||
&send_to_socket, &receive_from_socket, &start_timer, &timer_status);
|
||||
this->sec_handler = coap_security_create(parent->socket, this->timer.id, this, ECJPAKE,
|
||||
&secure_session_sendto, &secure_session_recvfrom, &start_timer, &timer_status);
|
||||
if( !this->sec_handler ){
|
||||
ns_dyn_mem_free(this);
|
||||
return NULL;
|
||||
|
@ -173,15 +180,14 @@ static void clear_secure_sessions(internal_socket_t *this){
|
|||
}
|
||||
}
|
||||
|
||||
static secure_session_t *secure_session_find(internal_socket_t *parent, uint8_t *address_ptr, uint16_t port)
|
||||
static secure_session_t *secure_session_find(internal_socket_t *parent, const uint8_t *address_ptr, uint16_t port)
|
||||
{
|
||||
secure_session_t *this = NULL;
|
||||
ns_list_foreach(secure_session_t, cur_ptr, &secure_session_list) {
|
||||
if( cur_ptr->sec_handler ){
|
||||
if (cur_ptr->parent == parent && cur_ptr->sec_handler->_remote_port == port &&
|
||||
memcmp(cur_ptr->sec_handler->_remote_address, address_ptr, 16) == 0) {
|
||||
if (cur_ptr->parent == parent && cur_ptr->remote_host.identifier == port &&
|
||||
memcmp(cur_ptr->remote_host.address, address_ptr, 16) == 0) {
|
||||
this = cur_ptr;
|
||||
// hack_save_remote_address(address_ptr, port);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -211,32 +217,36 @@ static internal_socket_t *int_socket_create(uint16_t listen_port, bool use_ephem
|
|||
this->listen_port = listen_port;
|
||||
this->real_socket = real_socket;
|
||||
this->bypass_link_sec = bypassSec;
|
||||
this->listen_socket = -1;
|
||||
this->socket = -1;
|
||||
if( real_socket ){
|
||||
if( use_ephemeral_port ){ //socket_api creates ephemeral port if the one provided is 0
|
||||
listen_port = 0;
|
||||
}
|
||||
if( !is_secure ){
|
||||
this->listen_socket = socket_open(SOCKET_UDP, listen_port, recv_sckt_msg);
|
||||
this->socket = socket_open(SOCKET_UDP, listen_port, recv_sckt_msg);
|
||||
}else{
|
||||
this->listen_socket = socket_open(SOCKET_UDP, listen_port, secure_recv_sckt_msg);
|
||||
#ifdef COAP_SECURITY_AVAILABLE
|
||||
this->socket = socket_open(SOCKET_UDP, listen_port, secure_recv_sckt_msg);
|
||||
#else
|
||||
tr_err("Secure CoAP unavailable - SSL library not configured, possibly due to lack of entropy source");
|
||||
#endif
|
||||
}
|
||||
// Socket create failed
|
||||
if(this->listen_socket < 0){
|
||||
if(this->socket < 0){
|
||||
ns_dyn_mem_free(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
socket_setsockopt(this->listen_socket, SOCKET_IPPROTO_IPV6, SOCKET_LINK_LAYER_SECURITY, &(const int8_t) {
|
||||
bypassSec ? 0 : 1
|
||||
}, sizeof(int8_t));
|
||||
socket_setsockopt(this->socket, SOCKET_IPPROTO_IPV6, SOCKET_LINK_LAYER_SECURITY, &(const int8_t) {bypassSec ? 0 : 1}, sizeof(int8_t));
|
||||
|
||||
// XXX API for this? May want to get clever to do recommended first query = 1 hop, retries = whole PAN
|
||||
socket_setsockopt(this->listen_socket, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_MULTICAST_HOPS, &(const int16_t) {
|
||||
16
|
||||
}, sizeof(int16_t));
|
||||
socket_setsockopt(this->socket, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_MULTICAST_HOPS, &(const int16_t) {16}, sizeof(int16_t));
|
||||
|
||||
// Set socket option to receive packet info
|
||||
socket_setsockopt(this->socket, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_RECVPKTINFO, &(const bool) {1}, sizeof(bool));
|
||||
|
||||
}else{
|
||||
this->listen_socket = -1;
|
||||
this->socket = -1;
|
||||
}
|
||||
|
||||
ns_list_add_to_start(&socket_list, this);
|
||||
|
@ -249,7 +259,7 @@ static void int_socket_delete(internal_socket_t *this)
|
|||
this->usage_counter--;
|
||||
if(this->usage_counter == 0){
|
||||
clear_secure_sessions(this);
|
||||
socket_free(this->listen_socket);
|
||||
socket_close(this->socket);
|
||||
ns_list_remove(&socket_list, this);
|
||||
if( this->data ){
|
||||
ns_dyn_mem_free(this->data);
|
||||
|
@ -267,7 +277,7 @@ static internal_socket_t *int_socket_find_by_socket_id(int8_t id)
|
|||
{
|
||||
internal_socket_t *this = NULL;
|
||||
ns_list_foreach(internal_socket_t, cur_ptr, &socket_list) {
|
||||
if( cur_ptr->listen_socket == id ) {
|
||||
if( cur_ptr->socket == id ) {
|
||||
this = cur_ptr;
|
||||
break;
|
||||
}
|
||||
|
@ -290,16 +300,55 @@ static internal_socket_t *int_socket_find(uint16_t port, bool is_secure, bool is
|
|||
return this;
|
||||
}
|
||||
|
||||
static int send_to_socket(int8_t socket_id, uint8_t *address_ptr, uint16_t port, const unsigned char *buf, size_t len)
|
||||
static int8_t send_to_real_socket(int8_t socket_id, const ns_address_t *address, const uint8_t source_address[static 16], const void *buffer, uint16_t length)
|
||||
{
|
||||
ns_iovec_t msg_iov;
|
||||
ns_msghdr_t msghdr;
|
||||
|
||||
msghdr.msg_name = (void*)address;
|
||||
msghdr.msg_namelen = sizeof(ns_address_t);
|
||||
msghdr.msg_iov = &msg_iov;
|
||||
msghdr.msg_iovlen = 1;
|
||||
msghdr.flags = 0;
|
||||
|
||||
if (memcmp(source_address, ns_in6addr_any, 16)) {
|
||||
uint8_t ancillary_databuffer[NS_CMSG_SPACE(sizeof(ns_in6_pktinfo_t))];
|
||||
ns_cmsghdr_t *cmsg;
|
||||
ns_in6_pktinfo_t *pktinfo;
|
||||
|
||||
tr_debug("send from source address %s", trace_array(source_address, 16));
|
||||
msghdr.msg_control = ancillary_databuffer;
|
||||
msghdr.msg_controllen = sizeof(ancillary_databuffer);
|
||||
|
||||
cmsg = NS_CMSG_FIRSTHDR(&msghdr);
|
||||
cmsg->cmsg_type = SOCKET_IPV6_PKTINFO;
|
||||
cmsg->cmsg_level = SOCKET_IPPROTO_IPV6;
|
||||
cmsg->cmsg_len = NS_CMSG_LEN(sizeof(ns_in6_pktinfo_t));
|
||||
|
||||
pktinfo = (ns_in6_pktinfo_t*)NS_CMSG_DATA(cmsg);
|
||||
pktinfo->ipi6_ifindex = 0;
|
||||
memcpy(pktinfo->ipi6_addr, source_address, 16);
|
||||
} else {
|
||||
msghdr.msg_control = NULL;
|
||||
msghdr.msg_controllen = 0;
|
||||
}
|
||||
|
||||
msg_iov.iov_base = (void *)buffer;
|
||||
msg_iov.iov_len = length;
|
||||
|
||||
return socket_sendmsg(socket_id, &msghdr, 0);
|
||||
}
|
||||
|
||||
static int secure_session_sendto(int8_t socket_id, void *handle, const void *buf, size_t len)
|
||||
{
|
||||
secure_session_t *session = handle;
|
||||
internal_socket_t *sock = int_socket_find_by_socket_id(socket_id);
|
||||
if(!sock){
|
||||
return -1;
|
||||
}
|
||||
if(!sock->real_socket){
|
||||
//In this case all clients will have socket_id -1 and socket will not have a real address
|
||||
//so sock->dest_addr cannot be used here
|
||||
int ret = sock->parent->_send_cb(sock->listen_socket, address_ptr, port, buf, len);
|
||||
// Send to virtual socket cb
|
||||
int ret = sock->parent->_send_cb(sock->socket, session->remote_host.address, session->remote_host.identifier, buf, len);
|
||||
if( ret < 0 )
|
||||
return ret;
|
||||
return len;
|
||||
|
@ -310,17 +359,19 @@ static int send_to_socket(int8_t socket_id, uint8_t *address_ptr, uint16_t port,
|
|||
if (sock->bypass_link_sec) {
|
||||
securityLinkLayer = 0;
|
||||
}
|
||||
socket_setsockopt(sock->listen_socket, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_ADDR_PREFERENCES, &opt_name, sizeof(int));
|
||||
socket_setsockopt(sock->listen_socket, SOCKET_IPPROTO_IPV6, SOCKET_LINK_LAYER_SECURITY, &securityLinkLayer, sizeof(int8_t));
|
||||
socket_setsockopt(sock->socket, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_ADDR_PREFERENCES, &opt_name, sizeof(int));
|
||||
socket_setsockopt(sock->socket, SOCKET_IPPROTO_IPV6, SOCKET_LINK_LAYER_SECURITY, &securityLinkLayer, sizeof(int8_t));
|
||||
//For some reason socket_sendto returns 0 in success, while other socket impls return number of bytes sent!!!
|
||||
//TODO: check if address_ptr is valid and use that instead if it is
|
||||
int ret = socket_sendto(sock->listen_socket, &sock->dest_addr, (unsigned char*)buf, len);
|
||||
if( ret < 0 )
|
||||
|
||||
int8_t ret = send_to_real_socket(sock->socket, &session->remote_host, session->local_address, buf, len);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
static int receive_from_socket(int8_t socket_id, unsigned char *buf, size_t len)
|
||||
static int secure_session_recvfrom(int8_t socket_id, unsigned char *buf, size_t len)
|
||||
{
|
||||
(void)len;
|
||||
internal_socket_t *sock = int_socket_find_by_socket_id(socket_id);
|
||||
|
@ -406,28 +457,71 @@ static int timer_status(int8_t timer_id)
|
|||
return TIMER_STATE_CANCELLED;
|
||||
}
|
||||
|
||||
static int read_data(socket_callback_t *sckt_data, internal_socket_t *sock, ns_address_t *src_address)
|
||||
static int read_data(socket_callback_t *sckt_data, internal_socket_t *sock, ns_address_t *src_address, uint8_t dst_address[static 16])
|
||||
{
|
||||
sock->data_len = 0;
|
||||
if (sckt_data->event_type == SOCKET_DATA && sckt_data->d_len > 0) {
|
||||
uint8_t ancillary_databuffer[NS_CMSG_SPACE(sizeof(ns_in6_pktinfo_t))];
|
||||
ns_iovec_t msg_iov;
|
||||
ns_msghdr_t msghdr;
|
||||
ns_in6_pktinfo_t *pkt = NULL;
|
||||
|
||||
if (sock->data) {
|
||||
ns_dyn_mem_free(sock->data);
|
||||
sock->data = NULL;
|
||||
}
|
||||
|
||||
sock->data = ns_dyn_mem_temporary_alloc(sckt_data->d_len);
|
||||
if (!sock->data) {
|
||||
sock->data = NULL;
|
||||
return -1;
|
||||
}
|
||||
sock->data_len = socket_read(sckt_data->socket_id, src_address, sock->data, sckt_data->d_len);
|
||||
|
||||
msghdr.msg_name = src_address;
|
||||
msghdr.msg_namelen = sizeof(ns_address_t);
|
||||
msghdr.msg_iov = &msg_iov;
|
||||
msghdr.msg_iovlen = 1;
|
||||
msghdr.msg_control = ancillary_databuffer;
|
||||
msghdr.msg_controllen = sizeof(ancillary_databuffer);
|
||||
msghdr.flags = 0;
|
||||
|
||||
msg_iov.iov_base = sock->data;
|
||||
msg_iov.iov_len = sckt_data->d_len;
|
||||
|
||||
sock->data_len = socket_recvmsg(sckt_data->socket_id, &msghdr, 0);
|
||||
|
||||
if (sock->data_len > 0) {
|
||||
ns_cmsghdr_t *cmsg = NS_CMSG_FIRSTHDR(&msghdr);
|
||||
|
||||
while (cmsg) {
|
||||
switch (cmsg->cmsg_type) {
|
||||
case SOCKET_IPV6_PKTINFO:
|
||||
pkt = (ns_in6_pktinfo_t*)NS_CMSG_DATA(cmsg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if( sock->data_len < 1){
|
||||
cmsg = NS_CMSG_NXTHDR(&msghdr, cmsg);
|
||||
}
|
||||
if (pkt) {
|
||||
memcpy(dst_address, pkt->ipi6_addr, 16);
|
||||
} else {
|
||||
goto return_failure;
|
||||
}
|
||||
} else {
|
||||
goto return_failure;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
return_failure:
|
||||
ns_dyn_mem_free(sock->data);
|
||||
sock->data = NULL;
|
||||
sock->data_len = 0;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
static void secure_recv_sckt_msg(void *cb_res)
|
||||
|
@ -435,27 +529,35 @@ static void secure_recv_sckt_msg(void *cb_res)
|
|||
socket_callback_t *sckt_data = cb_res;
|
||||
internal_socket_t *sock = int_socket_find_by_socket_id(sckt_data->socket_id);
|
||||
ns_address_t src_address;
|
||||
uint8_t dst_address[16] = {0};
|
||||
memset(&src_address, 0, sizeof(ns_address_t));
|
||||
|
||||
if( sock && read_data(sckt_data, sock, &src_address) == 0 ){
|
||||
if (sock && read_data(sckt_data, sock, &src_address, dst_address) == 0) {
|
||||
/* If received from multicast address, reject */
|
||||
if (*(dst_address) == 0xFF) {
|
||||
return;
|
||||
}
|
||||
secure_session_t *session = secure_session_find(sock, src_address.address, src_address.identifier);
|
||||
|
||||
// Create session
|
||||
if (!session) {
|
||||
memcpy( sock->dest_addr.address, src_address.address, 16 );
|
||||
sock->dest_addr.identifier = src_address.identifier;
|
||||
sock->dest_addr.type = src_address.type;
|
||||
session = secure_session_create(sock, src_address.address, src_address.identifier);
|
||||
}
|
||||
if (!session) {
|
||||
tr_err("secure_recv_sckt_msg session creation failed - OOM");
|
||||
return;
|
||||
}
|
||||
// Record the destination. We are not strict on local address - all
|
||||
// session_find calls match only on remote address and port. But we
|
||||
// record the last-used destination address to use it as the source of
|
||||
// outgoing packets.
|
||||
memcpy(session->local_address, dst_address, 16);
|
||||
session->last_contact_time = coap_service_get_internal_timer_ticks();
|
||||
// Start handshake
|
||||
if( !session->sec_handler->_is_started ){
|
||||
uint8_t *pw = (uint8_t *)ns_dyn_mem_alloc(64);
|
||||
if (!coap_security_handler_is_started(session->sec_handler) ){
|
||||
uint8_t *pw = ns_dyn_mem_alloc(64);
|
||||
uint8_t pw_len;
|
||||
if( sock->parent->_get_password_cb && 0 == sock->parent->_get_password_cb(sock->listen_socket, src_address.address, src_address.identifier, pw, &pw_len)){
|
||||
if( sock->parent->_get_password_cb && 0 == sock->parent->_get_password_cb(sock->socket, src_address.address, src_address.identifier, pw, &pw_len)){
|
||||
//TODO: get_password_cb should support certs and PSK also
|
||||
coap_security_keys_t keys;
|
||||
keys._priv = pw;
|
||||
|
@ -474,12 +576,11 @@ static void secure_recv_sckt_msg(void *cb_res)
|
|||
session->timer.timer = NULL;
|
||||
session->session_state = SECURE_SESSION_OK;
|
||||
if( sock->parent->_security_done_cb ){
|
||||
sock->parent->_security_done_cb(sock->listen_socket, src_address.address,
|
||||
sock->parent->_security_done_cb(sock->socket, src_address.address,
|
||||
src_address.identifier,
|
||||
session->sec_handler->_keyblk.value);
|
||||
(void *)coap_security_handler_keyblock(session->sec_handler));
|
||||
}
|
||||
}
|
||||
else if (ret < 0){
|
||||
} else if (ret < 0){
|
||||
// error handling
|
||||
// TODO: here we also should clear CoAP retransmission buffer and inform that CoAP request sending is failed.
|
||||
secure_session_delete(session);
|
||||
|
@ -490,11 +591,14 @@ static void secure_recv_sckt_msg(void *cb_res)
|
|||
int len = 0;
|
||||
len = coap_security_handler_read(session->sec_handler, data, sock->data_len);
|
||||
if( len < 0 ){
|
||||
ns_dyn_mem_free(data);
|
||||
if (len != MBEDTLS_ERR_SSL_WANT_READ && len != MBEDTLS_ERR_SSL_WANT_WRITE &&
|
||||
len != MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE) {
|
||||
secure_session_delete(session);
|
||||
}
|
||||
ns_dyn_mem_free(data);
|
||||
} else {
|
||||
if (sock->parent->_recv_cb) {
|
||||
sock->parent->_recv_cb(sock->listen_socket, src_address.address, src_address.identifier, data, len);
|
||||
sock->parent->_recv_cb(sock->socket, src_address.address, src_address.identifier, dst_address, data, len);
|
||||
}
|
||||
ns_dyn_mem_free(data);
|
||||
}
|
||||
|
@ -508,9 +612,11 @@ static void recv_sckt_msg(void *cb_res)
|
|||
socket_callback_t *sckt_data = cb_res;
|
||||
internal_socket_t *sock = int_socket_find_by_socket_id(sckt_data->socket_id);
|
||||
ns_address_t src_address;
|
||||
if( sock && read_data(sckt_data, sock, &src_address) == 0 ){
|
||||
uint8_t dst_address[16];
|
||||
|
||||
if (sock && read_data(sckt_data, sock, &src_address, dst_address) == 0) {
|
||||
if (sock->parent && sock->parent->_recv_cb) {
|
||||
sock->parent->_recv_cb(sock->listen_socket, src_address.address, src_address.identifier, sock->data, sock->data_len);
|
||||
sock->parent->_recv_cb(sock->socket, src_address.address, src_address.identifier, dst_address, sock->data, sock->data_len);
|
||||
}
|
||||
ns_dyn_mem_free(sock->data);
|
||||
sock->data = NULL;
|
||||
|
@ -553,10 +659,10 @@ int coap_connection_handler_virtual_recv(coap_conn_handler_t *handler, uint8_t a
|
|||
|
||||
session->last_contact_time = coap_service_get_internal_timer_ticks();
|
||||
|
||||
if( !session->sec_handler->_is_started ){
|
||||
uint8_t *pw = (uint8_t *)ns_dyn_mem_alloc(64);
|
||||
if (!coap_security_handler_is_started(session->sec_handler)) {
|
||||
uint8_t *pw = ns_dyn_mem_alloc(64);
|
||||
uint8_t pw_len;
|
||||
if( sock->parent->_get_password_cb && 0 == sock->parent->_get_password_cb(sock->listen_socket, address, port, pw, &pw_len)){
|
||||
if (sock->parent->_get_password_cb && 0 == sock->parent->_get_password_cb(sock->socket, address, port, pw, &pw_len)) {
|
||||
//TODO: get_password_cb should support certs and PSK also
|
||||
coap_security_keys_t keys;
|
||||
keys._priv = pw;
|
||||
|
@ -575,14 +681,13 @@ int coap_connection_handler_virtual_recv(coap_conn_handler_t *handler, uint8_t a
|
|||
if(ret == 0){
|
||||
session->session_state = SECURE_SESSION_OK;
|
||||
if( handler->_security_done_cb ){
|
||||
handler->_security_done_cb(sock->listen_socket,
|
||||
handler->_security_done_cb(sock->socket,
|
||||
address, port,
|
||||
session->sec_handler->_keyblk.value);
|
||||
(void *)coap_security_handler_keyblock(session->sec_handler));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else if(ret < 0)
|
||||
{
|
||||
else if (ret < 0) {
|
||||
// error handling
|
||||
// TODO: here we also should clear CoAP retransmission buffer and inform that CoAP request sending is failed.
|
||||
secure_session_delete(session);
|
||||
|
@ -593,12 +698,15 @@ int coap_connection_handler_virtual_recv(coap_conn_handler_t *handler, uint8_t a
|
|||
int len = 0;
|
||||
len = coap_security_handler_read(session->sec_handler, data, sock->data_len);
|
||||
if (len < 0) {
|
||||
ns_dyn_mem_free(data);
|
||||
if (len != MBEDTLS_ERR_SSL_WANT_READ && len != MBEDTLS_ERR_SSL_WANT_WRITE &&
|
||||
len != MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE) {
|
||||
secure_session_delete(session);
|
||||
}
|
||||
ns_dyn_mem_free(data);
|
||||
return 0;
|
||||
} else {
|
||||
if (sock->parent->_recv_cb) {
|
||||
sock->parent->_recv_cb(sock->listen_socket, address, port, data, len);
|
||||
sock->parent->_recv_cb(sock->socket, address, port, ns_in6addr_any, data, len);
|
||||
}
|
||||
ns_dyn_mem_free(data);
|
||||
data = NULL;
|
||||
|
@ -607,8 +715,9 @@ int coap_connection_handler_virtual_recv(coap_conn_handler_t *handler, uint8_t a
|
|||
}
|
||||
}
|
||||
} else {
|
||||
/* unsecure*/
|
||||
if (sock->parent->_recv_cb) {
|
||||
sock->parent->_recv_cb(sock->listen_socket, address, port, sock->data, sock->data_len);
|
||||
sock->parent->_recv_cb(sock->socket, address, port, ns_in6addr_any, sock->data, sock->data_len);
|
||||
}
|
||||
if (sock->data) {
|
||||
ns_dyn_mem_free(sock->data);
|
||||
|
@ -696,16 +805,13 @@ int coap_connection_handler_open_connection(coap_conn_handler_t *handler, uint16
|
|||
return 0;
|
||||
}
|
||||
|
||||
int coap_connection_handler_send_data(coap_conn_handler_t *handler, ns_address_t *dest_addr, uint8_t *data_ptr, uint16_t data_len, bool bypass_link_sec)
|
||||
int coap_connection_handler_send_data(coap_conn_handler_t *handler, const ns_address_t *dest_addr, const uint8_t src_address[static 16], uint8_t *data_ptr, uint16_t data_len, bool bypass_link_sec)
|
||||
{
|
||||
if (!handler || !handler->socket || !dest_addr) {
|
||||
return -1;
|
||||
}
|
||||
if (handler->socket->is_secure) {
|
||||
handler->socket->bypass_link_sec = bypass_link_sec;
|
||||
memcpy(handler->socket->dest_addr.address, dest_addr->address, 16);
|
||||
handler->socket->dest_addr.identifier = dest_addr->identifier;
|
||||
handler->socket->dest_addr.type = dest_addr->type;
|
||||
secure_session_t *session = secure_session_find(handler->socket, dest_addr->address, dest_addr->identifier);
|
||||
if (!session) {
|
||||
session = secure_session_create(handler->socket, dest_addr->address, dest_addr->identifier);
|
||||
|
@ -713,16 +819,13 @@ int coap_connection_handler_send_data(coap_conn_handler_t *handler, ns_address_t
|
|||
return -1;
|
||||
}
|
||||
session->last_contact_time = coap_service_get_internal_timer_ticks();
|
||||
memcpy( handler->socket->dest_addr.address, dest_addr->address, 16 );
|
||||
handler->socket->dest_addr.identifier = dest_addr->identifier;
|
||||
handler->socket->dest_addr.type = dest_addr->type;
|
||||
uint8_t *pw = (uint8_t *)ns_dyn_mem_alloc(64);
|
||||
uint8_t *pw = ns_dyn_mem_alloc(64);
|
||||
if (!pw) {
|
||||
//todo: free secure session?
|
||||
return -1;
|
||||
}
|
||||
uint8_t pw_len;
|
||||
if( handler->_get_password_cb && 0 == handler->_get_password_cb(handler->socket->listen_socket, dest_addr->address, dest_addr->identifier, pw, &pw_len)){
|
||||
if (handler->_get_password_cb && 0 == handler->_get_password_cb(handler->socket->socket, (uint8_t*)dest_addr->address, dest_addr->identifier, pw, &pw_len)) {
|
||||
//TODO: get_password_cb should support certs and PSK also
|
||||
coap_security_keys_t keys;
|
||||
keys._priv = pw;
|
||||
|
@ -744,16 +847,18 @@ int coap_connection_handler_send_data(coap_conn_handler_t *handler, ns_address_t
|
|||
return -1;
|
||||
}else{
|
||||
if (!handler->socket->real_socket && handler->_send_cb) {
|
||||
return handler->_send_cb((int8_t)handler->socket->listen_socket, dest_addr->address, dest_addr->identifier, data_ptr, data_len);
|
||||
return handler->_send_cb((int8_t)handler->socket->socket, dest_addr->address, dest_addr->identifier, data_ptr, data_len);
|
||||
}
|
||||
int opt_name = SOCKET_IPV6_PREFER_SRC_6LOWPAN_SHORT;
|
||||
int8_t securityLinkLayer = 1;
|
||||
if (bypass_link_sec) {
|
||||
securityLinkLayer = 0;
|
||||
}
|
||||
socket_setsockopt(handler->socket->listen_socket, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_ADDR_PREFERENCES, &opt_name, sizeof(int));
|
||||
socket_setsockopt(handler->socket->listen_socket, SOCKET_IPPROTO_IPV6, SOCKET_LINK_LAYER_SECURITY, &securityLinkLayer, sizeof(int8_t));
|
||||
return socket_sendto(handler->socket->listen_socket, dest_addr, data_ptr, data_len);
|
||||
|
||||
socket_setsockopt(handler->socket->socket, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_ADDR_PREFERENCES, &opt_name, sizeof(int));
|
||||
socket_setsockopt(handler->socket->socket, SOCKET_IPPROTO_IPV6, SOCKET_LINK_LAYER_SECURITY, &securityLinkLayer, sizeof(int8_t));
|
||||
|
||||
return send_to_real_socket(handler->socket->socket, dest_addr, src_address, data_ptr, data_len);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -763,7 +868,7 @@ bool coap_connection_handler_socket_belongs_to(coap_conn_handler_t *handler, int
|
|||
return false;
|
||||
}
|
||||
|
||||
if( handler->socket->listen_socket == socket_id){
|
||||
if( handler->socket->socket == socket_id){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -4,8 +4,10 @@
|
|||
|
||||
#include <string.h>
|
||||
#include "nsdynmemLIB.h"
|
||||
#include "coap_service_api_internal.h"
|
||||
#include "coap_message_handler.h"
|
||||
#include "sn_coap_protocol.h"
|
||||
#include "socket_api.h"
|
||||
#include "ns_types.h"
|
||||
#include "ns_list.h"
|
||||
#include "ns_trace.h"
|
||||
|
@ -73,44 +75,73 @@ static coap_transaction_t *transaction_create(void)
|
|||
if (this) {
|
||||
memset(this, 0, sizeof(coap_transaction_t));
|
||||
this->client_request = true;// default to client initiated method
|
||||
this->create_time = coap_service_get_internal_timer_ticks();
|
||||
ns_list_add_to_start(&request_list, this);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
static void transaction_delete(coap_transaction_t *this)
|
||||
|
||||
static void transaction_free(coap_transaction_t *this)
|
||||
{
|
||||
if (this) {
|
||||
ns_list_remove(&request_list, this);
|
||||
if (!this) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->data_ptr) {
|
||||
ns_dyn_mem_free(this->data_ptr);
|
||||
}
|
||||
ns_dyn_mem_free(this);
|
||||
}
|
||||
|
||||
void transaction_delete(coap_transaction_t *this)
|
||||
{
|
||||
if (this) {
|
||||
ns_list_remove(&request_list, this);
|
||||
transaction_free(this);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void transactions_delete_all(uint8_t *address_ptr, uint16_t port)
|
||||
{
|
||||
coap_transaction_t *transaction = transaction_find_by_address(address_ptr, port);
|
||||
|
||||
while (transaction) {
|
||||
ns_list_remove(&request_list, transaction);
|
||||
if (transaction->resp_cb) {
|
||||
transaction->resp_cb(transaction->service_id, address_ptr, port, NULL);
|
||||
}
|
||||
sn_coap_protocol_delete_retransmission(coap_service_handle->coap, transaction->msg_id);
|
||||
transaction_free(transaction);
|
||||
transaction = transaction_find_by_address(address_ptr, port);
|
||||
}
|
||||
}
|
||||
|
||||
static int8_t coap_rx_function(sn_coap_hdr_s *resp_ptr, sn_nsdl_addr_s *address_ptr, void *param)
|
||||
{
|
||||
coap_transaction_t *this = NULL;
|
||||
(void)address_ptr;
|
||||
(void)param;
|
||||
tr_warn("transaction was not handled");
|
||||
tr_warn("transaction was not handled %d", resp_ptr->msg_id);
|
||||
if (!resp_ptr) {
|
||||
return -1;
|
||||
}
|
||||
if( resp_ptr->token_ptr ){
|
||||
this = transaction_find_client_by_token(resp_ptr->token_ptr);
|
||||
}
|
||||
if (this && this->resp_cb) {
|
||||
this->resp_cb(this->service_id, address_ptr->addr_ptr, address_ptr->port, NULL);
|
||||
}
|
||||
transaction_delete(this);
|
||||
if (!this) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void coap_service_build_content_format(sn_coap_hdr_s *header, sn_coap_content_format_e format);
|
||||
ns_list_remove(&request_list, this);
|
||||
if (this->resp_cb) {
|
||||
this->resp_cb(this->service_id, address_ptr->addr_ptr, address_ptr->port, NULL);
|
||||
}
|
||||
transaction_free(this);
|
||||
return 0;
|
||||
}
|
||||
|
||||
coap_msg_handler_t *coap_message_handler_init(void *(*used_malloc_func_ptr)(uint16_t), void (*used_free_func_ptr)(void *),
|
||||
uint8_t (*used_tx_callback_ptr)(uint8_t *, uint16_t, sn_nsdl_addr_s *, void *)){
|
||||
|
@ -177,7 +208,7 @@ coap_transaction_t *coap_message_handler_find_transaction(uint8_t *address_ptr,
|
|||
return transaction_find_by_address( address_ptr, port );
|
||||
}
|
||||
|
||||
int16_t coap_message_handler_coap_msg_process(coap_msg_handler_t *handle, int8_t socket_id, uint8_t source_addr_ptr[static 16], uint16_t port,
|
||||
int16_t coap_message_handler_coap_msg_process(coap_msg_handler_t *handle, int8_t socket_id, const uint8_t source_addr_ptr[static 16], uint16_t port, const uint8_t dst_addr_ptr[static 16],
|
||||
uint8_t *data_ptr, uint16_t data_len, int16_t (cb)(int8_t, sn_coap_hdr_s *, coap_transaction_t *))
|
||||
{
|
||||
if (!cb || !handle) {
|
||||
|
@ -185,7 +216,7 @@ int16_t coap_message_handler_coap_msg_process(coap_msg_handler_t *handle, int8_t
|
|||
}
|
||||
sn_nsdl_addr_s src_addr;
|
||||
sn_coap_hdr_s *coap_message;
|
||||
src_addr.addr_ptr = source_addr_ptr;
|
||||
src_addr.addr_ptr = (uint8_t *)source_addr_ptr;
|
||||
src_addr.addr_len = 16;
|
||||
src_addr.type = SN_NSDL_ADDRESS_TYPE_IPV6;
|
||||
src_addr.port = port;
|
||||
|
@ -202,15 +233,14 @@ int16_t coap_message_handler_coap_msg_process(coap_msg_handler_t *handle, int8_t
|
|||
sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, coap_message);
|
||||
return -1;
|
||||
}
|
||||
/* Request received */
|
||||
if (coap_message->msg_code > 0 && coap_message->msg_code < 32) {
|
||||
|
||||
//TODO Sorry
|
||||
|
||||
coap_transaction_t *transaction_ptr = transaction_create();
|
||||
if (transaction_ptr) {
|
||||
|
||||
transaction_ptr->service_id = coap_service_id_find_by_socket(socket_id);
|
||||
transaction_ptr->msg_id = coap_message->msg_id;
|
||||
transaction_ptr->client_request = false;// this is server transaction
|
||||
memcpy(transaction_ptr->local_address, *(dst_addr_ptr) == 0xFF ? ns_in6addr_any : dst_addr_ptr, 16);
|
||||
memcpy(transaction_ptr->remote_address, source_addr_ptr, 16);
|
||||
transaction_ptr->remote_port = port;
|
||||
|
||||
|
@ -224,8 +254,8 @@ int16_t coap_message_handler_coap_msg_process(coap_msg_handler_t *handle, int8_t
|
|||
} else {
|
||||
//TODO: handle error case
|
||||
}
|
||||
/* Response received */
|
||||
} else {
|
||||
//response find by MSG id
|
||||
coap_transaction_t *this = NULL;
|
||||
if (coap_message->token_ptr) {
|
||||
this = transaction_find_client_by_token(coap_message->token_ptr);
|
||||
|
@ -236,12 +266,14 @@ int16_t coap_message_handler_coap_msg_process(coap_msg_handler_t *handle, int8_t
|
|||
return -1;
|
||||
}
|
||||
tr_debug("Service %d, response received", this->service_id);
|
||||
ns_list_remove(&request_list, this);
|
||||
if (this->resp_cb) {
|
||||
this->resp_cb(this->service_id, source_addr_ptr, port, coap_message);
|
||||
this->resp_cb(this->service_id, (uint8_t *)source_addr_ptr, port, coap_message);
|
||||
}
|
||||
sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, coap_message);
|
||||
transaction_delete(this);
|
||||
transaction_free(this);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
@ -280,7 +312,7 @@ uint16_t coap_message_handler_request_send(coap_msg_handler_t *handle, int8_t se
|
|||
request.msg_code = msg_code;
|
||||
request.uri_path_ptr = (uint8_t *)uri;
|
||||
request.uri_path_len = strlen(uri);
|
||||
coap_service_build_content_format(&request, cont_type);
|
||||
request.content_format = cont_type;
|
||||
|
||||
do{
|
||||
randLIB_get_n_bytes_random(token,4);
|
||||
|
@ -310,7 +342,6 @@ uint16_t coap_message_handler_request_send(coap_msg_handler_t *handle, int8_t se
|
|||
return transaction_ptr->msg_id;
|
||||
}
|
||||
|
||||
//TODO: refactor this to use nsdl
|
||||
int8_t coap_message_handler_response_send(coap_msg_handler_t *handle, int8_t service_id, uint8_t options, sn_coap_hdr_s *request_ptr, sn_coap_msg_code_e message_code, sn_coap_content_format_e content_type, const uint8_t *payload_ptr, uint16_t payload_len)
|
||||
{
|
||||
coap_transaction_t *transaction_ptr;
|
||||
|
@ -344,46 +375,34 @@ int8_t coap_message_handler_response_send(coap_msg_handler_t *handle, int8_t ser
|
|||
}
|
||||
response->payload_len = payload_len;
|
||||
response->payload_ptr = (uint8_t *) payload_ptr; // Cast away const and trust that nsdl doesn't modify...
|
||||
coap_service_build_content_format(response, content_type);
|
||||
response->content_format = content_type;
|
||||
|
||||
data_len = sn_coap_builder_calc_needed_packet_data_size(response);
|
||||
data_ptr = own_alloc(data_len);
|
||||
if (data_len > 0 && !data_ptr) {
|
||||
sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, response);
|
||||
//TODO deallocate stuff i quess
|
||||
return -1;
|
||||
}
|
||||
sn_coap_protocol_build(handle->coap, &dst_addr, data_ptr, response, transaction_ptr);
|
||||
sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, response);
|
||||
handle->sn_coap_tx_callback(data_ptr, data_len, &dst_addr, transaction_ptr);
|
||||
sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, request_ptr);
|
||||
transaction_delete(transaction_ptr);
|
||||
own_free(data_ptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int8_t coap_message_handler_exec(coap_msg_handler_t *handle, uint32_t current_time){
|
||||
|
||||
if( !handle ){
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Remove outdated transactions from queue
|
||||
ns_list_foreach_safe(coap_transaction_t, transaction, &request_list) {
|
||||
if ((transaction->create_time + TRANSACTION_LIFETIME) < current_time) {
|
||||
transaction_delete(transaction);
|
||||
}
|
||||
}
|
||||
|
||||
return sn_coap_protocol_exec(handle->coap, current_time);
|
||||
}
|
||||
|
||||
static void coap_service_build_content_format(sn_coap_hdr_s *header, sn_coap_content_format_e format)
|
||||
{
|
||||
header->content_format = format;
|
||||
|
||||
// if (format == COAP_CT_NONE) {
|
||||
// return;
|
||||
// }
|
||||
// if (format == 0) { /* text/plain */
|
||||
// header->content_type_len = 0;
|
||||
// } else if (format <= 0xff) {
|
||||
// header->content_type_ptr[0] = format;
|
||||
// header->content_type_len = 1;
|
||||
// } else {
|
||||
// header->content_type_ptr[0] = format >> 8;
|
||||
// header->content_type_ptr[1] = format & 0xff;
|
||||
// header->content_type_len = 2;
|
||||
// }
|
||||
}
|
||||
|
|
|
@ -6,18 +6,54 @@
|
|||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "coap_security_handler.h"
|
||||
|
||||
#ifdef COAP_SECURITY_AVAILABLE
|
||||
|
||||
#include "mbedtls/sha256.h"
|
||||
#include "mbedtls/error.h"
|
||||
#include "mbedtls/platform.h"
|
||||
#include "mbedtls/ssl_cookie.h"
|
||||
#include "mbedtls/entropy.h"
|
||||
#include "mbedtls/entropy_poll.h"
|
||||
#include "mbedtls/ssl.h"
|
||||
#include "mbedtls/ctr_drbg.h"
|
||||
#include "mbedtls/ssl_ciphersuites.h"
|
||||
|
||||
#include "ns_trace.h"
|
||||
#include "nsdynmemLIB.h"
|
||||
#include "coap_connection_handler.h"
|
||||
#include "coap_security_handler.h"
|
||||
#include "randLIB.h"
|
||||
#include "mbedtls/ssl_ciphersuites.h"
|
||||
|
||||
struct coap_security_s {
|
||||
mbedtls_ssl_config _conf;
|
||||
mbedtls_ssl_context _ssl;
|
||||
|
||||
mbedtls_ctr_drbg_context _ctr_drbg;
|
||||
mbedtls_entropy_context _entropy;
|
||||
bool _is_started;
|
||||
simple_cookie_t _cookie;
|
||||
key_block_t _keyblk;
|
||||
|
||||
SecureConnectionMode _conn_mode;
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
||||
mbedtls_x509_crt _cacert;
|
||||
mbedtls_x509_crt _owncert;
|
||||
#endif
|
||||
mbedtls_pk_context _pkey;
|
||||
|
||||
uint8_t _pw[64];
|
||||
uint8_t _pw_len;
|
||||
|
||||
bool _is_blocking;
|
||||
int8_t _socket_id;
|
||||
int8_t _timer_id;
|
||||
void *_handle;
|
||||
send_cb *_send_cb;
|
||||
receive_cb *_receive_cb;
|
||||
start_timer_cb *_start_timer_cb;
|
||||
timer_status_cb *_timer_status_cb;
|
||||
|
||||
};
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
|
||||
const int ECJPAKE_SUITES[] = {
|
||||
|
@ -77,6 +113,16 @@ static int coap_security_handler_init(coap_security_t *sec){
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool coap_security_handler_is_started(const coap_security_t *sec)
|
||||
{
|
||||
return sec->_is_started;
|
||||
}
|
||||
|
||||
const void *coap_security_handler_keyblock(const coap_security_t *sec)
|
||||
{
|
||||
return sec->_keyblk.value;
|
||||
}
|
||||
|
||||
static void coap_security_handler_reset(coap_security_t *sec){
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
||||
mbedtls_x509_crt_free(&sec->_cacert);
|
||||
|
@ -92,13 +138,13 @@ static void coap_security_handler_reset(coap_security_t *sec){
|
|||
}
|
||||
|
||||
|
||||
coap_security_t *coap_security_create(int8_t socket_id, int8_t timer_id, uint8_t *address_ptr, uint16_t port, SecureConnectionMode mode,
|
||||
send_cb *send_cb,
|
||||
receive_cb *receive_cb,
|
||||
start_timer_cb *start_timer_cb,
|
||||
timer_status_cb *timer_status_cb)
|
||||
coap_security_t *coap_security_create(int8_t socket_id, int8_t timer_id, void *handle, SecureConnectionMode mode,
|
||||
send_cb *socket_cb,
|
||||
receive_cb *receive_data_cb,
|
||||
start_timer_cb *timer_start_cb,
|
||||
timer_status_cb *timer_stat_cb)
|
||||
{
|
||||
if( !address_ptr || send_cb == NULL || receive_cb == NULL || start_timer_cb == NULL || timer_status_cb == NULL){
|
||||
if (socket_cb == NULL || receive_data_cb == NULL || timer_start_cb == NULL || timer_stat_cb == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
coap_security_t *this = ns_dyn_mem_alloc(sizeof(coap_security_t));
|
||||
|
@ -110,17 +156,16 @@ coap_security_t *coap_security_create(int8_t socket_id, int8_t timer_id, uint8_t
|
|||
ns_dyn_mem_free(this);
|
||||
return NULL;
|
||||
}
|
||||
this->_remote_port = port;
|
||||
memcpy(this->_remote_address, address_ptr, 16);
|
||||
this->_handle = handle;
|
||||
this->_conn_mode = mode;
|
||||
memset(this->_pw, 0, 64);
|
||||
this->_pw_len = 0;
|
||||
this->_socket_id = socket_id;
|
||||
this->_timer_id = timer_id;
|
||||
this->_send_cb = send_cb;
|
||||
this->_receive_cb = receive_cb;
|
||||
this->_start_timer_cb = start_timer_cb;
|
||||
this->_timer_status_cb = timer_status_cb;
|
||||
this->_send_cb = socket_cb;
|
||||
this->_receive_cb = receive_data_cb;
|
||||
this->_start_timer_cb = timer_start_cb;
|
||||
this->_timer_status_cb = timer_stat_cb;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
@ -551,7 +596,7 @@ static int get_timer(void *sec_obj)
|
|||
|
||||
int f_send( void *ctx, const unsigned char *buf, size_t len){
|
||||
coap_security_t *sec = (coap_security_t *)ctx;
|
||||
return sec->_send_cb(sec->_socket_id, sec->_remote_address, sec->_remote_port, buf, len);
|
||||
return sec->_send_cb(sec->_socket_id, sec->_handle, buf, len);
|
||||
}
|
||||
|
||||
int f_recv(void *ctx, unsigned char *buf, size_t len){
|
||||
|
@ -579,3 +624,5 @@ int entropy_poll( void *ctx, unsigned char *output, size_t len,
|
|||
ns_dyn_mem_free(c);
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#endif // COAP_SECURITY_AVAILABLE
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
#include "coap_connection_handler.h"
|
||||
#include "net_interface.h"
|
||||
#include "coap_service_api_internal.h"
|
||||
#include "coap_message_handler.h"
|
||||
|
||||
static int16_t coap_service_coap_msg_process(int8_t socket_id, uint8_t source_addr_ptr[static 16], uint16_t port, uint8_t *data_ptr, uint16_t data_len);
|
||||
static int16_t coap_msg_process_callback(int8_t socket_id, sn_coap_hdr_s *coap_message, coap_transaction_t *transaction_ptr);
|
||||
|
||||
typedef struct uri_registration {
|
||||
|
@ -130,7 +130,7 @@ static uint8_t coap_tx_function(uint8_t *data_ptr, uint16_t data_len, sn_nsdl_ad
|
|||
return -1;
|
||||
}
|
||||
|
||||
tr_debug("Service %d, CoAP TX Function", transaction_ptr->service_id);
|
||||
tr_debug("Service %d, CoAP TX Function - mid: %d", transaction_ptr->service_id, common_read_16_bit(data_ptr + 2));
|
||||
|
||||
this = service_find(transaction_ptr->service_id);
|
||||
if (!this) {
|
||||
|
@ -141,7 +141,8 @@ static uint8_t coap_tx_function(uint8_t *data_ptr, uint16_t data_len, sn_nsdl_ad
|
|||
dest_addr.identifier = address_ptr->port;
|
||||
dest_addr.type = ADDRESS_IPV6;
|
||||
|
||||
if( -2 == coap_connection_handler_send_data(this->conn_handler, &dest_addr, data_ptr, data_len, (this->service_options & COAP_SERVICE_OPTIONS_SECURE_BYPASS) == COAP_SERVICE_OPTIONS_SECURE_BYPASS) ){
|
||||
if (-2 == coap_connection_handler_send_data(this->conn_handler, &dest_addr, transaction_ptr->local_address,
|
||||
data_ptr, data_len, (this->service_options & COAP_SERVICE_OPTIONS_SECURE_BYPASS) == COAP_SERVICE_OPTIONS_SECURE_BYPASS)) {
|
||||
transaction_ptr->data_ptr = ns_dyn_mem_alloc(data_len);
|
||||
if (!transaction_ptr->data_ptr) {
|
||||
tr_debug("coap tx out of memory");
|
||||
|
@ -150,6 +151,8 @@ static uint8_t coap_tx_function(uint8_t *data_ptr, uint16_t data_len, sn_nsdl_ad
|
|||
}
|
||||
memcpy(transaction_ptr->data_ptr, data_ptr, data_len);
|
||||
transaction_ptr->data_len = data_len;
|
||||
} else if (transaction_ptr->resp_cb == NULL ) {
|
||||
transaction_delete(transaction_ptr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -173,18 +176,24 @@ static void service_event_handler(arm_event_s *event)
|
|||
static int16_t coap_msg_process_callback(int8_t socket_id, sn_coap_hdr_s *coap_message, coap_transaction_t *transaction_ptr)
|
||||
{
|
||||
coap_service_t *this;
|
||||
if( !coap_message ){
|
||||
if (!coap_message || !transaction_ptr) {
|
||||
return -1;
|
||||
}
|
||||
// Message is request find correct handle
|
||||
|
||||
// Message is request, find correct handle
|
||||
this = service_find_by_uri(socket_id, coap_message->uri_path_ptr, coap_message->uri_path_len);
|
||||
if (!this) {
|
||||
tr_warn("not registered uri %.*s", coap_message->uri_path_len, coap_message->uri_path_ptr);
|
||||
tr_debug("not registered uri %.*s", coap_message->uri_path_len, coap_message->uri_path_ptr);
|
||||
if (coap_message->msg_type == COAP_MSG_TYPE_CONFIRMABLE) {
|
||||
coap_message_handler_response_send(coap_service_handle, transaction_ptr->service_id, COAP_SERVICE_OPTIONS_NONE, coap_message,
|
||||
COAP_MSG_CODE_RESPONSE_NOT_FOUND, COAP_CT_NONE, NULL, 0);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
uri_registration_t *uri_reg_ptr = uri_registration_find(this, coap_message->uri_path_ptr, coap_message->uri_path_len);
|
||||
if (transaction_ptr && uri_reg_ptr && uri_reg_ptr->request_recv_cb) {
|
||||
if (uri_reg_ptr && uri_reg_ptr->request_recv_cb) {
|
||||
tr_debug("Service %d, call request recv cb uri %.*s", this->service_id, coap_message->uri_path_len, coap_message->uri_path_ptr);
|
||||
|
||||
if ((this->service_options & COAP_SERVICE_OPTIONS_SECURE_BYPASS) == COAP_SERVICE_OPTIONS_SECURE_BYPASS ) {//TODO Add secure bypass option
|
||||
|
@ -198,19 +207,18 @@ static int16_t coap_msg_process_callback(int8_t socket_id, sn_coap_hdr_s *coap_m
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int16_t coap_service_coap_msg_process(int8_t socket_id, uint8_t source_addr_ptr[static 16], uint16_t port, uint8_t *data_ptr, uint16_t data_len)
|
||||
{
|
||||
return coap_message_handler_coap_msg_process( coap_service_handle, socket_id, source_addr_ptr, port, data_ptr, data_len, &coap_msg_process_callback);
|
||||
}
|
||||
|
||||
static int recv_cb(int8_t socket_id, uint8_t address[static 16], uint16_t port, unsigned char *data, int len)
|
||||
static int recv_cb(int8_t socket_id, uint8_t src_address[static 16], uint16_t port, const uint8_t dst_address[static 16], unsigned char *data, int len)
|
||||
{
|
||||
uint8_t *data_ptr = NULL;
|
||||
uint16_t data_len = 0;
|
||||
|
||||
if (!data || !len) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
data_ptr = own_alloc(len);
|
||||
|
||||
if (!data_ptr || len < 1) {
|
||||
if (!data_ptr) {
|
||||
return -1;
|
||||
}
|
||||
memcpy(data_ptr, data, len);
|
||||
|
@ -218,28 +226,21 @@ static int recv_cb(int8_t socket_id, uint8_t address[static 16], uint16_t port,
|
|||
tr_debug("service recv socket data len %d ", data_len);
|
||||
|
||||
//parse coap message what CoAP to use
|
||||
int ret = coap_service_coap_msg_process(socket_id, address, port, data_ptr, data_len);
|
||||
int ret = coap_message_handler_coap_msg_process(coap_service_handle, socket_id, src_address, port, dst_address, data_ptr, data_len, &coap_msg_process_callback);
|
||||
own_free(data_ptr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int send_cb(int8_t socket_id, uint8_t address[static 16], uint16_t port, const unsigned char *data_ptr, int data_len)
|
||||
static int send_cb(int8_t socket_id, const uint8_t address[static 16], uint16_t port, const void *data_ptr, int data_len)
|
||||
{
|
||||
coap_service_t *this = service_find_by_socket(socket_id);
|
||||
if (this && this->virtual_socket_send_cb) {
|
||||
tr_debug("send to virtual socket");
|
||||
return this->virtual_socket_send_cb(this->service_id, address, port, data_ptr, data_len);
|
||||
return this->virtual_socket_send_cb(this->service_id, (uint8_t*)address, port, data_ptr, data_len);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//static void sec_conn_closed_cb(int8_t socket_id)
|
||||
//{
|
||||
// coap_service_t *this = service_find_by_socket(socket_id);
|
||||
|
||||
// tr_debug("Secure socket was closed by end device");
|
||||
//}
|
||||
|
||||
static void sec_done_cb(int8_t socket_id, uint8_t address[static 16], uint16_t port, uint8_t keyblock[static 40])
|
||||
{
|
||||
//TODO: this is not enough if shared socket. Inform all!
|
||||
|
@ -248,7 +249,6 @@ static void sec_done_cb(int8_t socket_id, uint8_t address[static 16], uint16_t p
|
|||
this->coap_security_done_cb(this->service_id, address, keyblock);
|
||||
}
|
||||
|
||||
//TODO refactor this away. There should be no transaction_ptr(s) before done_cb has been called
|
||||
//TODO: send all unsend transactions if more than 1
|
||||
coap_transaction_t *transaction_ptr = coap_message_handler_find_transaction(address, port);
|
||||
if (transaction_ptr && transaction_ptr->data_ptr) {
|
||||
|
@ -258,11 +258,14 @@ static void sec_done_cb(int8_t socket_id, uint8_t address[static 16], uint16_t p
|
|||
dest_addr.identifier = port;
|
||||
dest_addr.type = ADDRESS_IPV6;
|
||||
|
||||
coap_connection_handler_send_data(this->conn_handler, &dest_addr, transaction_ptr->data_ptr, transaction_ptr->data_len, (this->service_options & COAP_SERVICE_OPTIONS_SECURE_BYPASS) == COAP_SERVICE_OPTIONS_SECURE_BYPASS);
|
||||
coap_connection_handler_send_data(this->conn_handler, &dest_addr, transaction_ptr->local_address,
|
||||
transaction_ptr->data_ptr, transaction_ptr->data_len, (this->service_options & COAP_SERVICE_OPTIONS_SECURE_BYPASS) == COAP_SERVICE_OPTIONS_SECURE_BYPASS);
|
||||
ns_dyn_mem_free(transaction_ptr->data_ptr);
|
||||
transaction_ptr->data_ptr = NULL;
|
||||
transaction_ptr->data_len = 0;
|
||||
//TODO: who deletes transaction incase no response is required
|
||||
if (transaction_ptr->resp_cb == NULL) {
|
||||
transaction_delete(transaction_ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -471,3 +474,10 @@ uint32_t coap_service_get_internal_timer_ticks(void)
|
|||
{
|
||||
return coap_ticks;
|
||||
}
|
||||
|
||||
uint16_t coap_service_id_find_by_socket(int8_t socket_id)
|
||||
{
|
||||
coap_service_t *this = service_find_by_socket(socket_id);
|
||||
|
||||
return this ? this->service_id:0;
|
||||
}
|
||||
|
|
|
@ -32,8 +32,8 @@
|
|||
|
||||
struct internal_socket_s;
|
||||
|
||||
typedef int send_to_socket_cb(int8_t socket_id, uint8_t address[static 16], uint16_t port, const unsigned char *, int);
|
||||
typedef int receive_from_socket_cb(int8_t socket_id, uint8_t address[static 16], uint16_t port, unsigned char *, int);
|
||||
typedef int send_to_socket_cb(int8_t socket_id, const uint8_t address[static 16], uint16_t port, const void *, int);
|
||||
typedef int receive_from_socket_cb(int8_t socket_id, uint8_t src_address[static 16], uint16_t port, const uint8_t dst_address[static 16], unsigned char *, int);
|
||||
typedef int get_pw_cb(int8_t socket_id, uint8_t address[static 16], uint16_t port, uint8_t *pw_ptr, uint8_t *pw_len);
|
||||
typedef void security_done_cb(int8_t socket_id, uint8_t address[static 16], uint16_t port, uint8_t keyblock[static 40]);
|
||||
|
||||
|
@ -58,7 +58,7 @@ void connection_handler_close_secure_connection( coap_conn_handler_t *handler, u
|
|||
int coap_connection_handler_open_connection(coap_conn_handler_t *handler, uint16_t listen_port, bool use_ephemeral_port, bool is_secure, bool real_socket, bool bypassSec);
|
||||
|
||||
//If returns -2, it means security was started and data was not send
|
||||
int coap_connection_handler_send_data(coap_conn_handler_t *handler, ns_address_t *dest_addr, uint8_t *data_ptr, uint16_t data_len, bool bypass_link_sec);
|
||||
int coap_connection_handler_send_data(coap_conn_handler_t *handler, const ns_address_t *dest_addr, const uint8_t src_address[static 16], uint8_t *data_ptr, uint16_t data_len, bool bypass_link_sec);
|
||||
|
||||
int coap_connection_handler_virtual_recv(coap_conn_handler_t *handler, uint8_t address[static 16], uint16_t port, uint8_t *data_ptr, uint16_t data_len);
|
||||
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
#include "sn_nsdl.h"
|
||||
#include "ns_list.h"
|
||||
|
||||
#define TRANSACTION_LIFETIME 180
|
||||
|
||||
/**
|
||||
* \brief Service message response receive callback.
|
||||
*
|
||||
|
@ -47,14 +49,17 @@ typedef struct coap_msg_handler_s {
|
|||
|
||||
typedef struct coap_transaction {
|
||||
uint8_t remote_address[16];
|
||||
uint16_t remote_port;
|
||||
uint8_t local_address[16];
|
||||
uint8_t token[4];
|
||||
uint32_t create_time;
|
||||
uint16_t remote_port;
|
||||
uint16_t msg_id;
|
||||
uint16_t data_len;
|
||||
int8_t service_id;
|
||||
uint8_t options;
|
||||
bool client_request: 1;
|
||||
uint8_t *data_ptr;
|
||||
uint16_t data_len;
|
||||
bool client_request: 1;
|
||||
|
||||
coap_message_handler_response_recv *resp_cb;
|
||||
ns_list_link_t link;
|
||||
} coap_transaction_t;
|
||||
|
@ -69,7 +74,7 @@ extern coap_transaction_t *coap_message_handler_transaction_valid(coap_transacti
|
|||
|
||||
extern coap_transaction_t *coap_message_handler_find_transaction(uint8_t *address_ptr, uint16_t port);
|
||||
|
||||
extern int16_t coap_message_handler_coap_msg_process(coap_msg_handler_t *handle, int8_t socket_id, uint8_t source_addr_ptr[static 16], uint16_t port,
|
||||
extern int16_t coap_message_handler_coap_msg_process(coap_msg_handler_t *handle, int8_t socket_id, const uint8_t source_addr_ptr[static 16], uint16_t port, const uint8_t dst_addr_ptr[static 16],
|
||||
uint8_t *data_ptr, uint16_t data_len, int16_t (cb)(int8_t, sn_coap_hdr_s *, coap_transaction_t *));
|
||||
|
||||
extern uint16_t coap_message_handler_request_send(coap_msg_handler_t *handle, int8_t service_id, uint8_t options, const uint8_t destination_addr[static 16],
|
||||
|
@ -81,4 +86,8 @@ extern int8_t coap_message_handler_response_send(coap_msg_handler_t *handle, int
|
|||
|
||||
extern int8_t coap_message_handler_exec(coap_msg_handler_t *handle, uint32_t current_time);
|
||||
|
||||
extern void transaction_delete(coap_transaction_t *this);
|
||||
|
||||
extern void transactions_delete_all(uint8_t *address_ptr, uint16_t port);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -21,11 +21,13 @@
|
|||
#include <stddef.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#ifdef NS_USE_EXTERNAL_MBED_TLS
|
||||
#include "mbedtls/ssl.h"
|
||||
#include "mbedtls/sha256.h"
|
||||
#include "mbedtls/entropy.h"
|
||||
#include "mbedtls/ctr_drbg.h"
|
||||
#ifdef MBEDTLS_SSL_TLS_C
|
||||
#define COAP_SECURITY_AVAILABLE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define COOKIE_SIMPLE_LEN 8
|
||||
typedef struct simple_cookie {
|
||||
|
@ -38,7 +40,7 @@ typedef struct key_block {
|
|||
unsigned char value[KEY_BLOCK_LEN];
|
||||
} key_block_t;
|
||||
|
||||
typedef int send_cb(int8_t socket_id, uint8_t *address_ptr, uint16_t port, const unsigned char *, size_t);
|
||||
typedef int send_cb(int8_t socket_id, void *handle, const void *buf, size_t);
|
||||
typedef int receive_cb(int8_t socket_id, unsigned char *, size_t);
|
||||
typedef void start_timer_cb(int8_t timer_id, uint32_t min, uint32_t fin);
|
||||
typedef int timer_status_cb(int8_t timer_id);
|
||||
|
@ -66,40 +68,11 @@ typedef struct {
|
|||
uint8_t _priv_len;
|
||||
} coap_security_keys_t;
|
||||
|
||||
typedef struct coap_security_s {
|
||||
mbedtls_ssl_config _conf;
|
||||
mbedtls_ssl_context _ssl;
|
||||
typedef struct coap_security_s coap_security_t;
|
||||
|
||||
mbedtls_ctr_drbg_context _ctr_drbg;
|
||||
mbedtls_entropy_context _entropy;
|
||||
bool _is_started;
|
||||
simple_cookie_t _cookie;
|
||||
key_block_t _keyblk;
|
||||
#ifdef COAP_SECURITY_AVAILABLE
|
||||
|
||||
SecureConnectionMode _conn_mode;
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
||||
mbedtls_x509_crt _cacert;
|
||||
mbedtls_x509_crt _owncert;
|
||||
#endif
|
||||
mbedtls_pk_context _pkey;
|
||||
|
||||
uint8_t _remote_address[16];
|
||||
uint16_t _remote_port;
|
||||
|
||||
uint8_t _pw[64];
|
||||
uint8_t _pw_len;
|
||||
|
||||
bool _is_blocking;
|
||||
int8_t _socket_id;
|
||||
int8_t _timer_id;
|
||||
send_cb *_send_cb;
|
||||
receive_cb *_receive_cb;
|
||||
start_timer_cb *_start_timer_cb;
|
||||
timer_status_cb *_timer_status_cb;
|
||||
|
||||
} coap_security_t;
|
||||
|
||||
coap_security_t *coap_security_create(int8_t socket_id, int8_t timer_id, uint8_t *address_ptr, uint16_t port,
|
||||
coap_security_t *coap_security_create(int8_t socket_id, int8_t timer_id, void *handle,
|
||||
SecureConnectionMode mode,
|
||||
send_cb *send_cb,
|
||||
receive_cb *receive_cb,
|
||||
|
@ -120,4 +93,30 @@ int coap_security_send_close_alert(coap_security_t *sec);
|
|||
|
||||
int coap_security_handler_read(coap_security_t *sec, unsigned char* buffer, size_t len);
|
||||
|
||||
bool coap_security_handler_is_started(const coap_security_t *sec);
|
||||
|
||||
const void *coap_security_handler_keyblock(const coap_security_t *sec);
|
||||
|
||||
#else
|
||||
|
||||
/* Dummy definitions, including needed error codes */
|
||||
#define MBEDTLS_ERR_SSL_TIMEOUT (-1)
|
||||
#define MBEDTLS_ERR_SSL_WANT_READ (-2)
|
||||
#define MBEDTLS_ERR_SSL_WANT_WRITE (-3)
|
||||
#define MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE (-4)
|
||||
|
||||
#define coap_security_create(socket_id, timer_id, handle, \
|
||||
mode, send_cb, receive_cb, start_timer_cb, timer_status_cb) ((coap_security_t *) 0)
|
||||
#define coap_security_destroy(sec) ((void) 0)
|
||||
#define coap_security_handler_connect(sec, is_server, sock_mode, keys) (-1)
|
||||
#define coap_security_handler_connect_non_blocking(sec, is_server, sock_mode, keys, timeout_min, timeout_max) (-1)
|
||||
#define coap_security_handler_continue_connecting(sec) (-1)
|
||||
#define coap_security_handler_send_message(sec, message, len) (-1)
|
||||
#define coap_security_send_close_alert(sec) (-1)
|
||||
#define coap_security_handler_read(sec, buffer, len) (-1)
|
||||
#define coap_security_handler_is_started(sec) false
|
||||
#define coap_security_handler_keyblock(sec) ((void *) 0)
|
||||
|
||||
#endif /* COAP_SECURITY_AVAILABLE */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -19,7 +19,13 @@
|
|||
#ifndef __COAP_SERVICE_API_INTERNAL_H__
|
||||
#define __COAP_SERVICE_API_INTERNAL_H__
|
||||
|
||||
#include "coap_message_handler.h"
|
||||
|
||||
|
||||
extern coap_msg_handler_t *coap_service_handle;
|
||||
|
||||
uint32_t coap_service_get_internal_timer_ticks(void);
|
||||
|
||||
uint16_t coap_service_id_find_by_socket(int8_t socket_id);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
#scan for folders having "Makefile" in them and remove 'this' to prevent loop
|
||||
ifeq ($(OS),Windows_NT)
|
||||
all:
|
||||
clean:
|
||||
else
|
||||
DIRS := $(filter-out ./, $(sort $(dir $(shell find . -name 'Makefile'))))
|
||||
|
||||
all:
|
||||
for dir in $(DIRS); do \
|
||||
cd $$dir; make gcov; cd ..;\
|
||||
done
|
||||
|
||||
clean:
|
||||
for dir in $(DIRS); do \
|
||||
cd $$dir; make clean; cd ..;\
|
||||
done
|
||||
rm -rf stub/*gcov stub/*gcda stubs/*o
|
||||
rm -rf results/*
|
||||
rm -rf coverages/*
|
||||
rm -rf results
|
||||
rm -rf coverages
|
||||
endif
|
||||
|
0
features/nanostack/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/MakefileWorker.mk
Normal file → Executable file
0
features/nanostack/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/MakefileWorker.mk
Normal file → Executable file
|
@ -0,0 +1,26 @@
|
|||
include ../makefile_defines.txt
|
||||
|
||||
COMPONENT_NAME = coap_connection_handler_unit
|
||||
|
||||
#This must be changed manually
|
||||
SRC_FILES = \
|
||||
../../../../source/coap_connection_handler.c
|
||||
|
||||
TEST_SRC_FILES = \
|
||||
main.cpp \
|
||||
coap_connection_handlertest.cpp \
|
||||
test_coap_connection_handler.c \
|
||||
../stub/mbed_trace_stub.c \
|
||||
../stub/ns_list_stub.c \
|
||||
../stub/ns_timer_stub.c \
|
||||
../stub/timeout_stub.c \
|
||||
../stub/nsdynmemLIB_stub.c \
|
||||
../stub/socket_api_stub.c \
|
||||
../stub/coap_security_handler_stub.c \
|
||||
../stub/coap_service_api_stub.c \
|
||||
../stub/coap_message_handler_stub.c \
|
||||
|
||||
include ../MakefileWorker.mk
|
||||
|
||||
CPPUTESTFLAGS += -DFEA_TRACE_SUPPORT -DHAVE_THREAD
|
||||
|
|
@ -105,7 +105,7 @@ bool test_coap_connection_handler_open_connection()
|
|||
bool test_coap_connection_handler_send_data()
|
||||
{
|
||||
coap_security_handler_stub.counter = -1;
|
||||
if( -1 != coap_connection_handler_send_data(NULL, NULL, NULL, 0, false))
|
||||
if( -1 != coap_connection_handler_send_data(NULL, NULL, ns_in6addr_any, NULL, 0, false))
|
||||
return false;
|
||||
|
||||
ns_address_t addr;
|
||||
|
@ -118,15 +118,12 @@ bool test_coap_connection_handler_send_data()
|
|||
if( 0 != coap_connection_handler_open_connection(handler, 22,false,true,false,false) )
|
||||
return false;
|
||||
|
||||
if( -1 != coap_connection_handler_send_data(handler, &addr, NULL, 0, true))
|
||||
if( -1 != coap_connection_handler_send_data(handler, &addr, ns_in6addr_any, NULL, 0, true))
|
||||
return false;
|
||||
|
||||
connection_handler_destroy(handler);
|
||||
|
||||
coap_security_handler_stub.sec_obj = (coap_security_t *)malloc(sizeof(coap_security_t));
|
||||
memset(coap_security_handler_stub.sec_obj, 0, sizeof(coap_security_t));
|
||||
coap_security_handler_stub.sec_obj->_remote_port = 22;
|
||||
memset(coap_security_handler_stub.sec_obj->_remote_address, 1, 16 );
|
||||
coap_security_handler_stub.sec_obj = coap_security_handler_stub_alloc();
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
handler = connection_handler_create(&receive_from_sock_cb, &send_to_sock_cb, NULL, NULL);
|
||||
|
@ -134,10 +131,10 @@ bool test_coap_connection_handler_send_data()
|
|||
if( 0 != coap_connection_handler_open_connection(handler, 22,false,true,false,false) )
|
||||
return false;
|
||||
|
||||
if( -1 != coap_connection_handler_send_data(handler, &addr, NULL, 0, true))
|
||||
if( -1 != coap_connection_handler_send_data(handler, &addr, ns_in6addr_any, NULL, 0, true))
|
||||
return false;
|
||||
|
||||
if( -1 != coap_connection_handler_send_data(handler, &addr, NULL, 0, true))
|
||||
if( -1 != coap_connection_handler_send_data(handler, &addr, ns_in6addr_any, NULL, 0, true))
|
||||
return false;
|
||||
|
||||
connection_handler_destroy(handler);
|
||||
|
@ -153,7 +150,7 @@ bool test_coap_connection_handler_send_data()
|
|||
return false;
|
||||
|
||||
|
||||
if( 1 != coap_connection_handler_send_data(handler, &addr, NULL, 0, true))
|
||||
if( 1 != coap_connection_handler_send_data(handler, &addr, ns_in6addr_any, NULL, 0, true))
|
||||
return false;
|
||||
connection_handler_destroy(handler);
|
||||
|
||||
|
@ -164,7 +161,7 @@ bool test_coap_connection_handler_send_data()
|
|||
return false;
|
||||
|
||||
socket_api_stub.int8_value = 7;
|
||||
if( 7 != coap_connection_handler_send_data(handler, &addr, NULL, 0, true))
|
||||
if( 7 != coap_connection_handler_send_data(handler, &addr, ns_in6addr_any, NULL, 0, true))
|
||||
return false;
|
||||
connection_handler_destroy(handler);
|
||||
|
||||
|
@ -200,10 +197,7 @@ bool test_coap_connection_handler_virtual_recv()
|
|||
return false;
|
||||
|
||||
//handler->socket->data still in memory
|
||||
coap_security_handler_stub.sec_obj = (coap_security_t *)malloc(sizeof(coap_security_t));
|
||||
memset(coap_security_handler_stub.sec_obj, 0, sizeof(coap_security_t));
|
||||
coap_security_handler_stub.sec_obj->_remote_port = 55;
|
||||
memset(coap_security_handler_stub.sec_obj->_remote_address, 4, 16 );
|
||||
coap_security_handler_stub.sec_obj = coap_security_handler_stub_alloc();
|
||||
|
||||
ns_timer_stub.int8_value = -1;
|
||||
nsdynmemlib_stub.returnCounter = 3;
|
||||
|
@ -229,8 +223,6 @@ bool test_coap_connection_handler_virtual_recv()
|
|||
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
coap_security_handler_stub.int_value = 0;
|
||||
coap_security_handler_stub.sec_obj->_remote_port = 12;
|
||||
memset(coap_security_handler_stub.sec_obj->_remote_address, 1, 16 );
|
||||
if( 0 != coap_connection_handler_virtual_recv(handler2,buf, 12, &buf, 1) )
|
||||
return false;
|
||||
|
||||
|
@ -300,11 +292,7 @@ bool test_timer_callbacks()
|
|||
return false;
|
||||
|
||||
//handler->socket->data still in memory
|
||||
coap_security_handler_stub.sec_obj = (coap_security_t *)malloc(sizeof(coap_security_t));
|
||||
memset(coap_security_handler_stub.sec_obj, 0, sizeof(coap_security_t));
|
||||
coap_security_handler_stub.sec_obj->_remote_port = 55;
|
||||
memset(coap_security_handler_stub.sec_obj->_remote_address, 4, 16 );
|
||||
coap_security_handler_stub.sec_obj->_timer_id = 5;
|
||||
coap_security_handler_stub.sec_obj = coap_security_handler_stub_alloc();
|
||||
|
||||
ns_timer_stub.int8_value = 0;
|
||||
nsdynmemlib_stub.returnCounter = 3;
|
||||
|
@ -353,8 +341,7 @@ bool test_socket_api_callbacks()
|
|||
socket_callback_t *sckt_data = (socket_callback_t *)malloc(sizeof(socket_callback_t));
|
||||
memset(sckt_data, 0, sizeof(socket_callback_t));
|
||||
|
||||
coap_security_handler_stub.sec_obj = (coap_security_t *)malloc(sizeof(coap_security_t));
|
||||
memset(coap_security_handler_stub.sec_obj, 0, sizeof(coap_security_t));
|
||||
coap_security_handler_stub.sec_obj = coap_security_handler_stub_alloc();
|
||||
|
||||
socket_api_stub.int8_value = 0;
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
|
@ -433,8 +420,7 @@ bool test_security_callbacks()
|
|||
socket_callback_t *sckt_data = (socket_callback_t *)malloc(sizeof(socket_callback_t));
|
||||
memset(sckt_data, 0, sizeof(socket_callback_t));
|
||||
|
||||
coap_security_handler_stub.sec_obj = (coap_security_t *)malloc(sizeof(coap_security_t));
|
||||
memset(coap_security_handler_stub.sec_obj, 0, sizeof(coap_security_t));
|
||||
coap_security_handler_stub.sec_obj = coap_security_handler_stub_alloc();
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
coap_conn_handler_t *handler = connection_handler_create(&receive_from_sock_cb, &send_to_sock_cb, NULL, NULL);
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
include ../makefile_defines.txt
|
||||
|
||||
COMPONENT_NAME = coap_message_handler_unit
|
||||
|
||||
#This must be changed manually
|
||||
SRC_FILES = \
|
||||
../../../../source/coap_message_handler.c
|
||||
|
||||
TEST_SRC_FILES = \
|
||||
main.cpp \
|
||||
coap_message_handlertest.cpp \
|
||||
test_coap_message_handler.c \
|
||||
../stub/mbed_trace_stub.c \
|
||||
../stub/sn_coap_protocol_stub.c \
|
||||
../stub/sn_coap_parser_stub.c \
|
||||
../stub/sn_coap_builder_stub.c \
|
||||
../stub/nsdynmemLIB_stub.c \
|
||||
../stub/ns_list_stub.c \
|
||||
../stub/randLIB_stub.c \
|
||||
../stub/coap_service_api_stub.c \
|
||||
../stub/socket_api_stub.c \
|
||||
|
||||
include ../MakefileWorker.mk
|
||||
|
||||
CPPUTESTFLAGS += -DFEA_TRACE_SUPPORT
|
||||
|
|
@ -8,6 +8,7 @@
|
|||
#include "nsdynmemLIB_stub.h"
|
||||
#include "sn_coap_builder_stub.h"
|
||||
#include "sn_coap_parser_stub.h"
|
||||
#include "socket_api.h"
|
||||
|
||||
int retCounter = 0;
|
||||
int retValue = 0;
|
||||
|
@ -118,7 +119,7 @@ bool test_coap_message_handler_coap_msg_process()
|
|||
{
|
||||
uint8_t buf[16];
|
||||
memset(&buf, 1, 16);
|
||||
if( -1 != coap_message_handler_coap_msg_process(NULL, 0, buf, 22, NULL, 0, NULL))
|
||||
if( -1 != coap_message_handler_coap_msg_process(NULL, 0, buf, 22, ns_in6addr_any, NULL, 0, NULL))
|
||||
return false;
|
||||
|
||||
retCounter = 1;
|
||||
|
@ -127,13 +128,13 @@ bool test_coap_message_handler_coap_msg_process()
|
|||
coap_msg_handler_t *handle = coap_message_handler_init(&own_alloc, &own_free, &coap_tx_function);
|
||||
|
||||
sn_coap_protocol_stub.expectedHeader = NULL;
|
||||
if( -1 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, NULL, 0, process_cb))
|
||||
if( -1 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, ns_in6addr_any, NULL, 0, process_cb))
|
||||
return false;
|
||||
|
||||
sn_coap_protocol_stub.expectedHeader = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s));
|
||||
memset(sn_coap_protocol_stub.expectedHeader, 0, sizeof(sn_coap_hdr_s));
|
||||
sn_coap_protocol_stub.expectedHeader->coap_status = 66;
|
||||
if( -1 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, NULL, 0, process_cb))
|
||||
if( -1 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, ns_in6addr_any, NULL, 0, process_cb))
|
||||
return false;
|
||||
|
||||
sn_coap_protocol_stub.expectedHeader = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s));
|
||||
|
@ -141,12 +142,12 @@ bool test_coap_message_handler_coap_msg_process()
|
|||
sn_coap_protocol_stub.expectedHeader->coap_status = COAP_STATUS_OK;
|
||||
sn_coap_protocol_stub.expectedHeader->msg_code = 1;
|
||||
retValue = 0;
|
||||
if( 0 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, NULL, 0, process_cb))
|
||||
if( 0 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, ns_in6addr_any, NULL, 0, process_cb))
|
||||
return false;
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
retValue = -1;
|
||||
if( -1 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, NULL, 0, process_cb))
|
||||
if( -1 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, ns_in6addr_any, NULL, 0, process_cb))
|
||||
return false;
|
||||
|
||||
sn_coap_protocol_stub.expectedHeader = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s));
|
||||
|
@ -154,7 +155,7 @@ bool test_coap_message_handler_coap_msg_process()
|
|||
sn_coap_protocol_stub.expectedHeader->coap_status = COAP_STATUS_OK;
|
||||
sn_coap_protocol_stub.expectedHeader->msg_code = 333;
|
||||
|
||||
if( -1 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, NULL, 0, process_cb))
|
||||
if( -1 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, ns_in6addr_any, NULL, 0, process_cb))
|
||||
return false;
|
||||
|
||||
sn_coap_protocol_stub.expectedHeader = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s));
|
||||
|
@ -175,7 +176,7 @@ bool test_coap_message_handler_coap_msg_process()
|
|||
sn_coap_protocol_stub.expectedHeader->msg_id = 2;
|
||||
// sn_coap_protocol_stub.expectedHeader->token_ptr = (uint8_t*)malloc(4);
|
||||
// memset(sn_coap_protocol_stub.expectedHeader->token_ptr, 1, 4);
|
||||
if( -1 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, NULL, 0, process_cb))
|
||||
if( -1 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, ns_in6addr_any, NULL, 0, process_cb))
|
||||
return false;
|
||||
|
||||
// free(sn_coap_protocol_stub.expectedHeader->token_ptr);
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
include ../makefile_defines.txt
|
||||
|
||||
COMPONENT_NAME = coap_security_handler_unit
|
||||
|
||||
#This must be changed manually
|
||||
SRC_FILES = \
|
||||
../../../../source/coap_security_handler.c
|
||||
|
||||
TEST_SRC_FILES = \
|
||||
main.cpp \
|
||||
coap_security_handlertest.cpp \
|
||||
test_coap_security_handler.c \
|
||||
../stub/mbed_trace_stub.c \
|
||||
../stub/ns_list_stub.c \
|
||||
../stub/ns_timer_stub.c \
|
||||
../stub/mbedtls_stub.c \
|
||||
../stub/randLIB_stub.c \
|
||||
../stub/nsdynmemLIB_stub.c \
|
||||
../stub/socket_api_stub.c \
|
||||
|
||||
include ../MakefileWorker.mk
|
||||
|
||||
CPPUTESTFLAGS += -DFEA_TRACE_SUPPORT -DMBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED -DMBEDTLS_ECJPAKE_C -DMBEDTLS_SHA256_C -DMBEDTLS_ECP_DP_SECP256R1_ENABLED
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
#include "mbedtls_stub.h"
|
||||
#include "mbedtls/ssl.h"
|
||||
|
||||
static int send_to_socket(int8_t socket_id, uint8_t *address_ptr, uint16_t port, const unsigned char *buf, size_t len)
|
||||
static int send_to_socket(int8_t socket_id, void *handle, const unsigned char *buf, size_t len)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -30,27 +30,26 @@ static int timer_status_callback(int8_t timer_id)
|
|||
|
||||
bool test_thread_security_create()
|
||||
{
|
||||
uint8_t buf[16];
|
||||
if( NULL != coap_security_create(1,2,&buf,12,ECJPAKE,&send_to_socket, &receive_from_socket, &start_timer_callback, NULL) )
|
||||
if( NULL != coap_security_create(1,2,NULL,ECJPAKE,&send_to_socket, &receive_from_socket, &start_timer_callback, NULL) )
|
||||
return false;
|
||||
|
||||
if( NULL != coap_security_create(1,2,&buf,12,ECJPAKE,&send_to_socket, &receive_from_socket, &start_timer_callback, &timer_status_callback) )
|
||||
if( NULL != coap_security_create(1,2,NULL,ECJPAKE,&send_to_socket, &receive_from_socket, &start_timer_callback, &timer_status_callback) )
|
||||
return false;
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
mbedtls_stub.expected_int = -1;
|
||||
if( NULL != coap_security_create(1,2,&buf,12,ECJPAKE,&send_to_socket, &receive_from_socket, &start_timer_callback, &timer_status_callback) )
|
||||
if( NULL != coap_security_create(1,2,NULL,ECJPAKE,&send_to_socket, &receive_from_socket, &start_timer_callback, &timer_status_callback) )
|
||||
return false;
|
||||
|
||||
mbedtls_stub.expected_int = 0;
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
mbedtls_stub.crt_expected_int = -1;
|
||||
if( NULL != coap_security_create(1,2,&buf,12,ECJPAKE,&send_to_socket, &receive_from_socket, &start_timer_callback, &timer_status_callback) )
|
||||
if( NULL != coap_security_create(1,2,NULL,ECJPAKE,&send_to_socket, &receive_from_socket, &start_timer_callback, &timer_status_callback) )
|
||||
return false;
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
mbedtls_stub.crt_expected_int = 0;
|
||||
coap_security_t *handle = coap_security_create(1,2,&buf,12,ECJPAKE,&send_to_socket, &receive_from_socket, &start_timer_callback, &timer_status_callback);
|
||||
coap_security_t *handle = coap_security_create(1,2,NULL,ECJPAKE,&send_to_socket, &receive_from_socket, &start_timer_callback, &timer_status_callback);
|
||||
if( NULL == handle )
|
||||
return false;
|
||||
|
||||
|
@ -61,10 +60,9 @@ bool test_thread_security_create()
|
|||
|
||||
bool test_thread_security_destroy()
|
||||
{
|
||||
uint8_t buf[16];
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
mbedtls_stub.crt_expected_int = 0;
|
||||
coap_security_t *handle = coap_security_create(1,2,&buf,12,ECJPAKE,&send_to_socket, &receive_from_socket, &start_timer_callback, &timer_status_callback);
|
||||
coap_security_t *handle = coap_security_create(1,2,NULL,ECJPAKE,&send_to_socket, &receive_from_socket, &start_timer_callback, &timer_status_callback);
|
||||
if( NULL == handle )
|
||||
return false;
|
||||
|
||||
|
@ -74,10 +72,9 @@ bool test_thread_security_destroy()
|
|||
|
||||
bool test_coap_security_handler_connect()
|
||||
{
|
||||
uint8_t buf[16];
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
mbedtls_stub.crt_expected_int = 0;
|
||||
coap_security_t *handle = coap_security_create(1,2,&buf,12,ECJPAKE,&send_to_socket, &receive_from_socket, &start_timer_callback, &timer_status_callback);
|
||||
coap_security_t *handle = coap_security_create(1,2,NULL,ECJPAKE,&send_to_socket, &receive_from_socket, &start_timer_callback, &timer_status_callback);
|
||||
if( NULL == handle )
|
||||
return false;
|
||||
|
||||
|
@ -176,10 +173,9 @@ bool test_coap_security_handler_connect()
|
|||
|
||||
bool test_coap_security_handler_continue_connecting()
|
||||
{
|
||||
uint8_t buf[16];
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
mbedtls_stub.crt_expected_int = 0;
|
||||
coap_security_t *handle = coap_security_create(1,2,&buf,12,ECJPAKE,&send_to_socket, &receive_from_socket, &start_timer_callback, &timer_status_callback);
|
||||
coap_security_t *handle = coap_security_create(1,2,NULL,ECJPAKE,&send_to_socket, &receive_from_socket, &start_timer_callback, &timer_status_callback);
|
||||
if( NULL == handle )
|
||||
return false;
|
||||
|
||||
|
@ -224,10 +220,9 @@ bool test_coap_security_handler_continue_connecting()
|
|||
|
||||
bool test_coap_security_handler_send_message()
|
||||
{
|
||||
uint8_t buf[16];
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
mbedtls_stub.crt_expected_int = 0;
|
||||
coap_security_t *handle = coap_security_create(1,2,&buf,12,ECJPAKE,&send_to_socket, &receive_from_socket, &start_timer_callback, &timer_status_callback);
|
||||
coap_security_t *handle = coap_security_create(1,2,NULL,ECJPAKE,&send_to_socket, &receive_from_socket, &start_timer_callback, &timer_status_callback);
|
||||
if( NULL == handle )
|
||||
return false;
|
||||
|
||||
|
@ -245,10 +240,9 @@ bool test_coap_security_handler_send_message()
|
|||
|
||||
bool test_thread_security_send_close_alert()
|
||||
{
|
||||
uint8_t buf[16];
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
mbedtls_stub.crt_expected_int = 0;
|
||||
coap_security_t *handle = coap_security_create(1,2,&buf,12,ECJPAKE,&send_to_socket, &receive_from_socket, &start_timer_callback, &timer_status_callback);
|
||||
coap_security_t *handle = coap_security_create(1,2,NULL,ECJPAKE,&send_to_socket, &receive_from_socket, &start_timer_callback, &timer_status_callback);
|
||||
if( NULL == handle )
|
||||
return false;
|
||||
|
||||
|
@ -265,10 +259,9 @@ bool test_thread_security_send_close_alert()
|
|||
|
||||
bool test_coap_security_handler_read()
|
||||
{
|
||||
uint8_t buf[16];
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
mbedtls_stub.crt_expected_int = 0;
|
||||
coap_security_t *handle = coap_security_create(1,2,&buf,12,ECJPAKE,&send_to_socket, &receive_from_socket, &start_timer_callback, &timer_status_callback);
|
||||
coap_security_t *handle = coap_security_create(1,2,NULL,ECJPAKE,&send_to_socket, &receive_from_socket, &start_timer_callback, &timer_status_callback);
|
||||
if( NULL == handle )
|
||||
return false;
|
||||
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
include ../makefile_defines.txt
|
||||
|
||||
COMPONENT_NAME = coap_service_api_unit
|
||||
|
||||
#This must be changed manually
|
||||
SRC_FILES = \
|
||||
../../../../source/coap_service_api.c
|
||||
|
||||
TEST_SRC_FILES = \
|
||||
main.cpp \
|
||||
coap_service_apitest.cpp \
|
||||
test_coap_service_api.c \
|
||||
../stub/mbed_trace_stub.c \
|
||||
../stub/ns_list_stub.c \
|
||||
../stub/system_timer_stub.c \
|
||||
../stub/nsdynmemLIB_stub.c \
|
||||
../stub/eventOS_event_stub.c \
|
||||
../stub/coap_connection_handler_stub.c \
|
||||
../stub/coap_message_handler_stub.c \
|
||||
../stub/common_functions_stub.c
|
||||
|
||||
include ../MakefileWorker.mk
|
||||
|
||||
CPPUTESTFLAGS += -DFEA_TRACE_SUPPORT
|
||||
|
|
@ -330,14 +330,14 @@ bool test_conn_handler_callbacks()
|
|||
|
||||
if( thread_conn_handler_stub.receive_from_sock_cb ){
|
||||
coap_message_handler_stub.int16_value = 2;
|
||||
if( -1 != thread_conn_handler_stub.receive_from_sock_cb(1, buf, 12, NULL, 0))
|
||||
if( -1 != thread_conn_handler_stub.receive_from_sock_cb(1, buf, 12, NULL, NULL, 0))
|
||||
return false;
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
uint8_t * ptr = ns_dyn_mem_alloc(5);
|
||||
memset(ptr, 3, 5);
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
if( 2 != thread_conn_handler_stub.receive_from_sock_cb(1, buf, 12, ptr, 5))
|
||||
if( 2 != thread_conn_handler_stub.receive_from_sock_cb(1, buf, 12, NULL, ptr, 5))
|
||||
return false;
|
||||
ns_dyn_mem_free(ptr);
|
||||
coap_message_handler_stub.int16_value = 0;
|
||||
|
|
2
features/nanostack/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/makefile_defines.txt
Normal file → Executable file
2
features/nanostack/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/makefile_defines.txt
Normal file → Executable file
|
@ -32,7 +32,7 @@ INCLUDE_DIRS =\
|
|||
$(CPPUTEST_HOME)/include\
|
||||
|
||||
CPPUTESTFLAGS = -D__thumb2__ -w
|
||||
CPPUTEST_CFLAGS += -std=gnu99
|
||||
CPPUTEST_CFLAGS += -std=gnu99 -DNS_USE_EXTERNAL_MBED_TLS
|
||||
|
||||
#if you need to use -std=c++11 or c++0x you need to uncomment this
|
||||
#CPPUTESTFLAGS += -DCPPUTEST_STD_CPP_LIB_DISABLED
|
||||
|
|
|
@ -20,8 +20,8 @@ int coap_connection_handler_virtual_recv(coap_conn_handler_t *handler, uint8_t a
|
|||
return thread_conn_handler_stub.int_value;
|
||||
}
|
||||
|
||||
coap_conn_handler_t *connection_handler_create(int (*recv_cb)(int8_t socket_id, uint8_t address[static 16], uint16_t port, unsigned char *, int),
|
||||
int (*send_cb)(int8_t socket_id, uint8_t address[static 16], uint16_t port, const unsigned char *, int),
|
||||
coap_conn_handler_t *connection_handler_create(int (*recv_cb)(int8_t socket_id, uint8_t src_address[static 16], uint16_t port, const uint8_t dst_address[static 16], unsigned char *, int),
|
||||
int (*send_cb)(int8_t socket_id, uint8_t const address[static 16], uint16_t port, const void *, int),
|
||||
int (*pw_cb)(int8_t socket_id, uint8_t address[static 16], uint16_t port, uint8_t *pw_ptr, uint8_t *pw_len),
|
||||
void(*done_cb)(int8_t socket_id, uint8_t address[static 16], uint16_t port, uint8_t keyblock[static KEY_BLOCK_LEN]) )
|
||||
{
|
||||
|
@ -46,7 +46,7 @@ int coap_connection_handler_open_connection(coap_conn_handler_t *handler, uint16
|
|||
return thread_conn_handler_stub.int_value;
|
||||
}
|
||||
|
||||
int coap_connection_handler_send_data(coap_conn_handler_t *handler, ns_address_t *dest_addr, uint8_t *data_ptr, uint16_t data_len, bool bypass_link_sec)
|
||||
int coap_connection_handler_send_data(coap_conn_handler_t *handler, const ns_address_t *dest_addr, const uint8_t dst_address[static 16], uint8_t *data_ptr, uint16_t data_len, bool bypass_link_sec)
|
||||
{
|
||||
return thread_conn_handler_stub.int_value;
|
||||
}
|
||||
|
|
|
@ -32,8 +32,8 @@ typedef struct {
|
|||
bool bool_value;
|
||||
coap_conn_handler_t *handler_obj;
|
||||
|
||||
int (*send_to_sock_cb)(int8_t socket_id, uint8_t address[static 16], uint16_t port, const unsigned char *, int);
|
||||
int (*receive_from_sock_cb)(int8_t socket_id, uint8_t address[static 16], uint16_t port, unsigned char *, int);
|
||||
int (*send_to_sock_cb)(int8_t socket_id, uint8_t address[static 16], uint16_t port, const void *, int);
|
||||
int (*receive_from_sock_cb)(int8_t socket_id, uint8_t src_address[static 16], uint16_t port, const uint8_t dst_address[static 16], unsigned char *data, int len);
|
||||
int (*get_passwd_cb)(int8_t socket_id, uint8_t address[static 16], uint16_t port, uint8_t *pw_ptr, uint8_t *pw_len);
|
||||
void (*sec_done_cb)(int8_t socket_id, uint8_t address[static 16], uint16_t port, uint8_t keyblock[static 40]);
|
||||
|
||||
|
|
|
@ -17,6 +17,15 @@ coap_msg_handler_t *coap_message_handler_init(void *(*used_malloc_func_ptr)(uint
|
|||
return coap_message_handler_stub.coap_ptr;
|
||||
}
|
||||
|
||||
void transaction_delete(coap_transaction_t *this)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void transactions_delete_all(uint8_t *address_ptr, uint16_t port)
|
||||
{
|
||||
|
||||
}
|
||||
int8_t coap_message_handler_destroy(coap_msg_handler_t *handle)
|
||||
{
|
||||
return coap_message_handler_stub.int8_value;
|
||||
|
@ -32,7 +41,7 @@ coap_transaction_t *coap_message_handler_find_transaction(uint8_t *address_ptr,
|
|||
return coap_message_handler_stub.coap_tx_ptr;
|
||||
}
|
||||
|
||||
int16_t coap_message_handler_coap_msg_process(coap_msg_handler_t *handle, int8_t socket_id, uint8_t source_addr_ptr[static 16], uint16_t port,
|
||||
int16_t coap_message_handler_coap_msg_process(coap_msg_handler_t *handle, int8_t socket_id, const uint8_t source_addr_ptr[static 16], uint16_t port, const uint8_t dst_addr_ptr[static 16],
|
||||
uint8_t *data_ptr, uint16_t data_len, int16_t (cb)(int8_t, sn_coap_hdr_s *, coap_transaction_t *))
|
||||
{
|
||||
coap_message_handler_stub.cb = cb;
|
||||
|
|
|
@ -12,8 +12,12 @@
|
|||
|
||||
thread_sec_def coap_security_handler_stub;
|
||||
|
||||
coap_security_t *coap_security_create(int8_t socket_id, int8_t timer_id, uint8_t *address_ptr, uint16_t port, SecureConnectionMode mode,
|
||||
int (*send_cb)(int8_t socket_id, uint8_t *address_ptr, uint16_t port, const unsigned char *, size_t),
|
||||
struct coap_security_s {
|
||||
bool _is_started;
|
||||
};
|
||||
|
||||
coap_security_t *coap_security_create(int8_t socket_id, int8_t timer_id, void *handle, SecureConnectionMode mode,
|
||||
int (*send_cb)(int8_t socket_id, void *handle, const void *, size_t),
|
||||
int (*receive_cb)(int8_t socket_id, unsigned char *, size_t),
|
||||
void (*start_timer_cb)(int8_t timer_id, uint32_t min, uint32_t fin),
|
||||
int (*timer_status_cb)(int8_t timer_id))
|
||||
|
@ -25,6 +29,12 @@ coap_security_t *coap_security_create(int8_t socket_id, int8_t timer_id, uint8_t
|
|||
return coap_security_handler_stub.sec_obj;
|
||||
}
|
||||
|
||||
coap_security_t *coap_security_handler_stub_alloc(void)
|
||||
{
|
||||
return calloc(1, sizeof(coap_security_t));
|
||||
}
|
||||
|
||||
|
||||
void coap_security_destroy(coap_security_t *sec)
|
||||
{
|
||||
|
||||
|
@ -72,3 +82,13 @@ int coap_security_handler_read(coap_security_t *sec, unsigned char* buffer, size
|
|||
}
|
||||
return coap_security_handler_stub.int_value;
|
||||
}
|
||||
|
||||
bool coap_security_handler_is_started(const coap_security_t *sec)
|
||||
{
|
||||
return sec->_is_started;
|
||||
}
|
||||
|
||||
const void *coap_security_handler_keyblock(const coap_security_t *sec)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ typedef struct tsh{
|
|||
int counter;
|
||||
int values[10];
|
||||
|
||||
int (*send_cb)(int8_t socket_id, uint8_t *address_ptr, uint16_t port, const unsigned char *, size_t);
|
||||
int (*send_cb)(int8_t socket_id, const uint8_t *address_ptr, uint16_t port, const void *, size_t);
|
||||
int (*receive_cb)(int8_t socket_id, unsigned char *, size_t);
|
||||
void (*start_timer_cb)(int8_t timer_id, uint32_t min, uint32_t fin);
|
||||
int (*timer_status_cb)(int8_t timer_id);
|
||||
|
@ -35,4 +35,6 @@ typedef struct tsh{
|
|||
|
||||
extern thread_sec_def coap_security_handler_stub;
|
||||
|
||||
coap_security_t *coap_security_handler_stub_alloc(void);
|
||||
|
||||
#endif //__COAP_SECURITY_HANDLER_STUB_H__
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
#include "common_functions.h"
|
||||
#include "net_interface.h"
|
||||
|
||||
coap_msg_handler_t *coap_service_handle = NULL;
|
||||
|
||||
int8_t coap_service_initialize(int8_t interface_id, uint16_t listen_port, uint8_t service_options,
|
||||
coap_service_security_start_cb *start_ptr, coap_service_security_done_cb *coap_security_done_cb)
|
||||
{
|
||||
|
@ -62,3 +64,8 @@ uint32_t coap_service_get_internal_timer_ticks(void)
|
|||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint16_t coap_service_id_find_by_socket(int8_t socket_id)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* Copyright (c) 2016 ARM Limited. All rights reserved.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "ns_types.h"
|
||||
|
||||
uint16_t common_read_16_bit(const uint8_t data_buf[__static 2])
|
||||
{
|
||||
return 0;
|
||||
}
|
|
@ -33,12 +33,12 @@ uint32_t randLIB_get_32bit(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int8_t randLIB_get_n_bytes_random(uint8_t *data_ptr, uint8_t eight_bit_boundary)
|
||||
void *randLIB_get_n_bytes_random(void *data_ptr, uint8_t count)
|
||||
{
|
||||
if(data_ptr && eight_bit_boundary > 0){
|
||||
data_ptr[0] = counter++%255;
|
||||
if(data_ptr && count > 0){
|
||||
*((int*)data_ptr) = counter++%255;
|
||||
}
|
||||
return 0;
|
||||
return data_ptr;
|
||||
}
|
||||
|
||||
uint16_t randLIB_get_random_in_range(uint16_t min, uint16_t max)
|
||||
|
|
|
@ -94,3 +94,7 @@ coap_send_msg_s *sn_coap_protocol_allocate_mem_for_msg(struct coap_s *handle, sn
|
|||
return sn_coap_protocol_stub.expectedSendMsg;
|
||||
}
|
||||
|
||||
int8_t sn_coap_protocol_delete_retransmission(struct coap_s *handle, uint16_t msg_id)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "socket_api_stub.h"
|
||||
|
||||
socket_api_stub_data_t socket_api_stub;
|
||||
const uint8_t ns_in6addr_any[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
int8_t socket_raw_open(void (*passed_fptr)(void *))
|
||||
{
|
||||
|
@ -24,7 +25,7 @@ int8_t socket_open(uint8_t protocol, uint16_t identifier, void (*passed_fptr)(vo
|
|||
return socket_api_stub.int8_value;
|
||||
}
|
||||
|
||||
int8_t socket_free(int8_t socket)
|
||||
int8_t socket_close(int8_t socket)
|
||||
{
|
||||
if( socket_api_stub.counter >= 0){
|
||||
return socket_api_stub.values[socket_api_stub.counter--];
|
||||
|
@ -32,7 +33,7 @@ int8_t socket_free(int8_t socket)
|
|||
|
||||
return socket_api_stub.int8_value;
|
||||
}
|
||||
int8_t socket_listen(int8_t socket)
|
||||
int8_t socket_listen(int8_t socket, uint8_t backlog)
|
||||
{
|
||||
if( socket_api_stub.counter >= 0){
|
||||
return socket_api_stub.values[socket_api_stub.counter--];
|
||||
|
@ -56,14 +57,7 @@ int8_t socket_bind(int8_t socket, const ns_address_t *address)
|
|||
|
||||
return socket_api_stub.int8_value;
|
||||
}
|
||||
int8_t socket_close(int8_t socket, ns_address_t *address)
|
||||
{
|
||||
if( socket_api_stub.counter >= 0){
|
||||
return socket_api_stub.values[socket_api_stub.counter--];
|
||||
}
|
||||
|
||||
return socket_api_stub.int8_value;
|
||||
}
|
||||
int8_t socket_send(int8_t socket, uint8_t *buffer, uint16_t length)
|
||||
{
|
||||
if( socket_api_stub.counter >= 0){
|
||||
|
@ -116,3 +110,22 @@ int8_t socket_getsockopt(int8_t socket, uint8_t level, uint8_t opt_name, void *o
|
|||
|
||||
return socket_api_stub.int8_value;
|
||||
}
|
||||
|
||||
int8_t socket_sendmsg(int8_t socket, const ns_msghdr_t *msg, int flags)
|
||||
{
|
||||
if( socket_api_stub.counter >= 0){
|
||||
return socket_api_stub.values[socket_api_stub.counter--];
|
||||
}
|
||||
|
||||
return socket_api_stub.int8_value;
|
||||
}
|
||||
|
||||
int16_t socket_recvmsg(int8_t socket, ns_msghdr_t *msg, int flags)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
ns_cmsghdr_t *NS_CMSG_NXTHDR(const ns_msghdr_t *msgh, const ns_cmsghdr_t *cmsg)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -162,17 +162,9 @@ NanostackSocket::~NanostackSocket()
|
|||
if (mode != SOCKET_MODE_CLOSED) {
|
||||
close();
|
||||
}
|
||||
if (socket_id >= 0) {
|
||||
nsapi_error_t ret = socket_free(socket_id);
|
||||
MBED_ASSERT(0 == ret);
|
||||
MBED_ASSERT(socket_tbl[socket_id] == this);
|
||||
socket_tbl[socket_id] = NULL;
|
||||
socket_id = -1;
|
||||
data_free_all();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool NanostackSocket::open(void)
|
||||
{
|
||||
nanostack_assert_locked();
|
||||
|
@ -205,8 +197,11 @@ void NanostackSocket::close()
|
|||
MBED_ASSERT(mode != SOCKET_MODE_CLOSED);
|
||||
|
||||
if (socket_id >= 0) {
|
||||
nsapi_error_t ret = socket_close(socket_id, (addr_valid ? &ns_address : NULL));
|
||||
nsapi_error_t ret = socket_close(socket_id);
|
||||
MBED_ASSERT(0 == ret);
|
||||
MBED_ASSERT(socket_tbl[socket_id] == this);
|
||||
socket_tbl[socket_id] = NULL;
|
||||
socket_id = -1;
|
||||
} else {
|
||||
MBED_ASSERT(SOCKET_MODE_UNOPENED == mode);
|
||||
}
|
||||
|
@ -281,14 +276,14 @@ void NanostackSocket::socket_callback(void *cb) {
|
|||
tr_debug("SOCKET_BIND_DONE");
|
||||
socket->event_bind_done(sock_cb);
|
||||
break;
|
||||
case SOCKET_BIND_FAIL: // Not used in NS
|
||||
case SOCKET_BIND_FAIL:
|
||||
tr_debug("SOCKET_BIND_FAIL");
|
||||
break;
|
||||
case SOCKET_BIND_AUTH_FAIL: // Not used in NS
|
||||
case SOCKET_BIND_AUTH_FAIL:
|
||||
tr_debug("SOCKET_BIND_AUTH_FAIL");
|
||||
break;
|
||||
case SOCKET_SERVER_CONNECT_TO_CLIENT: // Not used in NS
|
||||
tr_debug("SOCKET_SERVER_CONNECT_TO_CLIENT");
|
||||
case SOCKET_INCOMING_CONNECTION:
|
||||
tr_debug("SOCKET_INCOMING_CONNECTION");
|
||||
break;
|
||||
case SOCKET_TX_FAIL:
|
||||
tr_debug("SOCKET_TX_FAIL");
|
||||
|
@ -297,8 +292,8 @@ void NanostackSocket::socket_callback(void *cb) {
|
|||
tr_debug("SOCKET_CONNECT_CLOSED");
|
||||
socket->event_connnect_closed(sock_cb);
|
||||
break;
|
||||
case SOCKET_CONNECT_FAIL_CLOSED: // Not used in NS
|
||||
tr_debug("SOCKET_CONNECT_FAIL_CLOSED");
|
||||
case SOCKET_CONNECTION_RESET:
|
||||
tr_debug("SOCKET_CONNECTION_RESET");
|
||||
break;
|
||||
case SOCKET_NO_ROUTE:
|
||||
tr_debug("SOCKET_NO_ROUTE");
|
||||
|
|
|
@ -20,7 +20,7 @@ TCP, UDP, or ICMP packets can be sent and received using the socket interface AP
|
|||
|
||||
For UDP/ICMP, a socket is ready to send and receive data after a successful call to `socket_open()` and when the `NET_READY` event has been received.
|
||||
|
||||
For TCP, when a socket is opened it is in _closed_ state. It must be set to either _listen_ or _connect_ state before using it for receiving or transmitting data. To receive data, the socket can be set to listen mode by calling `socket_listen()`. After that, the socket can accept an incoming connection from a remote host. To send data, `socket_connect()` is called with a set of arguments. When the socket event has confirmed the state change of the socket, data can then be sent using `socket_send()`. The function call `socket_close()` is used to close the socket.
|
||||
For TCP, when a socket is opened it is in _closed_ state. It must be set to either _listen_ or _connect_ state before using it for receiving or transmitting data. To receive data, the socket can be set to listen mode by calling `socket_listen()`. After that, the socket can accept an incoming connection from a remote host. To send data, `socket_connect()` is called with a set of arguments. When the socket event has confirmed the state change of the socket, data can then be sent using `socket_send()`. The function call `socket_shutdown()` is used to shut down the socket.
|
||||
|
||||
## Features
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@ This manual describes the APIs regarding the ARM mbed Networking stack, for exam
|
|||
|
||||
As Thread runs on top of the 6LoWPAN stack, most of the networking stack functionality is shared. However, when building the stack you can cherry-pick the features, configurations or functionalities. In such case, please refer to [Build time configurations](quick_start_build.md).
|
||||
|
||||
To read even more of the APIs, check the [Doxygen documentation](https://docs.mbed.com/docs/arm-ipv66lowpan-stack/en/latest/api/index.html).
|
||||
|
||||
## Intended audience
|
||||
|
||||
This manual has been written for experienced software developers to assist with using the ARM software product range.
|
||||
|
|
|
@ -85,10 +85,10 @@ Event type|Description
|
|||
`SOCKET_BIND_DONE`|TCP connection ready.
|
||||
`SOCKET_BIND_FAIL`|TCP connection failed.
|
||||
`SOCKET_BIND_AUTH_FAIL`|TCP connection authentication failed.
|
||||
`SOCKET_SERVER_CONNECT_TO_CLIENT`|TCP connection state change from listen to establishment.
|
||||
`SOCKET_INCOMING_CONNECTION`|TCP connection state change from listen to establishment.
|
||||
`SOCKET_TX_FAIL`|Socket data send failed.
|
||||
`SOCKET_CONNECT_CLOSED`|TCP connection closed.
|
||||
`SOCKET_CONNECT_FAIL_CLOSED`|TCP connection closed - no ACK received.
|
||||
`SOCKET_CONNECTION_RESET`|TCP connection reset.
|
||||
`SOCKET_NO_ROUTER`|No route available to destination.
|
||||
`SOCKET_TX_DONE`|Last socket TX process done, in TCP case whole TCP process is ready.
|
||||
`SOCKET_NO_RAM `|If no RAM is present.
|
||||
|
@ -143,7 +143,7 @@ To connect the TCP socket to a remote host, call `socket_connect( )` with the co
|
|||
|
||||
After receiving a successful state event, data can be sent using the `socket_send( )` call.
|
||||
|
||||
The connection can be closed by calling function `socket_close( )`. The 6LoWPAN stack closes the connection automatically after a server timeout or when the remote end closes the connection. When the socket is no longer needed it must be released by calling the function `socket_free( )`.
|
||||
The connection can be shut down by calling function `socket_shutdown( )`. The 6LoWPAN stack shuts down the connection automatically after a server timeout or when the remote end closes the connection. When the socket is no longer needed it must be released by calling the function `socket_close( )`.
|
||||
|
||||
## Using UDP and ICMP sockets
|
||||
|
||||
|
@ -182,7 +182,7 @@ Parameter|Description
|
|||
|
||||
To release a socket:
|
||||
|
||||
`int8_t socket_free( int8_t socket )`
|
||||
`int8_t socket_close( int8_t socket )`
|
||||
|
||||
Parameter|Description
|
||||
---------|-----------
|
||||
|
@ -302,7 +302,7 @@ Response Event|Socket Type|Description
|
|||
--------------|-----------|-----------
|
||||
`SOCKET_TX_DONE`|TCP/UDP|UDP link layer TX ready/TCP TX process ready by TCP _Acknowledgement_ (ACK).
|
||||
`SOCKET_TX_FAIL`|UDP|UDP link layer TX fails.
|
||||
`SOCKET_CONNECT_FAIL_CLOSED`|TCP|TX process fails and connection closed.
|
||||
`SOCKET_CONNECTION_RESET`|TCP|TX process fails and connection closed.
|
||||
|
||||
To transmit data on an unconnected socket:
|
||||
|
||||
|
@ -365,20 +365,22 @@ Function|Description
|
|||
--------|-----------
|
||||
`socket_listen()`|Set socket to the listen state.
|
||||
`socket_connect()`|Connect socket to a host.
|
||||
`socket_close()`|Close socket connection.
|
||||
`socket_shutdown()`|Shut down socket connection.
|
||||
|
||||
To set a TCP socket into the listen state:
|
||||
|
||||
```
|
||||
int8_t socket_listen
|
||||
(
|
||||
int8_t socket
|
||||
|
||||
int8_t socket,
|
||||
uint8_t backlog
|
||||
)
|
||||
```
|
||||
|
||||
Parameter|Description
|
||||
---------|-----------
|
||||
`socket`|The socket ID that is to be set to the listen state.
|
||||
`backlog`|The pending connections queue size. (Not yet implemented).
|
||||
|
||||
<dl>
|
||||
<dt>Return value</dt>
|
||||
|
@ -419,20 +421,20 @@ There are two possible responses from the stack for `socket_connect( )`:
|
|||
- `SOCKET_CONNECT_FAIL_CLOSED`
|
||||
- TCP handshake fail.
|
||||
|
||||
To close a TCP connection:
|
||||
To shut down a TCP connection:
|
||||
|
||||
```
|
||||
int8_t socket_close
|
||||
|
||||
int8_t socket_shutdown
|
||||
(
|
||||
int8_t socket,
|
||||
ns_address_t *address
|
||||
uint8_t how
|
||||
)
|
||||
```
|
||||
|
||||
Parameter|Description
|
||||
---------|-----------
|
||||
`socket`|The socket ID of the socket to be disconnected from the remote host.
|
||||
`address`|The destination client address; a client should use a null pointer for this parameter.
|
||||
`socket`|The socket ID of the socket to be shut down.
|
||||
`how`|How socket is to be shut down, one of `SOCKET_SHUT_RD`, `SOCKET_SHUT_WR` or `SOCKET_SHUT_RDWR`.
|
||||
|
||||
<dl>
|
||||
<dt>Return value</dt>
|
||||
|
|
|
@ -414,8 +414,8 @@ int8_t arm_nwk_6lowpan_link_panid_filter_for_nwk_scan
|
|||
Parameter|Description
|
||||
---------|-----------
|
||||
`interface_id`|The network interface ID.
|
||||
`pan_id_filter`|Values `0x0000-0xFFFD` enable the filter for a specific ID.<br>
|
||||
The value `0xFFFE` or `0xFFFF` (default) disables the filter.
|
||||
`pan_id_filter`|Values `0x0000-0xFFFE` enable the filter for a specific ID.<br>
|
||||
The value `0xFFFF` (default) disables the filter.
|
||||
|
||||
<dl>
|
||||
<dt>Return value</dt>
|
||||
|
|
|
@ -70,8 +70,11 @@ Various types of network stats can be collected using the structure `typedef str
|
|||
Member|Description
|
||||
------|-----------
|
||||
`mac_tx_buffer_overflow`|Provides a count MAC TX queue overflow.
|
||||
`mac_tx_queue_size`|Current MAC TX queue size.
|
||||
`mac_tx_queue_peak`|MAC TX queue peak size.
|
||||
`mac_rx_count`|Number of received MAC packets.
|
||||
`mac_tx_count`|Number of transmitted MAC packets.
|
||||
`mac_bc_tx_count`|>Number of transmitted MAC broadcast packets.
|
||||
`mac_rx_drop`|Number of dropped MAC packets.
|
||||
|
||||
### MAC payload flow
|
||||
|
@ -86,6 +89,17 @@ Member|Description
|
|||
`mac_tx_failed_cca`|Number of failed CCA attempts.
|
||||
`mac_security_drop`|Number of security packets dropped.
|
||||
|
||||
### FHSS related statistics
|
||||
|
||||
Member|Description
|
||||
------|-----------
|
||||
`fhss_drift_compensation`|FHSS synchronization drift compensation (us/channel).
|
||||
`fhss_hop_count`|FHSS hop count.
|
||||
`fhss_synch_parent_rssi`|FHSS synchronization parent RSSI.
|
||||
`fhss_synch_interval`|FHSS synchronization interval (s).
|
||||
`fhss_prev_avg_synch_fix`|Average of 5 preceding synchronization fixes (us).
|
||||
`fhss_synch_lost`|FHSS synchronization lost counter.
|
||||
|
||||
### 6LoWPAN related statistics
|
||||
|
||||
Member|Description
|
||||
|
@ -134,3 +148,10 @@ Member|Description
|
|||
`buf_headroom_realloc`|A buffer headroom allocation count.
|
||||
`buf_headroom_shuffle`|A buffer headroom shuffling count.
|
||||
`buf_headroom_fail`|A buffer headroom failure count.
|
||||
|
||||
### ETX statistics
|
||||
|
||||
Member|Description
|
||||
------|-----------
|
||||
`etx_1st_parent`|Primary parent ETX.
|
||||
`etx_2nd_parent`|Secondary parent ETX.
|
||||
|
|
|
@ -26,17 +26,17 @@ The mbed OS port of Nanostack consist of a few helper modules that provide easie
|
|||
|
||||

|
||||
|
||||
* [mbed Mesh API](https://github.com/ARMmbed/mbed-mesh-api) controls and initializes Nanostack on mbed OS.
|
||||
* [mbed Mesh API](https://github.com/ARMmbed/mbed-os/tree/master/features/nanostack/FEATURE_NANOSTACK/mbed-mesh-api) controls and initializes Nanostack on mbed OS.
|
||||
* Security settings.
|
||||
* Channel configuration.
|
||||
* Connection and reconnection logic.
|
||||
* [nanostack-hal-mbed-cmsis-rtos](https://github.com/ARMmbed/nanostack-hal-mbed-cmsis-rtos) implements Platform API for mbed OS.
|
||||
* [nanostack-hal-mbed-cmsis-rtos](https://github.com/ARMmbed/mbed-os/tree/master/features/FEATURE_COMMON_PAL/nanostack-hal-mbed-cmsis-rtos) implements Platform API for mbed OS.
|
||||
* An internal event handler is initialized when the stack starts.
|
||||
* The event handler is running in its own thread. Not visible for users.
|
||||
* `NanostackInterface` class implements Socket API.
|
||||
* [NanostackInterface](https://github.com/ARMmbed/mbed-os/tree/master/features/nanostack/FEATURE_NANOSTACK/nanostack-interface) class implements the network stack abstration for the socket layer.
|
||||
* Initializes the RF driver. See [Providing RF driver](#providing-rf-driver-for-mbed-os-applications).
|
||||
|
||||
In mbed OS, Socket API hides the differences between networking stacks. Users will only use one of its high level APIs:
|
||||
In mbed OS, Socket API hides the differences between the networking stacks. Users will only use one of its high level APIs:
|
||||
|
||||
* UDPSocket
|
||||
* TCPSocket
|
||||
|
@ -46,45 +46,22 @@ In mbed OS, Socket API hides the differences between networking stacks. Users wi
|
|||
|
||||
For an example of a simple application using Nanostack, see [Example mesh application for mbed OS](https://github.com/ARMmbed/mbed-os-example-mesh-minimal).
|
||||
|
||||
For documentation of Socket API see following links
|
||||
For documentation of Socket API see the following links
|
||||
|
||||
* [Socket API: Getting started](https://developer.mbed.org/teams/NetworkSocketAPI/wiki/Getting-Started)
|
||||
* [Socket API: Doxygen](https://developer.mbed.org/teams/NetworkSocketAPI/code/NetworkSocketAPI/docs/tip/)
|
||||
|
||||
#### Providing RF driver for mbed OS applications
|
||||
|
||||
For mbed OS 5, the RF driver actually lives outside the OS tree and is called from `NanostackInterface` in the initialization phase.
|
||||
For mbed OS 5, the RF driver implements the `NanostackRfPhy` API.
|
||||
`MeshInterfaceNanostack` requires the driver object to be provided when
|
||||
initializing.
|
||||
|
||||
`NanostackInterface` requires the driver to provide the following API:
|
||||

|
||||
|
||||
**Header:** `driverRFPhy.h`
|
||||
Applications use only `LoWPANNDInterface` or `ThreadInterface` directly to set up the network and provide a driver. Rest of the classes provide an abstration between Nanostack and Socket layers of mbed OS.
|
||||
|
||||
```
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "nanostack/platform/arm_hal_phy.h"
|
||||
|
||||
/** Registers RF driver to Nanostack.
|
||||
* \return driver ID
|
||||
*/
|
||||
int8_t rf_device_register(void);
|
||||
|
||||
/** Read EUI64 address from the device and write to pointer.
|
||||
* \param ptr Pointer to location where to copy the address.
|
||||
*/
|
||||
void rf_read_mac_address(uint8_t *ptr);
|
||||
|
||||
/** Return RF noise level from device.
|
||||
* Used to seed a internal pseudorandom generator.
|
||||
* \return random number.
|
||||
*/
|
||||
int8_t rf_read_random(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
```
|
||||
See [NanostackRfPhy.h](https://github.com/ARMmbed/mbed-os/blob/master/features/nanostack/FEATURE_NANOSTACK/nanostack-interface/NanostackRfPhy.h) for an up-to-date header file and API.
|
||||
|
||||
Driver API used for communication between the driver and Nanostack is documented in section [_Device Driver API_](driver_api.md).
|
||||
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
@startuml
|
||||
|
||||
class NanostackRfPhy {
|
||||
+int8_t rf_register()
|
||||
+int8_t rf_register()
|
||||
+void get_mac_address(uint8_t *mac)
|
||||
+void set_mac_address(uint8_t *mac)
|
||||
}
|
||||
|
||||
class MeshInterfaceNanostack {
|
||||
}
|
||||
MeshInterfaceNanostack o-- NanostackRfPhy
|
||||
MeshInterfaceNanostack o-- AbstractMesh
|
||||
MeshInterfaceNanostack o-- NanostackInterface
|
||||
|
||||
class MeshInterface {
|
||||
}
|
||||
NanostackInterface --|> NetworkStack
|
||||
MeshInterfaceNanostack --|> MeshInterface
|
||||
MeshInterface --|> NetworkInterface
|
||||
|
||||
LoWPANNDInterface --|> MeshInterfaceNanostack
|
||||
ThreadInterface --|> MeshInterfaceNanostack
|
||||
|
||||
AbstractMesh --|> AbstractNetworkInterface
|
||||
class AbstractNetworkInterface
|
||||
|
||||
@enduml
|
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
|
@ -14,7 +14,7 @@ Option Name | Features supported | Current binary size v2.1.13
|
|||
`lowpan_border_router_rf_tunnel` | 6LoWPAN-ND border router using an external microcontroller running the low level MAC functionality. | 313 kB
|
||||
`lowpan_host` | 6LoWPAN-ND not routing host mode. | 194 kB
|
||||
`lowpan_router` | 6LoWPAN-ND routing host mode. | 230 kB
|
||||
`mbedOS` | Everything but without security features (PANA, ECC, ECJPAKE). | 382 kB
|
||||
`nanostack_full` | Everything but without security features (PANA, ECC, ECJPAKE). | 382 kB
|
||||
`rf_interface` | RF interface running only low level MAC. To be used with `lowpan_border_router_rf_tunnel`. | 168 kB
|
||||
`thread_border_router` | Thread router device with border router capability. | 320 kB
|
||||
`thread_router` | Thread host with routing capability. | 302 kB
|
||||
|
@ -26,7 +26,7 @@ They will differ based on the toolchains or the status of the repository. The fi
|
|||
|
||||
For mbed OS 5.0, there will be only one binary module available. This is a temporary solution for mbed OS 5.0 toolchain and will be updated to support multiple configurations later.
|
||||
|
||||
The binary module for mbed OS 5.0 follows the `mbedOS` configuration.
|
||||
The binary module for mbed OS 5.0 follows the `nanostack_full` configuration.
|
||||
|
||||
## Using configuration option on mbed OS 3.0
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "nanostack",
|
||||
"config": {
|
||||
"configuration": "mbedOS"
|
||||
"configuration": "nanostack_full"
|
||||
},
|
||||
"macros": ["NS_USE_EXTERNAL_MBED_TLS"]
|
||||
}
|
||||
|
|
|
@ -249,6 +249,8 @@ typedef enum {
|
|||
macAutoRequestKeyIndex = 0x7b, /*>The index of the key used for automatic data*/
|
||||
macDefaultKeySource = 0x7c, /*>Default key source*/
|
||||
//NON standard extension
|
||||
macLoadBalancingBeaconTxPeriod = 0xfd, /*> Set Beacon periodic Tx interval.Value size uint16_t in seconds, Use 0 to disable */
|
||||
macLoadBalancingAcceptAnyBeacon = 0xfe, /*>Beacon accept state control from other network. Value size bool, data true=Enable, false=disable .*/
|
||||
macThreadForceLongAddressForBeacon = 0xff /*>Thread standard force beacon source address for extended 64-bit*/
|
||||
} mlme_attr_t;
|
||||
|
||||
|
|
|
@ -79,27 +79,27 @@ typedef enum arm_library_event_type_e {
|
|||
/** Socket event mask. */
|
||||
#define SOCKET_EVENT_MASK 0xF0
|
||||
/** Data received. */
|
||||
#define SOCKET_DATA 0
|
||||
#define SOCKET_DATA (0 << 4)
|
||||
/** TCP connection ready. */
|
||||
#define SOCKET_BIND_DONE 1 << 4
|
||||
#define SOCKET_BIND_DONE (1 << 4)
|
||||
/** TCP connection failure. */
|
||||
#define SOCKET_BIND_FAIL 2 << 4
|
||||
#define SOCKET_BIND_FAIL (2 << 4)
|
||||
/** TCP connection authentication failed. */
|
||||
#define SOCKET_BIND_AUTH_FAIL 3 << 4
|
||||
/** TCP state from listen to establishment. */
|
||||
#define SOCKET_SERVER_CONNECT_TO_CLIENT 4 << 4
|
||||
#define SOCKET_BIND_AUTH_FAIL (3 << 4)
|
||||
/** TCP incoming connection attempt to listening socket */
|
||||
#define SOCKET_INCOMING_CONNECTION (4 << 4)
|
||||
/** Socket data send failure. */
|
||||
#define SOCKET_TX_FAIL 5 << 4
|
||||
#define SOCKET_TX_FAIL (5 << 4)
|
||||
/** TCP connection closed. */
|
||||
#define SOCKET_CONNECT_CLOSED 6 << 4
|
||||
/** TCP connection closed because no ACK received. */
|
||||
#define SOCKET_CONNECT_FAIL_CLOSED 7 << 4
|
||||
#define SOCKET_CONNECT_CLOSED (6 << 4)
|
||||
/** TCP connection reset */
|
||||
#define SOCKET_CONNECTION_RESET (7 << 4)
|
||||
/** No route available to the destination. */
|
||||
#define SOCKET_NO_ROUTE 8 << 4
|
||||
#define SOCKET_NO_ROUTE (8 << 4)
|
||||
/** Socket TX done. */
|
||||
#define SOCKET_TX_DONE 9 << 4
|
||||
#define SOCKET_TX_DONE (9 << 4)
|
||||
/** Out of memory failure. */
|
||||
#define SOCKET_NO_RAM 10 << 4
|
||||
#define SOCKET_NO_RAM (10 << 4)
|
||||
|
||||
/*!
|
||||
* \enum net_security_t
|
||||
|
@ -477,7 +477,7 @@ extern int8_t arm_nwk_6lowpan_link_scan_parameter_set(int8_t interface_id, uint8
|
|||
* \brief A function to set the PAN ID filter.
|
||||
*
|
||||
* \param interface_id Network interface ID.
|
||||
* \param pan_id_filter The PAN ID to be allowed value 0xffff clean filter.
|
||||
* \param pan_id_filter Enable filter for specific PAN ID. 0xffff disables the filter.
|
||||
*
|
||||
* \return 0 Filter set OK.
|
||||
* \return -1 Unknown Network interface ID.
|
||||
|
|
|
@ -243,6 +243,17 @@ int thread_test_increment_key_sequence_counter(int8_t interface_id);
|
|||
*/
|
||||
int thread_test_key_sequence_counter_update(int8_t interface_id, uint32_t thrKeySequenceCounter);
|
||||
|
||||
/**
|
||||
* \brief Set new Thread key rotation value
|
||||
*
|
||||
* \param interface_id Network interface ID
|
||||
* \param thrKeyRotation Key rotation value in seconds
|
||||
*
|
||||
* \return 0, OK
|
||||
* \return <0 Error
|
||||
*/
|
||||
int thread_test_key_rotation_update(int8_t interface_id, uint32_t thrKeyRotation);
|
||||
|
||||
/**
|
||||
* \brief Thread router select threshold values set
|
||||
*
|
||||
|
|
|
@ -35,7 +35,7 @@ typedef enum address_type_t {
|
|||
* /struct ns_address_t
|
||||
* /brief Struct for the addresses used by the socket interface functions and net_address_get().
|
||||
*/
|
||||
typedef struct ns_address_t {
|
||||
typedef struct ns_address {
|
||||
address_type_t type; /**< Address type. */
|
||||
uint8_t address[16]; /**< Addresss. */
|
||||
uint16_t identifier; /**< TCP/UDP port number. */
|
||||
|
|
|
@ -37,8 +37,11 @@ extern "C" {
|
|||
typedef struct nwk_stats_t {
|
||||
/*mac stats*/
|
||||
uint16_t mac_tx_buffer_overflow; /**< MAC TX queue overflow count. */
|
||||
uint16_t mac_tx_queue_size; /**< MAC TX queue current size. */
|
||||
uint16_t mac_tx_queue_peak; /**< MAC TX queue peak size. */
|
||||
uint32_t mac_rx_count; /**< MAC RX packet count. */
|
||||
uint32_t mac_tx_count; /**< MAC TX packet count. */
|
||||
uint32_t mac_bc_tx_count; /**< MAC broadcast TX packet count. */
|
||||
uint32_t mac_rx_drop; /**< MAC RX packet drop count. */
|
||||
/* Mac Payload Flow */
|
||||
uint32_t mac_tx_bytes; /**< MAC TX bytes count. */
|
||||
|
@ -48,6 +51,13 @@ typedef struct nwk_stats_t {
|
|||
uint32_t mac_tx_cca_cnt; /**< MAC TX CCA count. */
|
||||
uint32_t mac_tx_failed_cca; /**< MAC failed CCA count. */
|
||||
uint32_t mac_security_drop; /**< MAC security packet drops count. */
|
||||
/* FHSS stats */
|
||||
int16_t fhss_drift_compensation; /**< FHSS synchronization drift compensation (us/channel). */
|
||||
uint8_t fhss_hop_count; /**< FHSS hop count. */
|
||||
int8_t fhss_synch_parent_rssi; /**< FHSS synchronization parent RSSI. */
|
||||
uint16_t fhss_synch_interval; /**< FHSS synchronization interval (s). */
|
||||
int16_t fhss_prev_avg_synch_fix; /**< Average of 5 preceding synchronization fixes (us). Updated after every fifth synch fix.*/
|
||||
uint32_t fhss_synch_lost; /**< FHSS synchronization lost counter. */
|
||||
/* 6Lowpan */
|
||||
uint32_t ip_rx_count; /**< IP RX packet count. */
|
||||
uint32_t ip_tx_count; /**< IP TX packet count. */
|
||||
|
@ -77,6 +87,10 @@ typedef struct nwk_stats_t {
|
|||
uint32_t buf_headroom_realloc; /**< Buffer headroom realloc count. */
|
||||
uint32_t buf_headroom_shuffle; /**< Buffer headroom shuffle count. */
|
||||
uint32_t buf_headroom_fail; /**< Buffer headroom failure count. */
|
||||
/* ETX */
|
||||
uint16_t etx_1st_parent; /**< Primary parent ETX. */
|
||||
uint16_t etx_2nd_parent; /**< Secondary parent ETX. */
|
||||
|
||||
} nwk_stats_t;
|
||||
|
||||
/**
|
||||
|
|
|
@ -23,20 +23,22 @@ extern "C" {
|
|||
*
|
||||
* \section socket-com Common socket API
|
||||
* - socket_open(), A function to open a socket.
|
||||
* - socket_free(), A function to free a socket.
|
||||
* - socket_close(), A function to close a socket.
|
||||
*
|
||||
* \section socket-read Socket read API at callback
|
||||
* - socket_read(), A function to read received data buffer from a socket.
|
||||
* - socket_recvmsg(), A function to read received data buffer from a socket to Posix defined message structure
|
||||
* - socket_read_session_address(), A function to read session info for a TCP event.
|
||||
*
|
||||
* \section socket-tx Socket TX API
|
||||
* - socket_send(), A function to write data buffer to a socket.
|
||||
* - socket_sendto(), A function to write data to a specific destination in the socket.
|
||||
* - socket_senmsg(), A function which support socket_send and socket_sendto functionality which supports ancillary data
|
||||
*
|
||||
* \section sock-connect TCP socket connection handle
|
||||
* - socket_listen(), A function to set the socket to listening mode.
|
||||
* - socket_connect(), A function to connect to a remote peer.
|
||||
* - socket_close(), A function to close a connection.
|
||||
* - socket_shutdown(), A function to shut down a connection.
|
||||
*
|
||||
* Sockets are a common abstraction model for network communication and are used in most operating systems.
|
||||
* 6LoWPAN Library API follows BSD socket API conventions closely with some extensions necessitated
|
||||
|
@ -85,7 +87,7 @@ extern "C" {
|
|||
*
|
||||
* \section socket-receive Socket receiving
|
||||
* When there is data to read from the socket, a receive callback function is called with the event type parameter set to SOCKET_DATA.
|
||||
* The application must read the received data with socket_read() during the callback because the stack will release the data
|
||||
* The application must read the received data with socket_read() or socket_recvmsg() during the callback because the stack will release the data
|
||||
* when returning from the receive callback.
|
||||
*
|
||||
* Socket event has event_type and socket_id fields. The receive callback function must be defined when socket is opened using socket_open() API.
|
||||
|
@ -99,7 +101,7 @@ extern "C" {
|
|||
* | SOCKET_BIND_DONE | 0x10 | TCP connection ready. |
|
||||
* | SOCKET_TX_FAIL | 0x50 | Socket data send failed. |
|
||||
* | SOCKET_CONNECT_CLOSED | 0x60 | TCP connection closed. |
|
||||
* | SOCKET_CONNECT_FAIL_CLOSED | 0x70 | TCP connection closed no ACK received. |
|
||||
* | SOCKET_CONNECTION_RESET | 0x70 | TCP connection reset. |
|
||||
* | SOCKET_NO_ROUTER | 0x80 | No route available to destination. |
|
||||
* | SOCKET_TX_DONE | 0x90 | Last socket TX process done, in TCP, whole TCP process is ready. |
|
||||
* | SOCKET_NO_RAM | 0xA0 | No RAM available. |
|
||||
|
@ -110,9 +112,10 @@ extern "C" {
|
|||
* | API | Socket Type | Description |
|
||||
* | :---------------------------: | :-----------: | :------------------------------------------------------------: |
|
||||
* | socket_open() | Server/Client | Open socket to specific or dynamic port number. |
|
||||
* | socket_close() | Server/Client | Close opened TCP connection. |
|
||||
* | socket_shutdown() | Client | Shut down opened TCP connection. |
|
||||
* | socket_listen() | Server | Set server port to listen state. |
|
||||
* | socket_connect() | Client | Connect client socket to specific destination. |
|
||||
* | socket_close() | Server/Client | Closes the TCP Socket. |
|
||||
* | socket_send() | Client | Send data to session based destination. |
|
||||
* | socket_sendto() | Server/Client | Send data to specific destination. |
|
||||
* | socket_read_session_address() | Server/Client | Read socket TCP session address and port information. |
|
||||
|
@ -120,11 +123,11 @@ extern "C" {
|
|||
* When the TCP socket is opened it is in closed state. It must be set either to listen or to connect state before it can be used to receive or transmit data.
|
||||
*
|
||||
* A socket can be set to listen mode with the socket_listen() function. After the call, the socket can accept an incoming connection from a remote host.
|
||||
* The listen mode closes the connection automatically after server timeout or when the client or application closes the connection manually by socket_close() function.
|
||||
* The listen mode closes the connection automatically after server timeout or when the client or application closes the connection manually by socket_shutdown() function.
|
||||
*
|
||||
* A TCP socket can be connected to a remote host with socket_connect() with correct arguments. After the function call, a (non-blocking) application must wait for the socket event to confirm the successful state change of the socket.
|
||||
* After the successful state change, data can be sent using socket_send() by client and socket_send() by server.
|
||||
* The connection can be closed with socket_close() function or by server timeout.
|
||||
* The connection can be shut down with socket_shutdown() function or by server timeout.
|
||||
*
|
||||
* \section socket-udpicmp How to use UDP and RAW socket:
|
||||
*
|
||||
|
@ -184,6 +187,116 @@ typedef struct socket_callback_t {
|
|||
uint8_t LINK_LQI; /**< LINK LQI info if interface cuold give */
|
||||
} socket_callback_t;
|
||||
|
||||
/*!
|
||||
* \struct ns_msghdr_t
|
||||
* \brief Normal IP socket message structure for socket_recvmsg() and socket_sendmsg().
|
||||
*/
|
||||
|
||||
typedef struct ns_msghdr {
|
||||
void *msg_name; /**< Optional address send use for destination and receive it will be source. MUST be ns_address_t */
|
||||
uint_fast16_t msg_namelen; /**< Length of optional address use sizeof(ns_address_t) when msg_name is defined */
|
||||
ns_iovec_t *msg_iov; /**< Message data vector list */
|
||||
uint_fast16_t msg_iovlen; /**< Data vector count in msg_iov */
|
||||
void *msg_control; /**< Ancillary data list of ns_cmsghdr_t pointer */
|
||||
uint_fast16_t msg_controllen; /**< Ancillary data length */
|
||||
int flags; /**< Flags for received messages */
|
||||
} ns_msghdr_t;
|
||||
|
||||
/*!
|
||||
* \struct ns_cmsghdr_t
|
||||
* \brief Control messages.
|
||||
*/
|
||||
typedef struct ns_cmsghdr {
|
||||
uint16_t cmsg_len; /**< Ancillary data control messages length including cmsghdr */
|
||||
uint8_t cmsg_level; /**< Originating protocol level should be SOCKET_IPPROTO_IPV6 */
|
||||
uint8_t cmsg_type; /**< Protocol Specific types for example SOCKET_IPV6_PKTINFO, */
|
||||
} ns_cmsghdr_t;
|
||||
|
||||
|
||||
/** \name socket_recvmsg() message error flags.
|
||||
* \anchor MSG_HEADER_FLAGS
|
||||
*/
|
||||
///@{
|
||||
/** In msg_flags, indicates that given data buffer was smaller than received datagram. Can also be passed as an flag parameter to recvmsg. */
|
||||
#define NS_MSG_TRUNC 1
|
||||
/** Indicates that given ancillary data buffer was smaller than enabled at socket msg->msg_controllen define proper writed data lengths. */
|
||||
#define NS_MSG_CTRUNC 2
|
||||
///@}
|
||||
/*!
|
||||
* \struct ns_in6_pktinfo_t
|
||||
* \brief IPv6 packet info which is used for socket_recvmsg() socket_sendmsg().
|
||||
*/
|
||||
typedef struct ns_in6_pktinfo {
|
||||
uint8_t ipi6_addr[16]; /**< src/dst IPv6 address */
|
||||
int8_t ipi6_ifindex; /**< send/recv interface index */
|
||||
} ns_in6_pktinfo_t;
|
||||
|
||||
#define CMSG_HEADER_ALIGN sizeof(long)
|
||||
|
||||
#define CMSG_DATA_ALIGN CMSG_HEADER_ALIGN
|
||||
|
||||
#ifndef NS_ALIGN_SIZE
|
||||
#define NS_ALIGN_SIZE(length, aligment_base) \
|
||||
((length + (aligment_base -1 )) & ~(aligment_base -1))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Parse first control message header from message ancillary data.
|
||||
*
|
||||
* \param msgh Pointer for socket message.
|
||||
*
|
||||
* \return Pointer to first control message header , Could be NULL when control_message is undefined.
|
||||
*/
|
||||
#define NS_CMSG_FIRSTHDR(msgh) \
|
||||
((msgh)->msg_controllen >= sizeof(struct ns_cmsghdr) ? \
|
||||
(struct ns_cmsghdr *)(msgh)->msg_control : \
|
||||
(struct ns_cmsghdr *)NULL )
|
||||
/**
|
||||
* \brief Parse next control message from message by current control message header.
|
||||
*
|
||||
* \param msgh Pointer for socket message.
|
||||
* \param cmsg Pointer for last parsed control message
|
||||
*
|
||||
* \return Pointer to Next control message header , Could be NULL when no more control messages data.
|
||||
*/
|
||||
|
||||
ns_cmsghdr_t *NS_CMSG_NXTHDR(const ns_msghdr_t *msgh, const ns_cmsghdr_t *cmsg);
|
||||
|
||||
/**
|
||||
* \brief Get Data pointer from control message header.
|
||||
*
|
||||
* \param cmsg Pointer (ns_cmsghdr_t) for last parsed control message
|
||||
*
|
||||
* \return Data pointer.
|
||||
*/
|
||||
#define NS_CMSG_DATA(cmsg) \
|
||||
((uint8_t *)(cmsg) + NS_ALIGN_SIZE(sizeof(ns_cmsghdr_t), CMSG_DATA_ALIGN))
|
||||
|
||||
/**
|
||||
* \brief Returns the total space required for a cmsg header plus the specified data, allowing for all padding
|
||||
*
|
||||
* \param length size of the ancillary data
|
||||
*
|
||||
* For example, the space required for a SOCKET_IPV6_PKTINFO is NS_CMSG_SPACE(sizeof(ns_in6_pktinfo))
|
||||
*
|
||||
* \return Total size of CMSG header, data and trailing padding.
|
||||
*/
|
||||
#define NS_CMSG_SPACE(length) \
|
||||
(NS_ALIGN_SIZE(sizeof(ns_cmsghdr_t), CMSG_DATA_ALIGN) + NS_ALIGN_SIZE(length, CMSG_HEADER_ALIGN))
|
||||
|
||||
/**
|
||||
* \brief Calculate length to store in cmsg_len with taking into account any necessary alignment.
|
||||
*
|
||||
* \param length size of the ancillary data
|
||||
*
|
||||
* For example, cmsg_len for a SOCKET_IPV6_PKTINFO is NS_CMSG_LEN(sizeof(ns_in6_pktinfo))
|
||||
*
|
||||
* \return Size of CMSG header plus data, without trailing padding.
|
||||
*/
|
||||
#define NS_CMSG_LEN(length) \
|
||||
(NS_ALIGN_SIZE(sizeof(ns_cmsghdr_t), CMSG_DATA_ALIGN) + length)
|
||||
|
||||
|
||||
/** IPv6 wildcard address IN_ANY */
|
||||
extern const uint8_t ns_in6addr_any[16];
|
||||
|
||||
|
@ -198,33 +311,47 @@ extern const uint8_t ns_in6addr_any[16];
|
|||
* \return -1 on failure.
|
||||
* \return -2 on port reserved.
|
||||
*/
|
||||
extern int8_t socket_open(uint8_t protocol, uint16_t identifier, void (*passed_fptr)(void *));
|
||||
int8_t socket_open(uint8_t protocol, uint16_t identifier, void (*passed_fptr)(void *));
|
||||
|
||||
/**
|
||||
* \brief A function to free a socket.
|
||||
* \brief A function to close a socket.
|
||||
*
|
||||
* \param socket ID of the socket to be released.
|
||||
* \param socket ID of the socket to be closed.
|
||||
*
|
||||
* \return 0 socket released.
|
||||
* \return -1 socket not released.
|
||||
* \return 0 socket closed.
|
||||
* \return -1 socket not closed.
|
||||
*/
|
||||
extern int8_t socket_free(int8_t socket);
|
||||
int8_t socket_close(int8_t socket);
|
||||
|
||||
/**
|
||||
* \brief A function to set the socket to listening mode.
|
||||
* \brief A function to set a socket to listening mode.
|
||||
*
|
||||
* \param socket Socket ID to bind.
|
||||
* \param socket The socket ID.
|
||||
* \param backlog The pending connections queue size. (Not yet implemented).
|
||||
* \return 0 on success.
|
||||
* \return -1 on failure.
|
||||
*/
|
||||
extern int8_t socket_listen(int8_t socket);
|
||||
int8_t socket_listen(int8_t socket, uint8_t backlog);
|
||||
|
||||
/**
|
||||
* \brief A function to accept a new connection on an socket.
|
||||
*
|
||||
* NOT YET IMPLEMENTED - PLACEHOLDER FOR FUTURE TCP CHANGES
|
||||
*
|
||||
* \param socket_id The socket ID of the listening socket.
|
||||
* \param addr Either NULL pointer or pointer to structure where the remote address of the connecting host is copied.
|
||||
* \param passed_fptr A function pointer to a function that is called whenever a data frame is received to the new socket.
|
||||
* \return 0 or greater on success; return value is the new socket ID.
|
||||
* \return -1 on failure.
|
||||
*/
|
||||
int8_t socket_accept(int8_t socket_id, ns_address_t *addr, void (*passed_fptr)(void *));
|
||||
|
||||
/**
|
||||
* \brief A function to connect to remote peer (TCP).
|
||||
*
|
||||
* \param socket The socket ID.
|
||||
* \param address The address of a remote peer.
|
||||
* \param randomly_take_src_number 1 enables find next free random port number for the current one.
|
||||
* \deprecated \param randomly_take_src_number Ignored - random local port is always chosen if not yet bound
|
||||
*
|
||||
* \return 0 on success.
|
||||
* \return -1 in case of an invalid socket ID or parameter.
|
||||
|
@ -235,7 +362,7 @@ extern int8_t socket_listen(int8_t socket);
|
|||
* \return -6 if the TCP session state is wrong.
|
||||
* \return -7 if the source address selection fails.
|
||||
*/
|
||||
extern int8_t socket_connect(int8_t socket, ns_address_t *address, uint8_t randomly_take_src_number);
|
||||
int8_t socket_connect(int8_t socket, ns_address_t *address, uint8_t randomly_take_src_number);
|
||||
|
||||
/**
|
||||
* \brief Bind socket to address.
|
||||
|
@ -249,10 +376,12 @@ extern int8_t socket_connect(int8_t socket, ns_address_t *address, uint8_t rando
|
|||
* \return 0 on success.
|
||||
* \return -1 if the given address is NULL.
|
||||
* \return -2 if the port is already bound to another socket.
|
||||
* \return -3 if address is not us.
|
||||
* \return -4 if the socket is already bound.
|
||||
* \return -5 bind is not supported on this type of socket
|
||||
* \return -5 bind is not supported on this type of socket.
|
||||
*
|
||||
*/
|
||||
extern int8_t socket_bind(int8_t socket, const ns_address_t *address);
|
||||
int8_t socket_bind(int8_t socket, const ns_address_t *address);
|
||||
|
||||
/**
|
||||
* \brief Bind a local address to a socket based on the destination address and
|
||||
|
@ -271,22 +400,26 @@ extern int8_t socket_bind(int8_t socket, const ns_address_t *address);
|
|||
* \return -5 if the source address selection fails.
|
||||
* \return -6 bind2addrsel is not supported on this type of socket.
|
||||
*/
|
||||
extern int8_t socket_bind2addrsel(int8_t socket, const ns_address_t *dst_address);
|
||||
int8_t socket_bind2addrsel(int8_t socket, const ns_address_t *dst_address);
|
||||
|
||||
/**
|
||||
* \brief A function to close a connection.
|
||||
* Options for the socket_shutdown() parameter 'how'.
|
||||
*/
|
||||
#define SOCKET_SHUT_RD 0 ///< Disables further receive operations.
|
||||
#define SOCKET_SHUT_WR 1 ///< Disables further send operations.
|
||||
#define SOCKET_SHUT_RDWR 2 ///< Disables further send and receive operations.
|
||||
|
||||
/**
|
||||
* \brief A function to shut down a connection.
|
||||
*
|
||||
* \param socket The ID of the socket to be closed.
|
||||
* \param address The address of the destination client. When using as a client, a null pointer shall be passed.
|
||||
* \param socket The ID of the socket to be shut down.
|
||||
* \param how How socket is to be shut down, one of SOCKET_SHUT_XX.
|
||||
*
|
||||
* \return 0 on success.
|
||||
* \return -1 if the given socket ID is not found, if the socket type is wrong or tcp_close() returns a failure.
|
||||
* \return -1 if the given socket ID is not found, if the socket type is wrong or TCP layer returns a failure.
|
||||
* \return -2 if no active TCP session was found.
|
||||
* \return -3 if the referred socket ID port is declared as a zero.
|
||||
*
|
||||
* Note: It is highly recommended to always use randomly_take_src_number. The stack generates a new source port between 49152-65534.
|
||||
*/
|
||||
extern int8_t socket_close(int8_t socket, ns_address_t *address);
|
||||
int8_t socket_shutdown(int8_t socket, uint8_t how);
|
||||
|
||||
/**
|
||||
* \brief Send data via a connected TCP socket by client.
|
||||
|
@ -301,12 +434,12 @@ extern int8_t socket_close(int8_t socket, ns_address_t *address);
|
|||
* \return 0 done
|
||||
* \return -1 Invalid socket ID.
|
||||
* \return -2 Socket memory allocation fail.
|
||||
* \return -3 TCP state not established.
|
||||
* \return -4 Socket TX process busy.
|
||||
* \return -5 Socket is not connected.
|
||||
* \return -6 Packet too short.
|
||||
* \return -3 TCP state not established or address scope not defined .
|
||||
* \return -4 Socket TX process busy or unknown interface.
|
||||
* \return -5 Socket not connected
|
||||
* \return -6 Packet too short (ICMP raw socket error).
|
||||
*/
|
||||
extern int8_t socket_send(int8_t socket, uint8_t *buffer, uint16_t length);
|
||||
int8_t socket_send(int8_t socket, uint8_t *buffer, uint16_t length);
|
||||
|
||||
/**
|
||||
* \brief A function to read received data buffer from a socket.
|
||||
|
@ -324,7 +457,32 @@ extern int8_t socket_send(int8_t socket, uint8_t *buffer, uint16_t length);
|
|||
* \return 0 if no data is available to read.
|
||||
* \return -1 invalid input parameters.
|
||||
*/
|
||||
extern int16_t socket_read(int8_t socket, ns_address_t *src_addr, uint8_t *buffer, uint16_t length);
|
||||
int16_t socket_read(int8_t socket, ns_address_t *src_addr, uint8_t *buffer, uint16_t length);
|
||||
|
||||
/**
|
||||
* \brief A function to read received message with ancillary data from a socket.
|
||||
*
|
||||
* Used by the application to get data from a socket. This method must be called once
|
||||
* from a socket callback when handling event SOCKET_DATA. If the received data does not fit
|
||||
* in the buffer provided the excess data bytes are discarded.
|
||||
*
|
||||
* Ancillary data must request by socket_setsockopt().
|
||||
*
|
||||
* msg->msg_controllen is updated to indicate actual length of ancillary data output
|
||||
*
|
||||
* The returned length is normally the length of data actually written to the buffer; if
|
||||
* NS_MSG_TRUNC is set in flags, then for non-stream sockets, the actual datagram length is
|
||||
* returned instead, which may be larger than the buffer size.
|
||||
*
|
||||
* \param socket The socket ID.
|
||||
* \param msg A pointer to a structure where messages is stored with or without ancillary data
|
||||
* \param flags A flags for message read.
|
||||
*
|
||||
* \return greater than 0 indicates the length of the data.
|
||||
* \return 0 if no data is available to read.
|
||||
* \return -1 invalid input parameters.
|
||||
*/
|
||||
int16_t socket_recvmsg(int8_t socket, ns_msghdr_t *msg, int flags);
|
||||
|
||||
/**
|
||||
* \brief A function to send UDP, TCP or raw ICMP data via the socket.
|
||||
|
@ -335,14 +493,43 @@ extern int16_t socket_read(int8_t socket, ns_address_t *src_addr, uint8_t *buffe
|
|||
* \param address A pointer to the destination address information.
|
||||
* \param buffer A pointer to data to be sent.
|
||||
* \param length Length of the data to be sent.
|
||||
*
|
||||
* \return 0 on success.
|
||||
* \return -1 Invalid socket ID.
|
||||
* \return -2 Socket memory allocation fail.
|
||||
* \return -3 TCP state not established.
|
||||
* \return -4 Socket TX process busy.
|
||||
* \return -6 Packet too short.
|
||||
* \return -3 TCP state not established or address scope not defined .
|
||||
* \return -4 Socket TX process busy or unknown interface.
|
||||
* \return -5 Socket not connected
|
||||
* \return -6 Packet too short (ICMP raw socket error).
|
||||
*/
|
||||
extern int8_t socket_sendto(int8_t socket, ns_address_t *address, uint8_t *buffer, uint16_t length);
|
||||
int8_t socket_sendto(int8_t socket, ns_address_t *address, uint8_t *buffer, uint16_t length);
|
||||
|
||||
/**
|
||||
* \brief A function to send UDP, TCP or raw ICMP data via the socket with or without ancillary data or destination address.
|
||||
*
|
||||
* Used by the application to send data message header support also vector list socket_send() and socket_sendto() use this functionality internally.
|
||||
*
|
||||
* \param socket The socket ID.
|
||||
* \param msg A pointer to the Message header which include address, payload and ancillary data.
|
||||
* \param flags A flags for message send for future usage (not supported yet)
|
||||
*
|
||||
* Messages destination address is defined by msg->msg_name which must be ns_address_t. If msg->msg_nme is NULL socket select connected address
|
||||
*
|
||||
* Messages payload and length is defined msg->msg_iov and msg->msg_iovlen. API support to send multiple data vector.
|
||||
*
|
||||
* Supported ancillary data for send defined by msg->msg_control and msg->msg_controllen.
|
||||
*
|
||||
* msg->flags and flags is ignored
|
||||
*
|
||||
* \return 0 on success.
|
||||
* \return -1 Invalid socket ID or message structure.
|
||||
* \return -2 Socket memory allocation fail.
|
||||
* \return -3 TCP state not established or address scope not defined .
|
||||
* \return -4 Socket TX process busy or unknown interface.
|
||||
* \return -5 Socket not connected
|
||||
* \return -6 Packet too short (ICMP raw socket error).
|
||||
*/
|
||||
int8_t socket_sendmsg(int8_t socket, const ns_msghdr_t *msg, int flags);
|
||||
|
||||
/**
|
||||
* \brief A function to read session info for TCP event.
|
||||
|
@ -358,7 +545,7 @@ extern int8_t socket_sendto(int8_t socket, ns_address_t *address, uint8_t *buffe
|
|||
* Note: This function should be called only at socket callback when the socket event is SOCKET_BIND_DONE or SOCKET_TX_DONE.
|
||||
* The following sections introduce those functions.
|
||||
*/
|
||||
extern int8_t socket_read_session_address(int8_t socket, ns_address_t *address);
|
||||
int8_t socket_read_session_address(int8_t socket, ns_address_t *address);
|
||||
|
||||
|
||||
/** \name Flags for SOCKET_IPV6_ADDR_PREFERENCES - opposites 16 bits apart. */
|
||||
|
@ -398,11 +585,46 @@ extern int8_t socket_read_session_address(int8_t socket, ns_address_t *address);
|
|||
#define SOCKET_IPV6_DONTFRAG 6
|
||||
/** Specify flow label for outgoing packets, as int32_t; valid values 0-0xfffff, or -1 for system default, or -2 to always autogenerate */
|
||||
#define SOCKET_IPV6_FLOW_LABEL 7
|
||||
/** Hop limit control for socket_sendmsg() and indicate for hop limit socket_recmsg(), as int16_t; valid values 0-255, -1 for default for outgoing packet */
|
||||
#define SOCKET_IPV6_HOPLIMIT 8
|
||||
/** Specify control messages packet info for send and receive as ns_in6_pktinfo_t socket_sendmsg() it define source address and outgoing interface. socket_recvmsg() it define messages destination address and arrival interface. Reference at RFC3542*/
|
||||
#define SOCKET_IPV6_PKTINFO 9
|
||||
|
||||
/** Specify socket_recvmsg() ancillary data request state for Packet info (destination address and interface id), as bool; valid values true write enabled, false write disabled */
|
||||
#define SOCKET_IPV6_RECVPKTINFO 10
|
||||
/** Specify socket_recvmsg() ancillary data request state for receive messages hop-limit, as bool; valid values true write enabled, false information write disabled */
|
||||
#define SOCKET_IPV6_RECVHOPLIMIT 11
|
||||
/** Specify socket_recvmsg() ancillary data request state for receive messages traffic class, as bool; valid values true write enabled, false information write disabled */
|
||||
#define SOCKET_IPV6_RECVTCLASS 12
|
||||
|
||||
#define SOCKET_BROADCAST_PAN 0xfc /**< Internal use - transmit with IEEE 802.15.4 broadcast PAN ID */
|
||||
#define SOCKET_LINK_LAYER_SECURITY 0xfd /**< Not standard enable or disable socket security at link layer (For 802.15.4). */
|
||||
#define SOCKET_INTERFACE_SELECT 0xfe /**< Not standard socket interface ID. */
|
||||
#define SOCKET_IPV6_ADDRESS_SELECT 0xff /**< Deprecated - use SOCKET_IPV6_ADDR_PREFERENCES instead. */
|
||||
|
||||
/** Socket options summary
|
||||
*
|
||||
* | opt_name / cmsg_type | Data type | set/getsockopt | sendmsg | recvmsg |
|
||||
* | :--------------------------: | :--------------: | :-------------: | :-----: | :-------------------------------: |
|
||||
* | SOCKET_IPV6_TCLASS | int16_t | Yes | Yes | If enabled with RECVTCLASS |
|
||||
* | SOCKET_IPV6_UNICAST_HOPS | int16_t | Yes | No | No |
|
||||
* | SOCKET_IPV6_MULTICAST_HOPS | int16_t | Yes | No | No |
|
||||
* | SOCKET_IPV6_ADDR_PREFERENCES | int | Yes | No | No |
|
||||
* | SOCKET_IPV6_USE_MIN_MTU | int8_t | Yes | Yes | No |
|
||||
* | SOCKET_IPV6_DONTFRAG | int8_t | Yes | Yes | No |
|
||||
* | SOCKET_IPV6_FLOW_LABEL | int32_t | Yes | No | No |
|
||||
* | SOCKET_IPV6_HOPLIMIT | int16_t | No | Yes | If enabled with RECVHOPLIMIT |
|
||||
* | SOCKET_IPV6_PKTINFO | ns_in6_pktinfo_t | No | Yes | If enabled with RECVPKTINFO |
|
||||
* | SOCKET_IPV6_RECVPKTINFO | bool | Yes | No | No |
|
||||
* | SOCKET_IPV6_RECVHOPLIMIT | bool | Yes | No | No |
|
||||
* | SOCKET_IPV6_RECVTCLASS | bool | Yes | No | No |
|
||||
* | SOCKET_BROADCAST_PAN | int8_t | Yes | No | No |
|
||||
* | SOCKET_LINK_LAYER_SECURITY | int8_t | Yes | No | No |
|
||||
* | SOCKET_INTERFACE_SELECT | int8_t | Yes | No | No |
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
///@}
|
||||
|
||||
/**
|
||||
|
@ -422,7 +644,7 @@ extern int8_t socket_read_session_address(int8_t socket, ns_address_t *address);
|
|||
* \return -2 invalid/unsupported option.
|
||||
* \return -3 invalid option value.
|
||||
*/
|
||||
extern int8_t socket_setsockopt(int8_t socket, uint8_t level, uint8_t opt_name, const void *opt_value, uint16_t opt_len);
|
||||
int8_t socket_setsockopt(int8_t socket, uint8_t level, uint8_t opt_name, const void *opt_value, uint16_t opt_len);
|
||||
|
||||
/**
|
||||
* \brief Get an option for a socket.
|
||||
|
@ -442,7 +664,7 @@ extern int8_t socket_setsockopt(int8_t socket, uint8_t level, uint8_t opt_name,
|
|||
* \return -1 invalid socket ID.
|
||||
* \return -2 invalid/unsupported option.
|
||||
*/
|
||||
extern int8_t socket_getsockopt(int8_t socket, uint8_t level, uint8_t opt_name, void *opt_value, uint16_t *opt_len);
|
||||
int8_t socket_getsockopt(int8_t socket, uint8_t level, uint8_t opt_name, void *opt_value, uint16_t *opt_len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -107,6 +107,10 @@ typedef struct {
|
|||
/**
|
||||
* Initialize Thread stack to node mode.
|
||||
*
|
||||
* If static configuration is given and new one is updated by commissioner
|
||||
* it will override current setup. it is save to always give this as
|
||||
* default configuration.
|
||||
*
|
||||
* \param interface_id Network interface ID.
|
||||
* \param channel_list A pointer to channel list. Can be NULL if all channels accepted.
|
||||
* \param device_configuration A pointer to device configuration.
|
||||
|
@ -286,6 +290,20 @@ int8_t thread_management_get_request_full_nwk_data(int8_t interface_id, bool *fu
|
|||
*/
|
||||
int thread_management_get_leader_address(int8_t interface_id, uint8_t *address_ptr);
|
||||
|
||||
/**
|
||||
* Get leader anycast address.
|
||||
*
|
||||
* Address should be used when contacting Leader without need to know the actual routing details.
|
||||
* This address will remain valid even after leader changes.
|
||||
*
|
||||
* \param interface_id Network interface ID.
|
||||
* \param address_ptr A pointer to the location of address after copying.
|
||||
*
|
||||
* \return 0, Read OK.
|
||||
* \return <0 Read fail. Not connected to Thread network.
|
||||
*/
|
||||
int thread_management_get_leader_aloc(int8_t interface_id, uint8_t *address_ptr);
|
||||
|
||||
/**
|
||||
* Get parent link local 16 address.
|
||||
*
|
||||
|
|
BIN
features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_nanostack_full.ar
Normal file → Executable file
BIN
features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_nanostack_full.ar
Normal file → Executable file
Binary file not shown.
BIN
features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_ARM/TARGET_M3/libnanostack_armcc_Cortex-M3_nanostack_full.ar
Normal file → Executable file
BIN
features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_ARM/TARGET_M3/libnanostack_armcc_Cortex-M3_nanostack_full.ar
Normal file → Executable file
Binary file not shown.
BIN
features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_nanostack_full.ar
Normal file → Executable file
BIN
features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_nanostack_full.ar
Normal file → Executable file
Binary file not shown.
BIN
features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_nanostack_full.a
Normal file → Executable file
BIN
features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_nanostack_full.a
Normal file → Executable file
Binary file not shown.
BIN
features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_GCC/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_nanostack_full.a
Normal file → Executable file
BIN
features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_GCC/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_nanostack_full.a
Normal file → Executable file
Binary file not shown.
BIN
features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_nanostack_full.a
Normal file → Executable file
BIN
features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_nanostack_full.a
Normal file → Executable file
Binary file not shown.
BIN
features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_nanostack_full.a
Normal file → Executable file
BIN
features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_nanostack_full.a
Normal file → Executable file
Binary file not shown.
BIN
features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_IAR/TARGET_M3/libnanostack_iccarm_Cortex-M3_nanostack_full.a
Normal file → Executable file
BIN
features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_IAR/TARGET_M3/libnanostack_iccarm_Cortex-M3_nanostack_full.a
Normal file → Executable file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue