Skip to content

Commit

Permalink
Merge pull request ARMmbed#1528 from ARMmbed/IOTTHD-2046
Browse files Browse the repository at this point in the history
Iotthd 2046
  • Loading branch information
Jarkko Paso committed Jan 10, 2018
2 parents 44a85e5 + 89a85a8 commit 209e49a
Show file tree
Hide file tree
Showing 7 changed files with 558 additions and 0 deletions.
163 changes: 163 additions & 0 deletions source/Service_Libs/fhss/channel_functions.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
/*
* Copyright (c) 2016-2017, Arm Limited and affiliates.
* 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 "nsconfig.h"

#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))

#define final(a,b,c) \
{ \
c ^= b; c -= rot(b, 14); \
a ^= c; a -= rot(c, 11); \
b ^= a; b -= rot(a, 25); \
c ^= b; c -= rot(b, 16); \
a ^= c; a -= rot(c, 4); \
b ^= a; b -= rot(a, 14); \
c ^= b; c -= rot(b, 24); \
}

#define mix(a,b,c) \
{ \
a -= c; a ^= rot(c, 4); c += b; \
b -= a; b ^= rot(a, 6); a += c; \
c -= b; c ^= rot(b, 8); b += a; \
a -= c; a ^= rot(c, 16); c += b; \
b -= a; b ^= rot(a, 19); a += c; \
c -= b; c ^= rot(b, 4); b += a; \
}

static uint32_t global_seed = 1;

void tr51_seed_rand(uint32_t seed)
{
if (!seed) {
seed = 1;
}
global_seed = seed;
}

int32_t tr51_get_rand(void)
{
uint32_t random_val = ((global_seed * 1103515245) + 12345) & 0x7fffffff;
global_seed = random_val;
return random_val;
}

void tr51_calculate_channel_table(uint16_t number_of_channels, uint16_t nearest_prime, int32_t *channel_table)
{
int32_t i,j,k;
tr51_seed_rand(1);
for (i=0; i < nearest_prime; i++) {
channel_table[i] = -1;
}
for (i=0; i < number_of_channels; i++) {
j = tr51_get_rand() % number_of_channels;
k=0;
while (k <= i) {
if (j == channel_table[k]) {
j = tr51_get_rand() % number_of_channels;
k=0;
} else {
k=k+1;
}
}
channel_table[i] = j;
}
}

void tr51_compute_cfd(uint8_t *mac, uint8_t *first_element, uint8_t *step_size, uint16_t channel_table_length)
{
*first_element = (mac[5] ^ mac[6] ^ mac[7]) % channel_table_length;
*step_size = (mac[7] % (channel_table_length - 1)) + 1;
}

static uint8_t tr51_find_excluded(int32_t channel, uint16_t *excluded_channels, uint16_t number_of_excluded_channels)
{
uint8_t count = 0;
if (excluded_channels != NULL) {
for (count = 0; count < number_of_excluded_channels; count++) {
if (channel == excluded_channels[count]) {
return 1;
}
}
}
return 0;
}

uint16_t tr51_calculate_hopping_sequence(int32_t *channel_table, uint16_t channel_table_length, uint8_t first_element, uint8_t step_size, int32_t *output_table, uint16_t *excluded_channels, uint16_t number_of_excluded_channels)
{
uint16_t cntr = channel_table_length;
uint8_t index = first_element;
uint8_t slot = 0;
while (cntr--) {
if (channel_table[index] != -1) {
if (!tr51_find_excluded(channel_table[index], excluded_channels, number_of_excluded_channels)) {
output_table[slot] = channel_table[index];
slot++;
}
}
index += step_size;
while (index >= channel_table_length) {
index -= channel_table_length;
}
}
return slot;
}

static uint32_t dh1cf_hashword(const uint32_t *key, size_t key_length, uint32_t init_value)
{
uint32_t a,b,c;
a = b = c = 0xdeadbeef + (((uint32_t)key_length) << 2) + init_value;
while (key_length > 3) {
a += key[0];
b += key[1];
c += key[2];
mix(a, b, c);
key_length -= 3;
key += 3;
}
switch(key_length) {
case 3 : c += key[2];
case 2 : b += key[1];
case 1 : a += key[0];
final(a, b, c);
case 0:
break;
}
return c;
}

int32_t dh1cf_get_uc_channel_index(uint16_t slot_number, uint8_t *mac, int16_t number_of_channels)
{
int32_t channel_number;
uint32_t key[3];
key[0] = (uint32_t)slot_number;
key[1] = mac[4] << 24 | mac[5] << 16 | mac[6] << 8 | mac[7];
key[2] = mac[0] << 24 | mac[1] << 16 | mac[2] << 8 | mac[3];
channel_number = dh1cf_hashword(key, 3, 0) % number_of_channels;
return channel_number;
}

int32_t dh1cf_get_bc_channel_index(uint16_t slot_number, uint16_t bsi, int16_t number_of_channels)
{
int32_t channel_number;
uint32_t key[3];
key[0] = (uint32_t)slot_number;
key[1] = bsi << 16;
key[2] = 0;
channel_number = dh1cf_hashword(key, 3, 0) % number_of_channels;
return channel_number;
}
55 changes: 55 additions & 0 deletions source/Service_Libs/fhss/channel_functions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright (c) 2016-2017, Arm Limited and affiliates.
* 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.
*/

