diff --git a/test/nanostack/unittest/service_libs/fhss_config/fhssconfigtest.cpp b/test/nanostack/unittest/service_libs/fhss_config/fhssconfigtest.cpp index fbf5f34f000..37ba994162d 100644 --- a/test/nanostack/unittest/service_libs/fhss_config/fhssconfigtest.cpp +++ b/test/nanostack/unittest/service_libs/fhss_config/fhssconfigtest.cpp @@ -48,3 +48,13 @@ TEST(fhss_config, test_ns_fhss_create) { CHECK(test_ns_fhss_create()); } + +TEST(fhss_config, test_ns_fhss_ws_set_parent) +{ + CHECK(test_ns_fhss_ws_set_parent()); +} + +TEST(fhss_config, test_ns_fhss_ws_remove_parent) +{ + CHECK(test_ns_fhss_ws_remove_parent()); +} diff --git a/test/nanostack/unittest/service_libs/fhss_config/test_fhss_config.c b/test/nanostack/unittest/service_libs/fhss_config/test_fhss_config.c index efd58838278..565ff1b8ee6 100644 --- a/test/nanostack/unittest/service_libs/fhss_config/test_fhss_config.c +++ b/test/nanostack/unittest/service_libs/fhss_config/test_fhss_config.c @@ -118,3 +118,38 @@ bool test_ns_fhss_configuration_set() ns_fhss_configuration_set(NULL, NULL); return true; } + +bool test_ns_fhss_ws_set_parent() +{ + fhss_api_t api; + uint8_t dest_address[8] = {1,2,3,4,5,6,7,8}; + broadcast_timing_info_t bc_timing_info; + // Test without api + fhss_common_stub.bool_value = false; + if (-1 != ns_fhss_ws_set_parent(NULL, dest_address, &bc_timing_info)) { + return false; + } + // Test success + fhss_common_stub.bool_value = true; + if (0 != ns_fhss_ws_set_parent(&api, dest_address, &bc_timing_info)) { + return false; + } + return true; +} + +bool test_ns_fhss_ws_remove_parent() +{ + fhss_api_t api; + uint8_t dest_address[8] = {1,2,3,4,5,6,7,8}; + // Test without api + fhss_common_stub.bool_value = false; + if (-1 != ns_fhss_ws_remove_parent(NULL, dest_address)) { + return false; + } + // Test success + fhss_common_stub.bool_value = true; + if (0 != ns_fhss_ws_remove_parent(&api, dest_address)) { + return false; + } + return true; +} diff --git a/test/nanostack/unittest/service_libs/fhss_config/test_fhss_config.h b/test/nanostack/unittest/service_libs/fhss_config/test_fhss_config.h index 3ce718ee889..ad8c4aad8b2 100644 --- a/test/nanostack/unittest/service_libs/fhss_config/test_fhss_config.h +++ b/test/nanostack/unittest/service_libs/fhss_config/test_fhss_config.h @@ -31,6 +31,10 @@ bool test_ns_fhss_ws_create(); bool test_ns_fhss_delete(); // Test setting synchronization time configuration bool test_ns_fhss_configuration_set(); +// Test setting WS parent +bool test_ns_fhss_ws_set_parent(); +// Test removing WS parent +bool test_ns_fhss_ws_remove_parent(); #ifdef __cplusplus diff --git a/test/nanostack/unittest/service_libs/fhss_ws/fhsswstest.cpp b/test/nanostack/unittest/service_libs/fhss_ws/fhsswstest.cpp index a65db921ee5..07ac76d5171 100644 --- a/test/nanostack/unittest/service_libs/fhss_ws/fhsswstest.cpp +++ b/test/nanostack/unittest/service_libs/fhss_ws/fhsswstest.cpp @@ -88,3 +88,13 @@ TEST(fhssws, test_fhss_unicast_handler) { CHECK(test_fhss_unicast_handler()); } + +TEST(fhssws, test_fhss_ws_set_parent) +{ + CHECK(test_fhss_ws_set_parent()); +} + +TEST(fhssws, test_fhss_ws_remove_parent) +{ + CHECK(test_fhss_ws_remove_parent()); +} diff --git a/test/nanostack/unittest/service_libs/fhss_ws/test_fhss_ws.c b/test/nanostack/unittest/service_libs/fhss_ws/test_fhss_ws.c index 61f0bee2884..b4d5b825259 100644 --- a/test/nanostack/unittest/service_libs/fhss_ws/test_fhss_ws.c +++ b/test/nanostack/unittest/service_libs/fhss_ws/test_fhss_ws.c @@ -27,6 +27,7 @@ #include "fhss_stub.h" #include "fhss_callbacks_stub.h" #include "fhss_platform_stub.h" +#include "channel_functions_stub.h" #include "common_functions_stub.h" #define VENDOR_CHANNEL 89 @@ -34,7 +35,7 @@ #define DEFAULT_PANID 0xabcd #define DEFAULT_FRAME_TYPE FHSS_DATA_FRAME #define DEFAULT_FHSS_STATE FHSS_SYNCHRONIZED -#define DEFAULT_TX_TIME 0 +#define DEFAULT_TX_TIME 1000000 #define DEFAULT_TIMER_DELAY 0 #define DEFAULT_FRAME_LENGTH 100 #define DEFAULT_PHY_HEAD_LENGTH 10 @@ -54,6 +55,11 @@ static int32_t app_channel_function(const fhss_api_t *api, uint16_t slot, uint8_ return VENDOR_CHANNEL; } +static fhss_ws_neighbor_timing_info_t *app_no_neighbor_info(const fhss_api_t *api, uint8_t eui64[8]) +{ + return NULL; +} + static fhss_ws_neighbor_timing_info_t *app_get_neighbor_info(const fhss_api_t *api, uint8_t eui64[8]) { return &neighbor_info; @@ -85,6 +91,10 @@ static fhss_api_t *test_generate_fhss_api(void) memset(&ws, 0, sizeof(fhss_ws_t)); memset(&fhss_callbacks_stub, 0, sizeof(fhss_callbacks_stub_def)); memset(&fhss_common_stub, 0, sizeof(fhss_common_stub_def)); + neighbor_info.uc_timing_info.ufsi = 1000000; + neighbor_info.uc_timing_info.unicast_channel_function = WS_TR51CF; + neighbor_info.uc_timing_info.unicast_dwell_interval = 200; + neighbor_info.uc_timing_info.utt_rx_timestamp = 100000; fhss_common_stub.fhss_struct.fhss_api = &fhss_api; fhss_common_stub.fhss_struct.ws = &ws; fhss_common_stub.fhss_struct.ws->fhss_configuration.fhss_uc_dwell_interval = 200; @@ -170,17 +180,53 @@ bool test_fhss_ws_tx_handle_callback() if (fhss_common_stub.fhss_struct.fhss_api->tx_handle(api, true, dest_address, DEFAULT_FRAME_TYPE, DEFAULT_FRAME_LENGTH, DEFAULT_PHY_HEAD_LENGTH, DEFAULT_PHY_TAIL_LENGTH, DEFAULT_TX_TIME) != 0) { return false; } - // Test fixed channel + // Test when no neighbor info found fhss_common_stub.fhss_struct.fhss_state = DEFAULT_FHSS_STATE; + fhss_common_stub.fhss_struct.ws->fhss_configuration.get_neighbor_info = &app_no_neighbor_info; + if (fhss_common_stub.fhss_struct.fhss_api->tx_handle(api, DEFAULT_IS_BC_DEST, dest_address, DEFAULT_FRAME_TYPE, DEFAULT_FRAME_LENGTH, DEFAULT_PHY_HEAD_LENGTH, DEFAULT_PHY_TAIL_LENGTH, DEFAULT_TX_TIME) != -1) { + return false; + } + // Test fixed channel + fhss_common_stub.fhss_struct.ws->fhss_configuration.get_neighbor_info = &app_get_neighbor_info; fhss_common_stub.fhss_struct.ws->fhss_configuration.ws_channel_function = WS_FIXED_CHANNEL; if (fhss_common_stub.fhss_struct.fhss_api->tx_handle(api, DEFAULT_IS_BC_DEST, dest_address, DEFAULT_FRAME_TYPE, DEFAULT_FRAME_LENGTH, DEFAULT_PHY_HEAD_LENGTH, DEFAULT_PHY_TAIL_LENGTH, DEFAULT_TX_TIME) != -1) { return false; } - // Test TR51 channel function + /* Test TR51 channel function + * Dest. slot: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | + * |dest. ufsi| 900ms | + * timestamps: 100000us| 1000000us| + */ fhss_common_stub.fhss_struct.ws->fhss_configuration.ws_channel_function = WS_TR51CF; - if (fhss_common_stub.fhss_struct.fhss_api->tx_handle(api, DEFAULT_IS_BC_DEST, dest_address, DEFAULT_FRAME_TYPE, DEFAULT_FRAME_LENGTH, DEFAULT_PHY_HEAD_LENGTH, DEFAULT_PHY_TAIL_LENGTH, DEFAULT_TX_TIME) != 0) { + if ((fhss_common_stub.fhss_struct.fhss_api->tx_handle(api, DEFAULT_IS_BC_DEST, dest_address, DEFAULT_FRAME_TYPE, DEFAULT_FRAME_LENGTH, DEFAULT_PHY_HEAD_LENGTH, DEFAULT_PHY_TAIL_LENGTH, DEFAULT_TX_TIME) != 0) + || (channel_functions_stub.uint8_value != 7)) { return false; } + /* Test TR51 channel function when timestamp overflows + * Dest. slot: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | + * |dest. ufsi| 1000ms | + * timestamps: 4294867000us| 900000us| + */ + neighbor_info.uc_timing_info.utt_rx_timestamp = 4294867000; + fhss_common_stub.fhss_struct.ws->fhss_configuration.ws_channel_function = WS_TR51CF; + if ((fhss_common_stub.fhss_struct.fhss_api->tx_handle(api, DEFAULT_IS_BC_DEST, dest_address, DEFAULT_FRAME_TYPE, DEFAULT_FRAME_LENGTH, DEFAULT_PHY_HEAD_LENGTH, DEFAULT_PHY_TAIL_LENGTH, 900000) != 0) + || (channel_functions_stub.uint8_value != 7)) { + return false; + } + /* Test TR51 channel function when channel list overflows + * Dest. slot: | 0 | 1 | 2 | 3 |...| 0 | 1 | 2 | 3 | + * |dest. ufsi| 10000ms | + * timestamps: 100000us| 10100000us| + */ + neighbor_info.uc_timing_info.utt_rx_timestamp = 100000; + uint32_t tx_time = neighbor_info.uc_timing_info.utt_rx_timestamp + (fhss_common_stub.fhss_struct.number_of_channels * neighbor_info.uc_timing_info.unicast_dwell_interval * 1000); + fhss_common_stub.fhss_struct.ws->fhss_configuration.ws_channel_function = WS_TR51CF; + if ((fhss_common_stub.fhss_struct.fhss_api->tx_handle(api, DEFAULT_IS_BC_DEST, dest_address, DEFAULT_FRAME_TYPE, DEFAULT_FRAME_LENGTH, DEFAULT_PHY_HEAD_LENGTH, DEFAULT_PHY_TAIL_LENGTH, tx_time) != 0) + || (channel_functions_stub.uint8_value != 2)) { + return false; + } + // For more coverage, set neighbor info NULL + memset(&neighbor_info, 0, sizeof(fhss_ws_neighbor_timing_info_t)); // Test direct hash channel function fhss_common_stub.fhss_struct.ws->fhss_configuration.ws_channel_function = WS_DH1CF; if (fhss_common_stub.fhss_struct.fhss_api->tx_handle(api, DEFAULT_IS_BC_DEST, dest_address, DEFAULT_FRAME_TYPE, DEFAULT_FRAME_LENGTH, DEFAULT_PHY_HEAD_LENGTH, DEFAULT_PHY_TAIL_LENGTH, DEFAULT_TX_TIME) != 0) { @@ -418,3 +464,62 @@ bool test_fhss_unicast_handler() fhss_common_stub.callback[0](fhss_common_stub.fhss_struct.fhss_api, DEFAULT_TIMER_DELAY); return true; } + +bool test_fhss_ws_set_parent() +{ + uint8_t dest_address[8] = {1,2,3,4,5,6,7,8}; + broadcast_timing_info_t bc_timing_info; + memset(&bc_timing_info, 0, sizeof(broadcast_timing_info_t)); + fhss_api_t *api = test_generate_fhss_api(); + + // Test without WS enabled FHSS + fhss_structure_t fake_fhss_structure; + memset(&fake_fhss_structure, 0, sizeof(fhss_structure_t)); + if (-1 != fhss_ws_set_parent(&fake_fhss_structure, dest_address, &bc_timing_info)) { + return false; + } + // Test success + bc_timing_info.broadcast_channel_function = WS_TR51CF; + bc_timing_info.broadcast_dwell_interval = 250; + bc_timing_info.broadcast_interval = 1000; + bc_timing_info.broadcast_interval_offset = 2000; + bc_timing_info.broadcast_schedule_id = 1; + bc_timing_info.broadcast_slot = 10; + bc_timing_info.bt_rx_timestamp = 100000; + if (0 != fhss_ws_set_parent(&fhss_common_stub.fhss_struct, dest_address, &bc_timing_info) + || (fhss_common_stub.fhss_struct.ws->parent_bc_info->broadcast_channel_function != WS_TR51CF) + || (fhss_common_stub.fhss_struct.ws->parent_bc_info->broadcast_dwell_interval != 250) + || (fhss_common_stub.fhss_struct.ws->parent_bc_info->broadcast_interval != 1000) + || (fhss_common_stub.fhss_struct.ws->parent_bc_info->broadcast_interval_offset != 2000) + || (fhss_common_stub.fhss_struct.ws->parent_bc_info->broadcast_schedule_id != 1) + || (fhss_common_stub.fhss_struct.ws->parent_bc_info->broadcast_slot != 10) + || (fhss_common_stub.fhss_struct.ws->parent_bc_info->bt_rx_timestamp != 100000)) { + return false; + } + // Test updating value + bc_timing_info.broadcast_interval_offset = 5000; + if (fhss_common_stub.fhss_struct.ws->parent_bc_info->broadcast_interval_offset != 5000) { + return false; + } + return true; +} + +bool test_fhss_ws_remove_parent() +{ + uint8_t dest_address[8] = {1,2,3,4,5,6,7,8}; + fhss_api_t *api = test_generate_fhss_api(); + broadcast_timing_info_t bc_timing_info; + fhss_common_stub.fhss_struct.ws->parent_bc_info = &bc_timing_info; + + // Test without WS enabled FHSS + fhss_structure_t fake_fhss_structure; + memset(&fake_fhss_structure, 0, sizeof(fhss_structure_t)); + if (-1 != fhss_ws_remove_parent(&fake_fhss_structure, dest_address)) { + return false; + } + // Test success + if ((0 != fhss_ws_remove_parent(&fhss_common_stub.fhss_struct, dest_address)) || (fhss_common_stub.fhss_struct.ws->parent_bc_info != NULL)) { + return false; + } + return true; +} diff --git a/test/nanostack/unittest/service_libs/fhss_ws/test_fhss_ws.h b/test/nanostack/unittest/service_libs/fhss_ws/test_fhss_ws.h index 9f700ef0b19..2c11bec332c 100644 --- a/test/nanostack/unittest/service_libs/fhss_ws/test_fhss_ws.h +++ b/test/nanostack/unittest/service_libs/fhss_ws/test_fhss_ws.h @@ -35,6 +35,8 @@ bool test_fhss_ws_write_synch_info_callback(); bool test_fhss_broadcast_handler(); bool test_fhss_ws_update_uc_channel_callback(); bool test_fhss_unicast_handler(); +bool test_fhss_ws_set_parent(); +bool test_fhss_ws_remove_parent(); #ifdef __cplusplus } diff --git a/test/nanostack/unittest/stub/channel_functions_stub.c b/test/nanostack/unittest/stub/channel_functions_stub.c index 9d3a54f3d5e..6c2bde5bdce 100644 --- a/test/nanostack/unittest/stub/channel_functions_stub.c +++ b/test/nanostack/unittest/stub/channel_functions_stub.c @@ -15,8 +15,11 @@ * limitations under the License. */ #include "nsconfig.h" +#include "channel_functions_stub.h" #include +channel_functions_stub_def channel_functions_stub; + int32_t dh1cf_get_uc_channel_index(uint16_t slot_number, uint8_t *mac, int16_t number_of_channels) { return 1; @@ -29,6 +32,7 @@ int32_t dh1cf_get_bc_channel_index(uint16_t slot_number, uint16_t bsi, int16_t n int32_t tr51_get_uc_channel_index(uint16_t slot_number, uint8_t *mac, int16_t number_of_channels) { + channel_functions_stub.uint8_value = slot_number; return 3; } diff --git a/test/nanostack/unittest/stub/channel_functions_stub.h b/test/nanostack/unittest/stub/channel_functions_stub.h new file mode 100644 index 00000000000..546b0cf44ec --- /dev/null +++ b/test/nanostack/unittest/stub/channel_functions_stub.h @@ -0,0 +1,36 @@ +/* + * 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. + */ + +#ifndef __CHANNEL_FUNCTIONS_STUB_H__ +#define __CHANNEL_FUNCTIONS_STUB_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct { + uint8_t uint8_value; +} channel_functions_stub_def; + +extern channel_functions_stub_def channel_functions_stub; + +#ifdef __cplusplus +} +#endif + +#endif // __CHANNEL_FUNCTIONS_STUB_H__