/**
* @brief Calculate channel table based on TR51 channel function.
* @param number_of_channels Number of channels in table.
* @param nearest_prime Nearest prime number. Must be equal to or larger than number_of_channels.
* @param channel_table Output channel table. Has to be at least nearest_prime in length.
*/
void tr51_calculate_channel_table(uint16_t number_of_channels, uint16_t nearest_prime, int32_t *channel_table);

/**
* @brief Calculate hopping sequence for a specific peer.
* @param channel_table Used channel table.
* @param channel_table_length Length of the used channel table.
* @param first_element Start generated by CFD function.
* @param step_size Step size generated by CFD function.
* @param output_table Output hopping sequence table.
* @param excluded_channels List of not used channels.
* @param number_of_excluded_channels Number of not used channels.
* @return Number of channels in sequence.
*/
uint16_t tr51_calculate_hopping_sequence(int32_t *channel_table, uint16_t channel_table_length, uint8_t first_element, uint8_t step_size, int32_t *output_table, uint16_t *excluded_channels, uint16_t number_of_excluded_channels);

/**
* @brief Compute the unicast schedule channel index.
* @param slot_number Current slot number.
* @param mac MAC address of the node for which the index is calculated.
* @param number_of_channels Number of channels.
* @return Channel index.
*/
int32_t dh1cf_get_uc_channel_index(uint16_t slot_number, uint8_t *mac, int16_t number_of_channels);

/**
* @brief Compute the broadcast schedule channel index.
* @param slot_number Current slot number.
* @param bsi Broadcast schedule identifier of the node for which the index is calculated.
* @param number_of_channels Number of channels.
* @return Channel index.
*/
int32_t dh1cf_get_bc_channel_index(uint16_t slot_number, uint16_t bsi, int16_t number_of_channels);
18 changes: 18 additions & 0 deletions test/nanostack/unittest/service_libs/channel_functions/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
include ../../makefile_defines.txt

COMPONENT_NAME = channel_functions_unit

#This must be changed manually
SRC_FILES = \
../../../../../source/Service_Libs/fhss/channel_functions.c \


TEST_SRC_FILES = \
main.cpp \
channelfunctest.cpp \
test_channel_functions.c \

include ../../MakefileWorker.mk

CPPUTESTFLAGS += -DFEA_TRACE_SUPPORT

Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright (c) 2016, Arm Limited and affiliates.
* 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 "CppUTest/TestHarness.h"
#include "test_channel_functions.h"


TEST_GROUP(channel_functions)
{
void setup()
{
}

void teardown()
{
}
};

TEST(channel_functions, test_tr51_get_rand)
{
CHECK(test_tr51_get_rand());
}

TEST(channel_functions, test_tr51_calculate_channel_table)
{
CHECK(test_tr51_calculate_channel_table());
}

TEST(channel_functions, test_tr51_compute_cfd)
{
CHECK(test_tr51_compute_cfd());
}

TEST(channel_functions, test_tr51_calculate_hopping_sequence)
{
CHECK(test_tr51_calculate_hopping_sequence());
}

TEST(channel_functions, test_dh1cf_get_uc_channel_index)
{
CHECK(test_dh1cf_get_uc_channel_index());
}

TEST(channel_functions, test_dh1cf_get_bc_channel_index)
{
CHECK(test_dh1cf_get_bc_channel_index());
}
28 changes: 28 additions & 0 deletions test/nanostack/unittest/service_libs/channel_functions/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright (c) 2016, Arm Limited and affiliates.
* 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 "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(channel_functions);

Loading

0 comments on commit 209e49a

Please sign in to comment.