mirror of https://github.com/ARMmbed/mbed-os.git
Squashed 'features/nanostack/sal-stack-nanostack/' changes from 513a38e..c5ee9e4
c5ee9e4 Remove content from unit tests f7ca82a Merge branch 'release_internal' into release_external b400a6a Fix for pr #1984 (#1987) 30d25bc Fix compiler warnings (#1986) d46d7b3 Prioritise thread control messages (#1984) e59dbd8 Update domain address lifetime (#1985) 8a5cb75 Merge pull request #1980 from ARMmbed/sync_with_MbedOS bd6feab Update coding style ff14e80 (via Mbed OS) nanostack: icmpv6: fix build warning f5e3423 (via Mbed OS) Require dependencies from nanostack mbed_lib.json 3aec837 Restore ws_management_api.h to the latest version cd7ae3f (via Mbed OS) Review changes corrected 4f23008 (via Mbed OS) This is a initial version of Wi-Sun interface implementation. To get Wi-Sun mesh network working, also nanostack with Wi-Sun support is needed. ws_empty_functions.c and ws_management_api.h are temporary included here, so that wisun_tasklet will compiled without problems. They will replaced with the official versions with next nanostack release. e029444 Merge pull request #1981 from ARMmbed/iotthd-3111 d7e8aea Path control size from 5->7. a5fe76f randomise challenge tlv for parent request retries. (#1977) a1c8277 Merge pull request #1978 from ARMmbed/IOTTHD-3219 62f8b41 Fix compiler warnings 1ec7a84 Fix issues found by coverity 5fe7120 Merge pull request #1974 from ARMmbed/iotthd-3100 51358f9 Removed Unncessary debug print. 136d1b1 Merge pull request #1973 from ARMmbed/IOTTHD-3018 4e557ae DHCPv6 update: 85b33e1 Update BBR prefix assignment (#1972) 899b2c5 DHCPv6 client and server update: 9009eaf Update copyright year to test files 6a56318 Update copyright year to Nanostack files a83472e Added Wi-Sun certificate and security test interfaces 7f4ebf1 Corrected compiler warnings 52e4c3f Added supplicant PAE NVM storage 92df57b Added key data access functions to key storage 5972bc3 Merge pull request #1959 from ARMmbed/ws_eapol_ie_update 98af118 Merge pull request #1965 from ARMmbed/IOTTHD-3193 fc76d1e Merge pull request #1963 from ARMmbed/rename_socket_h ba3a649 Added WS flagging to EAP header parser 048f14a Rename address.h 5739b4a Fixed aro registration error 887d931 Rename socket.h to ns_socket.h 7ebaa8e Add Nanostack configuration for WS (#1961) ed87161 Code style fix. e20028a Fix compiler warnings (#1957) b86f885 EAPOL data flow IE update 65472de Fixed Function protype typo. f539287 Added support for write/READ EA-IE header IE Element's ce72b55 Merge pull request #1958 from ARMmbed/tls_conf_err 1e8b18c Added handling for mbed TLS configuration error bdfea40 WS: Use common channel number calc function 4802aae Merge pull request #1930 from ARMmbed/IOTTHD-3027 2b8c846 PAE BR address write/read interface 9777ad1 Remove yotta references (#1954) af8890b Merge pull request #1949 from ARMmbed/eapol_eap_and_tls c546d4f WS: Fixed EU domain channel numbers in neighbor class cff6f0b WS: Missing return value fix ebcdba5 Changed EAP-TLS identity to anonymous 34d2f15 Corrected defects and coding style 79c7157 WS: Default domain config update 0724863 Merge branch 'master' into IOTTHD-3027 65ccc41 WS: RF config set in own functions 76d235e MAC: Fixed virtual driver warnings 88641c1 Updates to PAEs and other security protocols f57138f Security key storage and certificate info updates b7177c5 TLS security protocol and mbed TLS security protocol library 9c9e3c9 EAP-TLS protocol implementation 9c5fc92 WS: Fixed code style acce0dd Added empty function for test 4b28192 Added support for ARO registration failure 9d251fa Added empty function fr new interface 61f520f Added api to configure network size parameters 4d26258 Flagged mbed TLS KW header and corrected bool definitions 3d903fa Corrected NIST AES KW flagging 2f4e099 Removed temporary KW functions and corrected ut and style 6481549 Added GKH MIC validation and encryption cc3ce58 Moved 4WH functions to library and added constants 650771c Added unit test to NIST AES KW library 6a82e7d added parent priority handling. (#1942) 7b7f1c1 Merge pull request #1945 from ARMmbed/fix_synch_parent_warn 38b28e2 Fix coverity error (#1943) c4afedc thread_mle_message_handler: fix build warning (#1940) a5be64a Follow Mbed OS coding style (#1941) 6298cef Sync mbed_lib.json with Mbed OS (#1935) afe3ec6 Added Wi-Sun flagging to eapol helper 28d10d6 Merge pull request #1901 from ARMmbed/kmp_pae_init 3f56121 Disabled EAPOL flags 97f07a9 Tuned EAPOL timers for small networks 6e063b6 added Wi-SUN neighbor table management to Wi-SUN 7f4c61d Corrected KMP api start on authenticator 91ca2e6 Corrected KMP timer active check and security protocol address get 65d983f If mbedtls NIST AES KW is not enabled defined it as null algorithm 16dbe27 Added unit test stub for PAE controller a524936 Moved EAPOL relay port and IP address configuration to bootstrap 68fa4f6 Added extra debug info flags to new security libraries c4411ea Removed extra memory frees from KMP socket and eapol if and fixed KMP comments 8088a86 Added and fixed security protocols comments cc32457 Modified PAEs to use protocol core timer function call 03469f3 Modified PAE entities to be bound to interface 369c8a0 Added 4WH integrity protection and encryption ebae1d5 Added HMAC-SHA1, IEEE 802.11 PRF and NIST AES KW libraries 2d50887 Corrected Wi-SUN security component initializations 8a8b6ef Added configuration flags for supplicant and authenticator PAEs and EAPOL relay 3868ff1 PAE and security protocols timer support c61066a Corrected GKH to set eapol-KEY message group key negotation bit correctly dfe52d9 Added 4WH,GKH and EAP-TLS module and modified kmp service 782f3fb Relay message flow optimization bbd6ee1 Integrate EAPOL new encode and decode functionality 1802ee7 EAPOL message parser and write helper function. da15653 EAPOL relay and KMP changes fad633f EAPOL relay cc97054 Unicast Shedule update a099524 EAPOL authtentication start fix 3f32a7a Fix valgrind uninitilaized data use. 6e9f6a4 Corrected memory errors and some compiler warnings c5f1af3 Initial EAPOL changes e48aa79 WS: Use Tack in Ack wait time 59a65ea Change FHSS timing defaults be06ecb FHSS WS: Fixed synch parent warning a3aa38b Thread extension commission updates (#1870) 3e89d0a Multicast registrations update (#1931) e18055a MAC: Update symbol rate when RF configuration changed 9eada28 WS: Store RF configuration 35145a3 MAC: RF configuration delivery implemented d6b2bbc Merge pull request #1928 from ARMmbed/IOTTHD-3028 80683e2 MAC/WS: Implemented Ack wait duration set 0e9ead2 Remove excess tracing (#1927) ae210cd Merge pull request #1923 from ARMmbed/IOTTHD-3080 17fad47 Merge pull request #1924 from ARMmbed/IOTTHD-1608 6fd6bd5 Update thread neighbor table initialisation (#1926) c09d38a Merge pull request #1925 from ARMmbed/fix_protocol_if_fhss 9ac5301 MAC MLME: Removed BEA TX trace which was causing stack overflow 5dee7b1 FHSS: Use debug callback in TX/RX slot switch f779fad WS/Protocol: Fixed getting interface pointer using FHSS api 4177fa4 Prevalidate CoAP msg source address 5451b1a FHSS unit tests: Updated timestamp callback a2997b1 FHSS: Removed debug trace which was causing crash 3b6a921 FHSS: Debug callback update ec1c41d FHSS: Use given TX time in synch calculation f0c0f66 MAC: Write FHSS synch info with tx time 78ea0eb FHSS: Debug callbacks added c4ef759 MAC: Write FHSS synch info before calling PHY TX function 9cca341 FHSS: Use timestamp delivered by MAC be46564 Add CoAP message validation 883eb46 Add callback for CoAP message prevalidation (#1918) 59bbe31 Merge pull request #1917 from ARMmbed/IOTTHD-3029 ac4a76e Fixed promiscuous/sniffer mode bc2fb64 FHSS WS: time convert to support negative values 7dce509 FHSS WS: Clock drift compensation implemented ac7c90a Fix Thread resolution client initialisation (#1915) b744186 Set the default unicast channel function as Direct Hash 612c4b5 Update DHCP to follow Wi-SUN specification eeb5168 IPv6 route metrics update (#1912) 1debcca Fix compilation warnings noticed in mbed-os (#1909) 0a18231 Change ARO routes to be direct route instead of on-link 7fb321e Merge pull request #1906 from ARMmbed/parent_update_fix b5afc35 Fixed missing broadcast synch information loose with default zeroes. 3dbc874 Add missing closing bracket 0d746f0 Changed Wi-SUN HW type to match specification 2804bf4 Enabled roaming and routing between multiple Wi-SUN BR git-subtree-dir: features/nanostack/sal-stack-nanostack git-subtree-split: c5ee9e4e6682c4e4c23845f7b13c02d259162c36pull/9838/head
parent
77818568c6
commit
780e9afb8f
|
@ -1,5 +1,4 @@
|
||||||
.settings/
|
.settings/
|
||||||
.yotta.json
|
|
||||||
*.dep
|
*.dep
|
||||||
*.htm
|
*.htm
|
||||||
*.crf
|
*.crf
|
||||||
|
@ -66,8 +65,7 @@ cscope.files
|
||||||
!debugger.ini
|
!debugger.ini
|
||||||
*Log.txt
|
*Log.txt
|
||||||
*.mpw
|
*.mpw
|
||||||
yotta_modules
|
|
||||||
yotta_targets
|
|
||||||
build
|
build
|
||||||
html
|
html
|
||||||
site
|
site
|
||||||
|
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -109,7 +109,7 @@ clean-extra: $(CLEANTESTDIRS)
|
||||||
# 3. TBD: importing to mbed OS
|
# 3. TBD: importing to mbed OS
|
||||||
|
|
||||||
TARGET_DIR:=release
|
TARGET_DIR:=release
|
||||||
CONFIGURATIONS_TO_BUILD:=lowpan_border_router lowpan_host lowpan_router nanostack_full thread_border_router thread_router thread_end_device ethernet_host
|
CONFIGURATIONS_TO_BUILD:=lowpan_border_router lowpan_host lowpan_router nanostack_full thread_border_router thread_router thread_end_device ethernet_host ws_border_router ws_router
|
||||||
TOOLCHAINS_TO_BUILD:=GCC ARM ARMC6 IAR
|
TOOLCHAINS_TO_BUILD:=GCC ARM ARMC6 IAR
|
||||||
CORES_TO_BUILD:=Cortex-M0 Cortex-M3
|
CORES_TO_BUILD:=Cortex-M0 Cortex-M3
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,25 @@
|
||||||
{
|
{
|
||||||
"name": "nanostack",
|
"name": "nanostack",
|
||||||
|
"requires": ["nanostack-eventloop", "coap-service"],
|
||||||
"config": {
|
"config": {
|
||||||
"configuration": "nanostack_full"
|
"configuration": {
|
||||||
|
"help": "Build time configuration. Refer to Handbook for valid values. Default: full stack",
|
||||||
|
"value": "nanostack_full"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"macros": ["NS_USE_EXTERNAL_MBED_TLS"]
|
"macros": ["NS_USE_EXTERNAL_MBED_TLS"],
|
||||||
|
"target_overrides": {
|
||||||
|
"KW24D": {
|
||||||
|
"nanostack.configuration": "lowpan_router"
|
||||||
|
},
|
||||||
|
"NCS36510": {
|
||||||
|
"nanostack.configuration": "lowpan_router"
|
||||||
|
},
|
||||||
|
"TB_SENSE_12": {
|
||||||
|
"nanostack.configuration": "lowpan_router"
|
||||||
|
},
|
||||||
|
"KW41Z": {
|
||||||
|
"nanostack.configuration": "lowpan_router"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2017, Arm Limited and affiliates.
|
* Copyright (c) 2013-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2017, Arm Limited and affiliates.
|
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -264,6 +264,7 @@ typedef enum {
|
||||||
macAutoRequestKeyIndex = 0x7b, /*<The index of the key used for automatic data*/
|
macAutoRequestKeyIndex = 0x7b, /*<The index of the key used for automatic data*/
|
||||||
macDefaultKeySource = 0x7c, /*<Default key source*/
|
macDefaultKeySource = 0x7c, /*<Default key source*/
|
||||||
//NON standard extension
|
//NON standard extension
|
||||||
|
macRfConfiguration = 0xfb, /*<RF channel configuration parameters*/
|
||||||
macAcceptByPassUnknowDevice = 0xfc, /*< Accept data trough MAC if packet is data can be authenticated by group key nad MIC. Security enforsment point must be handled carefully these packets */
|
macAcceptByPassUnknowDevice = 0xfc, /*< Accept data trough MAC if packet is data can be authenticated by group key nad MIC. Security enforsment point must be handled carefully these packets */
|
||||||
macLoadBalancingBeaconTx = 0xfd, /*< Trig Beacon from load balance module periodic */
|
macLoadBalancingBeaconTx = 0xfd, /*< Trig Beacon from load balance module periodic */
|
||||||
macLoadBalancingAcceptAnyBeacon = 0xfe, /*<Beacon accept state control from other network. Value size bool, data true=Enable, false=disable .*/
|
macLoadBalancingAcceptAnyBeacon = 0xfe, /*<Beacon accept state control from other network. Value size bool, data true=Enable, false=disable .*/
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2012-2017, Arm Limited and affiliates.
|
* Copyright (c) 2012-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2017, Arm Limited and affiliates.
|
* Copyright (c) 2013-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2018, Arm Limited and affiliates.
|
* Copyright (c) 2014-2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -235,6 +235,18 @@ typedef struct {
|
||||||
const uint8_t *key_chain[4]; /**< Certificate private key. */
|
const uint8_t *key_chain[4]; /**< Certificate private key. */
|
||||||
} arm_certificate_chain_entry_s;
|
} arm_certificate_chain_entry_s;
|
||||||
|
|
||||||
|
/** Certificate structure. */
|
||||||
|
typedef struct {
|
||||||
|
const uint8_t *cert; /**< Certificate pointer. */
|
||||||
|
uint16_t cert_len; /**< Certificate length. */
|
||||||
|
} arm_certificate_entry_s;
|
||||||
|
|
||||||
|
/** Certificate Revocation List structure. */
|
||||||
|
typedef struct {
|
||||||
|
const uint8_t *crl; /**< Certificate Revocation List pointer. */
|
||||||
|
uint16_t crl_len; /**< Certificate Revocation List length. */
|
||||||
|
} arm_cert_revocation_list_entry_s;
|
||||||
|
|
||||||
/** Structure for the network keys used by net_network_key_get */
|
/** Structure for the network keys used by net_network_key_get */
|
||||||
typedef struct ns_keys_t
|
typedef struct ns_keys_t
|
||||||
|
|
||||||
|
@ -880,12 +892,56 @@ extern int8_t arm_net_route_delete(const uint8_t *prefix, uint8_t prefix_len, co
|
||||||
extern int8_t arm_nwk_6lowpan_border_router_nd_context_load(int8_t interface_id, uint8_t *contex_data); //NVM
|
extern int8_t arm_nwk_6lowpan_border_router_nd_context_load(int8_t interface_id, uint8_t *contex_data); //NVM
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set certificate chain for PANA
|
* Set certificate chain
|
||||||
|
*
|
||||||
* \param chain_info Certificate chain.
|
* \param chain_info Certificate chain.
|
||||||
* \return 0 on success, negative on failure.
|
* \return 0 on success, negative on failure.
|
||||||
*/
|
*/
|
||||||
extern int8_t arm_network_certificate_chain_set(const arm_certificate_chain_entry_s *chain_info);
|
extern int8_t arm_network_certificate_chain_set(const arm_certificate_chain_entry_s *chain_info);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add trusted certificate
|
||||||
|
*
|
||||||
|
* This is used to add trusted root or intermediate certificate in addition to those
|
||||||
|
* added using certificate chain set call. Function can be called several times to add
|
||||||
|
* more than one certificate.
|
||||||
|
*
|
||||||
|
* \param cert Certificate.
|
||||||
|
* \return 0 on success, negative on failure.
|
||||||
|
*/
|
||||||
|
extern int8_t arm_network_trusted_certificate_add(const arm_certificate_entry_s *cert);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove trusted certificate
|
||||||
|
*
|
||||||
|
* This is used to remove trusted root or intermediate certificate.
|
||||||
|
*
|
||||||
|
* \param cert Certificate.
|
||||||
|
* \return 0 on success, negative on failure.
|
||||||
|
*/
|
||||||
|
extern int8_t arm_network_trusted_certificate_remove(const arm_certificate_entry_s *cert);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add Certificate Revocation List
|
||||||
|
*
|
||||||
|
* This is used to add Certificate Revocation List (CRL). Function can be called several
|
||||||
|
* times to add more than one Certificate Revocation List.
|
||||||
|
*
|
||||||
|
* \param crl Certificate revocation list
|
||||||
|
* \return 0 on success, negative on failure.
|
||||||
|
*/
|
||||||
|
extern int8_t arm_network_certificate_revocation_list_add(const arm_cert_revocation_list_entry_s *crl);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove Certificate Revocation List
|
||||||
|
*
|
||||||
|
* This is used to remove Certificate Revocation List.
|
||||||
|
*
|
||||||
|
* \param crl Certificate revocation list
|
||||||
|
* \return 0 on success, negative on failure.
|
||||||
|
*/
|
||||||
|
extern int8_t arm_network_certificate_revocation_list_remove(const arm_cert_revocation_list_entry_s *crl);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Add PSK key to TLS library.
|
* \brief Add PSK key to TLS library.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2017, Arm Limited and affiliates.
|
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2017, Arm Limited and affiliates.
|
* Copyright (c) 2013-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2018, Arm Limited and affiliates.
|
* Copyright (c) 2014-2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -530,6 +530,30 @@ int thread_test_mle_message_send(int8_t interface_id, uint8_t *dst_address, uint
|
||||||
* \return <0 Failure
|
* \return <0 Failure
|
||||||
*/
|
*/
|
||||||
int thread_test_extension_name_set(int8_t interface_id, char extension_name[16]);
|
int thread_test_extension_name_set(int8_t interface_id, char extension_name[16]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Set multicast addresses per message.
|
||||||
|
*
|
||||||
|
* \param value Number of addresses per message (valid range 1-15)
|
||||||
|
*
|
||||||
|
* \return 0 OK
|
||||||
|
* \return <0 Failure
|
||||||
|
*/
|
||||||
|
int8_t thread_test_mcast_address_per_message_set(uint8_t value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thread router parent priority set.
|
||||||
|
*
|
||||||
|
* This function is used to set parent priority in connectivity TLV.
|
||||||
|
*
|
||||||
|
* \param interface_id Network interface ID.
|
||||||
|
* \param parent_priority value to be set (0x40 High, 0x00 Medium, 0xC0 Low, 0x80 Do not use) .
|
||||||
|
*
|
||||||
|
* \return 0, Set OK.
|
||||||
|
* \return <0 Set Fail.
|
||||||
|
*/
|
||||||
|
int thread_test_parent_priority_set(int8_t interface_id, uint8_t parent_priority);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,157 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014-2019, 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 NET_WS_TEST_H_
|
||||||
|
#define NET_WS_TEST_H_
|
||||||
|
|
||||||
|
/* Prevent this file being inserted in public Doxygen generated file
|
||||||
|
* this is not part of our external API. */
|
||||||
|
#ifndef DOXYGEN
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file net_ws_test.h
|
||||||
|
* \brief Wi-SUN Library Test API.
|
||||||
|
*
|
||||||
|
* \warning NOTICE! This is test API must not be used externally.
|
||||||
|
*
|
||||||
|
* \warning This file is not part of the version number control and can change any time.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "ns_types.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Set Pan size.
|
||||||
|
*
|
||||||
|
* Pan size is reported to advertisement. Using this function
|
||||||
|
* actual value can be overridden.
|
||||||
|
*
|
||||||
|
* Set pan_size to 0xffff to stop override
|
||||||
|
*
|
||||||
|
* \param interface_id Network Interface
|
||||||
|
* \param pan_size Pan size reported in advertisements
|
||||||
|
*
|
||||||
|
* \return 0 OK
|
||||||
|
* \return <0 Failure
|
||||||
|
*/
|
||||||
|
int ws_test_pan_size_set(int8_t interface_id, uint16_t pan_size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Set maximum child count.
|
||||||
|
*
|
||||||
|
* Maximum amount of children allowed for this device
|
||||||
|
*
|
||||||
|
* Values above MAC neighbor table - RPL parents - temporary entries will cause undefined behaviour
|
||||||
|
*
|
||||||
|
* Set child count to 0xffff to stop override
|
||||||
|
*
|
||||||
|
* \param interface_id Network Interface
|
||||||
|
* \param child_count Pan size reported in advertisements
|
||||||
|
*
|
||||||
|
* \return 0 OK
|
||||||
|
* \return <0 Failure
|
||||||
|
*/
|
||||||
|
int ws_test_max_child_count_set(int8_t interface_id, uint16_t child_count);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets Group Transient Keys.
|
||||||
|
*
|
||||||
|
* Sets Group Transient Keys (GTKs). Up to four GTKs can be set (GTKs from index
|
||||||
|
* 0 to 3). At least one GTK must be set. GTKs provided in this function call are
|
||||||
|
* compared to current GTKs on node or border router GTK storage. If GTK is new
|
||||||
|
* or modified it is updated to GTK storage. If GTK is same as previous one, no
|
||||||
|
* changes are made. If GTK is NULL then it is removed from GTK storage. When a
|
||||||
|
* new GTK is inserted or GTK is modified, GTK lifetime is set to default. If GTKs
|
||||||
|
* are set to border router after bootstrap, border router initiates GTK update
|
||||||
|
* to network.
|
||||||
|
*
|
||||||
|
* \param interface_id Network interface ID.
|
||||||
|
* \param gtk GTK array, if GTK is not set, pointer for the index shall be NULL.
|
||||||
|
*
|
||||||
|
* \return 0 GTKs are set
|
||||||
|
* \return <0 GTK set has failed
|
||||||
|
*/
|
||||||
|
int ws_test_gtk_set(int8_t interface_id, uint8_t *gtk[4]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets index of active key.
|
||||||
|
*
|
||||||
|
* Sets index of active Group Transient Key (GTK) to border router. If index is
|
||||||
|
* set after bootstrap, initiates dissemination of new key index to network.
|
||||||
|
*
|
||||||
|
* \param interface_id Network interface ID.
|
||||||
|
* \param index Key index
|
||||||
|
*
|
||||||
|
* \return 0 Active key index has been set
|
||||||
|
* \return <0 Active key index set has failed
|
||||||
|
*/
|
||||||
|
int ws_test_active_key_set(int8_t interface_id, uint8_t index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets lifetime for keys
|
||||||
|
*
|
||||||
|
* Sets Group Transient Key (GTK), Pairwise Master Key (PMK) and
|
||||||
|
* Pairwise Transient Key (PTK) lifetimes.
|
||||||
|
*
|
||||||
|
* \param interface_id Network interface ID.
|
||||||
|
* \param gtk_lifetime GTK lifetime in minutes
|
||||||
|
* \param pmk_lifetime PMK lifetime in minutes
|
||||||
|
* \param ptk_lifetime PTK lifetime in minutes
|
||||||
|
*
|
||||||
|
* \return 0 Lifetimes are set
|
||||||
|
* \return <0 Lifetime set has failed
|
||||||
|
*/
|
||||||
|
int ws_test_key_lifetime_set(
|
||||||
|
int8_t interface_id,
|
||||||
|
uint32_t gtk_lifetime,
|
||||||
|
uint32_t pmk_lifetime,
|
||||||
|
uint32_t ptk_lifetime
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets time configurations for GTK keys
|
||||||
|
*
|
||||||
|
* Sets GTK Revocation Lifetime Reduction and GTK New Activation Time values
|
||||||
|
* as parts of the GTK lifetime (e.g. value 3 is 1/3 * lifetime). Sets GTK
|
||||||
|
* maximum mismatch time in minutes.
|
||||||
|
*
|
||||||
|
* \param interface_id Network interface ID.
|
||||||
|
* \param revocat_lifetime_reduct GTK Revocation Lifetime Reduction (1 / value * GTK lifetime)
|
||||||
|
* \param new_activation_time GTK New Activation Time (1 / value * GTK lifetime)
|
||||||
|
* \param max_mismatch GTK maximum mismatch in minutes
|
||||||
|
*
|
||||||
|
* \return 0 Lifetimes are set
|
||||||
|
* \return <0 Lifetime set has failed.
|
||||||
|
*/
|
||||||
|
int ws_test_gtk_time_settings_set(
|
||||||
|
int8_t interface_id,
|
||||||
|
uint8_t revocat_lifetime_reduct,
|
||||||
|
uint8_t new_activation_time,
|
||||||
|
uint32_t max_mismatch
|
||||||
|
);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* DOXYGEN */
|
||||||
|
#endif /* NET_THREAD_TEST_H_ */
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, Arm Limited and affiliates.
|
* Copyright (c) 2017-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2017, Arm Limited and affiliates.
|
* Copyright (c) 2006-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -64,6 +64,7 @@ typedef enum {
|
||||||
PHY_EXTENSION_GET_TIMESTAMP, /**< Read 32-bit constant monotonic time stamp in us */
|
PHY_EXTENSION_GET_TIMESTAMP, /**< Read 32-bit constant monotonic time stamp in us */
|
||||||
PHY_EXTENSION_SET_CSMA_PARAMETERS, /**< CSMA parameter's are given by phy_csma_params_t structure remember type cast uint8_t pointer to structure type*/
|
PHY_EXTENSION_SET_CSMA_PARAMETERS, /**< CSMA parameter's are given by phy_csma_params_t structure remember type cast uint8_t pointer to structure type*/
|
||||||
PHY_EXTENSION_GET_SYMBOLS_PER_SECOND, /**< Read Symbols per seconds which will help to convert symbol time to real time */
|
PHY_EXTENSION_GET_SYMBOLS_PER_SECOND, /**< Read Symbols per seconds which will help to convert symbol time to real time */
|
||||||
|
PHY_EXTENSION_SET_RF_CONFIGURATION /**< Set RF configuration using phy_rf_channel_parameters_s structure */
|
||||||
} phy_extension_type_e;
|
} phy_extension_type_e;
|
||||||
|
|
||||||
/** Address types */
|
/** Address types */
|
||||||
|
@ -130,6 +131,7 @@ typedef enum phy_modulation_e {
|
||||||
M_OQPSK, ///< OQPSK
|
M_OQPSK, ///< OQPSK
|
||||||
M_BPSK, ///< BPSK
|
M_BPSK, ///< BPSK
|
||||||
M_GFSK, ///< GFSK
|
M_GFSK, ///< GFSK
|
||||||
|
M_2FSK, ///< 2FSK
|
||||||
M_UNDEFINED ///< UNDEFINED
|
M_UNDEFINED ///< UNDEFINED
|
||||||
} phy_modulation_e;
|
} phy_modulation_e;
|
||||||
|
|
||||||
|
@ -146,13 +148,21 @@ typedef enum {
|
||||||
CHANNEL_PAGE_10 = 10 ///< Page 10
|
CHANNEL_PAGE_10 = 10 ///< Page 10
|
||||||
} channel_page_e;
|
} channel_page_e;
|
||||||
|
|
||||||
|
/** Modulation index */
|
||||||
|
typedef enum {
|
||||||
|
MODULATION_INDEX_0_5 = 0, ///< Modulation index 0.5
|
||||||
|
MODULATION_INDEX_1_0 = 1, ///< Modulation index 1.0
|
||||||
|
MODULATION_INDEX_UNDEFINED ///< Modulation index undefined
|
||||||
|
} phy_modulation_index_e;
|
||||||
|
|
||||||
/** Channel configuration */
|
/** Channel configuration */
|
||||||
typedef struct phy_rf_channel_configuration_s {
|
typedef struct phy_rf_channel_configuration_s {
|
||||||
uint32_t channel_0_center_frequency; ///< Center frequency
|
uint32_t channel_0_center_frequency; ///< Center frequency
|
||||||
uint32_t channel_spacing; ///< Channel spacing
|
uint32_t channel_spacing; ///< Channel spacing
|
||||||
uint32_t datarate; ///< Data rate
|
uint32_t datarate; ///< Data rate
|
||||||
uint16_t number_of_channels; ///< Number of channels
|
uint16_t number_of_channels; ///< Number of channels
|
||||||
phy_modulation_e modulation; ///< Modulation scheme
|
phy_modulation_e modulation; ///< Modulation scheme
|
||||||
|
phy_modulation_index_e modulation_index; ///< Modulation index
|
||||||
} phy_rf_channel_configuration_s;
|
} phy_rf_channel_configuration_s;
|
||||||
|
|
||||||
/** Channel page configuration */
|
/** Channel page configuration */
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2017, Arm Limited and affiliates.
|
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2010-2017, Arm Limited and affiliates.
|
* Copyright (c) 2010-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2017, Arm Limited and affiliates.
|
* Copyright (c) 2015-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2017, Arm Limited and affiliates.
|
* Copyright (c) 2015-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2017, Arm Limited and affiliates.
|
* Copyright (c) 2015-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2017, Arm Limited and affiliates.
|
* Copyright (c) 2015-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017-2019, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file ws_bbr_api.h
|
||||||
|
* \brief Wi-SUN backbone border router (BBR) application interface.
|
||||||
|
*
|
||||||
|
* This is Wi-SUN backbone Border router service.
|
||||||
|
* When started the module takes care of starting the
|
||||||
|
* components that enables default border router functionality in Wi-SUN network.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WS_BBR_API_H_
|
||||||
|
#define WS_BBR_API_H_
|
||||||
|
|
||||||
|
#include "ns_types.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start backbone border router service.
|
||||||
|
*
|
||||||
|
* if backbone interface is enabled and allows routing.
|
||||||
|
* Enables ND proxy for address found from backbone
|
||||||
|
*
|
||||||
|
* \param interface_id Wi-SUN network interface id.
|
||||||
|
* \param backbone_interface_id backbone interface id.
|
||||||
|
*
|
||||||
|
* \return 0 on success
|
||||||
|
* \return <0 in case of errors
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int ws_bbr_start(int8_t interface_id, int8_t backbone_interface_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop backbone Border router.
|
||||||
|
*
|
||||||
|
* \param interface_id interface ID of the Wi-SUN network
|
||||||
|
*
|
||||||
|
* \return 0 on success
|
||||||
|
* \return <0 in case of errors
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void ws_bbr_stop(int8_t interface_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove node's keys from border router
|
||||||
|
*
|
||||||
|
* Removes node's keys from border router i.e. Pairwise Master Key (PMK)
|
||||||
|
* and Pairwise Transient Key (PTK). This function is used on revocation of
|
||||||
|
* node's access procedure after authentication service is configured
|
||||||
|
* to reject authentication attempts of the node (e.g. node's certificate is
|
||||||
|
* revoked). Sub sequential calls to function can be used to remove several
|
||||||
|
* nodes from border router.
|
||||||
|
*
|
||||||
|
* \param interface_id Network interface ID.
|
||||||
|
* \param eui64 EUI-64 of revoked node
|
||||||
|
*
|
||||||
|
* \return 0, Node's keys has been removed
|
||||||
|
* \return <0 Node's key remove has failed (e.g. unknown address)
|
||||||
|
*/
|
||||||
|
int ws_bbr_node_keys_remove(int8_t interface_id, uint8_t *eui64);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start revocation of node's access
|
||||||
|
*
|
||||||
|
* Starts revocation of node's access procedure on border router. Before
|
||||||
|
* the call to this function, authentication service must be configured to
|
||||||
|
* reject authentication attempts of the removed nodes (e.g. certificates
|
||||||
|
* of the nodes are revoked). Also the keys for the nodes must be removed
|
||||||
|
* from the border router.
|
||||||
|
*
|
||||||
|
* \param interface_id Network interface ID.
|
||||||
|
*
|
||||||
|
* \return 0, Revocation started OK.
|
||||||
|
* \return <0 Revocation start failed.
|
||||||
|
*/
|
||||||
|
int ws_bbr_node_access_revoke_start(int8_t interface_id);
|
||||||
|
|
||||||
|
#endif /* WS_BBR_API_H_ */
|
|
@ -0,0 +1,261 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2019, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file ws_management_if.h
|
||||||
|
* \brief Wi-SUN management interface.
|
||||||
|
*
|
||||||
|
* This interface is used for configuring Wi-SUN devices.
|
||||||
|
* After creating the Wi-SUN interface, you can use this interface to configure the Wi-SUN device
|
||||||
|
* behaviour. When you are done with the configurations, you need to call interface up to enable a Wi-SUN node.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WS_MANAGEMENT_API_H_
|
||||||
|
#define WS_MANAGEMENT_API_H_
|
||||||
|
|
||||||
|
#include "ns_types.h"
|
||||||
|
#include "net_interface.h" /* Declaration for channel_list_s. */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Regulatory domain values*/
|
||||||
|
#define REG_DOMAIN_WW 0x00 // World wide
|
||||||
|
#define REG_DOMAIN_NA 0x01 // North America
|
||||||
|
#define REG_DOMAIN_JP 0x02 // Japan
|
||||||
|
#define REG_DOMAIN_EU 0x03 // European Union
|
||||||
|
#define REG_DOMAIN_CH 0x04 // China
|
||||||
|
#define REG_DOMAIN_IN 0x05 // India
|
||||||
|
#define REG_DOMAIN_MX 0x06 //
|
||||||
|
#define REG_DOMAIN_BZ 0x07 // Brazil
|
||||||
|
#define REG_DOMAIN_AZ 0x08 // Australia
|
||||||
|
#define REG_DOMAIN_NZ 0x08 // New zealand
|
||||||
|
#define REG_DOMAIN_KR 0x09 // Korea
|
||||||
|
#define REG_DOMAIN_PH 0x0A //
|
||||||
|
#define REG_DOMAIN_MY 0x0B //
|
||||||
|
#define REG_DOMAIN_HK 0x0C //
|
||||||
|
#define REG_DOMAIN_SG 0x0D // band 866-869
|
||||||
|
#define REG_DOMAIN_TH 0x0E //
|
||||||
|
#define REG_DOMAIN_VN 0x0F //
|
||||||
|
#define REG_DOMAIN_SG_H 0x10 // band 920-925
|
||||||
|
|
||||||
|
#define OPERATING_MODE_1a 0x1a
|
||||||
|
#define OPERATING_MODE_1b 0x1b
|
||||||
|
#define OPERATING_MODE_2a 0x2a
|
||||||
|
#define OPERATING_MODE_2b 0x2b
|
||||||
|
#define OPERATING_MODE_3 0x03
|
||||||
|
#define OPERATING_MODE_4a 0x4a
|
||||||
|
#define OPERATING_MODE_4b 0x4b
|
||||||
|
#define OPERATING_MODE_5 0x05
|
||||||
|
|
||||||
|
#define CHANNEL_FUNCTION_FIXED 0x00 // Fixed channel
|
||||||
|
#define CHANNEL_FUNCTION_TR51CF 0x01 // TR51CF
|
||||||
|
#define CHANNEL_FUNCTION_DH1CF 0x02 // Direct Hash
|
||||||
|
#define CHANNEL_FUNCTION_VENDOR_DEFINED 0x03 // vendor given channel hop schedule
|
||||||
|
|
||||||
|
#define CHANNEL_SPACING_200 0x00 // 200 khz
|
||||||
|
#define CHANNEL_SPACING_400 0x01 // 400 khz
|
||||||
|
#define CHANNEL_SPACING_600 0x02 // 600 khz
|
||||||
|
#define CHANNEL_SPACING_100 0x03 // 100 khz
|
||||||
|
#define CHANNEL_SPACING_250 0x04 // 250 khz
|
||||||
|
|
||||||
|
#define NETWORK_SIZE_AUTOMATIC 0x00
|
||||||
|
#define NETWORK_SIZE_SMALL 0x01
|
||||||
|
#define NETWORK_SIZE_LARGE 0x10
|
||||||
|
|
||||||
|
|
||||||
|
/** Temporary API change flag. this will be removed when new version of API is implemented on applications
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define WS_MANAGEMENT_API_VER_2
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize Wi-SUN stack.
|
||||||
|
*
|
||||||
|
* Generates the default configuration for Wi-SUN operation
|
||||||
|
*
|
||||||
|
* \param interface_id Network interface ID.
|
||||||
|
* \param regulatory_domain Mandatory regulatory domain value of the device.
|
||||||
|
* \param network_name_ptr Network name where to join if no configuration found from storage.
|
||||||
|
* \param fhss_timer_ptr FHSS functions for timer adaptation to platform.
|
||||||
|
*
|
||||||
|
* \return 0, Init OK.
|
||||||
|
* \return <0 Init fail.
|
||||||
|
*/
|
||||||
|
int ws_management_node_init(
|
||||||
|
int8_t interface_id,
|
||||||
|
uint8_t regulatory_domain,
|
||||||
|
char *network_name_ptr,
|
||||||
|
fhss_timer_t *fhss_timer_ptr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure regulatory domain of Wi-SUN stack.
|
||||||
|
*
|
||||||
|
* Change the default configuration for Wi-SUN PHY operation.
|
||||||
|
*
|
||||||
|
* Supported values:
|
||||||
|
* Domain: "NA"(0x01), "KR"(0x09)
|
||||||
|
* Operating class: (1), (2)
|
||||||
|
* operation mode: "1b" (symbol rate 50, modulation index 1)
|
||||||
|
*
|
||||||
|
* if value of 255 is given then previous value is used.
|
||||||
|
*
|
||||||
|
* \param interface_id Network interface ID.
|
||||||
|
* \param regulatory_domain FHSS regulatory domain default to "KR" 0x09.
|
||||||
|
* \param operating_class FHSS operating class default to 1.
|
||||||
|
* \param operating_mode FHSS phy operating mode default to "1b".
|
||||||
|
*
|
||||||
|
* \return 0, Init OK.
|
||||||
|
* \return <0 Init fail.
|
||||||
|
*/
|
||||||
|
int ws_management_regulatory_domain_set(
|
||||||
|
int8_t interface_id,
|
||||||
|
uint8_t regulatory_domain,
|
||||||
|
uint8_t operating_class,
|
||||||
|
uint8_t operating_mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set timing parameters related to network size.
|
||||||
|
*
|
||||||
|
* timing parameters follows the specification example from Wi-SUN specification
|
||||||
|
*
|
||||||
|
* Default value: automatic
|
||||||
|
* small network size: hundreds of devices
|
||||||
|
* Large network size: thousands of devices
|
||||||
|
* automatic: when discovering the network network size is learned
|
||||||
|
* from advertisements and timings adjusted accordingly
|
||||||
|
*
|
||||||
|
* \param interface_id Network interface ID.
|
||||||
|
* \param network_size define from NETWORK_SIZE_*.
|
||||||
|
*
|
||||||
|
* \return 0, Init OK.
|
||||||
|
* \return <0 Init fail.
|
||||||
|
*/
|
||||||
|
int ws_management_network_size_set(
|
||||||
|
int8_t interface_id,
|
||||||
|
uint8_t network_size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set channel mask for FHSS operation.
|
||||||
|
*
|
||||||
|
* Default value: all channels are allowed.
|
||||||
|
*
|
||||||
|
* \param interface_id Network interface ID.
|
||||||
|
* \param channel_mask set bits matching the channel 1 to allow channel 0 to disallow.
|
||||||
|
*
|
||||||
|
* \return 0, Init OK.
|
||||||
|
* \return <0 Init fail.
|
||||||
|
*/
|
||||||
|
int ws_management_channel_mask_set(
|
||||||
|
int8_t interface_id,
|
||||||
|
uint32_t channel_mask[8]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure Application defined channel plan.
|
||||||
|
*
|
||||||
|
* Change the application defined channel plan.
|
||||||
|
* This changes our channel plan that is reported to our children.
|
||||||
|
* PHY driver must be configured to follow these settings to make the configuration active.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* \param interface_id Network interface ID.
|
||||||
|
* \param channel_plan Channel plan must be 1 application defined if deviating from regulatory domain (0).
|
||||||
|
* \param uc_channel_function 0: Fixed channel, 1:TR51CF, 2: Direct Hash, 3: Vendor defined.
|
||||||
|
* \param bc_channel_function 0: Fixed channel, 1:TR51CF, 2: Direct Hash, 3: Vendor defined.
|
||||||
|
* \param ch0_freq ch0 center frequency.
|
||||||
|
* \param channel_spacing Channel spacing value 0:200k, 1:400k, 2:600k, 3:100k.
|
||||||
|
* \param number_of_channels FHSS phy operating mode default to "1b".
|
||||||
|
*
|
||||||
|
* \return 0, Init OK.
|
||||||
|
* \return <0 Init fail.
|
||||||
|
*/
|
||||||
|
int ws_management_channel_plan_set(
|
||||||
|
int8_t interface_id,
|
||||||
|
uint8_t channel_plan,
|
||||||
|
uint8_t uc_channel_function,
|
||||||
|
uint8_t bc_channel_function,
|
||||||
|
uint32_t ch0_freq, // Stack can not modify this
|
||||||
|
uint8_t channel_spacing,// Stack can not modify this
|
||||||
|
uint8_t number_of_channels);// Stack can not modify this
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure timing values for FHSS.
|
||||||
|
*
|
||||||
|
* Change the default configuration for Wi-SUN FHSS operation.
|
||||||
|
*
|
||||||
|
* \param interface_id Network interface ID.
|
||||||
|
* \param fhss_uc_dwell_interval default to 250 ms.
|
||||||
|
* \param fhss_broadcast_interval default to 800 ms.
|
||||||
|
* \param fhss_bc_dwell_interval default to 200 ms.
|
||||||
|
*
|
||||||
|
* \return 0, Init OK.
|
||||||
|
* \return <0 Init fail.
|
||||||
|
*/
|
||||||
|
int ws_management_fhss_timing_configure(
|
||||||
|
int8_t interface_id,
|
||||||
|
uint8_t fhss_uc_dwell_interval,
|
||||||
|
uint32_t fhss_broadcast_interval,
|
||||||
|
uint8_t fhss_bc_dwell_interval);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure unicast channel function.
|
||||||
|
*
|
||||||
|
* Change the default configuration for Wi-SUN FHSS operation.
|
||||||
|
* if application defined is used the behaviour is undefined
|
||||||
|
*
|
||||||
|
* \param interface_id Network interface ID.
|
||||||
|
* \param channel_function Unicast channel function.
|
||||||
|
* \param fixed_channel Used channel when channel function is fixed channel. If 0xFFFF, randomly chosen channel is used.
|
||||||
|
* \param dwell_interval Used dwell interval when channel function is TR51 or DH1.
|
||||||
|
*
|
||||||
|
* \return 0, Init OK.
|
||||||
|
* \return <0 Init fail.
|
||||||
|
*/
|
||||||
|
int ws_management_fhss_unicast_channel_function_configure(
|
||||||
|
int8_t interface_id,
|
||||||
|
uint8_t channel_function,
|
||||||
|
uint16_t fixed_channel,
|
||||||
|
uint8_t dwell_interval);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure broadcast channel function.
|
||||||
|
*
|
||||||
|
* Change the default configuration for Wi-SUN FHSS operation.
|
||||||
|
* if application defined is used the behaviour is undefined
|
||||||
|
*
|
||||||
|
* \param interface_id Network interface ID.
|
||||||
|
* \param channel_function Broadcast channel function.
|
||||||
|
* \param fixed_channel Used channel when channel function is fixed channel. If 0xFFFF, randomly chosen channel is used.
|
||||||
|
* \param dwell_interval Broadcast channel dwell interval.
|
||||||
|
* \param broadcast_interval Broadcast interval.
|
||||||
|
*
|
||||||
|
* \return 0, Init OK.
|
||||||
|
* \return <0 Init fail.
|
||||||
|
*/
|
||||||
|
int ws_management_fhss_broadcast_channel_function_configure(
|
||||||
|
int8_t interface_id,
|
||||||
|
uint8_t channel_function,
|
||||||
|
uint16_t fixed_channel,
|
||||||
|
uint8_t dwell_interval,
|
||||||
|
uint32_t broadcast_interval);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /* WS_MANAGEMENT_API_H_ */
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2017, Arm Limited and affiliates.
|
* Copyright (c) 2013-2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
#include "nsconfig.h"
|
#include "nsconfig.h"
|
||||||
#include "ns_types.h"
|
#include "ns_types.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "Core/include/socket.h"
|
#include "Core/include/ns_socket.h"
|
||||||
#include "nsdynmemLIB.h"
|
#include "nsdynmemLIB.h"
|
||||||
#include "ns_trace.h"
|
#include "ns_trace.h"
|
||||||
#include "NWK_INTERFACE/Include/protocol.h"
|
#include "NWK_INTERFACE/Include/protocol.h"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2018, Arm Limited and affiliates.
|
* Copyright (c) 2013-2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -22,7 +22,7 @@
|
||||||
#include "eventOS_scheduler.h"
|
#include "eventOS_scheduler.h"
|
||||||
#include "ns_trace.h"
|
#include "ns_trace.h"
|
||||||
#include "nsdynmemLIB.h"
|
#include "nsdynmemLIB.h"
|
||||||
#include "Core/include/socket.h"
|
#include "Core/include/ns_socket.h"
|
||||||
#include "NWK_INTERFACE/Include/protocol.h"
|
#include "NWK_INTERFACE/Include/protocol.h"
|
||||||
#include "Common_Protocols/udp.h"
|
#include "Common_Protocols/udp.h"
|
||||||
#include "Common_Protocols/ipv6.h"
|
#include "Common_Protocols/ipv6.h"
|
||||||
|
@ -373,6 +373,7 @@ void protocol_6lowpan_configure_core(protocol_interface_info_entry_t *cur)
|
||||||
cur->ipv6_neighbour_cache.link_mtu = LOWPAN_MTU;
|
cur->ipv6_neighbour_cache.link_mtu = LOWPAN_MTU;
|
||||||
#ifdef HAVE_6LOWPAN_ND
|
#ifdef HAVE_6LOWPAN_ND
|
||||||
cur->ipv6_neighbour_cache.send_nud_probes = nd_params.send_nud_probes;
|
cur->ipv6_neighbour_cache.send_nud_probes = nd_params.send_nud_probes;
|
||||||
|
cur->ipv6_neighbour_cache.probe_avoided_routers = nd_params.send_nud_probes;
|
||||||
cur->iids_map_to_mac = nd_params.iids_map_to_mac;
|
cur->iids_map_to_mac = nd_params.iids_map_to_mac;
|
||||||
#endif
|
#endif
|
||||||
cur->ip_multicast_as_mac_unicast_to_parent = false;
|
cur->ip_multicast_as_mac_unicast_to_parent = false;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2018, Arm Limited and affiliates.
|
* Copyright (c) 2015-2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -1408,6 +1408,8 @@ static void lowpan_mle_receive_security_bypass_cb(int8_t interface_id, mle_messa
|
||||||
pana_reset_client_session();
|
pana_reset_client_session();
|
||||||
bootsrap_next_state_kick(ER_PANA_AUTH_ERROR, interface);
|
bootsrap_next_state_kick(ER_PANA_AUTH_ERROR, interface);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
(void)mle_msg;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2017, Arm Limited and affiliates.
|
* Copyright (c) 2013-2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -26,7 +26,7 @@
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "ns_trace.h"
|
#include "ns_trace.h"
|
||||||
#include "randLIB.h"
|
#include "randLIB.h"
|
||||||
#include "Core/include/socket.h"
|
#include "Core/include/ns_socket.h"
|
||||||
#include "6LoWPAN/IPHC_Decode/cipv6.h"
|
#include "6LoWPAN/IPHC_Decode/cipv6.h"
|
||||||
#include "6LoWPAN/Fragmentation/cipv6_fragmenter.h"
|
#include "6LoWPAN/Fragmentation/cipv6_fragmenter.h"
|
||||||
#include "NWK_INTERFACE/Include/protocol.h"
|
#include "NWK_INTERFACE/Include/protocol.h"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2017, Arm Limited and affiliates.
|
* Copyright (c) 2014-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2017, Arm Limited and affiliates.
|
* Copyright (c) 2014-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2017, Arm Limited and affiliates.
|
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2017, Arm Limited and affiliates.
|
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
* Copyright (c) 2016-2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -19,7 +19,7 @@
|
||||||
#define MAC_HELPER_H
|
#define MAC_HELPER_H
|
||||||
|
|
||||||
#include "mlme.h"
|
#include "mlme.h"
|
||||||
#include "Core/include/address.h"
|
#include "Core/include/ns_address_internal.h"
|
||||||
|
|
||||||
struct channel_list_s;
|
struct channel_list_s;
|
||||||
struct nwk_scan_params;
|
struct nwk_scan_params;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
* Copyright (c) 2016-2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -22,8 +22,8 @@
|
||||||
#include "NWK_INTERFACE/Include/protocol_abstract.h"
|
#include "NWK_INTERFACE/Include/protocol_abstract.h"
|
||||||
#include "NWK_INTERFACE/Include/protocol_timer.h"
|
#include "NWK_INTERFACE/Include/protocol_timer.h"
|
||||||
#include "Service_Libs/mle_service/mle_service_api.h"
|
#include "Service_Libs/mle_service/mle_service_api.h"
|
||||||
#include "Core/include/address.h"
|
#include "Core/include/ns_address_internal.h"
|
||||||
#include "Core/include/socket.h"
|
#include "Core/include/ns_socket.h"
|
||||||
#include "6LoWPAN/Thread/thread_common.h"
|
#include "6LoWPAN/Thread/thread_common.h"
|
||||||
#include "6LoWPAN/Thread/thread_management_internal.h"
|
#include "6LoWPAN/Thread/thread_management_internal.h"
|
||||||
#include "6LoWPAN/MAC/mac_helper.h"
|
#include "6LoWPAN/MAC/mac_helper.h"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2017, Arm Limited and affiliates.
|
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2017, Arm Limited and affiliates.
|
* Copyright (c) 2014-2017, 2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -29,7 +29,7 @@
|
||||||
#include "NWK_INTERFACE/Include/protocol.h"
|
#include "NWK_INTERFACE/Include/protocol.h"
|
||||||
#include "NWK_INTERFACE/Include/protocol_stats.h"
|
#include "NWK_INTERFACE/Include/protocol_stats.h"
|
||||||
#include "6LoWPAN/IPHC_Decode/cipv6.h"
|
#include "6LoWPAN/IPHC_Decode/cipv6.h"
|
||||||
#include "Core/include/socket.h"
|
#include "Core/include/ns_socket.h"
|
||||||
#include "6LoWPAN/Mesh/mesh.h"
|
#include "6LoWPAN/Mesh/mesh.h"
|
||||||
#include "6LoWPAN/MAC/mac_helper.h"
|
#include "6LoWPAN/MAC/mac_helper.h"
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2017, Arm Limited and affiliates.
|
* Copyright (c) 2014-2017, 2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
#ifndef ND_DEFINES_H_
|
#ifndef ND_DEFINES_H_
|
||||||
#define ND_DEFINES_H_
|
#define ND_DEFINES_H_
|
||||||
|
|
||||||
#include "Core/include/address.h"
|
#include "Core/include/ns_address_internal.h"
|
||||||
#include "ns_list.h"
|
#include "ns_list.h"
|
||||||
#include "6LoWPAN/IPHC_Decode/lowpan_context.h"
|
#include "6LoWPAN/IPHC_Decode/lowpan_context.h"
|
||||||
#include "Common_Protocols/icmpv6_prefix.h"
|
#include "Common_Protocols/icmpv6_prefix.h"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2018, Arm Limited and affiliates.
|
* Copyright (c) 2013-2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -831,6 +831,8 @@ buffer_t *nd_dar_parse(buffer_t *buf, protocol_interface_info_entry_t *cur_inter
|
||||||
}
|
}
|
||||||
|
|
||||||
drop:
|
drop:
|
||||||
|
#else
|
||||||
|
(void)cur_interface;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return buffer_free(buf);
|
return buffer_free(buf);
|
||||||
|
@ -845,7 +847,7 @@ static void nd_update_registration(protocol_interface_info_entry_t *cur_interfac
|
||||||
neigh->lifetime = aro->lifetime * UINT32_C(60);
|
neigh->lifetime = aro->lifetime * UINT32_C(60);
|
||||||
ipv6_neighbour_set_state(&cur_interface->ipv6_neighbour_cache, neigh, IP_NEIGHBOUR_STALE);
|
ipv6_neighbour_set_state(&cur_interface->ipv6_neighbour_cache, neigh, IP_NEIGHBOUR_STALE);
|
||||||
/* Register with 2 seconds off the lifetime - don't want the NCE to expire before the route */
|
/* Register with 2 seconds off the lifetime - don't want the NCE to expire before the route */
|
||||||
ipv6_route_add(neigh->ip_address, 128, cur_interface->id, NULL, ROUTE_ARO, neigh->lifetime - 2, 0);
|
ipv6_route_add_metric(neigh->ip_address, 128, cur_interface->id, neigh->ip_address, ROUTE_ARO, NULL, 0, neigh->lifetime - 2, 32);
|
||||||
|
|
||||||
/* We need to know peer is a host before publishing - this needs MLE. Not yet established
|
/* We need to know peer is a host before publishing - this needs MLE. Not yet established
|
||||||
* what to do without MLE - might need special external/non-external prioritisation at root.
|
* what to do without MLE - might need special external/non-external prioritisation at root.
|
||||||
|
@ -864,19 +866,19 @@ static void nd_update_registration(protocol_interface_info_entry_t *cur_interfac
|
||||||
neigh->type = IP_NEIGHBOUR_TENTATIVE;
|
neigh->type = IP_NEIGHBOUR_TENTATIVE;
|
||||||
neigh->lifetime = 2;
|
neigh->lifetime = 2;
|
||||||
ipv6_neighbour_set_state(&cur_interface->ipv6_neighbour_cache, neigh, IP_NEIGHBOUR_STALE);
|
ipv6_neighbour_set_state(&cur_interface->ipv6_neighbour_cache, neigh, IP_NEIGHBOUR_STALE);
|
||||||
ipv6_route_add(neigh->ip_address, 128, cur_interface->id, NULL, ROUTE_ARO, 4, 0);
|
ipv6_route_add_metric(neigh->ip_address, 128, cur_interface->id, neigh->ip_address, ROUTE_ARO, NULL, 0, 4, 32);
|
||||||
rpl_control_unpublish_address(protocol_6lowpan_rpl_domain, neigh->ip_address);
|
rpl_control_unpublish_address(protocol_6lowpan_rpl_domain, neigh->ip_address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void nd_remove_registration(protocol_interface_info_entry_t *cur_interface, addrtype_t ll_type, const uint8_t *ll_address)
|
void nd_remove_registration(protocol_interface_info_entry_t *cur_interface, addrtype_t ll_type, const uint8_t *ll_address)
|
||||||
{
|
{
|
||||||
|
|
||||||
ns_list_foreach_safe(ipv6_neighbour_t, cur, &cur_interface->ipv6_neighbour_cache.list) {
|
ns_list_foreach_safe(ipv6_neighbour_t, cur, &cur_interface->ipv6_neighbour_cache.list) {
|
||||||
if ((cur->type == IP_NEIGHBOUR_REGISTERED
|
if ((cur->type == IP_NEIGHBOUR_REGISTERED
|
||||||
|| cur->type == IP_NEIGHBOUR_TENTATIVE)
|
|| cur->type == IP_NEIGHBOUR_TENTATIVE)
|
||||||
&& ipv6_neighbour_ll_addr_match(cur, ll_type, ll_address)) {
|
&& ipv6_neighbour_ll_addr_match(cur, ll_type, ll_address)) {
|
||||||
ipv6_route_delete(cur->ip_address, 128, cur_interface->id, NULL,
|
|
||||||
|
ipv6_route_delete(cur->ip_address, 128, cur_interface->id, cur->ip_address,
|
||||||
ROUTE_ARO);
|
ROUTE_ARO);
|
||||||
ipv6_neighbour_entry_remove(&cur_interface->ipv6_neighbour_cache,
|
ipv6_neighbour_entry_remove(&cur_interface->ipv6_neighbour_cache,
|
||||||
cur);
|
cur);
|
||||||
|
@ -923,6 +925,12 @@ bool nd_ns_aro_handler(protocol_interface_info_entry_t *cur_interface, const uin
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO - check hard upper limit on registrations? */
|
/* TODO - check hard upper limit on registrations? */
|
||||||
|
if (ws_info(cur_interface) &&
|
||||||
|
!ws_common_allow_child_registration(cur_interface)) {
|
||||||
|
aro_out->present = true;
|
||||||
|
aro_out->status = ARO_FULL;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* We need to have entry in the Neighbour Cache */
|
/* We need to have entry in the Neighbour Cache */
|
||||||
ipv6_neighbour_t *neigh = ipv6_neighbour_lookup_or_create(&cur_interface->ipv6_neighbour_cache, src_addr);
|
ipv6_neighbour_t *neigh = ipv6_neighbour_lookup_or_create(&cur_interface->ipv6_neighbour_cache, src_addr);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, Arm Limited and affiliates.
|
* Copyright (c) 2017-2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -22,7 +22,7 @@
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "randLIB.h"
|
#include "randLIB.h"
|
||||||
#include "nsdynmemLIB.h"
|
#include "nsdynmemLIB.h"
|
||||||
#include "Core/include/socket.h"
|
#include "Core/include/ns_socket.h"
|
||||||
#include "NWK_INTERFACE/Include/protocol.h"
|
#include "NWK_INTERFACE/Include/protocol.h"
|
||||||
#include "6LoWPAN/MAC/mac_helper.h"
|
#include "6LoWPAN/MAC/mac_helper.h"
|
||||||
#include "6LoWPAN/NVM/nwk_nvm.h"
|
#include "6LoWPAN/NVM/nwk_nvm.h"
|
||||||
|
|
|
@ -757,6 +757,7 @@ bool thread_bbr_routing_enabled(protocol_interface_info_entry_t *cur)
|
||||||
|
|
||||||
void thread_bbr_network_data_update_notify(protocol_interface_info_entry_t *cur)
|
void thread_bbr_network_data_update_notify(protocol_interface_info_entry_t *cur)
|
||||||
{
|
{
|
||||||
|
(void)cur;
|
||||||
thread_mdns_network_data_update_notify();
|
thread_mdns_network_data_update_notify();
|
||||||
thread_extension_bbr_route_update(cur);
|
thread_extension_bbr_route_update(cur);
|
||||||
}
|
}
|
||||||
|
@ -1000,6 +1001,7 @@ int thread_bbr_dua_entry_add(int8_t interface_id, const uint8_t *addr_data_ptr,
|
||||||
// Route info autofreed
|
// Route info autofreed
|
||||||
route->info_autofree = true;
|
route->info_autofree = true;
|
||||||
}
|
}
|
||||||
|
route->lifetime = lifetime; // update lifetime also from old route
|
||||||
map = route->info.info;
|
map = route->info.info;
|
||||||
memcpy(map->mleid_ptr, mleid_ptr, 8);
|
memcpy(map->mleid_ptr, mleid_ptr, 8);
|
||||||
map->last_contact_time = protocol_core_monotonic_time;
|
map->last_contact_time = protocol_core_monotonic_time;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2017, Arm Limited and affiliates.
|
* Copyright (c) 2015-2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2017, Arm Limited and affiliates.
|
* Copyright (c) 2015-2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
|
|
@ -902,6 +902,7 @@ void thread_interface_init(protocol_interface_info_entry_t *cur)
|
||||||
cur->if_snoop = thread_nd_snoop;
|
cur->if_snoop = thread_nd_snoop;
|
||||||
cur->if_icmp_handler = thread_nd_icmp_handler;
|
cur->if_icmp_handler = thread_nd_icmp_handler;
|
||||||
cur->ipv6_neighbour_cache.send_nud_probes = false;
|
cur->ipv6_neighbour_cache.send_nud_probes = false;
|
||||||
|
cur->ipv6_neighbour_cache.probe_avoided_routers = false;
|
||||||
cur->ipv6_neighbour_cache.recv_addr_reg = true;
|
cur->ipv6_neighbour_cache.recv_addr_reg = true;
|
||||||
cur->send_mld = false;
|
cur->send_mld = false;
|
||||||
cur->ip_multicast_as_mac_unicast_to_parent = true;
|
cur->ip_multicast_as_mac_unicast_to_parent = true;
|
||||||
|
@ -1514,6 +1515,7 @@ int thread_bootstrap_reset(protocol_interface_info_entry_t *cur)
|
||||||
cur->thread_info->thread_attached_state = THREAD_STATE_NETWORK_DISCOVER;
|
cur->thread_info->thread_attached_state = THREAD_STATE_NETWORK_DISCOVER;
|
||||||
}
|
}
|
||||||
cur->ipv6_neighbour_cache.send_nud_probes = false; //Disable NUD probing
|
cur->ipv6_neighbour_cache.send_nud_probes = false; //Disable NUD probing
|
||||||
|
cur->ipv6_neighbour_cache.probe_avoided_routers = false;
|
||||||
cur->ip_multicast_as_mac_unicast_to_parent = true;
|
cur->ip_multicast_as_mac_unicast_to_parent = true;
|
||||||
//Define Default Contexts
|
//Define Default Contexts
|
||||||
if (cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_SLEEPY_END_DEVICE) {
|
if (cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_SLEEPY_END_DEVICE) {
|
||||||
|
@ -2726,7 +2728,7 @@ int thread_bootstrap_network_data_activate(protocol_interface_info_entry_t *cur)
|
||||||
thread_border_router_network_data_update_notify(cur);
|
thread_border_router_network_data_update_notify(cur);
|
||||||
thread_bbr_network_data_update_notify(cur);
|
thread_bbr_network_data_update_notify(cur);
|
||||||
|
|
||||||
thread_maintenance_timer_set(cur, THREAD_MAINTENANCE_TIMER_INTERVAL);
|
thread_maintenance_timer_set(cur);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2846,7 +2848,7 @@ void thread_bootstrap_network_prefixes_process(protocol_interface_info_entry_t *
|
||||||
thread_addr_write_mesh_local_16(addr, curBorderRouter->routerID, cur->thread_info);
|
thread_addr_write_mesh_local_16(addr, curBorderRouter->routerID, cur->thread_info);
|
||||||
/* Do not allow multiple DHCP solicits from one prefix => delete previous */
|
/* Do not allow multiple DHCP solicits from one prefix => delete previous */
|
||||||
dhcp_client_global_address_delete(cur->id, NULL, curPrefix->servicesPrefix);
|
dhcp_client_global_address_delete(cur->id, NULL, curPrefix->servicesPrefix);
|
||||||
if (dhcp_client_get_global_address(cur->id, addr, curPrefix->servicesPrefix, cur->mac, thread_dhcp_client_gua_error_cb) == 0) {
|
if (dhcp_client_get_global_address(cur->id, addr, curPrefix->servicesPrefix, cur->mac, DHCPV6_DUID_HARDWARE_EUI64_TYPE, thread_dhcp_client_gua_error_cb) == 0) {
|
||||||
tr_debug("GP Address Requested");
|
tr_debug("GP Address Requested");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2856,8 +2858,8 @@ void thread_bootstrap_network_prefixes_process(protocol_interface_info_entry_t *
|
||||||
if ((cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_HOST ||
|
if ((cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_HOST ||
|
||||||
cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_SLEEPY_HOST) &&
|
cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_SLEEPY_HOST) &&
|
||||||
cur->thread_info->requestFullNetworkData == false) {
|
cur->thread_info->requestFullNetworkData == false) {
|
||||||
|
tr_debug("Invalidate router ID: %04x", curBorderRouter->routerID);
|
||||||
curBorderRouter->routerID = 0xfffe;
|
curBorderRouter->routerID = 0xfffe;
|
||||||
tr_debug("Invalidated router ID: %04x", curBorderRouter->routerID);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2868,7 +2870,9 @@ void thread_bootstrap_network_prefixes_process(protocol_interface_info_entry_t *
|
||||||
}
|
}
|
||||||
// generate address based on res1 bit
|
// generate address based on res1 bit
|
||||||
if (curBorderRouter->P_res1) {
|
if (curBorderRouter->P_res1) {
|
||||||
thread_extension_dua_address_generate(cur, curPrefix->servicesPrefix, 64);
|
if (!thread_dhcpv6_address_entry_available(curPrefix->servicesPrefix, &cur->ip_addresses)) {
|
||||||
|
thread_extension_dua_address_generate(cur, curPrefix->servicesPrefix, 64);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // for each borderRouterList
|
} // for each borderRouterList
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2017, Arm Limited and affiliates.
|
* Copyright (c) 2016-2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2017, Arm Limited and affiliates.
|
* Copyright (c) 2015-2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2017, Arm Limited and affiliates.
|
* Copyright (c) 2014-2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2015, 2017-2018, Arm Limited and affiliates.
|
* Copyright (c) 2014-2015, 2017-2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -88,7 +88,7 @@
|
||||||
#include "6LoWPAN/MAC/mac_pairwise_key.h"
|
#include "6LoWPAN/MAC/mac_pairwise_key.h"
|
||||||
#include "6LoWPAN/MAC/mac_data_poll.h"
|
#include "6LoWPAN/MAC/mac_data_poll.h"
|
||||||
#include "Service_Libs/etx/etx.h"
|
#include "Service_Libs/etx/etx.h"
|
||||||
#include "Core/include/address.h"
|
#include "Core/include/ns_address_internal.h"
|
||||||
#include "6LoWPAN/Thread/thread_nvm_store.h"
|
#include "6LoWPAN/Thread/thread_nvm_store.h"
|
||||||
|
|
||||||
#define TRACE_GROUP "thrd"
|
#define TRACE_GROUP "thrd"
|
||||||
|
@ -484,7 +484,9 @@ int thread_info_allocate_and_init(protocol_interface_info_entry_t *cur)
|
||||||
cur->thread_info->version = thread_version; // Default implementation version
|
cur->thread_info->version = thread_version; // Default implementation version
|
||||||
cur->thread_info->thread_device_mode = THREAD_DEVICE_MODE_END_DEVICE;
|
cur->thread_info->thread_device_mode = THREAD_DEVICE_MODE_END_DEVICE;
|
||||||
cur->thread_info->childUpdateReqTimer = -1;
|
cur->thread_info->childUpdateReqTimer = -1;
|
||||||
|
cur->thread_info->parent_priority = CONNECTIVITY_PP_INVALID; // default invalid - calculated using child count
|
||||||
|
|
||||||
|
thread_maintenance_timer_set(cur);
|
||||||
thread_routing_init(&cur->thread_info->routing);
|
thread_routing_init(&cur->thread_info->routing);
|
||||||
thread_network_local_server_data_base_init(&cur->thread_info->localServerDataBase);
|
thread_network_local_server_data_base_init(&cur->thread_info->localServerDataBase);
|
||||||
memset(&cur->thread_info->registered_commissioner, 0, sizeof(thread_commissioner_t));
|
memset(&cur->thread_info->registered_commissioner, 0, sizeof(thread_commissioner_t));
|
||||||
|
@ -961,7 +963,9 @@ static void thread_maintenance_timer(protocol_interface_info_entry_t *cur, uint3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_info(cur)->thread_maintenance_timer = THREAD_MAINTENANCE_TIMER_INTERVAL ;
|
thread_maintenance_timer_set(cur);
|
||||||
|
|
||||||
|
tr_debug("NWK data maintenance scan");
|
||||||
|
|
||||||
thread_bootstrap_network_data_activate(cur);
|
thread_bootstrap_network_data_activate(cur);
|
||||||
}
|
}
|
||||||
|
@ -1245,7 +1249,9 @@ uint8_t *thread_connectivity_tlv_write(uint8_t *ptr, protocol_interface_info_ent
|
||||||
*ptr++ = 10;
|
*ptr++ = 10;
|
||||||
|
|
||||||
// determine parent priority
|
// determine parent priority
|
||||||
if ((mode & MLE_DEV_MASK) == MLE_RFD_DEV && (3 * mle_class_rfd_entry_count_get(cur) > 2 * THREAD_MAX_MTD_CHILDREN)) {
|
if ((thread->parent_priority & CONNECTIVITY_PP_MASK) != CONNECTIVITY_PP_INVALID) {
|
||||||
|
*ptr++ = thread->parent_priority & CONNECTIVITY_PP_MASK;
|
||||||
|
} else if ((mode & MLE_DEV_MASK) == MLE_RFD_DEV && (3 * mle_class_rfd_entry_count_get(cur) > 2 * THREAD_MAX_MTD_CHILDREN)) {
|
||||||
*ptr++ = CONNECTIVITY_PP_LOW;
|
*ptr++ = CONNECTIVITY_PP_LOW;
|
||||||
} else if (!(mode & MLE_RX_ON_IDLE) && (3 * mle_class_sleepy_entry_count_get(cur) > 2 * THREAD_MAX_SED_CHILDREN)) {
|
} else if (!(mode & MLE_RX_ON_IDLE) && (3 * mle_class_sleepy_entry_count_get(cur) > 2 * THREAD_MAX_SED_CHILDREN)) {
|
||||||
*ptr++ = CONNECTIVITY_PP_LOW;
|
*ptr++ = CONNECTIVITY_PP_LOW;
|
||||||
|
@ -2155,9 +2161,9 @@ void thread_neighbor_communication_update(protocol_interface_info_entry_t *cur,
|
||||||
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, neighbor_attribute_index);
|
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, neighbor_attribute_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void thread_maintenance_timer_set(protocol_interface_info_entry_t *cur, uint16_t delay)
|
void thread_maintenance_timer_set(protocol_interface_info_entry_t *cur)
|
||||||
{
|
{
|
||||||
thread_info(cur)->thread_maintenance_timer = delay;
|
thread_info(cur)->thread_maintenance_timer = THREAD_MAINTENANCE_TIMER_INTERVAL + randLIB_get_random_in_range(0, THREAD_MAINTENANCE_TIMER_INTERVAL / 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2018, Arm Limited and affiliates.
|
* Copyright (c) 2014-2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -68,6 +68,7 @@ struct mac_neighbor_table_entry;
|
||||||
#define THREAD_KEY_INDEX(seq) ((uint8_t) (((seq) & 0x0000007f) + 1))
|
#define THREAD_KEY_INDEX(seq) ((uint8_t) (((seq) & 0x0000007f) + 1))
|
||||||
|
|
||||||
extern uint8_t thread_version;
|
extern uint8_t thread_version;
|
||||||
|
extern uint8_t thread_max_mcast_addr;
|
||||||
extern uint32_t thread_delay_timer_default;
|
extern uint32_t thread_delay_timer_default;
|
||||||
extern uint32_t thread_router_selection_jitter;
|
extern uint32_t thread_router_selection_jitter;
|
||||||
extern uint16_t thread_joiner_port;
|
extern uint16_t thread_joiner_port;
|
||||||
|
@ -316,6 +317,7 @@ typedef struct thread_info_s {
|
||||||
//uint8_t lastValidRouteMask[8];
|
//uint8_t lastValidRouteMask[8];
|
||||||
int8_t interface_id; //Thread Interface ID
|
int8_t interface_id; //Thread Interface ID
|
||||||
uint8_t version;
|
uint8_t version;
|
||||||
|
uint8_t parent_priority;
|
||||||
uint8_t testMaxActiveRouterIdLimit; //Default for this is 32
|
uint8_t testMaxActiveRouterIdLimit; //Default for this is 32
|
||||||
uint8_t maxChildCount; //Default for this is 24
|
uint8_t maxChildCount; //Default for this is 24
|
||||||
uint8_t partition_weighting;
|
uint8_t partition_weighting;
|
||||||
|
@ -448,7 +450,7 @@ bool thread_partition_match(protocol_interface_info_entry_t *cur, thread_leader_
|
||||||
void thread_partition_info_update(protocol_interface_info_entry_t *cur, thread_leader_data_t *leaderData);
|
void thread_partition_info_update(protocol_interface_info_entry_t *cur, thread_leader_data_t *leaderData);
|
||||||
void thread_neighbor_communication_update(protocol_interface_info_entry_t *cur, uint8_t neighbor_attribute_index);
|
void thread_neighbor_communication_update(protocol_interface_info_entry_t *cur, uint8_t neighbor_attribute_index);
|
||||||
bool thread_stable_context_check(protocol_interface_info_entry_t *cur, buffer_t *buf);
|
bool thread_stable_context_check(protocol_interface_info_entry_t *cur, buffer_t *buf);
|
||||||
void thread_maintenance_timer_set(protocol_interface_info_entry_t *cur, uint16_t delay);
|
void thread_maintenance_timer_set(protocol_interface_info_entry_t *cur);
|
||||||
#else // HAVE_THREAD
|
#else // HAVE_THREAD
|
||||||
|
|
||||||
NS_DUMMY_DEFINITIONS_OK
|
NS_DUMMY_DEFINITIONS_OK
|
||||||
|
|
|
@ -247,7 +247,7 @@
|
||||||
* value for better performance.
|
* value for better performance.
|
||||||
*/
|
*/
|
||||||
#define THREAD_INDIRECT_BIG_PACKETS_TOTAL 10
|
#define THREAD_INDIRECT_BIG_PACKETS_TOTAL 10
|
||||||
#define THREAD_INDIRECT_SMALL_PACKETS_PER_CHILD 2
|
#define THREAD_INDIRECT_SMALL_PACKETS_PER_CHILD 3
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximum number of MTD children, default 16
|
* Maximum number of MTD children, default 16
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
* Copyright (c) 2016-2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -186,4 +186,6 @@
|
||||||
/** Thread prefix minimum lifetime in seconds */
|
/** Thread prefix minimum lifetime in seconds */
|
||||||
#define THREAD_MIN_PREFIX_LIFETIME 3600
|
#define THREAD_MIN_PREFIX_LIFETIME 3600
|
||||||
|
|
||||||
|
#define THREAD_MCAST_ADDR_PER_MSG 4 // One multicast registration message fits 4 addresses by default
|
||||||
|
|
||||||
#endif /* THREAD_CONSTANTS_H_ */
|
#endif /* THREAD_CONSTANTS_H_ */
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018, Arm Limited and affiliates.
|
* Copyright (c) 2015, 2018-2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
|
|
@ -85,7 +85,7 @@ uint8_t *thread_extension_discover_response_write(protocol_interface_info_entry_
|
||||||
#define thread_extension_version_check(version) (false)
|
#define thread_extension_version_check(version) (false)
|
||||||
#define thread_extension_discover_response_read(nwk_info, discover_response_tlv, data_ptr, data_len) ((void) 0)
|
#define thread_extension_discover_response_read(nwk_info, discover_response_tlv, data_ptr, data_len) ((void) 0)
|
||||||
#define thread_extension_discover_response_tlv_write(data, version, securityPolicy) ((void) 0)
|
#define thread_extension_discover_response_tlv_write(data, version, securityPolicy) ((void) 0)
|
||||||
#define thread_extension_service_init(cur) (0)
|
#define thread_extension_service_init(cur) ((void) 0)
|
||||||
#define thread_extension_joining_enabled(interface_id) (false)
|
#define thread_extension_joining_enabled(interface_id) (false)
|
||||||
#define thread_extension_discover_response_len(cur) (0)
|
#define thread_extension_discover_response_len(cur) (0)
|
||||||
#define thread_extension_discover_response_write(cur, ptr) (ptr)
|
#define thread_extension_discover_response_write(cur, ptr) (ptr)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, Arm Limited and affiliates.
|
* Copyright (c) 2017-2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2018, Arm Limited and affiliates.
|
* Copyright (c) 2015-2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -73,7 +73,7 @@
|
||||||
#include "Service_Libs/blacklist/blacklist.h"
|
#include "Service_Libs/blacklist/blacklist.h"
|
||||||
#include "6LoWPAN/MAC/mac_helper.h"
|
#include "6LoWPAN/MAC/mac_helper.h"
|
||||||
#include "6LoWPAN/MAC/mac_data_poll.h"
|
#include "6LoWPAN/MAC/mac_data_poll.h"
|
||||||
#include "Core/include/address.h"
|
#include "Core/include/ns_address_internal.h"
|
||||||
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
|
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
|
||||||
|
|
||||||
#define TRACE_GROUP "tebs"
|
#define TRACE_GROUP "tebs"
|
||||||
|
@ -470,8 +470,9 @@ static bool thread_host_prefer_parent_response(protocol_interface_info_entry_t *
|
||||||
{
|
{
|
||||||
(void) connectivity;
|
(void) connectivity;
|
||||||
(void) cur;
|
(void) cur;
|
||||||
|
bool cur_version = thread_extension_version_check(thread_info(cur)->version);
|
||||||
|
|
||||||
if (!thread_extension_version_check(thread_info(cur)->version)) {
|
if (!cur_version) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -393,11 +393,6 @@ static int thread_leader_service_active_set_cb(int8_t service_id, uint8_t source
|
||||||
|
|
||||||
response_ptr = payload;
|
response_ptr = payload;
|
||||||
|
|
||||||
if (!thread_management_server_source_address_check(this->interface_id, source_address)) {
|
|
||||||
response_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST;
|
|
||||||
goto send_error_response;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (3 <= thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_CHANNEL, &ptr) &&
|
if (3 <= thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_CHANNEL, &ptr) &&
|
||||||
(linkConfiguration->rfChannel != common_read_16_bit(&ptr[1]) || linkConfiguration->channel_page != *ptr)) {
|
(linkConfiguration->rfChannel != common_read_16_bit(&ptr[1]) || linkConfiguration->channel_page != *ptr)) {
|
||||||
tr_debug("Channel changed");
|
tr_debug("Channel changed");
|
||||||
|
@ -559,11 +554,6 @@ static int thread_leader_service_pending_set_cb(int8_t service_id, uint8_t sourc
|
||||||
|
|
||||||
tr_info("thread management Pending set");
|
tr_info("thread management Pending set");
|
||||||
|
|
||||||
if (!thread_management_server_source_address_check(this->interface_id, source_address)) {
|
|
||||||
response_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST;
|
|
||||||
goto send_error_response;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (2 <= thread_meshcop_tlv_data_get_uint16(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_COMMISSIONER_SESSION_ID, &session_id)) {
|
if (2 <= thread_meshcop_tlv_data_get_uint16(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_COMMISSIONER_SESSION_ID, &session_id)) {
|
||||||
// Session id present must be valid
|
// Session id present must be valid
|
||||||
if (cur->thread_info->registered_commissioner.session_id != session_id) {
|
if (cur->thread_info->registered_commissioner.session_id != session_id) {
|
||||||
|
@ -660,7 +650,6 @@ send_error_response:
|
||||||
static int thread_leader_service_commissioner_set_cb(int8_t service_id, uint8_t source_address[16], uint16_t source_port, sn_coap_hdr_s *request_ptr)
|
static int thread_leader_service_commissioner_set_cb(int8_t service_id, uint8_t source_address[16], uint16_t source_port, sn_coap_hdr_s *request_ptr)
|
||||||
{
|
{
|
||||||
thread_leader_service_t *this = thread_leader_service_find_by_service(service_id);
|
thread_leader_service_t *this = thread_leader_service_find_by_service(service_id);
|
||||||
sn_coap_msg_code_e response_code = COAP_MSG_CODE_RESPONSE_CHANGED;
|
|
||||||
uint16_t session_id;
|
uint16_t session_id;
|
||||||
uint16_t br_locator;
|
uint16_t br_locator;
|
||||||
uint8_t payload[5]; // 4 + 1
|
uint8_t payload[5]; // 4 + 1
|
||||||
|
@ -682,10 +671,6 @@ static int thread_leader_service_commissioner_set_cb(int8_t service_id, uint8_t
|
||||||
|
|
||||||
tr_info("thread management commissioner set");
|
tr_info("thread management commissioner set");
|
||||||
|
|
||||||
if (!thread_management_server_source_address_check(this->interface_id, source_address)) {
|
|
||||||
response_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST;
|
|
||||||
goto send_error_response;
|
|
||||||
}
|
|
||||||
//Check if the CoAp payload is greater than maximum commissioner data size and reject
|
//Check if the CoAp payload is greater than maximum commissioner data size and reject
|
||||||
if (request_ptr->payload_len > THREAD_MAX_COMMISSIONER_DATA_SIZE) {
|
if (request_ptr->payload_len > THREAD_MAX_COMMISSIONER_DATA_SIZE) {
|
||||||
tr_error("Payload length greater than maximum commissioner data size");
|
tr_error("Payload length greater than maximum commissioner data size");
|
||||||
|
@ -725,9 +710,7 @@ static int thread_leader_service_commissioner_set_cb(int8_t service_id, uint8_t
|
||||||
send_response:
|
send_response:
|
||||||
// build response
|
// build response
|
||||||
ptr = thread_meshcop_tlv_data_write_uint8(ptr, MESHCOP_TLV_STATE, ret == 0 ? 1 : 0xff);
|
ptr = thread_meshcop_tlv_data_write_uint8(ptr, MESHCOP_TLV_STATE, ret == 0 ? 1 : 0xff);
|
||||||
|
coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, COAP_MSG_CODE_RESPONSE_CHANGED, COAP_CT_OCTET_STREAM, payload, ptr - payload);
|
||||||
send_error_response:
|
|
||||||
coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, response_code, COAP_CT_OCTET_STREAM, payload, ptr - payload);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1050,7 +1033,6 @@ static int thread_leader_service_release_cb(int8_t service_id, uint8_t source_ad
|
||||||
static int thread_leader_service_petition_cb(int8_t service_id, uint8_t source_address[16], uint16_t source_port, sn_coap_hdr_s *request_ptr)
|
static int thread_leader_service_petition_cb(int8_t service_id, uint8_t source_address[16], uint16_t source_port, sn_coap_hdr_s *request_ptr)
|
||||||
{
|
{
|
||||||
thread_leader_service_t *this = thread_leader_service_find_by_service(service_id);
|
thread_leader_service_t *this = thread_leader_service_find_by_service(service_id);
|
||||||
sn_coap_msg_code_e response_code = COAP_MSG_CODE_RESPONSE_CHANGED;
|
|
||||||
uint8_t payload[79];// max length for commissioner id is 64 + 4 byte header + 4 + 1 + 4 + 2
|
uint8_t payload[79];// max length for commissioner id is 64 + 4 byte header + 4 + 1 + 4 + 2
|
||||||
uint8_t *ptr;
|
uint8_t *ptr;
|
||||||
uint16_t session_id = 0;
|
uint16_t session_id = 0;
|
||||||
|
@ -1067,11 +1049,6 @@ static int thread_leader_service_petition_cb(int8_t service_id, uint8_t source_a
|
||||||
|
|
||||||
tr_debug("Thread management commissioner petition");
|
tr_debug("Thread management commissioner petition");
|
||||||
|
|
||||||
if (!thread_management_server_source_address_check(this->interface_id, source_address)) {
|
|
||||||
response_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST;
|
|
||||||
goto send_error_response;
|
|
||||||
}
|
|
||||||
|
|
||||||
// save values from message
|
// save values from message
|
||||||
tlv_length = thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_COMMISSIONER_ID, &tlv_data_ptr);
|
tlv_length = thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_COMMISSIONER_ID, &tlv_data_ptr);
|
||||||
|
|
||||||
|
@ -1098,8 +1075,7 @@ static int thread_leader_service_petition_cb(int8_t service_id, uint8_t source_a
|
||||||
|
|
||||||
tr_debug("Petition req recv id %s, RESP session id: %d ret %d", commissioner_id_ptr ? commissioner_id_ptr : "(none)", session_id, ret);
|
tr_debug("Petition req recv id %s, RESP session id: %d ret %d", commissioner_id_ptr ? commissioner_id_ptr : "(none)", session_id, ret);
|
||||||
|
|
||||||
send_error_response:
|
coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, COAP_MSG_CODE_RESPONSE_CHANGED, COAP_CT_OCTET_STREAM, payload, ptr - payload);
|
||||||
coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, response_code, COAP_CT_OCTET_STREAM, payload, ptr - payload);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1110,7 +1086,6 @@ send_error_response:
|
||||||
static int thread_leader_service_petition_ka_cb(int8_t service_id, uint8_t source_address[16], uint16_t source_port, sn_coap_hdr_s *request_ptr)
|
static int thread_leader_service_petition_ka_cb(int8_t service_id, uint8_t source_address[16], uint16_t source_port, sn_coap_hdr_s *request_ptr)
|
||||||
{
|
{
|
||||||
thread_leader_service_t *this = thread_leader_service_find_by_service(service_id);
|
thread_leader_service_t *this = thread_leader_service_find_by_service(service_id);
|
||||||
sn_coap_msg_code_e response_code = COAP_MSG_CODE_RESPONSE_CHANGED;
|
|
||||||
uint8_t payload[5]; //status 4 + 1
|
uint8_t payload[5]; //status 4 + 1
|
||||||
uint8_t *ptr;
|
uint8_t *ptr;
|
||||||
uint16_t session_id = 0;
|
uint16_t session_id = 0;
|
||||||
|
@ -1125,12 +1100,6 @@ static int thread_leader_service_petition_ka_cb(int8_t service_id, uint8_t sourc
|
||||||
|
|
||||||
tr_debug("Thread management commissioner keep alive");
|
tr_debug("Thread management commissioner keep alive");
|
||||||
|
|
||||||
if (!thread_management_server_source_address_check(this->interface_id, source_address)) {
|
|
||||||
response_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST;
|
|
||||||
ptr = payload;
|
|
||||||
goto send_error_response;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (2 <= thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_COMMISSIONER_SESSION_ID, &ptr)) {
|
if (2 <= thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_COMMISSIONER_SESSION_ID, &ptr)) {
|
||||||
session_id = common_read_16_bit(ptr);
|
session_id = common_read_16_bit(ptr);
|
||||||
}
|
}
|
||||||
|
@ -1149,8 +1118,7 @@ static int thread_leader_service_petition_ka_cb(int8_t service_id, uint8_t sourc
|
||||||
ptr = payload;
|
ptr = payload;
|
||||||
ptr = thread_meshcop_tlv_data_write_uint8(ptr, MESHCOP_TLV_STATE, state == true ? 1 : 0xff);
|
ptr = thread_meshcop_tlv_data_write_uint8(ptr, MESHCOP_TLV_STATE, state == true ? 1 : 0xff);
|
||||||
|
|
||||||
send_error_response:
|
coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, COAP_MSG_CODE_RESPONSE_CHANGED, COAP_CT_OCTET_STREAM, payload, ptr - payload);
|
||||||
coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, response_code, COAP_CT_OCTET_STREAM, payload, ptr - payload);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, Arm Limited and affiliates.
|
* Copyright (c) 2017-2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2017, Arm Limited and affiliates.
|
* Copyright (c) 2015-2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2018, Arm Limited and affiliates.
|
* Copyright (c) 2014-2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -94,6 +94,7 @@ static const uint8_t thread_discovery_extented_address[8] = {0x35, 0x06, 0xfe, 0
|
||||||
uint32_t thread_delay_timer_default = THREAD_DELAY_TIMER_DEFAULT_SECONDS;
|
uint32_t thread_delay_timer_default = THREAD_DELAY_TIMER_DEFAULT_SECONDS;
|
||||||
uint32_t thread_router_selection_jitter = THREAD_ROUTER_SELECTION_JITTER;
|
uint32_t thread_router_selection_jitter = THREAD_ROUTER_SELECTION_JITTER;
|
||||||
uint16_t thread_joiner_port = THREAD_DEFAULT_JOINER_PORT;
|
uint16_t thread_joiner_port = THREAD_DEFAULT_JOINER_PORT;
|
||||||
|
uint8_t thread_max_mcast_addr = THREAD_MCAST_ADDR_PER_MSG;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prototypes
|
* Prototypes
|
||||||
|
@ -1345,6 +1346,11 @@ int8_t thread_management_get_request_full_nwk_data(int8_t interface_id, bool *fu
|
||||||
|
|
||||||
int thread_management_device_certificate_set(int8_t interface_id, const unsigned char *device_certificate_ptr, uint16_t device_certificate_len, const unsigned char *priv_key_ptr, uint16_t priv_key_len)
|
int thread_management_device_certificate_set(int8_t interface_id, const unsigned char *device_certificate_ptr, uint16_t device_certificate_len, const unsigned char *priv_key_ptr, uint16_t priv_key_len)
|
||||||
{
|
{
|
||||||
|
(void) device_certificate_ptr;
|
||||||
|
(void) device_certificate_len;
|
||||||
|
(void) priv_key_ptr;
|
||||||
|
(void) priv_key_len;
|
||||||
|
|
||||||
#ifdef HAVE_THREAD
|
#ifdef HAVE_THREAD
|
||||||
protocol_interface_info_entry_t *cur;
|
protocol_interface_info_entry_t *cur;
|
||||||
|
|
||||||
|
@ -1358,17 +1364,19 @@ int thread_management_device_certificate_set(int8_t interface_id, const unsigned
|
||||||
|
|
||||||
#else
|
#else
|
||||||
(void) interface_id;
|
(void) interface_id;
|
||||||
(void) device_certificate_ptr;
|
|
||||||
(void) device_certificate_len;
|
|
||||||
(void) priv_key_ptr;
|
|
||||||
(void) priv_key_len;
|
|
||||||
return -1;
|
return -1;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
int thread_management_network_certificate_set(int8_t interface_id, const unsigned char *network_certificate_ptr, uint16_t network_certificate_len, const unsigned char *priv_key_ptr, uint16_t priv_key_len)
|
int thread_management_network_certificate_set(int8_t interface_id, const unsigned char *network_certificate_ptr, uint16_t network_certificate_len, const unsigned char *priv_key_ptr, uint16_t priv_key_len)
|
||||||
{
|
{
|
||||||
|
(void) network_certificate_ptr;
|
||||||
|
(void) network_certificate_len;
|
||||||
|
(void) priv_key_ptr;
|
||||||
|
(void) priv_key_len;
|
||||||
|
|
||||||
#ifdef HAVE_THREAD
|
#ifdef HAVE_THREAD
|
||||||
protocol_interface_info_entry_t *cur;
|
protocol_interface_info_entry_t *cur;
|
||||||
|
int ret_val;
|
||||||
|
|
||||||
cur = protocol_stack_interface_info_get_by_id(interface_id);
|
cur = protocol_stack_interface_info_get_by_id(interface_id);
|
||||||
if (!cur) {
|
if (!cur) {
|
||||||
|
@ -1376,17 +1384,14 @@ int thread_management_network_certificate_set(int8_t interface_id, const unsigne
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 > thread_extension_bootstrap_network_certificate_set(cur, network_certificate_ptr, network_certificate_len)) {
|
ret_val = thread_extension_bootstrap_network_certificate_set(cur, network_certificate_ptr, network_certificate_len);
|
||||||
|
if (0 > ret_val) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return thread_extension_bootstrap_network_private_key_set(cur, priv_key_ptr, priv_key_len);
|
return thread_extension_bootstrap_network_private_key_set(cur, priv_key_ptr, priv_key_len);
|
||||||
#else
|
#else
|
||||||
(void) interface_id;
|
(void) interface_id;
|
||||||
(void) network_certificate_ptr;
|
|
||||||
(void) network_certificate_len;
|
|
||||||
(void) priv_key_ptr;
|
|
||||||
(void) priv_key_len;
|
|
||||||
return -1;
|
return -1;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2018, Arm Limited and affiliates.
|
* Copyright (c) 2014-2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -66,10 +66,19 @@
|
||||||
#include "thread_management_server.h"
|
#include "thread_management_server.h"
|
||||||
#include "mac_api.h"
|
#include "mac_api.h"
|
||||||
#include "6LoWPAN/MAC/mac_data_poll.h"
|
#include "6LoWPAN/MAC/mac_data_poll.h"
|
||||||
|
#include "Common_Protocols/ipv6_constants.h"
|
||||||
|
#include "Core/include/ns_address_internal.h"
|
||||||
#include "mlme.h"
|
#include "mlme.h"
|
||||||
|
|
||||||
#ifdef HAVE_THREAD
|
#ifdef HAVE_THREAD
|
||||||
|
|
||||||
|
//#define TRACE_DEEP
|
||||||
|
#ifdef TRACE_DEEP
|
||||||
|
#define tr_deep tr_debug
|
||||||
|
#else
|
||||||
|
#define tr_deep(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct scan_query {
|
typedef struct scan_query {
|
||||||
int8_t coap_service_id;
|
int8_t coap_service_id;
|
||||||
uint8_t channel_mask[6]; //<!** first byte is channel page
|
uint8_t channel_mask[6]; //<!** first byte is channel page
|
||||||
|
@ -393,6 +402,7 @@ send_response:
|
||||||
static int thread_management_server_get_command_cb(int8_t service_id, uint8_t source_address[16], uint16_t source_port, sn_coap_hdr_s *request_ptr)
|
static int thread_management_server_get_command_cb(int8_t service_id, uint8_t source_address[16], uint16_t source_port, sn_coap_hdr_s *request_ptr)
|
||||||
{
|
{
|
||||||
(void) source_port;
|
(void) source_port;
|
||||||
|
(void) source_address;
|
||||||
|
|
||||||
thread_management_server_t *this = thread_management_find_by_service(service_id);
|
thread_management_server_t *this = thread_management_find_by_service(service_id);
|
||||||
|
|
||||||
|
@ -400,12 +410,6 @@ static int thread_management_server_get_command_cb(int8_t service_id, uint8_t so
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!thread_management_server_source_address_check(this->interface_id, source_address)) {
|
|
||||||
// request is coming from illegal address, return error immediately
|
|
||||||
coap_service_response_send(service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, COAP_MSG_CODE_RESPONSE_BAD_REQUEST, COAP_CT_OCTET_STREAM, NULL, 0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return thread_management_server_tmf_get_request_handler(this->interface_id, service_id, request_ptr);
|
return thread_management_server_tmf_get_request_handler(this->interface_id, service_id, request_ptr);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -416,7 +420,6 @@ static int thread_management_server_commissioner_get_cb(int8_t service_id, uint8
|
||||||
(void) source_port;
|
(void) source_port;
|
||||||
protocol_interface_info_entry_t *cur;
|
protocol_interface_info_entry_t *cur;
|
||||||
thread_management_server_t *this = thread_management_find_by_service(service_id);
|
thread_management_server_t *this = thread_management_find_by_service(service_id);
|
||||||
sn_coap_msg_code_e return_code = COAP_MSG_CODE_RESPONSE_CHANGED;
|
|
||||||
uint8_t response_msg[2 + 2 + 2 + 2 + 2 + 16 + 2 + 2];
|
uint8_t response_msg[2 + 2 + 2 + 2 + 2 + 16 + 2 + 2];
|
||||||
uint8_t *request_tlv_ptr = NULL;
|
uint8_t *request_tlv_ptr = NULL;
|
||||||
uint16_t request_tlv_len;
|
uint16_t request_tlv_len;
|
||||||
|
@ -432,11 +435,6 @@ static int thread_management_server_commissioner_get_cb(int8_t service_id, uint8
|
||||||
}
|
}
|
||||||
payload_ptr = ptr = response_msg;
|
payload_ptr = ptr = response_msg;
|
||||||
|
|
||||||
if (!thread_management_server_source_address_check(this->interface_id, source_address)) {
|
|
||||||
return_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST;
|
|
||||||
goto send_response;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!cur->thread_info->registered_commissioner.commissioner_valid) {
|
if (!cur->thread_info->registered_commissioner.commissioner_valid) {
|
||||||
//Error in message is responded with Thread status or if we have access rights problem
|
//Error in message is responded with Thread status or if we have access rights problem
|
||||||
tr_warn("No registered commissioner");
|
tr_warn("No registered commissioner");
|
||||||
|
@ -464,7 +462,7 @@ static int thread_management_server_commissioner_get_cb(int8_t service_id, uint8
|
||||||
goto send_response;
|
goto send_response;
|
||||||
}
|
}
|
||||||
send_response:
|
send_response:
|
||||||
coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, return_code, COAP_CT_OCTET_STREAM, payload_ptr, ptr - payload_ptr);
|
coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, COAP_MSG_CODE_RESPONSE_CHANGED, COAP_CT_OCTET_STREAM, payload_ptr, ptr - payload_ptr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1118,6 +1116,58 @@ error_exit:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int coap_msg_prevalidate_cb(int8_t local_interface_id, uint8_t local_address[static 16], uint16_t local_port, int8_t recv_interface_id, uint8_t source_address[static 16], uint16_t source_port, char *coap_uri)
|
||||||
|
{
|
||||||
|
protocol_interface_info_entry_t *cur_local, *cur_source;
|
||||||
|
uint_fast8_t addr_scope;
|
||||||
|
|
||||||
|
(void) source_address;
|
||||||
|
(void) source_port;
|
||||||
|
(void) coap_uri;
|
||||||
|
|
||||||
|
cur_local = protocol_stack_interface_info_get_by_id(local_interface_id);
|
||||||
|
|
||||||
|
if (!cur_local) {
|
||||||
|
tr_error("No interface for %d", local_interface_id);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (local_port != THREAD_MANAGEMENT_PORT) {
|
||||||
|
// Message not sent to THREAD_MANAGEMENT_PORT, let it come through
|
||||||
|
tr_deep("Message %s port %d is not mgmt port", coap_uri, local_port);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check message source address
|
||||||
|
if (!thread_management_server_source_address_check(local_interface_id, source_address)) {
|
||||||
|
tr_deep("Drop CoAP msg %s from %s", coap_uri, trace_ipv6(source_address));
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check our local address scope */
|
||||||
|
addr_scope = addr_ipv6_scope(local_address, cur_local);
|
||||||
|
if (addr_scope > IPV6_SCOPE_REALM_LOCAL) {
|
||||||
|
tr_deep("Drop CoAP msg %s to %s due %d", coap_uri, trace_ipv6(local_address), addr_scope);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (local_interface_id != recv_interface_id) {
|
||||||
|
// message received from different interface
|
||||||
|
cur_source = protocol_stack_interface_info_get_by_id(recv_interface_id);
|
||||||
|
if (!cur_source) {
|
||||||
|
tr_deep("No cur for if %d", recv_interface_id);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
addr_scope = addr_ipv6_scope(source_address, cur_source);
|
||||||
|
if (addr_scope < IPV6_SCOPE_REALM_LOCAL) {
|
||||||
|
tr_deep("Drop CoAP msg %s from %s to %s due %d", coap_uri, trace_ipv6(source_address), trace_ipv6(local_address), addr_scope);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Public interface functions
|
* Public interface functions
|
||||||
*/
|
*/
|
||||||
|
@ -1162,6 +1212,7 @@ int thread_management_server_init(int8_t interface_id)
|
||||||
ns_dyn_mem_free(this);
|
ns_dyn_mem_free(this);
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
|
coap_service_msg_prevalidate_callback_set(THREAD_MANAGEMENT_PORT, coap_msg_prevalidate_cb);
|
||||||
#ifdef HAVE_THREAD_ROUTER
|
#ifdef HAVE_THREAD_ROUTER
|
||||||
if (thread_leader_service_init(interface_id, this->coap_service_id) != 0) {
|
if (thread_leader_service_init(interface_id, this->coap_service_id) != 0) {
|
||||||
tr_error("Thread leader service init failed");
|
tr_error("Thread leader service init failed");
|
||||||
|
@ -1554,10 +1605,15 @@ int thread_management_server_commisoner_data_get(int8_t interface_id, thread_man
|
||||||
bool thread_management_server_source_address_check(int8_t interface_id, uint8_t source_address[16])
|
bool thread_management_server_source_address_check(int8_t interface_id, uint8_t source_address[16])
|
||||||
{
|
{
|
||||||
link_configuration_s *linkConfiguration;
|
link_configuration_s *linkConfiguration;
|
||||||
linkConfiguration = thread_joiner_application_get_config(interface_id);
|
|
||||||
|
|
||||||
|
if (memcmp(ADDR_LINK_LOCAL_PREFIX, source_address, 8) == 0) {
|
||||||
|
// Source address is from Link local address
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
linkConfiguration = thread_joiner_application_get_config(interface_id);
|
||||||
if (!linkConfiguration) {
|
if (!linkConfiguration) {
|
||||||
tr_error("No link configuration.");
|
tr_error("No link cfg for if %d", interface_id);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1566,15 +1622,12 @@ bool thread_management_server_source_address_check(int8_t interface_id, uint8_t
|
||||||
// Source address is RLOC or ALOC
|
// Source address is RLOC or ALOC
|
||||||
} else if (memcmp(source_address, linkConfiguration->mesh_local_ula_prefix, 8) == 0) {
|
} else if (memcmp(source_address, linkConfiguration->mesh_local_ula_prefix, 8) == 0) {
|
||||||
// Source address is ML64 TODO this should check that destination address is ALOC or RLOC CoaP Service does not support
|
// Source address is ML64 TODO this should check that destination address is ALOC or RLOC CoaP Service does not support
|
||||||
} else if (memcmp(ADDR_LINK_LOCAL_PREFIX, source_address, 8)) {
|
|
||||||
// Source address is from Link local address
|
|
||||||
} else {
|
} else {
|
||||||
tr_error("Message out of thread network; ML prefix: %s, src addr: %s",
|
tr_deep("Message out of thread network; ML prefix: %s, src addr: %s",
|
||||||
trace_ipv6_prefix(linkConfiguration->mesh_local_ula_prefix, 64),
|
trace_ipv6_prefix(linkConfiguration->mesh_local_ula_prefix, 64),
|
||||||
trace_ipv6(source_address));
|
trace_ipv6(source_address));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// TODO: Add other (security) related checks here
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2017, Arm Limited and affiliates.
|
* Copyright (c) 2014-2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, Arm Limited and affiliates.
|
* Copyright (c) 2017-2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2017, Arm Limited and affiliates.
|
* Copyright (c) 2015-2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
* Copyright (c) 2016-2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -759,7 +759,7 @@ static void thread_host_child_update_request_process(protocol_interface_info_ent
|
||||||
uint64_t pending_timestamp = 0;// means no pending timestamp
|
uint64_t pending_timestamp = 0;// means no pending timestamp
|
||||||
mac_neighbor_table_entry_t *entry_temp;
|
mac_neighbor_table_entry_t *entry_temp;
|
||||||
bool data_request_needed = false;
|
bool data_request_needed = false;
|
||||||
mle_tlv_info_t tlv_info = {0};
|
mle_tlv_info_t tlv_info = {MLE_TYPE_SRC_ADDRESS, 0, 0};
|
||||||
|
|
||||||
tr_debug("Child update request");
|
tr_debug("Child update request");
|
||||||
entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL);
|
entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL);
|
||||||
|
@ -831,7 +831,7 @@ static void thread_parse_child_update_response(protocol_interface_info_entry_t *
|
||||||
thread_leader_data_t leaderData = {0};
|
thread_leader_data_t leaderData = {0};
|
||||||
uint8_t status;
|
uint8_t status;
|
||||||
bool leader_data_received;
|
bool leader_data_received;
|
||||||
mle_tlv_info_t tlv_info = {0};
|
mle_tlv_info_t tlv_info = {MLE_TYPE_SRC_ADDRESS, 0, 0};
|
||||||
|
|
||||||
if (cur->thread_info->thread_endnode_parent == NULL) {
|
if (cur->thread_info->thread_endnode_parent == NULL) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2018, Arm Limited and affiliates.
|
* Copyright (c) 2014-2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -42,7 +42,7 @@
|
||||||
#include "eventOS_event.h"
|
#include "eventOS_event.h"
|
||||||
#include "common_functions.h"
|
#include "common_functions.h"
|
||||||
#include "socket_api.h"
|
#include "socket_api.h"
|
||||||
#include "Core/include/socket.h"
|
#include "Core/include/ns_socket.h"
|
||||||
#include "NWK_INTERFACE/Include/protocol.h"
|
#include "NWK_INTERFACE/Include/protocol.h"
|
||||||
#include "Common_Protocols/ipv6.h"
|
#include "Common_Protocols/ipv6.h"
|
||||||
#include "6LoWPAN/Bootstraps/protocol_6lowpan.h"
|
#include "6LoWPAN/Bootstraps/protocol_6lowpan.h"
|
||||||
|
@ -213,6 +213,7 @@ static mac_neighbor_table_entry_t *thread_nd_child_mleid_get(protocol_interface_
|
||||||
|
|
||||||
static int thread_nd_address_query_lookup(int8_t interface_id, const uint8_t target_addr[static 16], uint16_t *rloc, uint16_t *addr_out, bool *proxy, uint32_t *last_transaction_time, uint8_t *mleid_ptr)
|
static int thread_nd_address_query_lookup(int8_t interface_id, const uint8_t target_addr[static 16], uint16_t *rloc, uint16_t *addr_out, bool *proxy, uint32_t *last_transaction_time, uint8_t *mleid_ptr)
|
||||||
{
|
{
|
||||||
|
(void) rloc;
|
||||||
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
|
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
|
||||||
if (!cur) {
|
if (!cur) {
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -1565,14 +1565,12 @@ int thread_nd_local_list_add_service(thread_network_data_cache_entry_t *networkD
|
||||||
*/
|
*/
|
||||||
int thread_nd_local_list_add_on_mesh_prefix(thread_network_data_cache_entry_t *networkDataList, thread_prefix_tlv_t *prefixTlv, thread_border_router_tlv_entry_t *service)
|
int thread_nd_local_list_add_on_mesh_prefix(thread_network_data_cache_entry_t *networkDataList, thread_prefix_tlv_t *prefixTlv, thread_border_router_tlv_entry_t *service)
|
||||||
{
|
{
|
||||||
bool trigDataPropagate = false;
|
|
||||||
thread_network_data_prefix_cache_entry_t *prefix_entry;
|
thread_network_data_prefix_cache_entry_t *prefix_entry;
|
||||||
thread_network_server_data_entry_t *server_entry;
|
thread_network_server_data_entry_t *server_entry;
|
||||||
if (service->P_dhcp) {
|
bool trigDataPropagate = false;
|
||||||
tr_debug("Add DHCPv6 prefix:%s server: %04x", trace_ipv6_prefix(prefixTlv->Prefix, prefixTlv->PrefixLen), service->routerID);
|
|
||||||
} else {
|
tr_debug("Add %s%s%s prefix:%s server: %04x", service->P_dhcp ? "DHCPv6" : "", service->P_slaac ? "SLAAC " : "", service->P_res1 ? "P_res1 " : "",
|
||||||
tr_debug("Add SLAAC prefix:%s server: %04x", trace_ipv6_prefix(prefixTlv->Prefix, prefixTlv->PrefixLen), service->routerID);
|
trace_ipv6_prefix(prefixTlv->Prefix, prefixTlv->PrefixLen), service->routerID);
|
||||||
}
|
|
||||||
|
|
||||||
if (!networkDataList) {
|
if (!networkDataList) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1634,6 +1632,10 @@ int thread_nd_local_list_add_on_mesh_prefix(thread_network_data_cache_entry_t *n
|
||||||
trigDataPropagate = true;
|
trigDataPropagate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (server_entry->P_res1 != service->P_res1) {
|
||||||
|
server_entry->P_res1 = service->P_res1;
|
||||||
|
trigDataPropagate = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trigDataPropagate) {
|
if (trigDataPropagate) {
|
||||||
|
@ -1647,7 +1649,6 @@ int thread_nd_local_list_add_on_mesh_prefix(thread_network_data_cache_entry_t *n
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Del DHCPv6 Server information to route List
|
* Del DHCPv6 Server information to route List
|
||||||
*
|
*
|
||||||
|
@ -1671,13 +1672,8 @@ int thread_nd_local_list_del_on_mesh_server(thread_network_data_cache_entry_t *n
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (service->P_dhcp) {
|
tr_debug("Del %s%s%s prefix: %s", service->P_dhcp ? "DHCPv6" : "", service->P_slaac ? "SLAAC " : "", service->P_res1 ? "P_res1 " : "",
|
||||||
tr_debug("Del DHCPv6 server: %s",
|
trace_array(prefixTlv->Prefix, prefixBits_to_bytes(prefixTlv->PrefixLen)));
|
||||||
trace_array(prefixTlv->Prefix, prefixBits_to_bytes(prefixTlv->PrefixLen)));
|
|
||||||
} else {
|
|
||||||
tr_debug("Del SLAAC server: %s",
|
|
||||||
trace_array(prefixTlv->Prefix, prefixBits_to_bytes(prefixTlv->PrefixLen)));
|
|
||||||
}
|
|
||||||
|
|
||||||
main_list = thread_prefix_entry_get(&networkDataList->localPrefixList, prefixTlv);
|
main_list = thread_prefix_entry_get(&networkDataList->localPrefixList, prefixTlv);
|
||||||
if (!main_list) {
|
if (!main_list) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2018, Arm Limited and affiliates.
|
* Copyright (c) 2017-2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -35,7 +35,7 @@
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "Core/include/address.h"
|
#include "Core/include/ns_address_internal.h"
|
||||||
#include "ns_file_system.h"
|
#include "ns_file_system.h"
|
||||||
#include "thread_config.h"
|
#include "thread_config.h"
|
||||||
#include "thread_common.h"
|
#include "thread_common.h"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2017, Arm Limited and affiliates.
|
* Copyright (c) 2014-2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
#include "ns_list.h"
|
#include "ns_list.h"
|
||||||
#include "ns_trace.h"
|
#include "ns_trace.h"
|
||||||
#include "nsdynmemLIB.h"
|
#include "nsdynmemLIB.h"
|
||||||
#include "Core/include/address.h"
|
#include "Core/include/ns_address_internal.h"
|
||||||
#include "thread_tmfcop_lib.h"
|
#include "thread_tmfcop_lib.h"
|
||||||
|
|
||||||
#include "coap_service_api.h"
|
#include "coap_service_api.h"
|
||||||
|
@ -293,9 +293,14 @@ void thread_resolution_client_init(int8_t interface_id)
|
||||||
this->interface_id = interface_id;
|
this->interface_id = interface_id;
|
||||||
this->notification_cb_ptr = NULL;
|
this->notification_cb_ptr = NULL;
|
||||||
this->error_cb_ptr = NULL;
|
this->error_cb_ptr = NULL;
|
||||||
ns_list_init(&this->queries);
|
|
||||||
//TODO: Check if to use ephemeral port here
|
//TODO: Check if to use ephemeral port here
|
||||||
this->coap_service_id = thread_management_server_service_id_get(interface_id);
|
this->coap_service_id = thread_management_server_service_id_get(interface_id);
|
||||||
|
if (this->coap_service_id < 0) {
|
||||||
|
tr_err("Thread resolution client init failed");
|
||||||
|
ns_dyn_mem_free(this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ns_list_init(&this->queries);
|
||||||
ns_list_add_to_start(&instance_list, this);
|
ns_list_add_to_start(&instance_list, this);
|
||||||
|
|
||||||
coap_service_register_uri(this->coap_service_id, THREAD_URI_ADDRESS_NOTIFICATION, COAP_SERVICE_ACCESS_POST_ALLOWED, thread_resolution_client_notification_post_cb);
|
coap_service_register_uri(this->coap_service_id, THREAD_URI_ADDRESS_NOTIFICATION, COAP_SERVICE_ACCESS_POST_ALLOWED, thread_resolution_client_notification_post_cb);
|
||||||
|
|
|
@ -173,7 +173,7 @@ int thread_resolution_server_init(int8_t interface_id, thread_resolution_server_
|
||||||
this->interface_id = interface_id;
|
this->interface_id = interface_id;
|
||||||
this->coap_service_id = thread_management_server_service_id_get(interface_id);
|
this->coap_service_id = thread_management_server_service_id_get(interface_id);
|
||||||
if (this->coap_service_id < 0) {
|
if (this->coap_service_id < 0) {
|
||||||
tr_warn("Thread resolution srv init failed");
|
tr_err("Thread resolution srv init failed");
|
||||||
ns_dyn_mem_free(this);
|
ns_dyn_mem_free(this);
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2018, Arm Limited and affiliates.
|
* Copyright (c) 2015-2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -83,7 +83,7 @@
|
||||||
#include "mac_api.h"
|
#include "mac_api.h"
|
||||||
#include "6LoWPAN/MAC/mac_data_poll.h"
|
#include "6LoWPAN/MAC/mac_data_poll.h"
|
||||||
#include "thread_border_router_api.h"
|
#include "thread_border_router_api.h"
|
||||||
#include "Core/include/address.h"
|
#include "Core/include/ns_address_internal.h"
|
||||||
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
|
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
|
||||||
|
|
||||||
#ifdef HAVE_THREAD_ROUTER
|
#ifdef HAVE_THREAD_ROUTER
|
||||||
|
@ -1407,6 +1407,7 @@ static void thread_address_registration_tlv_parse(uint8_t *ptr, uint16_t data_le
|
||||||
//Register GP --> 16
|
//Register GP --> 16
|
||||||
int retVal = thread_nd_address_registration(cur, tempIPv6Address, mac16, cur->mac_parameters->pan_id, mac64, &new_neighbour_created);
|
int retVal = thread_nd_address_registration(cur, tempIPv6Address, mac16, cur->mac_parameters->pan_id, mac64, &new_neighbour_created);
|
||||||
thread_extension_address_registration(cur, tempIPv6Address, mac64, new_neighbour_created, retVal == -2);
|
thread_extension_address_registration(cur, tempIPv6Address, mac64, new_neighbour_created, retVal == -2);
|
||||||
|
(void) retVal;
|
||||||
} else {
|
} else {
|
||||||
tr_debug("No Context %u", ctxId);
|
tr_debug("No Context %u", ctxId);
|
||||||
}
|
}
|
||||||
|
@ -1427,6 +1428,7 @@ static void thread_address_registration_tlv_parse(uint8_t *ptr, uint16_t data_le
|
||||||
//Register GP --> 16
|
//Register GP --> 16
|
||||||
int retVal = thread_nd_address_registration(cur, ptr, mac16, cur->mac_parameters->pan_id, mac64, &new_neighbour_created);
|
int retVal = thread_nd_address_registration(cur, ptr, mac16, cur->mac_parameters->pan_id, mac64, &new_neighbour_created);
|
||||||
thread_extension_address_registration(cur, ptr, mac64, new_neighbour_created, retVal == -2);
|
thread_extension_address_registration(cur, ptr, mac64, new_neighbour_created, retVal == -2);
|
||||||
|
(void) retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr += 16;
|
ptr += 16;
|
||||||
|
@ -1809,6 +1811,11 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *
|
||||||
update_mac_mib = true;
|
update_mac_mib = true;
|
||||||
entry_temp->mac16 = shortAddress; // short address refreshed
|
entry_temp->mac16 = shortAddress; // short address refreshed
|
||||||
|
|
||||||
|
if (thread_is_router_addr(shortAddress)) {
|
||||||
|
// Set full data as REED/Router needs full data (SED will not make links)
|
||||||
|
thread_neighbor_class_request_full_data_setup_set(&cur->thread_info->neighbor_class, entry_temp->index, true);
|
||||||
|
}
|
||||||
|
|
||||||
if (entry_temp->connected_device) {
|
if (entry_temp->connected_device) {
|
||||||
if (mle_tlv_read_tlv(MLE_TYPE_ADDRESS_REGISTRATION, mle_msg->data_ptr, mle_msg->data_length, &addressRegisteredTlv)) {
|
if (mle_tlv_read_tlv(MLE_TYPE_ADDRESS_REGISTRATION, mle_msg->data_ptr, mle_msg->data_length, &addressRegisteredTlv)) {
|
||||||
if (!entry_temp->ffd_device) {
|
if (!entry_temp->ffd_device) {
|
||||||
|
@ -1942,9 +1949,9 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *
|
||||||
uint32_t timeout = 0;
|
uint32_t timeout = 0;
|
||||||
uint64_t active_timestamp = 0;
|
uint64_t active_timestamp = 0;
|
||||||
uint64_t pending_timestamp = 0;
|
uint64_t pending_timestamp = 0;
|
||||||
mle_tlv_info_t addressRegisterTlv = {0};
|
mle_tlv_info_t addressRegisterTlv = {MLE_TYPE_SRC_ADDRESS, 0, 0};
|
||||||
mle_tlv_info_t challengeTlv = {0};
|
mle_tlv_info_t challengeTlv = {MLE_TYPE_SRC_ADDRESS, 0, 0};
|
||||||
mle_tlv_info_t tlv_req = {0};
|
mle_tlv_info_t tlv_req = {MLE_TYPE_SRC_ADDRESS, 0, 0};
|
||||||
entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL);
|
entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL);
|
||||||
|
|
||||||
if (mle_tlv_read_8_bit_tlv(MLE_TYPE_STATUS, mle_msg->data_ptr, mle_msg->data_length, &status)) {
|
if (mle_tlv_read_8_bit_tlv(MLE_TYPE_STATUS, mle_msg->data_ptr, mle_msg->data_length, &status)) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2018, Arm Limited and affiliates.
|
* Copyright (c) 2014-2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -634,6 +634,7 @@ int thread_test_version_set(int8_t interface_id, uint8_t version)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
(void)version;
|
||||||
(void)interface_id;
|
(void)interface_id;
|
||||||
return -1;
|
return -1;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1269,6 +1270,23 @@ int8_t thread_test_joiner_router_joiner_port_set(uint16_t port)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int8_t thread_test_mcast_address_per_message_set(uint8_t value)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_THREAD
|
||||||
|
if (value == 0 || value > 15) {
|
||||||
|
tr_err("Value not in range. Valid range 1-15");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
thread_max_mcast_addr = value;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
(void)value;
|
||||||
|
return -1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
int thread_test_mle_message_send(int8_t interface_id, uint8_t *dst_address, uint8_t msg_id, bool write_src_addr, bool write_leader_data, bool write_network_data, bool write_timestamp, bool write_operational_set, bool write_challenge, uint8_t *msg_ptr, uint8_t msg_len)
|
int thread_test_mle_message_send(int8_t interface_id, uint8_t *dst_address, uint8_t msg_id, bool write_src_addr, bool write_leader_data, bool write_network_data, bool write_timestamp, bool write_operational_set, bool write_challenge, uint8_t *msg_ptr, uint8_t msg_len)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_THREAD
|
#ifdef HAVE_THREAD
|
||||||
|
@ -1341,6 +1359,8 @@ int thread_test_mle_message_send(int8_t interface_id, uint8_t *dst_address, uint
|
||||||
(void)msg_id;
|
(void)msg_id;
|
||||||
(void)write_src_addr;
|
(void)write_src_addr;
|
||||||
(void)write_leader_data;
|
(void)write_leader_data;
|
||||||
|
(void)write_network_data;
|
||||||
|
(void)write_timestamp;
|
||||||
(void)write_operational_set;
|
(void)write_operational_set;
|
||||||
(void)write_challenge;
|
(void)write_challenge;
|
||||||
(void)msg_ptr;
|
(void)msg_ptr;
|
||||||
|
@ -1367,3 +1387,27 @@ int thread_test_extension_name_set(int8_t interface_id, char extension_name[16])
|
||||||
return -1;
|
return -1;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int thread_test_parent_priority_set(int8_t interface_id, uint8_t parent_priority)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_THREAD
|
||||||
|
protocol_interface_info_entry_t *cur;
|
||||||
|
|
||||||
|
cur = protocol_stack_interface_info_get_by_id(interface_id);
|
||||||
|
if (!cur) {
|
||||||
|
tr_warn("Invalid interface id");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cur->thread_info) {
|
||||||
|
tr_warn("Not Thread specific interface");
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
cur->thread_info->parent_priority = parent_priority;
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
(void) interface_id;
|
||||||
|
(void) parent_priority;
|
||||||
|
return -1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
* Copyright (c) 2016-2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -23,8 +23,8 @@
|
||||||
#include "ns_list.h"
|
#include "ns_list.h"
|
||||||
#include "randLIB.h"
|
#include "randLIB.h"
|
||||||
#include "nsdynmemLIB.h"
|
#include "nsdynmemLIB.h"
|
||||||
#include "Core/include/address.h"
|
#include "Core/include/ns_address_internal.h"
|
||||||
#include "Core/include/socket.h"
|
#include "Core/include/ns_socket.h"
|
||||||
#include "mac_api.h"
|
#include "mac_api.h"
|
||||||
#include "mac_mcps.h"
|
#include "mac_mcps.h"
|
||||||
#include "mac_common_defines.h"
|
#include "mac_common_defines.h"
|
||||||
|
@ -40,6 +40,8 @@
|
||||||
#include "6LoWPAN/IPHC_Decode/iphc_decompress.h"
|
#include "6LoWPAN/IPHC_Decode/iphc_decompress.h"
|
||||||
#include "lowpan_adaptation_interface.h"
|
#include "lowpan_adaptation_interface.h"
|
||||||
#include "MLE/mle.h"
|
#include "MLE/mle.h"
|
||||||
|
#include "Service_Libs/mle_service/mle_service_api.h"
|
||||||
|
#include "Common_Protocols/icmpv6.h"
|
||||||
#ifdef HAVE_RPL
|
#ifdef HAVE_RPL
|
||||||
#include "RPL/rpl_data.h"
|
#include "RPL/rpl_data.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -787,49 +789,112 @@ static fragmenter_tx_entry_t *lowpan_adaptation_indirect_first_cached_request_ge
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lowpan_adaptation_make_room_for_small_packet(protocol_interface_info_entry_t *cur, fragmenter_interface_t *interface_ptr, mac_neighbor_table_entry_t *neighbour_to_count)
|
static bool lowpan_adaptation_is_priority_message(buffer_t *buf)
|
||||||
|
{
|
||||||
|
// Mle messages
|
||||||
|
if (buf->dst_sa.port == MLE_ALLOCATED_PORT || buf->src_sa.port == MLE_ALLOCATED_PORT) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Management messages: address solicit, response, query, notification
|
||||||
|
if (buf->dst_sa.port == THREAD_MANAGEMENT_PORT || buf->src_sa.port == THREAD_MANAGEMENT_PORT) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// dhcp messages
|
||||||
|
if (buf->dst_sa.port == DHCPV6_SERVER_PORT || buf->src_sa.port == DHCPV6_SERVER_PORT) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buf->dst_sa.port == DHCPV6_CLIENT_PORT || buf->src_sa.port == DHCPV6_CLIENT_PORT) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ICMPv6 messages
|
||||||
|
if (buf->options.type == ICMPV6_TYPE_ERROR_DESTINATION_UNREACH ||
|
||||||
|
buf->options.type == ICMPV6_TYPE_ERROR_PACKET_TOO_BIG ||
|
||||||
|
buf->options.type == ICMPV6_TYPE_ERROR_TIME_EXCEEDED ||
|
||||||
|
buf->options.type == ICMPV6_TYPE_ERROR_PARAMETER_PROBLEM) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool lowpan_adaptation_make_room_for_small_packet(protocol_interface_info_entry_t *cur, fragmenter_interface_t *interface_ptr, mac_neighbor_table_entry_t *neighbour_to_count, fragmenter_tx_entry_t *new_entry)
|
||||||
{
|
{
|
||||||
if (interface_ptr->max_indirect_small_packets_per_child == 0) {
|
if (interface_ptr->max_indirect_small_packets_per_child == 0) {
|
||||||
return;
|
// this means there is always space for small packets - no need to check further
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint_fast16_t count = 0;
|
uint_fast16_t count = 0;
|
||||||
|
fragmenter_tx_entry_t *low_priority_msg_ptr = NULL;
|
||||||
|
|
||||||
ns_list_foreach_reverse_safe(fragmenter_tx_entry_t, tx_entry, &interface_ptr->indirect_tx_queue) {
|
ns_list_foreach_reverse_safe(fragmenter_tx_entry_t, tx_entry, &interface_ptr->indirect_tx_queue) {
|
||||||
mac_neighbor_table_entry_t *tx_neighbour = mac_neighbor_table_address_discover(mac_neighbor_info(cur), tx_entry->buf->dst_sa.address + 2, tx_entry->buf->dst_sa.addr_type);
|
mac_neighbor_table_entry_t *tx_neighbour = mac_neighbor_table_address_discover(mac_neighbor_info(cur), tx_entry->buf->dst_sa.address + 2, tx_entry->buf->dst_sa.addr_type);
|
||||||
if (tx_neighbour == neighbour_to_count && buffer_data_length(tx_entry->buf) <= interface_ptr->indirect_big_packet_threshold) {
|
if (tx_neighbour == neighbour_to_count && buffer_data_length(tx_entry->buf) <= interface_ptr->indirect_big_packet_threshold) {
|
||||||
|
if (!lowpan_adaptation_is_priority_message(tx_entry->buf)) {
|
||||||
|
// if there is sub priorities inside message example age here you could compare
|
||||||
|
low_priority_msg_ptr = tx_entry;
|
||||||
|
}
|
||||||
if (++count >= interface_ptr->max_indirect_small_packets_per_child) {
|
if (++count >= interface_ptr->max_indirect_small_packets_per_child) {
|
||||||
tr_debug_extra("Purge seq: %d", tx_entry->buf->seq);
|
if (!low_priority_msg_ptr) {
|
||||||
if (lowpan_adaptation_indirect_queue_free_message(cur, interface_ptr, tx_entry) == false) {
|
// take last entry if no low priority entry found
|
||||||
|
if (lowpan_adaptation_is_priority_message(new_entry->buf)) {
|
||||||
|
low_priority_msg_ptr = tx_entry;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tr_debug_extra("Purge seq: %d", low_priority_msg_ptr->buf->seq);
|
||||||
|
if (lowpan_adaptation_indirect_queue_free_message(cur, interface_ptr, low_priority_msg_ptr) == false) {
|
||||||
/* entry could not be purged from mac, try next entry */
|
/* entry could not be purged from mac, try next entry */
|
||||||
tr_debug_extra("Purge failed, try next");
|
tr_debug_extra("Purge failed, try next");
|
||||||
count--;
|
count--;
|
||||||
}
|
}
|
||||||
|
low_priority_msg_ptr = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lowpan_adaptation_make_room_for_big_packet(struct protocol_interface_info_entry *cur, fragmenter_interface_t *interface_ptr)
|
static bool lowpan_adaptation_make_room_for_big_packet(struct protocol_interface_info_entry *cur, fragmenter_interface_t *interface_ptr, fragmenter_tx_entry_t *new_entry)
|
||||||
{
|
{
|
||||||
if (interface_ptr->max_indirect_big_packets_total == 0) {
|
if (interface_ptr->max_indirect_big_packets_total == 0) {
|
||||||
return;
|
// this means there is always space for big packets - no need to check further
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint_fast16_t count = 0;
|
uint_fast16_t count = 0;
|
||||||
|
fragmenter_tx_entry_t *low_priority_msg_ptr = NULL;
|
||||||
|
|
||||||
ns_list_foreach_reverse_safe(fragmenter_tx_entry_t, tx_entry, &interface_ptr->indirect_tx_queue) {
|
ns_list_foreach_reverse_safe(fragmenter_tx_entry_t, tx_entry, &interface_ptr->indirect_tx_queue) {
|
||||||
if (buffer_data_length(tx_entry->buf) > interface_ptr->indirect_big_packet_threshold) {
|
if (buffer_data_length(tx_entry->buf) > interface_ptr->indirect_big_packet_threshold) {
|
||||||
|
if (!lowpan_adaptation_is_priority_message(tx_entry->buf)) {
|
||||||
|
// if there is sub priorities inside message example age here you could compare
|
||||||
|
low_priority_msg_ptr = tx_entry;
|
||||||
|
}
|
||||||
if (++count >= interface_ptr->max_indirect_big_packets_total) {
|
if (++count >= interface_ptr->max_indirect_big_packets_total) {
|
||||||
tr_debug_extra("Purge seq: %d", tx_entry->buf->seq);
|
if (!low_priority_msg_ptr) {
|
||||||
if (lowpan_adaptation_indirect_queue_free_message(cur, interface_ptr, tx_entry) == false) {
|
// take last entry if no low priority entry found
|
||||||
tr_debug("Purge failed, try next entry");
|
if (lowpan_adaptation_is_priority_message(new_entry->buf)) {
|
||||||
|
low_priority_msg_ptr = tx_entry;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tr_debug_extra("Purge seq: %d", low_priority_msg_ptr->buf->seq);
|
||||||
|
if (lowpan_adaptation_indirect_queue_free_message(cur, interface_ptr, low_priority_msg_ptr) == false) {
|
||||||
|
tr_debug_extra("Purge failed, try next entry");
|
||||||
/* entry could not be purged from mac, try next entry */
|
/* entry could not be purged from mac, try next entry */
|
||||||
count--;
|
count--;
|
||||||
}
|
}
|
||||||
|
low_priority_msg_ptr = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lowpan_data_request_to_mac(protocol_interface_info_entry_t *cur, buffer_t *buf, fragmenter_tx_entry_t *tx_ptr, fragmenter_interface_t *interface_ptr)
|
static void lowpan_data_request_to_mac(protocol_interface_info_entry_t *cur, buffer_t *buf, fragmenter_tx_entry_t *tx_ptr, fragmenter_interface_t *interface_ptr)
|
||||||
|
@ -868,6 +933,7 @@ static void lowpan_data_request_to_mac(protocol_interface_info_entry_t *cur, buf
|
||||||
|
|
||||||
int8_t lowpan_adaptation_interface_tx(protocol_interface_info_entry_t *cur, buffer_t *buf)
|
int8_t lowpan_adaptation_interface_tx(protocol_interface_info_entry_t *cur, buffer_t *buf)
|
||||||
{
|
{
|
||||||
|
bool is_room_for_new_message;
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -940,9 +1006,9 @@ int8_t lowpan_adaptation_interface_tx(protocol_interface_info_entry_t *cur, buff
|
||||||
|
|
||||||
// Make room for new message if needed */
|
// Make room for new message if needed */
|
||||||
if (buffer_data_length(buf) <= interface_ptr->indirect_big_packet_threshold) {
|
if (buffer_data_length(buf) <= interface_ptr->indirect_big_packet_threshold) {
|
||||||
lowpan_adaptation_make_room_for_small_packet(cur, interface_ptr, neigh_entry_ptr);
|
is_room_for_new_message = lowpan_adaptation_make_room_for_small_packet(cur, interface_ptr, neigh_entry_ptr, tx_ptr);
|
||||||
} else {
|
} else {
|
||||||
lowpan_adaptation_make_room_for_big_packet(cur, interface_ptr);
|
is_room_for_new_message = lowpan_adaptation_make_room_for_big_packet(cur, interface_ptr, tx_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lowpan_adaptation_indirect_mac_data_request_active(interface_ptr, tx_ptr)) {
|
if (lowpan_adaptation_indirect_mac_data_request_active(interface_ptr, tx_ptr)) {
|
||||||
|
@ -951,7 +1017,15 @@ int8_t lowpan_adaptation_interface_tx(protocol_interface_info_entry_t *cur, buff
|
||||||
tx_ptr->indirect_data_cached = true;
|
tx_ptr->indirect_data_cached = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ns_list_add_to_end(&interface_ptr->indirect_tx_queue, tx_ptr);
|
if (is_room_for_new_message) {
|
||||||
|
ns_list_add_to_end(&interface_ptr->indirect_tx_queue, tx_ptr);
|
||||||
|
} else {
|
||||||
|
if (tx_ptr->fragmenter_buf) {
|
||||||
|
ns_dyn_mem_free(tx_ptr->fragmenter_buf);
|
||||||
|
}
|
||||||
|
ns_dyn_mem_free(tx_ptr);
|
||||||
|
goto tx_error_handler;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if current message can be delivered to MAC or should some cached message be delivered first
|
// Check if current message can be delivered to MAC or should some cached message be delivered first
|
||||||
tx_ptr_cached = lowpan_adaptation_indirect_first_cached_request_get(interface_ptr, tx_ptr);
|
tx_ptr_cached = lowpan_adaptation_indirect_first_cached_request_get(interface_ptr, tx_ptr);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
* Copyright (c) 2016-2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
#ifndef LOWPAN_ADAPTATION_INTERFACE_H_
|
#ifndef LOWPAN_ADAPTATION_INTERFACE_H_
|
||||||
#define LOWPAN_ADAPTATION_INTERFACE_H_
|
#define LOWPAN_ADAPTATION_INTERFACE_H_
|
||||||
#include "Core/include/address.h"
|
#include "Core/include/ns_address_internal.h"
|
||||||
|
|
||||||
struct protocol_interface_info_entry;
|
struct protocol_interface_info_entry;
|
||||||
struct mcps_data_conf_s;
|
struct mcps_data_conf_s;
|
||||||
|
|
|
@ -0,0 +1,488 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2019, 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 <string.h>
|
||||||
|
#include "nsconfig.h"
|
||||||
|
#include "ns_types.h"
|
||||||
|
#include "ns_trace.h"
|
||||||
|
#include "net_interface.h"
|
||||||
|
#include "eventOS_event.h"
|
||||||
|
#include "NWK_INTERFACE/Include/protocol.h"
|
||||||
|
#include "6LoWPAN/Bootstraps/protocol_6lowpan.h"
|
||||||
|
#include "6LoWPAN/Bootstraps/protocol_6lowpan_interface.h"
|
||||||
|
#include "6LoWPAN/ws/ws_config.h"
|
||||||
|
#include "6LoWPAN/ws/ws_common.h"
|
||||||
|
#include "6LoWPAN/ws/ws_bootstrap.h"
|
||||||
|
#include "RPL/rpl_control.h"
|
||||||
|
#include "RPL/rpl_data.h"
|
||||||
|
#include "Common_Protocols/icmpv6.h"
|
||||||
|
#include "Common_Protocols/icmpv6_radv.h"
|
||||||
|
#include "ws_management_api.h"
|
||||||
|
#include "net_rpl.h"
|
||||||
|
#include "Service_Libs/nd_proxy/nd_proxy.h"
|
||||||
|
#include "6LoWPAN/ws/ws_bbr_api_internal.h"
|
||||||
|
#include "DHCPv6_Server/DHCPv6_server_service.h"
|
||||||
|
|
||||||
|
#define TRACE_GROUP "wsbs"
|
||||||
|
|
||||||
|
#define RPL_INSTANCE_ID 1
|
||||||
|
|
||||||
|
#ifdef HAVE_WS_BORDER_ROUTER
|
||||||
|
|
||||||
|
|
||||||
|
/* when creating BBR make ULA dodag ID always and when network becomes available add prefix to DHCP
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static int8_t backbone_interface_id = -1; // BBR backbone information
|
||||||
|
|
||||||
|
static uint8_t static_dodag_prefix[8] = {0xfd, 0x00, 0x61, 0x72, 0x6d};
|
||||||
|
static uint8_t static_ula_address[16] = {0};
|
||||||
|
static uint8_t static_dodag_id[16] = {0};
|
||||||
|
static uint8_t global_dodag_id[16] = {0};
|
||||||
|
static uint32_t bbr_delay_timer = 20; // initial delay.
|
||||||
|
|
||||||
|
static rpl_dodag_conf_t rpl_conf = {
|
||||||
|
// Lifetime values
|
||||||
|
.default_lifetime = 120,
|
||||||
|
.lifetime_unit = 60,
|
||||||
|
.objective_code_point = 1, // MRHOF algorithm used
|
||||||
|
.authentication = 0,
|
||||||
|
.path_control_size = 7,
|
||||||
|
.dag_max_rank_increase = 2048,
|
||||||
|
.min_hop_rank_increase = 256,
|
||||||
|
// DIO configuration
|
||||||
|
.dio_interval_min = WS_RPL_DIO_IMIN,
|
||||||
|
.dio_interval_doublings = WS_RPL_DIO_DOUBLING,
|
||||||
|
.dio_redundancy_constant = WS_RPL_DIO_REDUNDANCY
|
||||||
|
};
|
||||||
|
|
||||||
|
void ws_bbr_rpl_config(uint8_t imin, uint8_t doubling, uint8_t redundancy)
|
||||||
|
{
|
||||||
|
if (imin == 0 || doubling == 0) {
|
||||||
|
// use default values
|
||||||
|
imin = WS_RPL_DIO_IMIN;
|
||||||
|
doubling = WS_RPL_DIO_DOUBLING;
|
||||||
|
redundancy = WS_RPL_DIO_REDUNDANCY;
|
||||||
|
}
|
||||||
|
if (rpl_conf.dio_interval_min == imin &&
|
||||||
|
rpl_conf.dio_interval_doublings == doubling &&
|
||||||
|
rpl_conf.dio_redundancy_constant == redundancy) {
|
||||||
|
// Same values no update needed
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rpl_conf.dio_interval_min = imin;
|
||||||
|
rpl_conf.dio_interval_doublings = doubling;
|
||||||
|
rpl_conf.dio_redundancy_constant = redundancy;
|
||||||
|
if (protocol_6lowpan_rpl_root_dodag) {
|
||||||
|
rpl_control_update_dodag_config(protocol_6lowpan_rpl_root_dodag, &rpl_conf);
|
||||||
|
rpl_control_increment_dodag_version(protocol_6lowpan_rpl_root_dodag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ws_bbr_rpl_root_start(uint8_t *dodag_id)
|
||||||
|
{
|
||||||
|
tr_info("RPL root start");
|
||||||
|
rpl_data_init_root();
|
||||||
|
|
||||||
|
if (protocol_6lowpan_rpl_root_dodag) {
|
||||||
|
rpl_control_delete_dodag_root(protocol_6lowpan_rpl_domain, protocol_6lowpan_rpl_root_dodag);
|
||||||
|
protocol_6lowpan_rpl_root_dodag = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
protocol_6lowpan_rpl_root_dodag = rpl_control_create_dodag_root(protocol_6lowpan_rpl_domain, RPL_INSTANCE_ID, dodag_id, &rpl_conf, rpl_conf.min_hop_rank_increase, RPL_GROUNDED | RPL_MODE_NON_STORING | RPL_DODAG_PREF(0));
|
||||||
|
if (!protocol_6lowpan_rpl_root_dodag) {
|
||||||
|
tr_err("RPL dodag init failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memcpy(static_dodag_id, dodag_id, 16);
|
||||||
|
|
||||||
|
// RPL memory limits set larger for Border router
|
||||||
|
rpl_control_set_memory_limits(64 * 1024, 0);
|
||||||
|
|
||||||
|
uint8_t t_flags = PIO_A;
|
||||||
|
|
||||||
|
rpl_control_update_dodag_prefix(protocol_6lowpan_rpl_root_dodag, dodag_id, 64, t_flags, 7200, 7200, false);
|
||||||
|
rpl_control_update_dodag_route(protocol_6lowpan_rpl_root_dodag, dodag_id, 64, 0x18, 7200, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ws_bbr_rpl_root_stop(void)
|
||||||
|
{
|
||||||
|
tr_info("RPL root stop");
|
||||||
|
rpl_control_delete_dodag_root(protocol_6lowpan_rpl_domain, protocol_6lowpan_rpl_root_dodag);
|
||||||
|
protocol_6lowpan_rpl_root_dodag = NULL;
|
||||||
|
memset(static_ula_address, 0, 16);
|
||||||
|
memset(static_dodag_id, 0, 16);
|
||||||
|
memset(global_dodag_id, 0, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ws_border_router_proxy_validate(int8_t interface_id, uint8_t *address)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Could also check route type, but I don't think it really matters */
|
||||||
|
ipv6_route_t *route;
|
||||||
|
route = ipv6_route_choose_next_hop(address, interface_id, NULL);
|
||||||
|
if (!route || route->prefix_len < 128) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ws_border_router_proxy_state_update(int8_t caller_interface_id, int8_t handler_interface_id, bool status)
|
||||||
|
{
|
||||||
|
(void)caller_interface_id;
|
||||||
|
|
||||||
|
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(handler_interface_id);
|
||||||
|
if (!cur) {
|
||||||
|
tr_error("No Interface");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status) {
|
||||||
|
tr_debug("Border router Backhaul link ready");
|
||||||
|
} else {
|
||||||
|
tr_debug("Border router Backhaul link down");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ws_bbr_static_ula_create(protocol_interface_info_entry_t *cur)
|
||||||
|
{
|
||||||
|
if (memcmp(static_ula_address, ADDR_UNSPECIFIED, 16) != 0) {
|
||||||
|
// address generated
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
tr_info("BBR generate ula prefix");
|
||||||
|
|
||||||
|
// This address is only used if no other address available.
|
||||||
|
if_address_entry_t *add_entry = icmpv6_slaac_address_add(cur, static_dodag_prefix, 64, 0xffffffff, 0, true, SLAAC_IID_FIXED);
|
||||||
|
if (!add_entry) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memcpy(static_ula_address, add_entry->address, 16);
|
||||||
|
tr_info("BBR generate ula prefix addr %s", trace_ipv6(static_ula_address));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 0 static non rooted self generated own address
|
||||||
|
* 1 static address with backbone connectivity
|
||||||
|
*/
|
||||||
|
static int ws_bbr_static_dodag_get(protocol_interface_info_entry_t *cur, uint8_t *dodag_id_ptr)
|
||||||
|
{
|
||||||
|
|
||||||
|
protocol_interface_info_entry_t *bb_interface = protocol_stack_interface_info_get_by_id(backbone_interface_id);
|
||||||
|
|
||||||
|
if (bb_interface && bb_interface->ipv6_configure->ipv6_stack_mode == NET_IPV6_BOOTSTRAP_STATIC) {
|
||||||
|
// static configuration for ethernet available
|
||||||
|
ns_list_foreach(if_address_entry_t, add_entry, &cur->ip_addresses) {
|
||||||
|
if (memcmp(add_entry->address, bb_interface->ipv6_configure->static_prefix64, 8) == 0) {
|
||||||
|
//tr_info("BBR static config available");
|
||||||
|
if (dodag_id_ptr) {
|
||||||
|
memcpy(dodag_id_ptr, add_entry->address, 16);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ws_bbr_static_ula_create(cur);
|
||||||
|
|
||||||
|
// only own generated prefix available
|
||||||
|
if (dodag_id_ptr) {
|
||||||
|
memcpy(dodag_id_ptr, static_ula_address, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int ws_bbr_dodag_get(protocol_interface_info_entry_t *cur, uint8_t *static_dodag_id_ptr, uint8_t *dodag_id_ptr)
|
||||||
|
{
|
||||||
|
uint8_t global_address[16];
|
||||||
|
|
||||||
|
if (static_dodag_id_ptr) {
|
||||||
|
memset(static_dodag_id_ptr, 0, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dodag_id_ptr) {
|
||||||
|
memset(dodag_id_ptr, 0, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ws_bbr_static_dodag_get(cur, static_dodag_id_ptr) < 0) {
|
||||||
|
// no static configuration available
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arm_net_address_get(backbone_interface_id, ADDR_IPV6_GP, global_address) != 0) {
|
||||||
|
// No global prefix available
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (memcmp(global_address, dodag_id_ptr, 8) == 0) {
|
||||||
|
// static address is same
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
memcpy(dodag_id_ptr, global_address, 16);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static void wisun_bbr_na_send(int8_t interface_id, const uint8_t target[static 16])
|
||||||
|
{
|
||||||
|
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
|
||||||
|
if (!cur) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer_t *buffer = icmpv6_build_na(cur, false, true, true, target, NULL, ADDR_UNSPECIFIED);
|
||||||
|
protocol_push(buffer);
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool wisun_dhcp_address_add_cb(int8_t interfaceId, dhcp_address_cache_update_t *address_info, void *route_src)
|
||||||
|
{
|
||||||
|
(void)route_src;
|
||||||
|
protocol_interface_info_entry_t *curPtr = protocol_stack_interface_info_get_by_id(interfaceId);
|
||||||
|
if (!curPtr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// When address is allocated we send NA to backbone to notify the new address and flush from other BBRs
|
||||||
|
wisun_bbr_na_send(backbone_interface_id, address_info->allocatedAddress);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void ws_bbr_rpl_status_check(protocol_interface_info_entry_t *cur)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint8_t static_id[16] = {0};
|
||||||
|
uint8_t global_id[16] = {0};
|
||||||
|
|
||||||
|
//tr_info("BBR status check");
|
||||||
|
|
||||||
|
ws_bbr_dodag_get(cur, static_id, global_id);
|
||||||
|
|
||||||
|
if (memcmp(static_dodag_id, static_id, 16) != 0) {
|
||||||
|
// Static id updated or first setup
|
||||||
|
ws_bbr_rpl_root_start(static_id);
|
||||||
|
}
|
||||||
|
if (memcmp(global_dodag_id, global_id, 16) != 0) {
|
||||||
|
// Global prefix changed
|
||||||
|
if (memcmp(global_dodag_id, ADDR_UNSPECIFIED, 16) != 0) {
|
||||||
|
// TODO remove old global prefix
|
||||||
|
tr_info("RPL GUA deactivate %s", trace_ipv6(global_dodag_id));
|
||||||
|
|
||||||
|
rpl_control_update_dodag_prefix(protocol_6lowpan_rpl_root_dodag, static_dodag_id, 64, PIO_A, 7200, 7200, false);
|
||||||
|
rpl_control_update_dodag_route(protocol_6lowpan_rpl_root_dodag, static_dodag_id, 64, 0x18, 7200, false);
|
||||||
|
|
||||||
|
// Old backbone information is deleted after 120 seconds
|
||||||
|
rpl_control_update_dodag_route(protocol_6lowpan_rpl_root_dodag, NULL, 0, 0, 120, true);
|
||||||
|
rpl_control_update_dodag_prefix(protocol_6lowpan_rpl_root_dodag, global_dodag_id, 64, 0, 120, 0, true);
|
||||||
|
rpl_control_update_dodag_route(protocol_6lowpan_rpl_root_dodag, global_dodag_id, 64, 0, 120, true);
|
||||||
|
ipv6_route_add_with_info(global_dodag_id, 64, backbone_interface_id, NULL, ROUTE_THREAD_BBR, NULL, 0, 120, 0);
|
||||||
|
DHCPv6_server_service_delete(cur->id, global_dodag_id, false);
|
||||||
|
|
||||||
|
// Set old addresses to deferred and timeout
|
||||||
|
ws_dhcp_client_address_delete(cur, global_dodag_id);
|
||||||
|
}
|
||||||
|
// TODO add global prefix
|
||||||
|
if (memcmp(global_id, ADDR_UNSPECIFIED, 16) != 0) {
|
||||||
|
//DHCPv6 Server set here
|
||||||
|
//Interface LL64 address
|
||||||
|
uint8_t ll[16];
|
||||||
|
memcpy(ll, ADDR_LINK_LOCAL_PREFIX, 8);
|
||||||
|
memcpy(&ll[8], cur->mac, 8);
|
||||||
|
ll[8] ^= 2;
|
||||||
|
|
||||||
|
if (DHCPv6_server_service_init(cur->id, global_id, cur->mac, DHCPV6_DUID_HARDWARE_IEEE_802_NETWORKS_TYPE) != 0) {
|
||||||
|
tr_error("DHCPv6 Server create fail");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
DHCPv6_server_service_callback_set(cur->id, global_id, NULL, wisun_dhcp_address_add_cb);
|
||||||
|
|
||||||
|
DHCPv6_server_service_set_address_autonous_flag(cur->id, global_id, true);
|
||||||
|
DHCPv6_server_service_set_address_validlifetime(cur->id, global_id, 7200);
|
||||||
|
|
||||||
|
tr_info("RPL GUA activate %s", trace_ipv6(global_id));
|
||||||
|
ws_dhcp_client_address_request(cur, global_id, ll);
|
||||||
|
|
||||||
|
rpl_control_update_dodag_route(protocol_6lowpan_rpl_root_dodag, NULL, 0, 0, 7200, false);
|
||||||
|
rpl_control_update_dodag_prefix(protocol_6lowpan_rpl_root_dodag, static_dodag_id, 64, PIO_A, 7200, 0, false);
|
||||||
|
rpl_control_update_dodag_route(protocol_6lowpan_rpl_root_dodag, static_dodag_id, 64, 0x18, 7200, false);
|
||||||
|
rpl_control_update_dodag_prefix(protocol_6lowpan_rpl_root_dodag, global_id, 64, 0, 7200, 7200, false);
|
||||||
|
rpl_control_update_dodag_route(protocol_6lowpan_rpl_root_dodag, global_id, 64, 0, 7200, false);
|
||||||
|
ipv6_route_add_with_info(global_id, 64, backbone_interface_id, NULL, ROUTE_THREAD_BBR, NULL, 0, 0xffffffff, 0);
|
||||||
|
}
|
||||||
|
memcpy(global_dodag_id, global_id, 16);
|
||||||
|
rpl_control_increment_dodag_version(protocol_6lowpan_rpl_root_dodag);
|
||||||
|
nd_proxy_downstream_interface_register(cur->id, ws_border_router_proxy_validate, ws_border_router_proxy_state_update);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ws_bbr_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t seconds)
|
||||||
|
{
|
||||||
|
(void)seconds;
|
||||||
|
|
||||||
|
if (!ws_info(cur)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (cur->bootsrap_mode != ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) {
|
||||||
|
// Not a border router
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!cur->rpl_domain) {
|
||||||
|
// RPL not started
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bbr_delay_timer > seconds) {
|
||||||
|
bbr_delay_timer -= seconds;
|
||||||
|
} else {
|
||||||
|
bbr_delay_timer = 20; // 20 second interval between status checks
|
||||||
|
|
||||||
|
// prequisists
|
||||||
|
// Wi-SUN network configuration started without RPL
|
||||||
|
|
||||||
|
// RPL configured simple
|
||||||
|
// 1. Wait for backend connection
|
||||||
|
// 2. When address becomes available in backend start RPL dodag
|
||||||
|
// 3. if address removed remove dodag
|
||||||
|
|
||||||
|
// RPL configured Advanced
|
||||||
|
// 1. Add ULA DODAG and and start ROOT even without backend
|
||||||
|
// a. If static prefix configured use it.
|
||||||
|
// b. generate random ULA and publish it to backend
|
||||||
|
// 2. if GUA prefix becomes available in backend add new prefix to DODAG
|
||||||
|
// 3. if GUA prefix is removed remove the prefix.
|
||||||
|
|
||||||
|
if (protocol_6lowpan_rpl_root_dodag) {
|
||||||
|
// Border router is active
|
||||||
|
if (0 != protocol_interface_address_compare(static_dodag_id)) {
|
||||||
|
// Dodag has become invalid need to delete
|
||||||
|
tr_info("RPL static dodag not valid anymore %s", trace_ipv6(static_dodag_id));
|
||||||
|
ws_bbr_rpl_root_stop();
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ws_bbr_rpl_status_check(cur);
|
||||||
|
|
||||||
|
}
|
||||||
|
// Normal BBR operation
|
||||||
|
if (protocol_6lowpan_rpl_root_dodag) {
|
||||||
|
if (cur->ws_info->pan_version_timer > seconds) {
|
||||||
|
cur->ws_info->pan_version_timer -= seconds;
|
||||||
|
} else {
|
||||||
|
// Border router has timed out
|
||||||
|
tr_debug("Border router version number update");
|
||||||
|
cur->ws_info->pan_version_timer = PAN_VERSION_LIFETIME;
|
||||||
|
cur->ws_info->pan_information.pan_version++;
|
||||||
|
// Inconsistent for border router to make information distribute faster
|
||||||
|
ws_bootstrap_configuration_trickle_reset(cur);
|
||||||
|
|
||||||
|
if (cur->ws_info->network_size_config == NETWORK_SIZE_AUTOMATIC) {
|
||||||
|
ws_common_network_size_configure(cur, cur->ws_info->pan_information.pan_size);
|
||||||
|
}
|
||||||
|
// We update the RPL version in same time to allow nodes to reselect parent
|
||||||
|
// As configuration is made so that devices cant move downward in dodag this allows it
|
||||||
|
// TODO think the correct rate for this
|
||||||
|
if (cur->ws_info->pan_information.pan_version && cur->ws_info->pan_information.pan_version % RPL_VERSION_LIFETIME / PAN_VERSION_LIFETIME == 0) {
|
||||||
|
// Third the rate of configuration version change at default 5 hours
|
||||||
|
rpl_control_increment_dodag_version(protocol_6lowpan_rpl_root_dodag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t test_pan_size_override = 0xffff;
|
||||||
|
|
||||||
|
uint16_t ws_bbr_pan_size(protocol_interface_info_entry_t *cur)
|
||||||
|
{
|
||||||
|
uint16_t result = 0;
|
||||||
|
if (test_pan_size_override != 0xffff) {
|
||||||
|
return test_pan_size_override;
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl_control_get_instance_dao_target_count(cur->rpl_domain, RPL_INSTANCE_ID, NULL, &result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif //HAVE_WS_BORDER_ROUTER
|
||||||
|
|
||||||
|
/* Public APIs
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
int ws_bbr_start(int8_t interface_id, int8_t bb_interface_id)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_WS_BORDER_ROUTER
|
||||||
|
|
||||||
|
(void)interface_id;
|
||||||
|
protocol_interface_info_entry_t *bb_interface = protocol_stack_interface_info_get_by_id(bb_interface_id);
|
||||||
|
|
||||||
|
if (!bb_interface) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// TODO make bb configurations
|
||||||
|
|
||||||
|
backbone_interface_id = bb_interface_id;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
(void)interface_id;
|
||||||
|
(void)bb_interface_id;
|
||||||
|
return -1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
void ws_bbr_stop(int8_t interface_id)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_WS_BORDER_ROUTER
|
||||||
|
|
||||||
|
(void)interface_id;
|
||||||
|
backbone_interface_id = -1;
|
||||||
|
|
||||||
|
if (!protocol_6lowpan_rpl_domain) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl_control_delete_dodag_root(protocol_6lowpan_rpl_domain, protocol_6lowpan_rpl_root_dodag);
|
||||||
|
protocol_6lowpan_rpl_root_dodag = NULL;
|
||||||
|
|
||||||
|
#else
|
||||||
|
(void)interface_id;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int ws_bbr_node_keys_remove(int8_t interface_id, uint8_t *eui64)
|
||||||
|
{
|
||||||
|
(void) interface_id;
|
||||||
|
(void) eui64;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ws_bbr_node_access_revoke_start(int8_t interface_id)
|
||||||
|
{
|
||||||
|
(void) interface_id;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2019, 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 WS_BBR_API_PRIVATE_H_
|
||||||
|
#define WS_BBR_API_PRIVATE_H_
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_WS_BORDER_ROUTER
|
||||||
|
|
||||||
|
extern uint16_t test_pan_size_override;
|
||||||
|
|
||||||
|
void ws_bbr_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t seconds);
|
||||||
|
|
||||||
|
uint16_t ws_bbr_pan_size(protocol_interface_info_entry_t *cur);
|
||||||
|
|
||||||
|
void ws_bbr_rpl_config(uint8_t imin, uint8_t doubling, uint8_t redundancy);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define ws_bbr_seconds_timer( cur, seconds)
|
||||||
|
#define ws_bbr_pan_size(cur) 0
|
||||||
|
#define ws_bbr_rpl_config( imin, doubling, redundancy);
|
||||||
|
|
||||||
|
#endif //HAVE_WS_BORDER_ROUTER
|
||||||
|
|
||||||
|
#endif /* WS_BBR_API_PRIVATE_H_ */
|
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
* Copyright (c) 2018-2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -37,6 +37,10 @@ void ws_bootstrap_state_machine(protocol_interface_info_entry_t *cur);
|
||||||
|
|
||||||
int ws_bootstrap_restart(int8_t interface_id);
|
int ws_bootstrap_restart(int8_t interface_id);
|
||||||
|
|
||||||
|
int ws_bootstrap_set_rf_config(protocol_interface_info_entry_t *cur, phy_rf_channel_configuration_s rf_configs);
|
||||||
|
|
||||||
|
int ws_bootstrap_neighbor_remove(protocol_interface_info_entry_t *cur, const uint8_t *ll_address);
|
||||||
|
|
||||||
/*State machine transactions*/
|
/*State machine transactions*/
|
||||||
void ws_bootstrap_event_discovery_start(protocol_interface_info_entry_t *cur);
|
void ws_bootstrap_event_discovery_start(protocol_interface_info_entry_t *cur);
|
||||||
|
|
||||||
|
@ -66,11 +70,14 @@ void ws_dhcp_client_address_request(protocol_interface_info_entry_t *cur, uint8_
|
||||||
|
|
||||||
void ws_dhcp_client_address_delete(protocol_interface_info_entry_t *cur, uint8_t *prefix);
|
void ws_dhcp_client_address_delete(protocol_interface_info_entry_t *cur, uint8_t *prefix);
|
||||||
|
|
||||||
|
bool ws_eapol_relay_state_active(protocol_interface_info_entry_t *cur);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define ws_bootstrap_init(interface_id, bootstrap_mode) (-1)
|
#define ws_bootstrap_init(interface_id, bootstrap_mode) (-1)
|
||||||
#define ws_bootstrap_state_machine(cur)
|
#define ws_bootstrap_state_machine(cur)
|
||||||
#define ws_bootstrap_restart(cur)
|
#define ws_bootstrap_restart(cur)
|
||||||
|
#define ws_bootstrap_neighbor_remove(cur, ll_address)
|
||||||
#define ws_primary_parent_update(interface, neighbor)
|
#define ws_primary_parent_update(interface, neighbor)
|
||||||
#define ws_secondary_parent_update(interface)
|
#define ws_secondary_parent_update(interface)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,381 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2019, 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 <string.h>
|
||||||
|
#include "nsconfig.h"
|
||||||
|
#include "ns_types.h"
|
||||||
|
#include "ns_trace.h"
|
||||||
|
#include "randLIB.h"
|
||||||
|
#include <ns_list.h>
|
||||||
|
#include <nsdynmemLIB.h>
|
||||||
|
#include "6LoWPAN/ws/ws_config.h"
|
||||||
|
#include "6LoWPAN/ws/ws_common_defines.h"
|
||||||
|
#include "6LoWPAN/ws/ws_common.h"
|
||||||
|
#include "6LoWPAN/ws/ws_bootstrap.h"
|
||||||
|
#include "6LoWPAN/ws/ws_bbr_api_internal.h"
|
||||||
|
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
|
||||||
|
#include "Service_Libs/blacklist/blacklist.h"
|
||||||
|
#include "ws_management_api.h"
|
||||||
|
#include "mac_api.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_WS
|
||||||
|
#define TRACE_GROUP "wscm"
|
||||||
|
|
||||||
|
int8_t DEVICE_MIN_SENS = -93;
|
||||||
|
|
||||||
|
#define TRICKLE_IMIN_60_SECS (60 * 10)
|
||||||
|
#define TRICKLE_IMIN_30_SECS (30 * 10)
|
||||||
|
#define TRICKLE_IMIN_15_SECS (15 * 10)
|
||||||
|
|
||||||
|
static const trickle_params_t trickle_params_pan_discovery_large = {
|
||||||
|
.Imin = TRICKLE_IMIN_60_SECS, /* 60 second; ticks are 1s */
|
||||||
|
.Imax = TRICKLE_IMIN_60_SECS << 4, /* 960 seconds 16 min*/
|
||||||
|
.k = 1, /* 1 */
|
||||||
|
.TimerExpirations = TRICKLE_EXPIRATIONS_INFINITE
|
||||||
|
};
|
||||||
|
|
||||||
|
static const trickle_params_t trickle_params_pan_discovery_medium = {
|
||||||
|
.Imin = TRICKLE_IMIN_30_SECS, /* 30 second; ticks are 1s */
|
||||||
|
.Imax = TRICKLE_IMIN_30_SECS << 3, /* 240 seconds 4 min*/
|
||||||
|
.k = 1, /* 1 */
|
||||||
|
.TimerExpirations = TRICKLE_EXPIRATIONS_INFINITE
|
||||||
|
};
|
||||||
|
|
||||||
|
static const trickle_params_t trickle_params_pan_discovery_small = {
|
||||||
|
.Imin = TRICKLE_IMIN_15_SECS, /* 15 second; ticks are 1s */
|
||||||
|
.Imax = TRICKLE_IMIN_15_SECS << 2, /* 60 seconds 1 min*/
|
||||||
|
.k = 1, /* 1 */
|
||||||
|
.TimerExpirations = TRICKLE_EXPIRATIONS_INFINITE
|
||||||
|
};
|
||||||
|
|
||||||
|
uint16_t test_max_child_count_override = 0xffff;
|
||||||
|
|
||||||
|
|
||||||
|
int8_t ws_generate_channel_list(uint32_t *channel_mask, uint16_t number_of_channels, uint8_t regulatory_domain)
|
||||||
|
{
|
||||||
|
(void)regulatory_domain;
|
||||||
|
for (uint8_t i = 0; i < number_of_channels; i++) {
|
||||||
|
channel_mask[0 + (i / 32)] |= (1 << (i % 32));
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t ws_decode_channel_spacing(uint8_t channel_spacing)
|
||||||
|
{
|
||||||
|
if (CHANNEL_SPACING_100 == channel_spacing) {
|
||||||
|
return 100000;
|
||||||
|
} else if (CHANNEL_SPACING_200 == channel_spacing) {
|
||||||
|
return 200000;
|
||||||
|
} else if (CHANNEL_SPACING_250 == channel_spacing) {
|
||||||
|
return 250000;
|
||||||
|
} else if (CHANNEL_SPACING_400 == channel_spacing) {
|
||||||
|
return 400000;
|
||||||
|
} else if (CHANNEL_SPACING_600 == channel_spacing) {
|
||||||
|
return 600000;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t ws_get_datarate_using_operating_mode(uint8_t operating_mode)
|
||||||
|
{
|
||||||
|
if ((OPERATING_MODE_1a == operating_mode) || (OPERATING_MODE_1b == operating_mode)) {
|
||||||
|
return 50000;
|
||||||
|
} else if ((OPERATING_MODE_2a == operating_mode) || (OPERATING_MODE_2b == operating_mode)) {
|
||||||
|
return 100000;
|
||||||
|
} else if (OPERATING_MODE_3 == operating_mode) {
|
||||||
|
return 150000;
|
||||||
|
} else if ((OPERATING_MODE_4a == operating_mode) || (OPERATING_MODE_4b == operating_mode)) {
|
||||||
|
return 200000;
|
||||||
|
} else if (OPERATING_MODE_5 == operating_mode) {
|
||||||
|
return 300000;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static phy_modulation_index_e ws_get_modulation_index_using_operating_mode(uint8_t operating_mode)
|
||||||
|
{
|
||||||
|
if ((OPERATING_MODE_1b == operating_mode) || (OPERATING_MODE_2b == operating_mode) || (OPERATING_MODE_4b == operating_mode)) {
|
||||||
|
return MODULATION_INDEX_1_0;
|
||||||
|
} else {
|
||||||
|
return MODULATION_INDEX_0_5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ws_set_domain_rf_config(protocol_interface_info_entry_t *cur)
|
||||||
|
{
|
||||||
|
phy_rf_channel_configuration_s rf_configs;
|
||||||
|
rf_configs.channel_0_center_frequency = (uint32_t)cur->ws_info->hopping_schdule.ch0_freq * 100000;
|
||||||
|
rf_configs.channel_spacing = ws_decode_channel_spacing(cur->ws_info->hopping_schdule.channel_spacing);
|
||||||
|
rf_configs.datarate = ws_get_datarate_using_operating_mode(cur->ws_info->hopping_schdule.operating_mode);
|
||||||
|
rf_configs.modulation_index = ws_get_modulation_index_using_operating_mode(cur->ws_info->hopping_schdule.operating_mode);
|
||||||
|
rf_configs.modulation = M_2FSK;
|
||||||
|
rf_configs.number_of_channels = cur->ws_info->hopping_schdule.number_of_channels;
|
||||||
|
ws_bootstrap_set_rf_config(cur, rf_configs);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t ws_common_regulatory_domain_config(protocol_interface_info_entry_t *cur)
|
||||||
|
{
|
||||||
|
cur->ws_info->hopping_schdule.channel_plan = 0;
|
||||||
|
|
||||||
|
if (cur->ws_info->hopping_schdule.regulatory_domain == REG_DOMAIN_KR) {
|
||||||
|
if (cur->ws_info->hopping_schdule.operating_class == 1) {
|
||||||
|
cur->ws_info->hopping_schdule.ch0_freq = 9171;
|
||||||
|
cur->ws_info->hopping_schdule.channel_spacing = CHANNEL_SPACING_200;
|
||||||
|
} else if (cur->ws_info->hopping_schdule.operating_class == 2) {
|
||||||
|
cur->ws_info->hopping_schdule.ch0_freq = 9173;
|
||||||
|
cur->ws_info->hopping_schdule.channel_spacing = CHANNEL_SPACING_400;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else if (cur->ws_info->hopping_schdule.regulatory_domain == REG_DOMAIN_EU) {
|
||||||
|
if (cur->ws_info->hopping_schdule.operating_class == 1) {
|
||||||
|
cur->ws_info->hopping_schdule.ch0_freq = 8631;
|
||||||
|
cur->ws_info->hopping_schdule.channel_spacing = CHANNEL_SPACING_100;
|
||||||
|
} else if (cur->ws_info->hopping_schdule.operating_class == 2) {
|
||||||
|
cur->ws_info->hopping_schdule.ch0_freq = 8631;
|
||||||
|
cur->ws_info->hopping_schdule.channel_spacing = CHANNEL_SPACING_200;
|
||||||
|
} else if (cur->ws_info->hopping_schdule.operating_class == 3) {
|
||||||
|
cur->ws_info->hopping_schdule.ch0_freq = 8701;
|
||||||
|
cur->ws_info->hopping_schdule.channel_spacing = CHANNEL_SPACING_100;
|
||||||
|
} else if (cur->ws_info->hopping_schdule.operating_class == 4) {
|
||||||
|
cur->ws_info->hopping_schdule.ch0_freq = 8702;
|
||||||
|
cur->ws_info->hopping_schdule.channel_spacing = CHANNEL_SPACING_200;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else if (cur->ws_info->hopping_schdule.regulatory_domain == REG_DOMAIN_NA) {
|
||||||
|
if (cur->ws_info->hopping_schdule.operating_class == 1) {
|
||||||
|
cur->ws_info->hopping_schdule.ch0_freq = 9022;
|
||||||
|
cur->ws_info->hopping_schdule.channel_spacing = CHANNEL_SPACING_200;
|
||||||
|
} else if (cur->ws_info->hopping_schdule.operating_class == 2) {
|
||||||
|
cur->ws_info->hopping_schdule.ch0_freq = 9024;
|
||||||
|
cur->ws_info->hopping_schdule.channel_spacing = CHANNEL_SPACING_400;
|
||||||
|
} else if (cur->ws_info->hopping_schdule.operating_class == 3) {
|
||||||
|
cur->ws_info->hopping_schdule.ch0_freq = 9026;
|
||||||
|
cur->ws_info->hopping_schdule.channel_spacing = CHANNEL_SPACING_600;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else if (cur->ws_info->hopping_schdule.regulatory_domain == REG_DOMAIN_JP) {
|
||||||
|
if (cur->ws_info->hopping_schdule.operating_class == 1) {
|
||||||
|
cur->ws_info->hopping_schdule.ch0_freq = 9206;
|
||||||
|
cur->ws_info->hopping_schdule.channel_spacing = CHANNEL_SPACING_200;
|
||||||
|
} else if (cur->ws_info->hopping_schdule.operating_class == 2) {
|
||||||
|
cur->ws_info->hopping_schdule.ch0_freq = 9209;
|
||||||
|
cur->ws_info->hopping_schdule.channel_spacing = CHANNEL_SPACING_400;
|
||||||
|
} else if (cur->ws_info->hopping_schdule.operating_class == 3) {
|
||||||
|
cur->ws_info->hopping_schdule.ch0_freq = 9208;
|
||||||
|
cur->ws_info->hopping_schdule.channel_spacing = CHANNEL_SPACING_600;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else if (cur->ws_info->hopping_schdule.regulatory_domain == REG_DOMAIN_WW) {
|
||||||
|
if (cur->ws_info->hopping_schdule.operating_class == 1) {
|
||||||
|
cur->ws_info->hopping_schdule.ch0_freq = 24002;
|
||||||
|
cur->ws_info->hopping_schdule.channel_spacing = CHANNEL_SPACING_200;
|
||||||
|
} else if (cur->ws_info->hopping_schdule.operating_class == 2) {
|
||||||
|
cur->ws_info->hopping_schdule.ch0_freq = 24004;
|
||||||
|
cur->ws_info->hopping_schdule.channel_spacing = CHANNEL_SPACING_400;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
cur->ws_info->hopping_schdule.number_of_channels = (uint8_t)ws_common_channel_number_calc(cur->ws_info->hopping_schdule.regulatory_domain, cur->ws_info->hopping_schdule.operating_class);
|
||||||
|
if (!cur->ws_info->hopping_schdule.number_of_channels) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// Note: doesn't work for Brazil region
|
||||||
|
ws_generate_channel_list(cur->ws_info->hopping_schdule.channel_mask, cur->ws_info->hopping_schdule.number_of_channels, cur->ws_info->hopping_schdule.regulatory_domain);
|
||||||
|
ws_set_domain_rf_config(cur);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t ws_common_channel_number_calc(uint8_t regulatory_domain, uint8_t operating_class)
|
||||||
|
{
|
||||||
|
if (regulatory_domain == REG_DOMAIN_KR) {
|
||||||
|
if (operating_class == 1) {
|
||||||
|
return 32;
|
||||||
|
} else if (operating_class == 2) {
|
||||||
|
return 16;
|
||||||
|
}
|
||||||
|
} else if (regulatory_domain == REG_DOMAIN_EU) {
|
||||||
|
if (operating_class == 1) {
|
||||||
|
return 69;
|
||||||
|
} else if (operating_class == 2) {
|
||||||
|
return 35;
|
||||||
|
} else if (operating_class == 3) {
|
||||||
|
return 55;
|
||||||
|
} else if (operating_class == 4) {
|
||||||
|
return 27;
|
||||||
|
}
|
||||||
|
} else if (regulatory_domain == REG_DOMAIN_NA) {
|
||||||
|
if (operating_class == 1) {
|
||||||
|
return 129;
|
||||||
|
} else if (operating_class == 2) {
|
||||||
|
return 64;
|
||||||
|
} else if (operating_class == 3) {
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
} else if (regulatory_domain == REG_DOMAIN_JP) {
|
||||||
|
if (operating_class == 1) {
|
||||||
|
return 38;
|
||||||
|
} else if (operating_class == 2) {
|
||||||
|
return 18;
|
||||||
|
} else if (operating_class == 3) {
|
||||||
|
return 12;
|
||||||
|
}
|
||||||
|
} else if (regulatory_domain == REG_DOMAIN_WW) {
|
||||||
|
if (operating_class == 1) {
|
||||||
|
// TODO we dont support this yet, but it is used as test value
|
||||||
|
return 416;
|
||||||
|
} else if (operating_class == 2) {
|
||||||
|
return 207;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t ws_common_allocate_and_init(protocol_interface_info_entry_t *cur)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!cur->ws_info) {
|
||||||
|
cur->ws_info = ns_dyn_mem_alloc(sizeof(ws_info_t));
|
||||||
|
}
|
||||||
|
if (!cur->ws_info) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(cur->ws_info, 0, sizeof(ws_info_t));
|
||||||
|
ns_list_init(&cur->ws_info->active_nud_process);
|
||||||
|
ns_list_init(&cur->ws_info->free_nud_entries);
|
||||||
|
|
||||||
|
cur->ws_info->pan_information.use_parent_bs = true;
|
||||||
|
cur->ws_info->pan_information.rpl_routing_method = true;
|
||||||
|
cur->ws_info->pan_information.version = WS_FAN_VERSION_1_0;
|
||||||
|
|
||||||
|
cur->ws_info->hopping_schdule.regulatory_domain = REG_DOMAIN_EU;
|
||||||
|
cur->ws_info->hopping_schdule.operating_mode = OPERATING_MODE_3;
|
||||||
|
cur->ws_info->hopping_schdule.operating_class = 2;
|
||||||
|
ws_common_regulatory_domain_config(cur);
|
||||||
|
ws_common_network_size_configure(cur, 10); // defaults to small network size
|
||||||
|
|
||||||
|
// Set defaults for the device. user can modify these.
|
||||||
|
cur->ws_info->fhss_uc_fixed_channel = 0xffff;
|
||||||
|
cur->ws_info->fhss_bc_fixed_channel = 0xffff;
|
||||||
|
cur->ws_info->fhss_uc_dwell_interval = WS_FHSS_UC_DWELL_INTERVAL;
|
||||||
|
cur->ws_info->fhss_bc_interval = WS_FHSS_BC_INTERVAL;
|
||||||
|
cur->ws_info->fhss_bc_dwell_interval = WS_FHSS_BC_DWELL_INTERVAL;
|
||||||
|
cur->ws_info->fhss_uc_channel_function = WS_DH1CF;
|
||||||
|
cur->ws_info->fhss_bc_channel_function = WS_DH1CF;
|
||||||
|
for (uint8_t n = 0; n < 8; n++) {
|
||||||
|
cur->ws_info->fhss_channel_mask[n] = 0xffffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
void ws_common_network_size_configure(protocol_interface_info_entry_t *cur, uint16_t network_size)
|
||||||
|
{
|
||||||
|
// TODO Modify NUD timings based on network size
|
||||||
|
// TODO Modify EAPOLL timings
|
||||||
|
|
||||||
|
if (network_size < 100) {
|
||||||
|
// Configure the Wi-SUN discovery trickle parameters
|
||||||
|
cur->ws_info->trickle_params_pan_discovery = trickle_params_pan_discovery_small;
|
||||||
|
// default values are for Wi-SUN small network parameters
|
||||||
|
// imin: 14 (16s)
|
||||||
|
// doublings:3 (128s)
|
||||||
|
// redundancy; 0 Disabled
|
||||||
|
ws_bbr_rpl_config(0, 0, 0);// set the default values
|
||||||
|
} else if (network_size < 300) {
|
||||||
|
// Configure the Wi-SUN discovery trickle parameters
|
||||||
|
cur->ws_info->trickle_params_pan_discovery = trickle_params_pan_discovery_medium;
|
||||||
|
// Something in between
|
||||||
|
// imin: 15 (32s)
|
||||||
|
// doublings:3 (262s)
|
||||||
|
// redundancy; 7
|
||||||
|
ws_bbr_rpl_config(15, 3, 7);
|
||||||
|
} else {
|
||||||
|
// Configure the Wi-SUN discovery trickle parameters
|
||||||
|
cur->ws_info->trickle_params_pan_discovery = trickle_params_pan_discovery_large;
|
||||||
|
// Wi-SUN Large network parameters
|
||||||
|
// imin: 19 (524s, 9 min)
|
||||||
|
// doublings:1 (1048s, 17 min)
|
||||||
|
// redundancy; 1 Really heavy redundancy
|
||||||
|
ws_bbr_rpl_config(19, 1, 1);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ws_common_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t seconds)
|
||||||
|
{
|
||||||
|
ws_bbr_seconds_timer(cur, seconds);
|
||||||
|
ws_bootstrap_seconds_timer(cur, seconds);
|
||||||
|
blacklist_ttl_update(seconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ws_common_fast_timer(protocol_interface_info_entry_t *cur, uint16_t ticks)
|
||||||
|
{
|
||||||
|
ws_bootstrap_trickle_timer(cur, ticks);
|
||||||
|
ws_nud_active_timer(cur, ticks);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ws_common_neighbor_update(protocol_interface_info_entry_t *cur, const uint8_t *ll_address)
|
||||||
|
{
|
||||||
|
//Neighbor connectected update
|
||||||
|
mac_neighbor_table_entry_t *mac_neighbor = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), ll_address, false, NULL);
|
||||||
|
if (mac_neighbor) {
|
||||||
|
ws_nud_entry_remove_active(cur, mac_neighbor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ws_common_aro_failure(protocol_interface_info_entry_t *cur, const uint8_t *ll_address)
|
||||||
|
{
|
||||||
|
//Neighbor connectected update
|
||||||
|
ws_bootstrap_neighbor_remove(cur, ll_address);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ws_common_allow_child_registration(protocol_interface_info_entry_t *interface)
|
||||||
|
{
|
||||||
|
uint8_t child_count = 0;
|
||||||
|
uint8_t max_child_count = mac_neighbor_info(interface)->list_total_size - WS_NON_CHILD_NEIGHBOUR_COUNT;
|
||||||
|
|
||||||
|
// Test API to limit child count
|
||||||
|
if (test_max_child_count_override != 0xffff) {
|
||||||
|
max_child_count = test_max_child_count_override;
|
||||||
|
}
|
||||||
|
|
||||||
|
ns_list_foreach_safe(mac_neighbor_table_entry_t, cur, &mac_neighbor_info(interface)->neighbour_list) {
|
||||||
|
|
||||||
|
if (ipv6_neighbour_has_registered_by_eui64(&interface->ipv6_neighbour_cache, cur->mac64)) {
|
||||||
|
child_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (child_count >= max_child_count) {
|
||||||
|
tr_warn("Child registration not allowed %d/%d, max:%d", child_count, max_child_count, mac_neighbor_info(interface)->list_total_size);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
tr_info("Child registration allowed %d/%d, max:%d", child_count, max_child_count, mac_neighbor_info(interface)->list_total_size);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // HAVE_WS
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
* Copyright (c) 2018-2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -24,10 +24,14 @@
|
||||||
#include "fhss_api.h"
|
#include "fhss_api.h"
|
||||||
#include "fhss_config.h"
|
#include "fhss_config.h"
|
||||||
#include "net_fhss.h"
|
#include "net_fhss.h"
|
||||||
|
#include "NWK_INTERFACE/Include/protocol.h"
|
||||||
#include "6LoWPAN/ws/ws_common_defines.h"
|
#include "6LoWPAN/ws/ws_common_defines.h"
|
||||||
#include "6LoWPAN/ws/ws_neighbor_class.h"
|
#include "6LoWPAN/ws/ws_neighbor_class.h"
|
||||||
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
|
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
|
||||||
|
|
||||||
|
|
||||||
|
extern uint16_t test_max_child_count_override;
|
||||||
|
|
||||||
struct ws_pan_information_s;
|
struct ws_pan_information_s;
|
||||||
struct ws_neighbor_class_s;
|
struct ws_neighbor_class_s;
|
||||||
|
|
||||||
|
@ -61,6 +65,8 @@ typedef struct ws_info_s {
|
||||||
trickle_t trickle_pan_config;
|
trickle_t trickle_pan_config;
|
||||||
trickle_t trickle_pan_advertisement_solicit;
|
trickle_t trickle_pan_advertisement_solicit;
|
||||||
trickle_t trickle_pan_advertisement;
|
trickle_t trickle_pan_advertisement;
|
||||||
|
trickle_params_t trickle_params_pan_discovery;
|
||||||
|
uint8_t network_size_config; // configuration for network size selection of application.
|
||||||
uint8_t rpl_state; // state from rpl_event_t
|
uint8_t rpl_state; // state from rpl_event_t
|
||||||
uint8_t pas_requests; // Amount of PAN solicits sent
|
uint8_t pas_requests; // Amount of PAN solicits sent
|
||||||
parent_info_t parent_info;
|
parent_info_t parent_info;
|
||||||
|
@ -98,20 +104,30 @@ int8_t ws_generate_channel_list(uint32_t *channel_mask, uint16_t number_of_chann
|
||||||
|
|
||||||
int8_t ws_common_regulatory_domain_config(protocol_interface_info_entry_t *cur);
|
int8_t ws_common_regulatory_domain_config(protocol_interface_info_entry_t *cur);
|
||||||
|
|
||||||
|
uint16_t ws_common_channel_number_calc(uint8_t regulatory_domain, uint8_t operating_class);
|
||||||
|
|
||||||
int8_t ws_common_allocate_and_init(protocol_interface_info_entry_t *cur);
|
int8_t ws_common_allocate_and_init(protocol_interface_info_entry_t *cur);
|
||||||
|
|
||||||
|
void ws_common_network_size_configure(protocol_interface_info_entry_t *cur, uint16_t network_size);
|
||||||
|
|
||||||
void ws_common_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t seconds);
|
void ws_common_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t seconds);
|
||||||
|
|
||||||
void ws_common_fast_timer(protocol_interface_info_entry_t *cur, uint16_t ticks);
|
void ws_common_fast_timer(protocol_interface_info_entry_t *cur, uint16_t ticks);
|
||||||
|
|
||||||
void ws_common_neighbor_update(protocol_interface_info_entry_t *cur, const uint8_t *ll_address);
|
void ws_common_neighbor_update(protocol_interface_info_entry_t *cur, const uint8_t *ll_address);
|
||||||
|
|
||||||
|
void ws_common_aro_failure(protocol_interface_info_entry_t *cur, const uint8_t *ll_address);
|
||||||
|
|
||||||
|
bool ws_common_allow_child_registration(protocol_interface_info_entry_t *cur);
|
||||||
|
|
||||||
#define ws_info(cur) ((cur)->ws_info)
|
#define ws_info(cur) ((cur)->ws_info)
|
||||||
#else
|
#else
|
||||||
#define ws_info(cur) ((ws_info_t *) NULL)
|
#define ws_info(cur) ((ws_info_t *) NULL)
|
||||||
#define ws_common_seconds_timer(cur, seconds)
|
#define ws_common_seconds_timer(cur, seconds)
|
||||||
#define ws_common_neighbor_update(cur, ll_address) ((void) 0)
|
#define ws_common_neighbor_update(cur, ll_address) ((void) 0)
|
||||||
|
#define ws_common_aro_failure(cur, ll_address)
|
||||||
#define ws_common_fast_timer(cur, ticks) ((void) 0)
|
#define ws_common_fast_timer(cur, ticks) ((void) 0)
|
||||||
|
#define ws_common_allow_child_registration(cur) (false)
|
||||||
|
|
||||||
|
|
||||||
#endif //HAVE_WS
|
#endif //HAVE_WS
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
* Copyright (c) 2018-2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
#define WH_IE_RSL_TYPE 4 /**< Received Signal Level information */
|
#define WH_IE_RSL_TYPE 4 /**< Received Signal Level information */
|
||||||
#define WH_IE_MHDS_TYPE 5 /**< MHDS information for mesh routing */
|
#define WH_IE_MHDS_TYPE 5 /**< MHDS information for mesh routing */
|
||||||
#define WH_IE_VH_TYPE 6 /**< Vendor header information */
|
#define WH_IE_VH_TYPE 6 /**< Vendor header information */
|
||||||
|
#define WH_IE_EA_TYPE 9 /**< Eapol Auhtenticator EUI-64 header information */
|
||||||
|
|
||||||
#define WS_WP_NESTED_IE 4 /**< WS nested Payload IE element'selement could include mltiple sub payload IE */
|
#define WS_WP_NESTED_IE 4 /**< WS nested Payload IE element'selement could include mltiple sub payload IE */
|
||||||
|
|
||||||
|
@ -215,12 +216,28 @@ typedef struct ws_bs_ie {
|
||||||
*/
|
*/
|
||||||
#define WS_RPL_DIS_TIMEOUT 1800
|
#define WS_RPL_DIS_TIMEOUT 1800
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MAC Ack wait duration in symbols. 2-FSK modulation used -> 1 bit per symbol.
|
||||||
|
*/
|
||||||
|
#define WS_ACK_WAIT_SYMBOLS 800
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tack max time in milliseconds.
|
||||||
|
*/
|
||||||
|
#define WS_TACK_MAX_MS 5
|
||||||
|
|
||||||
/* Default FHSS timing information
|
/* Default FHSS timing information
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#define WS_FHSS_UC_DWELL_INTERVAL 250;
|
#define WS_FHSS_UC_DWELL_INTERVAL 255;
|
||||||
#define WS_FHSS_BC_INTERVAL 800;
|
#define WS_FHSS_BC_INTERVAL 1020;
|
||||||
#define WS_FHSS_BC_DWELL_INTERVAL 200;
|
#define WS_FHSS_BC_DWELL_INTERVAL 255;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* EAPOL relay and PAE authenticator socket settings
|
||||||
|
*/
|
||||||
|
#define EAPOL_RELAY_SOCKET_PORT 10253
|
||||||
|
#define BR_EAPOL_RELAY_SOCKET_PORT 10255
|
||||||
|
#define PAE_AUTH_SOCKET_PORT 10254
|
||||||
|
|
||||||
#endif /* WS_COMMON_DEFINES_H_ */
|
#endif /* WS_COMMON_DEFINES_H_ */
|
||||||
|
|
|
@ -0,0 +1,124 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2019, 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 WS_CONFIG_H_
|
||||||
|
#define WS_CONFIG_H_
|
||||||
|
|
||||||
|
|
||||||
|
/*RPL parameters for DIO messages
|
||||||
|
*
|
||||||
|
* Small scale spec recomendation imin 15, doubling 2, redudancy 0
|
||||||
|
* Small scale values imin 14, doubling 3, redudancy 0
|
||||||
|
* Large scale network imin 19, doubling 1, redudancy 1
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define WS_RPL_DIO_IMIN 14
|
||||||
|
#define WS_RPL_DIO_DOUBLING 3
|
||||||
|
#define WS_RPL_DIO_REDUNDANCY 0
|
||||||
|
|
||||||
|
|
||||||
|
/* Border router version change interval
|
||||||
|
*
|
||||||
|
* Minimum interval at which a Border Router shall increment its PAN Version value.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define PAN_VERSION_LIFETIME 240
|
||||||
|
|
||||||
|
#define RPL_VERSION_LIFETIME 5*3600
|
||||||
|
|
||||||
|
/* Border router connection lost timeout
|
||||||
|
*
|
||||||
|
* Interval within which a node expects to detect a change in PAN Version
|
||||||
|
* (delivered via a PAN Configuration frame / PAN-IE).
|
||||||
|
*
|
||||||
|
* the maximum Trickle interval specified for DISC_IMAX (32 minutes).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define PAN_VERSION_TIMEOUT 1920
|
||||||
|
|
||||||
|
/* Routing Cost Weighting factor
|
||||||
|
*/
|
||||||
|
#define PRC_WEIGHT_FACTOR 256
|
||||||
|
|
||||||
|
/* Routing Cost Weighting factor
|
||||||
|
*/
|
||||||
|
#define PS_WEIGHT_FACTOR 64
|
||||||
|
|
||||||
|
/* Smoothing factor for RSL calculation 1/8
|
||||||
|
*/
|
||||||
|
#define WS_RSL_SCALING 3
|
||||||
|
|
||||||
|
/* Device min sensitivity. This value is dynamically configured and depends on radio
|
||||||
|
*
|
||||||
|
* Default value for us is -93
|
||||||
|
*/
|
||||||
|
extern int8_t DEVICE_MIN_SENS;
|
||||||
|
|
||||||
|
/* Candidate parent Threshold
|
||||||
|
*/
|
||||||
|
#define CAND_PARENT_THRESHOLD 10
|
||||||
|
|
||||||
|
/* Candidate parent Threshold hysteresis
|
||||||
|
*/
|
||||||
|
#define CAND_PARENT_HYSTERISIS 3
|
||||||
|
|
||||||
|
/* Maximum amount of Pan Configuration Solicits before restarting Discovery.
|
||||||
|
*/
|
||||||
|
#define PCS_MAX 5
|
||||||
|
|
||||||
|
|
||||||
|
/* Multicast MPL data message parameters
|
||||||
|
* IMIN = 10 seconds, IMAX = 3 doublings
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define DATA_MESSAGE_IMIN (10 * 1000)
|
||||||
|
#define DATA_MESSAGE_TIMER_EXPIRATIONS 3
|
||||||
|
#define DATA_MESSAGE_IMAX (DATA_MESSAGE_IMIN)
|
||||||
|
#define MPL_SEED_SET_ENTRY_TIMEOUT (DATA_MESSAGE_IMAX * 24 * 4 / 1000) // 10 seconds per hop making this 240 seconds
|
||||||
|
|
||||||
|
/* DHCP client timeout configuration values
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define WS_DHCP_SOLICIT_TIMEOUT 60
|
||||||
|
#define WS_DHCP_SOLICIT_MAX_RT 3600
|
||||||
|
#define WS_DHCP_SOLICIT_MAX_RC 0
|
||||||
|
|
||||||
|
|
||||||
|
/* Neighbour table configuration
|
||||||
|
*
|
||||||
|
* Amount of RPL candidate parents
|
||||||
|
* Amount of ND reply entries left
|
||||||
|
* rest are used as child count, but is related to neighbour table size
|
||||||
|
*/
|
||||||
|
#define WS_RPL_CANDIDATE_PARENT_COUNT 3 // Largest possible value
|
||||||
|
#define WS_TEMPORARY_NEIGHBOUR_ENTRIES 7
|
||||||
|
#define WS_NON_CHILD_NEIGHBOUR_COUNT (WS_RPL_CANDIDATE_PARENT_COUNT + WS_TEMPORARY_NEIGHBOUR_ENTRIES)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Neighbour blacklist timers
|
||||||
|
*/
|
||||||
|
#define WS_BLACKLIST_ENTRY_LIFETIME 60*30 // initial value for reject
|
||||||
|
#define WS_BLACKLIST_TIMER_MAX_TIMEOUT 60*60 // Can increase to this
|
||||||
|
#define WS_BLACKLIST_TIMER_TIMEOUT 60*30 // Blacklist is valid this time after first accept
|
||||||
|
#define WS_BLACKLIST_ENTRY_MAX_NBR 10
|
||||||
|
#define WS_BLACKLIST_PURGE_NBR 3
|
||||||
|
#define WS_BLACKLIST_PURGE_TIMER_TIMEOUT 60
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* WS_CONFIG_H_ */
|
|
@ -0,0 +1,205 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2019, 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"
|
||||||
|
#include <string.h>
|
||||||
|
#include "ns_types.h"
|
||||||
|
#include "ns_list.h"
|
||||||
|
#include "ns_trace.h"
|
||||||
|
#include "nsdynmemLIB.h"
|
||||||
|
#include "fhss_config.h"
|
||||||
|
#include "NWK_INTERFACE/Include/protocol.h"
|
||||||
|
#include "mac_api.h"
|
||||||
|
#include "mac_mcps.h"
|
||||||
|
#include "Common_Protocols/ipv6_constants.h"
|
||||||
|
#include "socket_api.h"
|
||||||
|
#include "6LoWPAN/MAC/mac_helper.h"
|
||||||
|
#include "6LoWPAN/MAC/mpx_api.h"
|
||||||
|
#include "6LoWPAN/ws/ws_config.h"
|
||||||
|
#include "6LoWPAN/ws/ws_eapol_pdu.h"
|
||||||
|
#include "6LoWPAN/ws/ws_eapol_relay_lib.h"
|
||||||
|
#include "6LoWPAN/ws/ws_eapol_auth_relay.h"
|
||||||
|
#include "common_functions.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_WS
|
||||||
|
#ifdef HAVE_PAE_AUTH
|
||||||
|
|
||||||
|
#define TRACE_GROUP "wsar"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
protocol_interface_info_entry_t *interface_ptr; /**< Interface pointer */
|
||||||
|
ns_address_t remote_addr; /**< Remote address and port */
|
||||||
|
ns_address_t relay_addr; /**< Relay address */
|
||||||
|
int8_t socket_id; /**< Socket ID for relay */
|
||||||
|
ns_list_link_t link; /**< Link */
|
||||||
|
} eapol_auth_relay_t;
|
||||||
|
|
||||||
|
static eapol_auth_relay_t *ws_eapol_auth_relay_get(protocol_interface_info_entry_t *interface_ptr);
|
||||||
|
static void ws_eapol_auth_relay_socket_cb(void *cb);
|
||||||
|
static int8_t ws_eapol_auth_relay_send_to_kmp(eapol_auth_relay_t *eapol_auth_relay, const uint8_t *eui_64, const uint8_t *ip_addr, uint16_t port, const void *data, uint16_t data_len);
|
||||||
|
|
||||||
|
static NS_LIST_DEFINE(eapol_auth_relay_list, eapol_auth_relay_t, link);
|
||||||
|
|
||||||
|
int8_t ws_eapol_auth_relay_start(protocol_interface_info_entry_t *interface_ptr, uint16_t local_port, const uint8_t *remote_addr, uint16_t remote_port)
|
||||||
|
{
|
||||||
|
if (!interface_ptr || !remote_addr) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ws_eapol_auth_relay_get(interface_ptr)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
eapol_auth_relay_t *eapol_auth_relay = ns_dyn_mem_alloc(sizeof(eapol_auth_relay_t));
|
||||||
|
if (!eapol_auth_relay) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
eapol_auth_relay->interface_ptr = interface_ptr;
|
||||||
|
|
||||||
|
eapol_auth_relay->remote_addr.type = ADDRESS_IPV6;
|
||||||
|
memcpy(&eapol_auth_relay->relay_addr.address, remote_addr, 16);
|
||||||
|
eapol_auth_relay->relay_addr.identifier = remote_port;
|
||||||
|
|
||||||
|
eapol_auth_relay->socket_id = socket_open(IPV6_NH_UDP, local_port, &ws_eapol_auth_relay_socket_cb);
|
||||||
|
if (eapol_auth_relay->socket_id < 0) {
|
||||||
|
ns_dyn_mem_free(eapol_auth_relay);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ns_list_add_to_end(&eapol_auth_relay_list, eapol_auth_relay);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t ws_eapol_auth_relay_delete(protocol_interface_info_entry_t *interface_ptr)
|
||||||
|
{
|
||||||
|
if (!interface_ptr) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
eapol_auth_relay_t *eapol_auth_relay = ws_eapol_auth_relay_get(interface_ptr);
|
||||||
|
if (!eapol_auth_relay) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
socket_close(eapol_auth_relay->socket_id);
|
||||||
|
|
||||||
|
ns_list_remove(&eapol_auth_relay_list, eapol_auth_relay);
|
||||||
|
ns_dyn_mem_free(eapol_auth_relay);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static eapol_auth_relay_t *ws_eapol_auth_relay_get(protocol_interface_info_entry_t *interface_ptr)
|
||||||
|
{
|
||||||
|
ns_list_foreach(eapol_auth_relay_t, entry, &eapol_auth_relay_list) {
|
||||||
|
if (entry->interface_ptr == interface_ptr) {
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ws_eapol_auth_relay_socket_cb(void *cb)
|
||||||
|
{
|
||||||
|
socket_callback_t *cb_data = cb;
|
||||||
|
|
||||||
|
if (cb_data->event_type != SOCKET_DATA) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
eapol_auth_relay_t *eapol_auth_relay = NULL;
|
||||||
|
|
||||||
|
ns_list_foreach(eapol_auth_relay_t, entry, &eapol_auth_relay_list) {
|
||||||
|
if (entry->socket_id == cb_data->socket_id) {
|
||||||
|
eapol_auth_relay = entry;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!eapol_auth_relay) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *socket_pdu = ns_dyn_mem_temporary_alloc(cb_data->d_len);
|
||||||
|
if (!socket_pdu) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ns_address_t src_addr;
|
||||||
|
|
||||||
|
if (socket_recvfrom(cb_data->socket_id, socket_pdu, cb_data->d_len, 0, &src_addr) != cb_data->d_len) {
|
||||||
|
ns_dyn_mem_free(socket_pdu);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Message from source port 10254 (KMP service) -> to IP relay on node or on authenticator
|
||||||
|
if (src_addr.identifier == eapol_auth_relay->relay_addr.identifier) {
|
||||||
|
uint8_t *ptr = socket_pdu;
|
||||||
|
uint8_t *eui_64;
|
||||||
|
ns_address_t relay_ip_addr;
|
||||||
|
relay_ip_addr.type = ADDRESS_IPV6;
|
||||||
|
memcpy(relay_ip_addr.address, ptr, 16);
|
||||||
|
ptr += 16;
|
||||||
|
relay_ip_addr.identifier = common_read_16_bit(ptr);
|
||||||
|
ptr += 2;
|
||||||
|
eui_64 = ptr;
|
||||||
|
ptr += 8;
|
||||||
|
uint16_t data_len = cb_data->d_len - 26;
|
||||||
|
ws_eapol_relay_lib_send_to_relay(eapol_auth_relay->socket_id, eui_64, &relay_ip_addr,
|
||||||
|
ptr, data_len);
|
||||||
|
ns_dyn_mem_free(socket_pdu);
|
||||||
|
// Other source port (either 10253 or node relay source port) -> to KMP service
|
||||||
|
} else {
|
||||||
|
uint8_t *ptr = socket_pdu;
|
||||||
|
ws_eapol_auth_relay_send_to_kmp(eapol_auth_relay, ptr, src_addr.address, src_addr.identifier,
|
||||||
|
ptr + 8, cb_data->d_len - 8);
|
||||||
|
ns_dyn_mem_free(socket_pdu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int8_t ws_eapol_auth_relay_send_to_kmp(eapol_auth_relay_t *eapol_auth_relay, const uint8_t *eui_64, const uint8_t *ip_addr, uint16_t port, const void *data, uint16_t data_len)
|
||||||
|
{
|
||||||
|
ns_address_t dest_addr = eapol_auth_relay->relay_addr;
|
||||||
|
|
||||||
|
uint8_t temp_array[26];
|
||||||
|
ns_iovec_t msg_iov[2];
|
||||||
|
ns_msghdr_t msghdr;
|
||||||
|
//Set messages name buffer
|
||||||
|
msghdr.msg_name = &dest_addr;
|
||||||
|
msghdr.msg_namelen = sizeof(dest_addr);
|
||||||
|
msghdr.msg_iov = &msg_iov[0];
|
||||||
|
msghdr.msg_iovlen = 2;
|
||||||
|
msghdr.msg_control = NULL;
|
||||||
|
msghdr.msg_controllen = 0;
|
||||||
|
uint8_t *ptr = temp_array;
|
||||||
|
memcpy(ptr, ip_addr, 16);
|
||||||
|
ptr += 16;
|
||||||
|
ptr = common_write_16_bit(port, ptr);
|
||||||
|
memcpy(ptr, eui_64, 8);
|
||||||
|
msg_iov[0].iov_base = temp_array;
|
||||||
|
msg_iov[0].iov_len = 26;
|
||||||
|
msg_iov[1].iov_base = (void *)data;
|
||||||
|
msg_iov[1].iov_len = data_len;
|
||||||
|
socket_sendmsg(eapol_auth_relay->socket_id, &msghdr, NS_MSG_LEGACY0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HAVE_PAE_AUTH */
|
||||||
|
#endif /* HAVE_WS */
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2019, 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 WS_EAPOL_AUTH_RELAY_H_
|
||||||
|
#define WS_EAPOL_AUTH_RELAY_H_
|
||||||
|
|
||||||
|
#ifdef HAVE_PAE_AUTH
|
||||||
|
|
||||||
|
/*
|
||||||
|
* EAPOL authenticator relay acts as a proxy between EAPOL UDP relay and
|
||||||
|
* authenticator PAE (KMP service). Relay is bound by default to EAPOL UDP
|
||||||
|
* relay port 10253 (set by local port parameter) and transfers messages
|
||||||
|
* to/from authenticator PAE. As default PAE is bound to UDP port 10254
|
||||||
|
* (set by remote address and port parameters).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ws_eapol_auth_relay_start start authenticator relay
|
||||||
|
*
|
||||||
|
* \param interface_ptr interface
|
||||||
|
* \param local_port local port
|
||||||
|
* \param remote_addr remote address
|
||||||
|
* \param remote_port remote port
|
||||||
|
*
|
||||||
|
* \return < 0 failure
|
||||||
|
* \return >= 0 success
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int8_t ws_eapol_auth_relay_start(protocol_interface_info_entry_t *interface_ptr, uint16_t local_port, const uint8_t *remote_addr, uint16_t remote_port);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ws_eapol_auth_relay_delete delete authenticator relay
|
||||||
|
*
|
||||||
|
* \param interface_ptr interface
|
||||||
|
*
|
||||||
|
* \return < 0 failure
|
||||||
|
* \return >= 0 success
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int8_t ws_eapol_auth_relay_delete(protocol_interface_info_entry_t *interface_ptr);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define ws_eapol_auth_relay_start(interface_ptr, local_port, remote_addr, remote_port)
|
||||||
|
#define ws_eapol_auth_relay_delete(interface_ptr)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* WS_EAPOL_AUTH_RELAY_H_ */
|
|
@ -0,0 +1,315 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2019, 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"
|
||||||
|
#include <string.h>
|
||||||
|
#include "ns_types.h"
|
||||||
|
#include "ns_list.h"
|
||||||
|
#include "ns_trace.h"
|
||||||
|
#include "nsdynmemLIB.h"
|
||||||
|
#include "fhss_config.h"
|
||||||
|
#include "NWK_INTERFACE/Include/protocol.h"
|
||||||
|
#include "mac_api.h"
|
||||||
|
#include "mac_mcps.h"
|
||||||
|
#include "Common_Protocols/ipv6_constants.h"
|
||||||
|
#include "socket_api.h"
|
||||||
|
#include "6LoWPAN/MAC/mac_helper.h"
|
||||||
|
#include "6LoWPAN/MAC/mpx_api.h"
|
||||||
|
#include "6LoWPAN/ws/ws_config.h"
|
||||||
|
#include "6LoWPAN/ws/ws_eapol_pdu.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_WS
|
||||||
|
|
||||||
|
#define TRACE_GROUP "wsep"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t handle;
|
||||||
|
void *data_ptr;
|
||||||
|
void *buffer;
|
||||||
|
ns_list_link_t link;
|
||||||
|
} eapol_pdu_msdu_t;
|
||||||
|
|
||||||
|
typedef NS_LIST_HEAD(eapol_pdu_msdu_t, link) eapol_pdu_msdu_list_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t priority;
|
||||||
|
ws_eapol_pdu_address_check *addr_check;
|
||||||
|
ws_eapol_pdu_receive *receive;
|
||||||
|
ns_list_link_t link;
|
||||||
|
} eapol_pdu_recv_cb_t;
|
||||||
|
|
||||||
|
typedef NS_LIST_HEAD(eapol_pdu_recv_cb_t, link) eapol_pdu_recv_cb_list_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
eapol_pdu_recv_cb_list_t recv_cb_list; /**< List of receive callbacks */
|
||||||
|
eapol_pdu_msdu_list_t msdu_list; /**< MSDU list */
|
||||||
|
ws_eapol_pdu_receive *receive; /**< data receive callback */
|
||||||
|
protocol_interface_info_entry_t *interface_ptr; /**< Interface pointer */
|
||||||
|
mpx_api_t *mpx_api; /**< MPX api */
|
||||||
|
uint16_t mpx_user_id; /**< MPX user identifier */
|
||||||
|
uint8_t msdu_handle; /**< MSDU handle */
|
||||||
|
ns_list_link_t link; /**< Link */
|
||||||
|
} eapol_pdu_data_t;
|
||||||
|
|
||||||
|
static void ws_eapol_pdu_mpx_data_confirm(const mpx_api_t *api, const struct mcps_data_conf_s *data);
|
||||||
|
static void ws_eapol_pdu_mpx_data_indication(const mpx_api_t *api, const struct mcps_data_ind_s *data);
|
||||||
|
static void ws_eapol_pdu_data_request_primitiv_set(mcps_data_req_t *dataReq, protocol_interface_info_entry_t *cur);
|
||||||
|
static eapol_pdu_data_t *ws_eapol_pdu_data_get(protocol_interface_info_entry_t *interface_ptr);
|
||||||
|
|
||||||
|
static NS_LIST_DEFINE(eapol_pdu_data_list, eapol_pdu_data_t, link);
|
||||||
|
|
||||||
|
int8_t ws_eapol_pdu_init(protocol_interface_info_entry_t *interface_ptr)
|
||||||
|
{
|
||||||
|
if (!interface_ptr) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ws_eapol_pdu_data_get(interface_ptr) != NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
eapol_pdu_data_t *eapol_pdu_data = ns_dyn_mem_alloc(sizeof(eapol_pdu_data_t));
|
||||||
|
if (!eapol_pdu_data) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
eapol_pdu_data->interface_ptr = interface_ptr;
|
||||||
|
ns_list_init(&eapol_pdu_data->recv_cb_list);
|
||||||
|
ns_list_init(&eapol_pdu_data->msdu_list);
|
||||||
|
eapol_pdu_data->msdu_handle = 0;
|
||||||
|
|
||||||
|
ns_list_add_to_end(&eapol_pdu_data_list, eapol_pdu_data);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t ws_eapol_pdu_delete(protocol_interface_info_entry_t *interface_ptr)
|
||||||
|
{
|
||||||
|
if (!interface_ptr) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
eapol_pdu_data_t *eapol_pdu_data = ws_eapol_pdu_data_get(interface_ptr);
|
||||||
|
|
||||||
|
if (!eapol_pdu_data) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ns_list_foreach_safe(eapol_pdu_recv_cb_t, cb_entry, &eapol_pdu_data->recv_cb_list) {
|
||||||
|
ns_list_remove(&eapol_pdu_data->recv_cb_list, cb_entry);
|
||||||
|
ns_dyn_mem_free(cb_entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
ns_list_foreach_safe(eapol_pdu_msdu_t, msdu_entry, &eapol_pdu_data->msdu_list) {
|
||||||
|
ns_list_remove(&eapol_pdu_data->msdu_list, msdu_entry);
|
||||||
|
ns_dyn_mem_free(msdu_entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
ns_list_remove(&eapol_pdu_data_list, eapol_pdu_data);
|
||||||
|
ns_dyn_mem_free(eapol_pdu_data);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t ws_eapol_pdu_cb_register(protocol_interface_info_entry_t *interface_ptr, const eapol_pdu_recv_cb_data_t *cb_data)
|
||||||
|
{
|
||||||
|
if (!interface_ptr || !cb_data) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
eapol_pdu_data_t *eapol_pdu_data = ws_eapol_pdu_data_get(interface_ptr);
|
||||||
|
|
||||||
|
if (!eapol_pdu_data) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
eapol_pdu_recv_cb_t *new_cb = ns_dyn_mem_alloc(sizeof(eapol_pdu_recv_cb_t));
|
||||||
|
if (!new_cb) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_cb->priority = cb_data->priority;
|
||||||
|
new_cb->addr_check = cb_data->addr_check;
|
||||||
|
new_cb->receive = cb_data->receive;
|
||||||
|
|
||||||
|
ns_list_foreach(eapol_pdu_recv_cb_t, entry, &eapol_pdu_data->recv_cb_list) {
|
||||||
|
if (new_cb->priority <= entry->priority) {
|
||||||
|
ns_list_add_before(&eapol_pdu_data->recv_cb_list, entry, new_cb);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ns_list_add_to_end(&eapol_pdu_data->recv_cb_list, new_cb);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t ws_eapol_pdu_cb_unregister(protocol_interface_info_entry_t *interface_ptr, const eapol_pdu_recv_cb_data_t *cb_data)
|
||||||
|
{
|
||||||
|
if (!interface_ptr || !cb_data) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
eapol_pdu_data_t *eapol_pdu_data = ws_eapol_pdu_data_get(interface_ptr);
|
||||||
|
|
||||||
|
if (!eapol_pdu_data) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ns_list_foreach_safe(eapol_pdu_recv_cb_t, entry, &eapol_pdu_data->recv_cb_list) {
|
||||||
|
if (entry->receive == cb_data->receive) {
|
||||||
|
ns_list_remove(&eapol_pdu_data->recv_cb_list, entry);
|
||||||
|
ns_dyn_mem_free(entry);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t ws_eapol_pdu_send_to_mpx(protocol_interface_info_entry_t *interface_ptr, const uint8_t *eui_64, void *data, uint16_t size, void *buffer)
|
||||||
|
{
|
||||||
|
eapol_pdu_data_t *eapol_pdu_data = ws_eapol_pdu_data_get(interface_ptr);
|
||||||
|
|
||||||
|
if (!eapol_pdu_data) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
mcps_data_req_t data_request;
|
||||||
|
ws_eapol_pdu_data_request_primitiv_set(&data_request, eapol_pdu_data->interface_ptr);
|
||||||
|
|
||||||
|
eapol_pdu_msdu_t *msdu_entry = ns_dyn_mem_temporary_alloc(sizeof(eapol_pdu_msdu_t));
|
||||||
|
if (!msdu_entry) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
msdu_entry->data_ptr = data;
|
||||||
|
msdu_entry->buffer = buffer;
|
||||||
|
msdu_entry->handle = eapol_pdu_data->msdu_handle++;
|
||||||
|
ns_list_add_to_start(&eapol_pdu_data->msdu_list, msdu_entry);
|
||||||
|
|
||||||
|
memcpy(data_request.DstAddr, eui_64, 8);
|
||||||
|
data_request.msdu = data;
|
||||||
|
data_request.msduLength = size;
|
||||||
|
|
||||||
|
eapol_pdu_data->mpx_api->mpx_data_request(eapol_pdu_data->mpx_api, &data_request, eapol_pdu_data->mpx_user_id);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ws_eapol_pdu_data_request_primitiv_set(mcps_data_req_t *dataReq, protocol_interface_info_entry_t *cur)
|
||||||
|
{
|
||||||
|
memset(dataReq, 0, sizeof(mcps_data_req_t));
|
||||||
|
|
||||||
|
dataReq->InDirectTx = false;
|
||||||
|
dataReq->TxAckReq = true;
|
||||||
|
dataReq->SrcAddrMode = ADDR_802_15_4_LONG;
|
||||||
|
dataReq->DstAddrMode = ADDR_802_15_4_LONG;
|
||||||
|
dataReq->DstPANId = mac_helper_panid_get(cur);
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t ws_eapol_pdu_mpx_register(protocol_interface_info_entry_t *interface_ptr, struct mpx_api_s *mpx_api, uint16_t mpx_user_id)
|
||||||
|
{
|
||||||
|
if (!interface_ptr) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
eapol_pdu_data_t *eapol_pdu_data = ws_eapol_pdu_data_get(interface_ptr);
|
||||||
|
|
||||||
|
if (!eapol_pdu_data) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mpx_api && eapol_pdu_data->mpx_api) {
|
||||||
|
//Disable Data Callbacks from MPX Class
|
||||||
|
eapol_pdu_data->mpx_api->mpx_user_registration(eapol_pdu_data->mpx_api, NULL, NULL, eapol_pdu_data->mpx_user_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
eapol_pdu_data->mpx_api = mpx_api;
|
||||||
|
eapol_pdu_data->mpx_user_id = mpx_user_id;
|
||||||
|
|
||||||
|
if (eapol_pdu_data->mpx_api) {
|
||||||
|
eapol_pdu_data->mpx_api->mpx_user_registration(eapol_pdu_data->mpx_api, ws_eapol_pdu_mpx_data_confirm, ws_eapol_pdu_mpx_data_indication, eapol_pdu_data->mpx_user_id);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ws_eapol_pdu_mpx_data_confirm(const mpx_api_t *api, const struct mcps_data_conf_s *data)
|
||||||
|
{
|
||||||
|
eapol_pdu_data_t *eapol_pdu_data = NULL;
|
||||||
|
|
||||||
|
ns_list_foreach(eapol_pdu_data_t, entry, &eapol_pdu_data_list) {
|
||||||
|
if (entry->mpx_api == api) {
|
||||||
|
eapol_pdu_data = entry;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!eapol_pdu_data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ns_list_foreach(eapol_pdu_msdu_t, msdu, &eapol_pdu_data->msdu_list) {
|
||||||
|
if (msdu->handle == data->msduHandle) {
|
||||||
|
ns_dyn_mem_free(msdu->buffer);
|
||||||
|
ns_list_remove(&eapol_pdu_data->msdu_list, msdu);
|
||||||
|
ns_dyn_mem_free(msdu);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ws_eapol_pdu_mpx_data_indication(const mpx_api_t *api, const struct mcps_data_ind_s *data)
|
||||||
|
{
|
||||||
|
if (!data || !data->msduLength || !data->msdu_ptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
eapol_pdu_data_t *eapol_pdu_data = NULL;
|
||||||
|
|
||||||
|
ns_list_foreach(eapol_pdu_data_t, entry, &eapol_pdu_data_list) {
|
||||||
|
if (entry->mpx_api == api) {
|
||||||
|
eapol_pdu_data = entry;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!eapol_pdu_data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ns_list_foreach(eapol_pdu_recv_cb_t, entry, &eapol_pdu_data->recv_cb_list) {
|
||||||
|
if (entry->addr_check(eapol_pdu_data->interface_ptr, data->SrcAddr) >= 0) {
|
||||||
|
entry->receive(eapol_pdu_data->interface_ptr, data->SrcAddr, data->msdu_ptr, data->msduLength);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static eapol_pdu_data_t *ws_eapol_pdu_data_get(protocol_interface_info_entry_t *interface_ptr)
|
||||||
|
{
|
||||||
|
eapol_pdu_data_t *eapol_pdu_data = NULL;
|
||||||
|
|
||||||
|
ns_list_foreach(eapol_pdu_data_t, entry, &eapol_pdu_data_list) {
|
||||||
|
if (entry->interface_ptr == interface_ptr) {
|
||||||
|
eapol_pdu_data = entry;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return eapol_pdu_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HAVE_WS */
|
||||||
|
|
|
@ -0,0 +1,145 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2019, 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 WS_EAPOL_PDU_H_
|
||||||
|
#define WS_EAPOL_PDU_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* EAPOL PDU module transfers EAPOL PDUs to/from MPX. Several users
|
||||||
|
* (e.g. supplicant PAE and EAPOL relay) can register to incoming
|
||||||
|
* EAPOL PDUs. When registering, users need to define priority that
|
||||||
|
* defines in which order incoming EAPOL PDUs are offered to them.
|
||||||
|
*
|
||||||
|
* Incoming EAPOL PDU user callbacks form a pair on EAPOL PDU module:
|
||||||
|
* address check callback is called first, and if it returns match
|
||||||
|
* then incoming EAPOL PDU callback is called.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ws_eapol_pdu_init initialize EAPOL PDU module
|
||||||
|
*
|
||||||
|
* \param interface_ptr interface
|
||||||
|
*
|
||||||
|
* \return < 0 failure
|
||||||
|
* \return >= 0 success
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int8_t ws_eapol_pdu_init(protocol_interface_info_entry_t *interface_ptr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ws_eapol_pdu_mpx_register register EAPOL PDU module to MPX
|
||||||
|
*
|
||||||
|
* \param interface_ptr interface
|
||||||
|
* \param mpx_api MPX API
|
||||||
|
* \param mpx_user_id MPX user id
|
||||||
|
*
|
||||||
|
* \return < 0 failure
|
||||||
|
* \return >= 0 success
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int8_t ws_eapol_pdu_mpx_register(protocol_interface_info_entry_t *interface_ptr, struct mpx_api_s *mpx_api, uint16_t mpx_user_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ws_eapol_pdu_delete delete EAPOL PDU module
|
||||||
|
*
|
||||||
|
* \param interface_ptr interface
|
||||||
|
*
|
||||||
|
* \return < 0 failure
|
||||||
|
* \return >= 0 success
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int8_t ws_eapol_pdu_delete(protocol_interface_info_entry_t *interface_ptr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ws_eapol_pdu_address_check check incoming EAPOL PDU address
|
||||||
|
*
|
||||||
|
* \param interface_ptr interface
|
||||||
|
* \param eui_64 source EUI-64
|
||||||
|
*
|
||||||
|
* \return < 0 address does not match
|
||||||
|
* \return >= 0 address matches, call the PDU receive callback
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef int8_t ws_eapol_pdu_address_check(protocol_interface_info_entry_t *interface_ptr, const uint8_t *eui_64);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ws_eapol_pdu_receive receive EAPOL PDU
|
||||||
|
*
|
||||||
|
* \param interface_ptr interface
|
||||||
|
* \param eui_64 source EUI-64
|
||||||
|
* \param data EAPOL PDU
|
||||||
|
* \param size PDU size
|
||||||
|
*
|
||||||
|
* \return < 0 failure
|
||||||
|
* \return >= 0 success
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef int8_t ws_eapol_pdu_receive(protocol_interface_info_entry_t *interface_ptr, const uint8_t *eui_64, void *data, uint16_t size);
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
EAPOL_PDU_RECV_HIGH_PRIORITY = 0,
|
||||||
|
EAPOL_PDU_RECV_MEDIUM_PRIORITY = 100,
|
||||||
|
EAPOL_PDU_RECV_LOW_PRIORITY = 200
|
||||||
|
} eapol_pdu_recv_prior_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
eapol_pdu_recv_prior_t priority; /**< Priority: high, medium or low */
|
||||||
|
ws_eapol_pdu_address_check *addr_check; /**< Address check callback */
|
||||||
|
ws_eapol_pdu_receive *receive; /**< PDU receive callback */
|
||||||
|
} eapol_pdu_recv_cb_data_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ws_eapol_pdu_cb_register register an incoming EAPOL PDU callback
|
||||||
|
*
|
||||||
|
* \param interface_ptr interface
|
||||||
|
* \param cb_data callback data
|
||||||
|
*
|
||||||
|
* \return < 0 failure
|
||||||
|
* \return >= 0 success
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int8_t ws_eapol_pdu_cb_register(protocol_interface_info_entry_t *interface_ptr, const eapol_pdu_recv_cb_data_t *cb_data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ws_eapol_pdu_cb_unregister unregister an incoming EAPOL PDU callback
|
||||||
|
*
|
||||||
|
* \param interface_ptr interface
|
||||||
|
* \param cb_data callback data
|
||||||
|
*
|
||||||
|
* \return < 0 failure
|
||||||
|
* \return >= 0 success
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int8_t ws_eapol_pdu_cb_unregister(protocol_interface_info_entry_t *interface_ptr, const eapol_pdu_recv_cb_data_t *cb_data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ws_eapol_pdu_send_to_mpx send EAPOL PDU to MPX
|
||||||
|
*
|
||||||
|
* \param interface_ptr interface
|
||||||
|
* \param eui_64 destination EUI-64
|
||||||
|
* \param data EAPOL PDU
|
||||||
|
* \param size PDU size
|
||||||
|
* \param buffer pointer to allocated buffer
|
||||||
|
*
|
||||||
|
* \return < 0 failure
|
||||||
|
* \return >= 0 success
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int8_t ws_eapol_pdu_send_to_mpx(protocol_interface_info_entry_t *interface_ptr, const uint8_t *eui_64, void *data, uint16_t size, void *buffer);
|
||||||
|
|
||||||
|
#endif /* WS_EAPOL_PDU_H_ */
|
|
@ -0,0 +1,193 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2019, 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"
|
||||||
|
#include <string.h>
|
||||||
|
#include "ns_types.h"
|
||||||
|
#include "ns_list.h"
|
||||||
|
#include "ns_trace.h"
|
||||||
|
#include "nsdynmemLIB.h"
|
||||||
|
#include "fhss_config.h"
|
||||||
|
#include "NWK_INTERFACE/Include/protocol.h"
|
||||||
|
#include "mac_api.h"
|
||||||
|
#include "mac_mcps.h"
|
||||||
|
#include "Common_Protocols/ipv6_constants.h"
|
||||||
|
#include "socket_api.h"
|
||||||
|
#include "6LoWPAN/MAC/mac_helper.h"
|
||||||
|
#include "6LoWPAN/MAC/mpx_api.h"
|
||||||
|
#include "6LoWPAN/ws/ws_config.h"
|
||||||
|
#include "6LoWPAN/ws/ws_eapol_pdu.h"
|
||||||
|
#include "6LoWPAN/ws/ws_eapol_relay_lib.h"
|
||||||
|
#include "6LoWPAN/ws/ws_eapol_relay.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_WS
|
||||||
|
#ifdef HAVE_EAPOL_RELAY
|
||||||
|
|
||||||
|
#define TRACE_GROUP "wser"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
protocol_interface_info_entry_t *interface_ptr; /**< Interface pointer */
|
||||||
|
ns_address_t remote_addr; /**< Remote address (border router address) */
|
||||||
|
int8_t socket_id; /**< Socket ID for relay */
|
||||||
|
ns_list_link_t link; /**< Link */
|
||||||
|
} eapol_relay_t;
|
||||||
|
|
||||||
|
static eapol_relay_t *ws_eapol_relay_get(protocol_interface_info_entry_t *interface_ptr);
|
||||||
|
static int8_t ws_eapol_relay_eapol_pdu_address_check(protocol_interface_info_entry_t *interface_ptr, const uint8_t *eui_64);
|
||||||
|
static int8_t ws_eapol_relay_eapol_pdu_receive(protocol_interface_info_entry_t *interface_ptr, const uint8_t *eui_64, void *pdu, uint16_t size);
|
||||||
|
static void ws_eapol_relay_socket_cb(void *cb);
|
||||||
|
|
||||||
|
static const eapol_pdu_recv_cb_data_t eapol_pdu_recv_cb_data = {
|
||||||
|
.priority = EAPOL_PDU_RECV_LOW_PRIORITY,
|
||||||
|
.addr_check = ws_eapol_relay_eapol_pdu_address_check,
|
||||||
|
.receive = ws_eapol_relay_eapol_pdu_receive
|
||||||
|
};
|
||||||
|
|
||||||
|
static NS_LIST_DEFINE(eapol_relay_list, eapol_relay_t, link);
|
||||||
|
|
||||||
|
int8_t ws_eapol_relay_start(protocol_interface_info_entry_t *interface_ptr, uint16_t local_port, const uint8_t *remote_addr, uint16_t remote_port)
|
||||||
|
{
|
||||||
|
if (!interface_ptr || !remote_addr) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ws_eapol_relay_get(interface_ptr)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
eapol_relay_t *eapol_relay = ns_dyn_mem_alloc(sizeof(eapol_relay_t));
|
||||||
|
if (!eapol_relay) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
eapol_relay->interface_ptr = interface_ptr;
|
||||||
|
|
||||||
|
eapol_relay->remote_addr.type = ADDRESS_IPV6;
|
||||||
|
memcpy(&eapol_relay->remote_addr.address, remote_addr, 16);
|
||||||
|
eapol_relay->remote_addr.identifier = remote_port;
|
||||||
|
|
||||||
|
eapol_relay->socket_id = socket_open(IPV6_NH_UDP, local_port, &ws_eapol_relay_socket_cb);
|
||||||
|
if (eapol_relay->socket_id < 0) {
|
||||||
|
ns_dyn_mem_free(eapol_relay);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ws_eapol_pdu_cb_register(interface_ptr, &eapol_pdu_recv_cb_data) < 0) {
|
||||||
|
ns_dyn_mem_free(eapol_relay);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ns_list_add_to_end(&eapol_relay_list, eapol_relay);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t ws_eapol_relay_delete(protocol_interface_info_entry_t *interface_ptr)
|
||||||
|
{
|
||||||
|
if (!interface_ptr) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
eapol_relay_t *eapol_relay = ws_eapol_relay_get(interface_ptr);
|
||||||
|
if (!eapol_relay) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
socket_close(eapol_relay->socket_id);
|
||||||
|
|
||||||
|
ws_eapol_pdu_cb_unregister(interface_ptr, &eapol_pdu_recv_cb_data);
|
||||||
|
|
||||||
|
ns_list_remove(&eapol_relay_list, eapol_relay);
|
||||||
|
ns_dyn_mem_free(eapol_relay);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static eapol_relay_t *ws_eapol_relay_get(protocol_interface_info_entry_t *interface_ptr)
|
||||||
|
{
|
||||||
|
ns_list_foreach(eapol_relay_t, entry, &eapol_relay_list) {
|
||||||
|
if (entry->interface_ptr == interface_ptr) {
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int8_t ws_eapol_relay_eapol_pdu_address_check(protocol_interface_info_entry_t *interface_ptr, const uint8_t *eui_64)
|
||||||
|
{
|
||||||
|
(void) eui_64;
|
||||||
|
(void) interface_ptr;
|
||||||
|
|
||||||
|
// Low priority, always route all here if asked
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int8_t ws_eapol_relay_eapol_pdu_receive(protocol_interface_info_entry_t *interface_ptr, const uint8_t *eui_64, void *pdu, uint16_t size)
|
||||||
|
{
|
||||||
|
eapol_relay_t *eapol_relay = ws_eapol_relay_get(interface_ptr);
|
||||||
|
if (!eapol_relay) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ws_eapol_relay_lib_send_to_relay(eapol_relay->socket_id, eui_64, &eapol_relay->remote_addr, pdu, size);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ws_eapol_relay_socket_cb(void *cb)
|
||||||
|
{
|
||||||
|
socket_callback_t *cb_data = cb;
|
||||||
|
|
||||||
|
if (cb_data->event_type != SOCKET_DATA) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
eapol_relay_t *eapol_relay = NULL;
|
||||||
|
|
||||||
|
ns_list_foreach(eapol_relay_t, entry, &eapol_relay_list) {
|
||||||
|
if (entry->socket_id == cb_data->socket_id) {
|
||||||
|
eapol_relay = entry;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!eapol_relay) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *socket_pdu = ns_dyn_mem_temporary_alloc(cb_data->d_len);
|
||||||
|
if (!socket_pdu) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ns_address_t src_addr;
|
||||||
|
|
||||||
|
if (socket_recvfrom(cb_data->socket_id, socket_pdu, cb_data->d_len, 0, &src_addr) != cb_data->d_len) {
|
||||||
|
ns_dyn_mem_free(socket_pdu);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//First 8 byte is EUID64 and rsr payload
|
||||||
|
if (ws_eapol_pdu_send_to_mpx(eapol_relay->interface_ptr, socket_pdu, socket_pdu + 8, cb_data->d_len - 8, socket_pdu) < 0) {
|
||||||
|
ns_dyn_mem_free(socket_pdu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HAVE_EAPOL_RELAY */
|
||||||
|
#endif /* HAVE_WS */
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2019, 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 WS_EAPOL_RELAY_H_
|
||||||
|
#define WS_EAPOL_RELAY_H_
|
||||||
|
|
||||||
|
#ifdef HAVE_EAPOL_RELAY
|
||||||
|
|
||||||
|
/*
|
||||||
|
* EAPOL relay conveys EAPOL PDUs between authenticator EAPOL relay and local
|
||||||
|
* MPX interface.
|
||||||
|
*
|
||||||
|
* On supplicant (i.e. node) relay should be bound to UDP port 10253 (local
|
||||||
|
* port parameter).
|
||||||
|
*
|
||||||
|
* On authenticator (border router) relay will need to use some other port than
|
||||||
|
* 10253 since authenticator EAPOL relay is bound to port 10253.
|
||||||
|
*
|
||||||
|
* Border router address needs to be set on start (remote address and remote port
|
||||||
|
* parameter).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ws_eapol_relay_start start EAPOL relay
|
||||||
|
*
|
||||||
|
* \param interface_ptr interface
|
||||||
|
* \param local_port local port
|
||||||
|
* \param remote_addr remote address (border router relay address)
|
||||||
|
* \param remote_port remote port (border router relay port)
|
||||||
|
*
|
||||||
|
* \return < 0 failure
|
||||||
|
* \return >= 0 success
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int8_t ws_eapol_relay_start(protocol_interface_info_entry_t *interface_ptr, uint16_t local_port, const uint8_t *remote_addr, uint16_t remote_port);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ws_eapol_relay_delete delete EAPOL
|
||||||
|
*
|
||||||
|
* \param interface_ptr interface
|
||||||
|
*
|
||||||
|
* \return < 0 failure
|
||||||
|
* \return >= 0 success
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int8_t ws_eapol_relay_delete(protocol_interface_info_entry_t *interface_ptr);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define ws_eapol_relay_start(interface_ptr, local_port, remote_addr, remote_port);
|
||||||
|
#define ws_eapol_relay_delete(interface_ptr);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* WS_EAPOL_RELAY_H_ */
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2019, 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"
|
||||||
|
#include <string.h>
|
||||||
|
#include "ns_types.h"
|
||||||
|
#include "ns_list.h"
|
||||||
|
#include "ns_trace.h"
|
||||||
|
#include "socket_api.h"
|
||||||
|
#include "6LoWPAN/ws/ws_config.h"
|
||||||
|
#include "6LoWPAN/ws/ws_eapol_relay_lib.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_WS
|
||||||
|
|
||||||
|
#define TRACE_GROUP "wsrl"
|
||||||
|
|
||||||
|
int8_t ws_eapol_relay_lib_send_to_relay(const uint8_t socket_id, const uint8_t *eui_64, const ns_address_t *dest_addr, const void *data, uint16_t data_len)
|
||||||
|
{
|
||||||
|
ns_address_t addr = *dest_addr;
|
||||||
|
|
||||||
|
ns_iovec_t msg_iov[2];
|
||||||
|
ns_msghdr_t msghdr;
|
||||||
|
//Set messages name buffer
|
||||||
|
msghdr.msg_name = &addr;
|
||||||
|
msghdr.msg_namelen = sizeof(addr);
|
||||||
|
msghdr.msg_iov = &msg_iov[0];
|
||||||
|
msghdr.msg_iovlen = 2;
|
||||||
|
msghdr.msg_control = NULL;
|
||||||
|
msghdr.msg_controllen = 0;
|
||||||
|
msg_iov[0].iov_base = (void *)eui_64;
|
||||||
|
msg_iov[0].iov_len = 8;
|
||||||
|
msg_iov[1].iov_base = (void *)data;
|
||||||
|
msg_iov[1].iov_len = data_len;
|
||||||
|
socket_sendmsg(socket_id, &msghdr, NS_MSG_LEGACY0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HAVE_WS */
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2019, 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 WS_EAPOL_RELAY_LIB_H_
|
||||||
|
#define WS_EAPOL_RELAY_LIB_H_
|
||||||
|
|
||||||
|
int8_t ws_eapol_relay_lib_send_to_relay(const uint8_t socket_id, const uint8_t *eui_64, const ns_address_t *dest_addr, const void *data, uint16_t data_len);
|
||||||
|
|
||||||
|
#endif /* WS_EAPOL_RELAY_LIB_H_ */
|
|
@ -0,0 +1,185 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2019, 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 <string.h>
|
||||||
|
#include "nsconfig.h"
|
||||||
|
#include "ns_types.h"
|
||||||
|
#include "ns_trace.h"
|
||||||
|
#include <ns_list.h>
|
||||||
|
#include <nsdynmemLIB.h>
|
||||||
|
#include "NWK_INTERFACE/Include/protocol.h"
|
||||||
|
#include "6LoWPAN/ws/ws_common.h"
|
||||||
|
|
||||||
|
#include "ws_management_api.h"
|
||||||
|
|
||||||
|
#ifndef HAVE_WS
|
||||||
|
int ws_management_node_init(
|
||||||
|
int8_t interface_id,
|
||||||
|
uint8_t regulatory_domain,
|
||||||
|
char *network_name_ptr,
|
||||||
|
fhss_timer_t *fhss_timer_ptr)
|
||||||
|
{
|
||||||
|
(void)interface_id;
|
||||||
|
(void)regulatory_domain;
|
||||||
|
(void)network_name_ptr;
|
||||||
|
(void)fhss_timer_ptr;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ws_management_regulatory_domain_set(
|
||||||
|
int8_t interface_id,
|
||||||
|
uint8_t regulatory_domain,
|
||||||
|
uint8_t operating_class,
|
||||||
|
uint8_t operating_mode)
|
||||||
|
{
|
||||||
|
(void)interface_id;
|
||||||
|
(void)regulatory_domain;
|
||||||
|
(void)operating_class;
|
||||||
|
(void)operating_mode;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ws_management_network_size_set(
|
||||||
|
int8_t interface_id,
|
||||||
|
uint8_t network_size)
|
||||||
|
{
|
||||||
|
(void)interface_id;
|
||||||
|
(void)network_size;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ws_management_channel_mask_set(
|
||||||
|
int8_t interface_id,
|
||||||
|
uint32_t channel_mask[8])
|
||||||
|
{
|
||||||
|
(void)interface_id;
|
||||||
|
(void)channel_mask;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ws_management_channel_plan_set(
|
||||||
|
int8_t interface_id,
|
||||||
|
uint8_t channel_plan,
|
||||||
|
uint8_t uc_channel_function,
|
||||||
|
uint8_t bc_channel_function,
|
||||||
|
uint32_t ch0_freq, // Stack can not modify this
|
||||||
|
uint8_t channel_spacing,// Stack can not modify this
|
||||||
|
uint8_t number_of_channels)
|
||||||
|
{
|
||||||
|
(void)interface_id;
|
||||||
|
(void)channel_plan;
|
||||||
|
(void)uc_channel_function;
|
||||||
|
(void)bc_channel_function;
|
||||||
|
(void)ch0_freq;
|
||||||
|
(void)channel_spacing;
|
||||||
|
(void)number_of_channels;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ws_management_fhss_timing_configure(
|
||||||
|
int8_t interface_id,
|
||||||
|
uint8_t fhss_uc_dwell_interval,
|
||||||
|
uint32_t fhss_broadcast_interval,
|
||||||
|
uint8_t fhss_bc_dwell_interval)
|
||||||
|
{
|
||||||
|
(void)interface_id;
|
||||||
|
(void)fhss_uc_dwell_interval;
|
||||||
|
(void)fhss_broadcast_interval;
|
||||||
|
(void)fhss_bc_dwell_interval;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ws_management_fhss_unicast_channel_function_configure(
|
||||||
|
int8_t interface_id,
|
||||||
|
uint8_t channel_function,
|
||||||
|
uint16_t fixed_channel,
|
||||||
|
uint8_t dwell_interval)
|
||||||
|
{
|
||||||
|
(void)interface_id;
|
||||||
|
(void)channel_function;
|
||||||
|
(void)fixed_channel;
|
||||||
|
(void)dwell_interval;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ws_management_fhss_broadcast_channel_function_configure(
|
||||||
|
int8_t interface_id,
|
||||||
|
uint8_t channel_function,
|
||||||
|
uint16_t fixed_channel,
|
||||||
|
uint8_t dwell_interval,
|
||||||
|
uint32_t broadcast_interval)
|
||||||
|
{
|
||||||
|
(void)interface_id;
|
||||||
|
(void)channel_function;
|
||||||
|
(void)fixed_channel;
|
||||||
|
(void)dwell_interval;
|
||||||
|
(void)broadcast_interval;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ### test api ### */
|
||||||
|
int ws_test_pan_size_set(int8_t interface_id, uint16_t pan_size)
|
||||||
|
{
|
||||||
|
(void) interface_id;
|
||||||
|
(void) pan_size;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int ws_test_max_child_count_set(int8_t interface_id, uint16_t child_count)
|
||||||
|
{
|
||||||
|
(void) interface_id;
|
||||||
|
(void) child_count;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ws_test_gtk_set(int8_t interface_id, uint8_t *gtk[4])
|
||||||
|
{
|
||||||
|
(void) interface_id;
|
||||||
|
(void) gtk;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ws_test_active_key_set(int8_t interface_id, uint8_t index)
|
||||||
|
{
|
||||||
|
(void) interface_id;
|
||||||
|
(void) index;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ws_test_key_lifetime_set(int8_t interface_id, uint32_t gtk_lifetime, uint32_t pmk_lifetime, uint32_t ptk_lifetime)
|
||||||
|
{
|
||||||
|
(void) interface_id;
|
||||||
|
(void) gtk_lifetime;
|
||||||
|
(void) pmk_lifetime;
|
||||||
|
(void) ptk_lifetime;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ws_test_gtk_time_settings_set(int8_t interface_id, uint8_t revocat_lifetime_reduct, uint8_t new_activation_time, uint32_t max_mismatch)
|
||||||
|
{
|
||||||
|
(void) interface_id;
|
||||||
|
(void) revocat_lifetime_reduct;
|
||||||
|
(void) new_activation_time;
|
||||||
|
(void) max_mismatch;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // no HAVE_WS
|
||||||
|
|
|
@ -0,0 +1,557 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2019, 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"
|
||||||
|
#include <string.h>
|
||||||
|
#include "ns_types.h"
|
||||||
|
#include "ns_list.h"
|
||||||
|
#include "ns_trace.h"
|
||||||
|
#include "common_functions.h"
|
||||||
|
#include "mac_common_defines.h"
|
||||||
|
#include "6LoWPAN/MAC/mac_ie_lib.h"
|
||||||
|
#include "6LoWPAN/ws/ws_common_defines.h"
|
||||||
|
#include "6LoWPAN/ws/ws_ie_lib.h"
|
||||||
|
|
||||||
|
static uint8_t *ws_wh_header_base_write(uint8_t *ptr, uint16_t length, uint8_t type)
|
||||||
|
{
|
||||||
|
ptr = mac_ie_header_base_write(ptr, MAC_HEADER_ASSIGNED_EXTERNAL_ORG_IE_ID, length + 1);
|
||||||
|
*ptr++ = type;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint16_t ws_channel_plan_length(uint8_t channel_plan)
|
||||||
|
{
|
||||||
|
switch (channel_plan) {
|
||||||
|
case 0:
|
||||||
|
//Regulator domain and operationg class inline
|
||||||
|
return 2;
|
||||||
|
case 1:
|
||||||
|
//CHo, Channel spasing and number of channel's inline
|
||||||
|
return 6;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint16_t ws_channel_function_length(uint8_t channel_function, uint16_t hop_channel_count)
|
||||||
|
{
|
||||||
|
switch (channel_function) {
|
||||||
|
case 0:
|
||||||
|
//Fixed channel inline
|
||||||
|
return 2;
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
return 0;
|
||||||
|
case 3:
|
||||||
|
//Hop count + channel hop list
|
||||||
|
return (1 + hop_channel_count);
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t ws_wp_nested_hopping_schedule_length(struct ws_hopping_schedule_s *hopping_schedule, bool unicast_schedule)
|
||||||
|
{
|
||||||
|
uint16_t length;
|
||||||
|
uint8_t channel_function;
|
||||||
|
if (unicast_schedule) {
|
||||||
|
length = 4;
|
||||||
|
channel_function = hopping_schedule->uc_channel_function;
|
||||||
|
} else {
|
||||||
|
length = 10;
|
||||||
|
channel_function = hopping_schedule->bc_channel_function;
|
||||||
|
}
|
||||||
|
|
||||||
|
length += ws_channel_plan_length(hopping_schedule->channel_plan);
|
||||||
|
|
||||||
|
length += ws_channel_function_length(channel_function, 1);
|
||||||
|
|
||||||
|
//Todo Derive some how exluded channel control
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *ws_wh_utt_write(uint8_t *ptr, uint8_t message_type)
|
||||||
|
{
|
||||||
|
ptr = ws_wh_header_base_write(ptr, 4, WH_IE_UTT_TYPE);
|
||||||
|
*ptr++ = message_type;
|
||||||
|
memset(ptr, 0, 3);
|
||||||
|
ptr += 3;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *ws_wh_bt_write(uint8_t *ptr)
|
||||||
|
{
|
||||||
|
ptr = ws_wh_header_base_write(ptr, 5, WH_IE_BT_TYPE);
|
||||||
|
memset(ptr, 0, 5);
|
||||||
|
ptr += 5;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t *ws_wh_fc_write(uint8_t *ptr, uint8_t flow_ctrl)
|
||||||
|
{
|
||||||
|
ptr = ws_wh_header_base_write(ptr, 1, WH_IE_FC_TYPE);
|
||||||
|
*ptr++ = flow_ctrl;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *ws_wh_rsl_write(uint8_t *ptr, int8_t rssi)
|
||||||
|
{
|
||||||
|
ptr = ws_wh_header_base_write(ptr, 1, WH_IE_RSL_TYPE);
|
||||||
|
*ptr++ = rssi;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *ws_wh_ea_write(uint8_t *ptr, uint8_t *eui64)
|
||||||
|
{
|
||||||
|
ptr = ws_wh_header_base_write(ptr, 8, WH_IE_EA_TYPE);
|
||||||
|
memcpy(ptr, eui64, 8);
|
||||||
|
ptr += 8;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *ws_wh_vh_write(uint8_t *ptr, uint8_t *vendor_header, uint8_t vendor_header_length)
|
||||||
|
{
|
||||||
|
ptr = ws_wh_header_base_write(ptr, vendor_header_length, WH_IE_VH_TYPE);
|
||||||
|
if (vendor_header_length) {
|
||||||
|
memcpy(ptr, vendor_header, vendor_header_length);
|
||||||
|
ptr += vendor_header_length;
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *ws_wp_base_write(uint8_t *ptr, uint16_t length)
|
||||||
|
{
|
||||||
|
return mac_ie_payload_base_write(ptr, WS_WP_NESTED_IE, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *ws_wp_nested_hopping_schedule_write(uint8_t *ptr, struct ws_hopping_schedule_s *hopping_schedule, bool unicast_schedule)
|
||||||
|
{
|
||||||
|
//Calculate length
|
||||||
|
uint16_t length = ws_wp_nested_hopping_schedule_length(hopping_schedule, unicast_schedule);
|
||||||
|
if (!unicast_schedule) {
|
||||||
|
ptr = mac_ie_nested_ie_long_base_write(ptr, WP_PAYLOAD_IE_BS_TYPE, length);
|
||||||
|
ptr = common_write_32_bit_inverse(hopping_schedule->fhss_broadcast_interval, ptr);
|
||||||
|
ptr = common_write_16_bit_inverse(hopping_schedule->fhss_bsi, ptr);
|
||||||
|
*ptr++ = hopping_schedule->fhss_bc_dwell_interval;
|
||||||
|
} else {
|
||||||
|
ptr = mac_ie_nested_ie_long_base_write(ptr, WP_PAYLOAD_IE_US_TYPE, length);
|
||||||
|
*ptr++ = hopping_schedule->fhss_uc_dwell_interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ptr++ = hopping_schedule->clock_drift;
|
||||||
|
*ptr++ = hopping_schedule->timing_accurancy;
|
||||||
|
uint8_t channel_info_base = 0;
|
||||||
|
channel_info_base = (hopping_schedule->channel_plan);
|
||||||
|
if (unicast_schedule) {
|
||||||
|
channel_info_base |= (hopping_schedule->uc_channel_function << 3);
|
||||||
|
} else {
|
||||||
|
channel_info_base |= (hopping_schedule->bc_channel_function << 3);
|
||||||
|
}
|
||||||
|
//Todo define excluded channel ctrl
|
||||||
|
|
||||||
|
*ptr++ = channel_info_base;
|
||||||
|
|
||||||
|
switch (hopping_schedule->channel_plan) {
|
||||||
|
case 0:
|
||||||
|
//Regulator domain and operationg class inline
|
||||||
|
*ptr++ = hopping_schedule->regulatory_domain;
|
||||||
|
*ptr++ = hopping_schedule->operating_class;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
//CHo, Channel spasing and number of channel's inline
|
||||||
|
ptr = common_write_24_bit(hopping_schedule->fhss_uc_dwell_interval, ptr);
|
||||||
|
*ptr++ = ((hopping_schedule->channel_spacing << 4) & 0xf0);
|
||||||
|
ptr = common_write_16_bit(hopping_schedule->number_of_channels, ptr);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
uint8_t cf = hopping_schedule->uc_channel_function;
|
||||||
|
uint16_t fixed_channel = hopping_schedule->uc_fixed_channel;
|
||||||
|
if (!unicast_schedule) {
|
||||||
|
cf = hopping_schedule->bc_channel_function;
|
||||||
|
}
|
||||||
|
switch (cf) {
|
||||||
|
case 0:
|
||||||
|
//Fixed channel inline
|
||||||
|
if (!unicast_schedule) {
|
||||||
|
fixed_channel = hopping_schedule->bc_fixed_channel;
|
||||||
|
}
|
||||||
|
ptr = common_write_16_bit_inverse(fixed_channel, ptr);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
//No Inline
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
//TODO do this properly
|
||||||
|
//Hop count + channel hop list
|
||||||
|
*ptr++ = 1;
|
||||||
|
*ptr++ = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *ws_wp_nested_vp_write(uint8_t *ptr, uint8_t *vendor_payload, uint16_t vendor_payload_length)
|
||||||
|
{
|
||||||
|
if (vendor_payload_length) {
|
||||||
|
ptr = mac_ie_nested_ie_long_base_write(ptr, WP_PAYLOAD_IE_VP_TYPE, vendor_payload_length);
|
||||||
|
memcpy(ptr, vendor_payload, vendor_payload_length);
|
||||||
|
ptr += vendor_payload_length;
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *ws_wp_nested_pan_info_write(uint8_t *ptr, struct ws_pan_information_s *pan_congiguration)
|
||||||
|
{
|
||||||
|
if (!pan_congiguration) {
|
||||||
|
return mac_ie_nested_ie_short_base_write(ptr, WP_PAYLOAD_IE_PAN_TYPE, 0);
|
||||||
|
}
|
||||||
|
ptr = mac_ie_nested_ie_short_base_write(ptr, WP_PAYLOAD_IE_PAN_TYPE, 5);
|
||||||
|
ptr = common_write_16_bit_inverse(pan_congiguration->pan_size, ptr);
|
||||||
|
ptr = common_write_16_bit_inverse(pan_congiguration->routing_cost, ptr);
|
||||||
|
uint8_t temp8 = 0;
|
||||||
|
temp8 |= (pan_congiguration->use_parent_bs << 0);
|
||||||
|
temp8 |= (pan_congiguration->rpl_routing_method << 1);
|
||||||
|
temp8 |= pan_congiguration->version << 5;
|
||||||
|
*ptr++ = temp8;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t *ws_wp_nested_netname_write(uint8_t *ptr, uint8_t *network_name, uint8_t network_name_length)
|
||||||
|
{
|
||||||
|
ptr = mac_ie_nested_ie_short_base_write(ptr, WP_PAYLOAD_IE_NETNAME_TYPE, network_name_length);
|
||||||
|
if (network_name_length) {
|
||||||
|
memcpy(ptr, network_name, network_name_length);
|
||||||
|
ptr += network_name_length;
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *ws_wp_nested_pan_ver_write(uint8_t *ptr, struct ws_pan_information_s *pan_congiguration)
|
||||||
|
{
|
||||||
|
if (!pan_congiguration) {
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
ptr = mac_ie_nested_ie_short_base_write(ptr, WP_PAYLOAD_IE_PAN_VER_TYPE, 2);
|
||||||
|
return common_write_16_bit_inverse(pan_congiguration->pan_version, ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *ws_wp_nested_gtkhash_write(uint8_t *ptr, uint8_t *gtkhash, uint8_t gtkhash_length)
|
||||||
|
{
|
||||||
|
ptr = mac_ie_nested_ie_short_base_write(ptr, WP_PAYLOAD_IE_GTKHASH_TYPE, gtkhash_length);
|
||||||
|
if (gtkhash_length) {
|
||||||
|
memcpy(ptr, gtkhash, 32);
|
||||||
|
ptr += 32;
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ws_wh_utt_read(uint8_t *data, uint16_t length, struct ws_utt_ie *utt_ie)
|
||||||
|
{
|
||||||
|
mac_header_IE_t utt_ie_data;
|
||||||
|
utt_ie_data.id = MAC_HEADER_ASSIGNED_EXTERNAL_ORG_IE_ID;
|
||||||
|
if (4 != mac_ie_header_sub_id_discover(data, length, &utt_ie_data, WH_IE_UTT_TYPE)) {
|
||||||
|
// NO UTT header
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
data = utt_ie_data.content_ptr;
|
||||||
|
utt_ie->message_type = *data++;
|
||||||
|
utt_ie->ufsi = common_read_24_bit_inverse(data);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ws_wh_bt_read(uint8_t *data, uint16_t length, struct ws_bt_ie *bt_ie)
|
||||||
|
{
|
||||||
|
mac_header_IE_t btt_ie_data;
|
||||||
|
btt_ie_data.id = MAC_HEADER_ASSIGNED_EXTERNAL_ORG_IE_ID;
|
||||||
|
if (5 != mac_ie_header_sub_id_discover(data, length, &btt_ie_data, WH_IE_BT_TYPE)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
data = btt_ie_data.content_ptr;
|
||||||
|
bt_ie->broadcast_slot_number = common_read_16_bit_inverse(data);
|
||||||
|
bt_ie->broadcast_interval_offset = common_read_24_bit_inverse(data + 2);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ws_wh_rsl_read(uint8_t *data, uint16_t length, int8_t *rsl)
|
||||||
|
{
|
||||||
|
mac_header_IE_t rsl_ie_data;
|
||||||
|
rsl_ie_data.id = MAC_HEADER_ASSIGNED_EXTERNAL_ORG_IE_ID;
|
||||||
|
if (1 != mac_ie_header_sub_id_discover(data, length, &rsl_ie_data, WH_IE_RSL_TYPE)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*rsl = *rsl_ie_data.content_ptr;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ws_wh_ea_read(uint8_t *data, uint16_t length, uint8_t *eui64)
|
||||||
|
{
|
||||||
|
mac_header_IE_t rsl_ie_data;
|
||||||
|
rsl_ie_data.id = MAC_HEADER_ASSIGNED_EXTERNAL_ORG_IE_ID;
|
||||||
|
if (8 != mac_ie_header_sub_id_discover(data, length, &rsl_ie_data, WH_IE_EA_TYPE)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
memcpy(eui64, rsl_ie_data.content_ptr, 8);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t *ws_channel_plan_zero_read(uint8_t *ptr, ws_channel_plan_zero_t *plan)
|
||||||
|
{
|
||||||
|
plan->regulator_domain = *ptr++;
|
||||||
|
plan->operation_class = *ptr++;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t *ws_channel_plan_one_read(uint8_t *ptr, ws_channel_plan_one_t *plan)
|
||||||
|
{
|
||||||
|
plan->ch0 = common_read_24_bit_inverse(ptr);
|
||||||
|
ptr += 3;
|
||||||
|
plan->channel_spacing = (*ptr++ & 0xf0) >> 4;
|
||||||
|
plan->number_of_channel = common_read_16_bit_inverse(ptr);
|
||||||
|
ptr += 2;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t *ws_channel_function_zero_read(uint8_t *ptr, ws_channel_function_zero_t *plan)
|
||||||
|
{
|
||||||
|
plan->fixed_channel = common_read_16_bit_inverse(ptr);
|
||||||
|
return ptr + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t *ws_channel_function_three_read(uint8_t *ptr, ws_channel_function_three_t *plan)
|
||||||
|
{
|
||||||
|
plan->channel_hop_count = *ptr++;
|
||||||
|
plan->channel_list = ptr++;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ws_wp_nested_us_read(uint8_t *data, uint16_t length, struct ws_us_ie *us_ie)
|
||||||
|
{
|
||||||
|
mac_nested_payload_IE_t nested_payload_ie;
|
||||||
|
nested_payload_ie.id = WP_PAYLOAD_IE_US_TYPE;
|
||||||
|
nested_payload_ie.type_long = true;
|
||||||
|
if (mac_ie_nested_discover(data, length, &nested_payload_ie) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
data = nested_payload_ie.content_ptr;
|
||||||
|
us_ie->dwell_interval = *data++;
|
||||||
|
us_ie->clock_drift = *data++;
|
||||||
|
us_ie->timing_accurancy = *data++;
|
||||||
|
us_ie->channel_plan = (*data & 3);
|
||||||
|
us_ie->channel_function = (*data & 0x38) >> 3;
|
||||||
|
us_ie->excluded_channel_ctrl = (*data & 0xc0) >> 6;
|
||||||
|
data++;
|
||||||
|
uint16_t info_length = 0;
|
||||||
|
nested_payload_ie.length -= 4;
|
||||||
|
info_length = ws_channel_plan_length(us_ie->channel_plan);
|
||||||
|
if (nested_payload_ie.length < info_length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
nested_payload_ie.length -= info_length;
|
||||||
|
switch (us_ie->channel_plan) {
|
||||||
|
case 0:
|
||||||
|
data = ws_channel_plan_zero_read(data, &us_ie->plan.zero);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
data = ws_channel_plan_one_read(data, &us_ie->plan.one);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
info_length = ws_channel_function_length(us_ie->channel_function, 0);
|
||||||
|
|
||||||
|
if (nested_payload_ie.length < info_length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
nested_payload_ie.length -= info_length;
|
||||||
|
|
||||||
|
|
||||||
|
switch (us_ie->channel_function) {
|
||||||
|
case 0:
|
||||||
|
data = ws_channel_function_zero_read(data, &us_ie->function.zero);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
|
||||||
|
data = ws_channel_function_three_read(data, &us_ie->function.three);
|
||||||
|
info_length = us_ie->function.three.channel_hop_count;
|
||||||
|
if (nested_payload_ie.length < info_length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
nested_payload_ie.length -= info_length;
|
||||||
|
data += info_length;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool ws_wp_nested_bs_read(uint8_t *data, uint16_t length, struct ws_bs_ie *bs_ie)
|
||||||
|
{
|
||||||
|
mac_nested_payload_IE_t nested_payload_ie;
|
||||||
|
nested_payload_ie.id = WP_PAYLOAD_IE_BS_TYPE;
|
||||||
|
nested_payload_ie.type_long = true;
|
||||||
|
if (mac_ie_nested_discover(data, length, &nested_payload_ie) < 10) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
data = nested_payload_ie.content_ptr;
|
||||||
|
bs_ie->broadcast_interval = common_read_32_bit_inverse(data);
|
||||||
|
bs_ie->broadcast_schedule_identifier = common_read_16_bit_inverse(data + 4);
|
||||||
|
data += 6;
|
||||||
|
bs_ie->dwell_interval = *data++;
|
||||||
|
bs_ie->clock_drift = *data++;
|
||||||
|
bs_ie->timing_accurancy = *data++;
|
||||||
|
|
||||||
|
bs_ie->channel_plan = (*data & 3);
|
||||||
|
bs_ie->channel_function = (*data & 0x38) >> 3;
|
||||||
|
bs_ie->excluded_channel_ctrl = (*data & 0xc0) >> 6;
|
||||||
|
data++;
|
||||||
|
nested_payload_ie.length -= 10;
|
||||||
|
uint16_t info_length = 0;
|
||||||
|
|
||||||
|
info_length = ws_channel_plan_length(bs_ie->channel_plan);
|
||||||
|
if (nested_payload_ie.length < info_length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
nested_payload_ie.length -= info_length;
|
||||||
|
switch (bs_ie->channel_plan) {
|
||||||
|
case 0:
|
||||||
|
data = ws_channel_plan_zero_read(data, &bs_ie->plan.zero);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
data = ws_channel_plan_one_read(data, &bs_ie->plan.one);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
info_length = ws_channel_function_length(bs_ie->channel_function, 0);
|
||||||
|
if (nested_payload_ie.length < info_length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
nested_payload_ie.length -= info_length;
|
||||||
|
|
||||||
|
switch (bs_ie->channel_function) {
|
||||||
|
case 0:
|
||||||
|
data = ws_channel_function_zero_read(data, &bs_ie->function.zero);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
data = ws_channel_function_three_read(data, &bs_ie->function.three);
|
||||||
|
info_length = bs_ie->function.three.channel_hop_count;
|
||||||
|
if (nested_payload_ie.length < info_length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
nested_payload_ie.length -= info_length;
|
||||||
|
data += info_length;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ws_wp_nested_pan_read(uint8_t *data, uint16_t length, struct ws_pan_information_s *pan_congiguration)
|
||||||
|
{
|
||||||
|
mac_nested_payload_IE_t nested_payload_ie;
|
||||||
|
nested_payload_ie.id = WP_PAYLOAD_IE_PAN_TYPE;
|
||||||
|
nested_payload_ie.type_long = false;
|
||||||
|
if (mac_ie_nested_discover(data, length, &nested_payload_ie) != 5) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pan_congiguration->pan_size = common_read_16_bit_inverse(nested_payload_ie.content_ptr);
|
||||||
|
pan_congiguration->routing_cost = common_read_16_bit_inverse(nested_payload_ie.content_ptr + 2);
|
||||||
|
pan_congiguration->use_parent_bs = (nested_payload_ie.content_ptr[4] & 0x01) == 0x01;
|
||||||
|
pan_congiguration->rpl_routing_method = (nested_payload_ie.content_ptr[4] & 0x02) == 0x02;
|
||||||
|
pan_congiguration->version = (nested_payload_ie.content_ptr[4] & 0xe0) >> 5;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ws_wp_nested_pan_version_read(uint8_t *data, uint16_t length, uint16_t *pan_version)
|
||||||
|
{
|
||||||
|
mac_nested_payload_IE_t nested_payload_ie;
|
||||||
|
nested_payload_ie.id = WP_PAYLOAD_IE_PAN_VER_TYPE;
|
||||||
|
nested_payload_ie.type_long = false;
|
||||||
|
if (mac_ie_nested_discover(data, length, &nested_payload_ie) != 2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*pan_version = common_read_16_bit_inverse(nested_payload_ie.content_ptr);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *ws_wp_nested_gtkhash_read(uint8_t *data, uint16_t length)
|
||||||
|
{
|
||||||
|
mac_nested_payload_IE_t nested_payload_ie;
|
||||||
|
nested_payload_ie.id = WP_PAYLOAD_IE_GTKHASH_TYPE;
|
||||||
|
nested_payload_ie.type_long = false;
|
||||||
|
if (mac_ie_nested_discover(data, length, &nested_payload_ie) != 32) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nested_payload_ie.content_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ws_wp_nested_network_name_read(uint8_t *data, uint16_t length, ws_wp_network_name_t *network_name)
|
||||||
|
{
|
||||||
|
mac_nested_payload_IE_t nested_payload_ie;
|
||||||
|
nested_payload_ie.id = WP_PAYLOAD_IE_NETNAME_TYPE;
|
||||||
|
nested_payload_ie.type_long = false;
|
||||||
|
|
||||||
|
if (0 == mac_ie_nested_discover(data, length, &nested_payload_ie)) {
|
||||||
|
return false;
|
||||||
|
} else if (nested_payload_ie.length > 32) {
|
||||||
|
//Too long name
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
network_name->network_name = nested_payload_ie.content_ptr;
|
||||||
|
network_name->network_name_length = nested_payload_ie.length;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2019, 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 WS_IE_LIB_H_
|
||||||
|
#define WS_IE_LIB_H_
|
||||||
|
|
||||||
|
struct ws_pan_information_s;
|
||||||
|
struct ws_utt_ie;
|
||||||
|
struct ws_bt_ie;
|
||||||
|
struct ws_us_ie;
|
||||||
|
struct ws_hopping_schedule_s;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ws_wp_network_name_t WS nested payload network name
|
||||||
|
*/
|
||||||
|
typedef struct ws_wp_network_name {
|
||||||
|
uint8_t network_name_length;
|
||||||
|
uint8_t *network_name;
|
||||||
|
} ws_wp_network_name_t;
|
||||||
|
|
||||||
|
/* WS_WH HEADER IE */
|
||||||
|
uint8_t *ws_wh_utt_write(uint8_t *ptr, uint8_t message_type);
|
||||||
|
uint8_t *ws_wh_bt_write(uint8_t *ptr);
|
||||||
|
uint8_t *ws_wh_fc_write(uint8_t *ptr, uint8_t flow_ctrl);
|
||||||
|
uint8_t *ws_wh_rsl_write(uint8_t *ptr, int8_t rssi);
|
||||||
|
uint8_t *ws_wh_vh_write(uint8_t *ptr, uint8_t *vendor_header, uint8_t vendor_header_length);
|
||||||
|
uint8_t *ws_wh_ea_write(uint8_t *ptr, uint8_t *eui64);
|
||||||
|
|
||||||
|
bool ws_wh_utt_read(uint8_t *data, uint16_t length, struct ws_utt_ie *utt_ie);
|
||||||
|
bool ws_wh_bt_read(uint8_t *data, uint16_t length, struct ws_bt_ie *bt_ie);
|
||||||
|
bool ws_wh_rsl_read(uint8_t *data, uint16_t length, int8_t *rsl);
|
||||||
|
bool ws_wh_ea_read(uint8_t *data, uint16_t length, uint8_t *eui64);
|
||||||
|
|
||||||
|
/* WS_WP_NESTED PAYLOD IE */
|
||||||
|
uint8_t *ws_wp_base_write(uint8_t *ptr, uint16_t length);
|
||||||
|
uint8_t *ws_wp_nested_hopping_schedule_write(uint8_t *ptr, struct ws_hopping_schedule_s *hopping_schedule, bool unicast_schedule);
|
||||||
|
uint8_t *ws_wp_nested_vp_write(uint8_t *ptr, uint8_t *vendor_payload, uint16_t vendor_payload_length);
|
||||||
|
uint8_t *ws_wp_nested_pan_info_write(uint8_t *ptr, struct ws_pan_information_s *pan_congiguration);
|
||||||
|
uint8_t *ws_wp_nested_netname_write(uint8_t *ptr, uint8_t *network_name, uint8_t network_name_length);
|
||||||
|
uint8_t *ws_wp_nested_pan_ver_write(uint8_t *ptr, struct ws_pan_information_s *pan_congiguration);
|
||||||
|
uint8_t *ws_wp_nested_gtkhash_write(uint8_t *ptr, uint8_t *gtkhash, uint8_t gtkhash_length);
|
||||||
|
uint16_t ws_wp_nested_hopping_schedule_length(struct ws_hopping_schedule_s *hopping_schedule, bool unicast_schedule);
|
||||||
|
|
||||||
|
bool ws_wp_nested_us_read(uint8_t *data, uint16_t length, struct ws_us_ie *us_ie);
|
||||||
|
bool ws_wp_nested_bs_read(uint8_t *data, uint16_t length, struct ws_bs_ie *bs_ie);
|
||||||
|
bool ws_wp_nested_pan_read(uint8_t *data, uint16_t length, struct ws_pan_information_s *pan_congiguration);
|
||||||
|
bool ws_wp_nested_pan_version_read(uint8_t *data, uint16_t length, uint16_t *pan_version);
|
||||||
|
bool ws_wp_nested_network_name_read(uint8_t *data, uint16_t length, ws_wp_network_name_t *network_name);
|
||||||
|
uint8_t *ws_wp_nested_gtkhash_read(uint8_t *data, uint16_t length);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* WS_IE_LIB_H_ */
|
|
@ -0,0 +1,208 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2019, 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 WS_LLC_H_
|
||||||
|
#define WS_LLC_H_
|
||||||
|
|
||||||
|
#include "6LoWPAN/ws/ws_neighbor_class.h"
|
||||||
|
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
|
||||||
|
|
||||||
|
struct protocol_interface_info_entry;
|
||||||
|
struct mcps_data_ind_s;
|
||||||
|
struct mcps_data_ie_list;
|
||||||
|
struct channel_list_s;
|
||||||
|
struct ws_pan_information_s;
|
||||||
|
struct mlme_security_s;
|
||||||
|
struct ws_hopping_schedule_s;
|
||||||
|
struct ws_neighbor_class_entry;
|
||||||
|
struct mac_neighbor_table_entry;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief wh_ie_sub_list_t ws asynch header IE elemnt request list
|
||||||
|
*/
|
||||||
|
typedef struct wh_ie_sub_list_s {
|
||||||
|
bool utt_ie: 1; /**< Unicast Timing and Frame type information */
|
||||||
|
bool bt_ie: 1; /**< Broadcast timing information */
|
||||||
|
bool fc_ie: 1; /**< Flow Control for Extended Direct Frame Exchange */
|
||||||
|
bool rsl_ie: 1; /**< Received Signal Level information */
|
||||||
|
bool vh_ie: 1; /**< Vendor header information */
|
||||||
|
bool ea_ie: 1; /**< EAPOL autheticator EUI-64 header information */
|
||||||
|
} wh_ie_sub_list_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief wp_nested_ie_sub_list_t ws asynch Nested Payload sub IE element request list
|
||||||
|
*/
|
||||||
|
typedef struct wp_nested_ie_sub_list_s {
|
||||||
|
bool us_ie: 1; /**< Unicast Schedule information */
|
||||||
|
bool bs_ie: 1; /**< Broadcast Schedule information */
|
||||||
|
bool vp_ie: 1; /**< Vendor Payload information */
|
||||||
|
bool pan_ie: 1; /**< PAN Information */
|
||||||
|
bool net_name_ie: 1; /**< Network Name information */
|
||||||
|
bool pan_version_ie: 1; /**< Pan configuration version */
|
||||||
|
bool gtkhash_ie: 1; /**< GTK Hash information */
|
||||||
|
} wp_nested_ie_sub_list_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief asynch_request_t Asynch message request parameters
|
||||||
|
*/
|
||||||
|
typedef struct asynch_request_s {
|
||||||
|
unsigned message_type: 3; /**< Asynch message type: WS_FT_PAN_ADVERT, WS_FT_PAN_ADVERT_SOL, WS_FT_PAN_CONF or WS_FT_PAN_CONF_SOL. */
|
||||||
|
wh_ie_sub_list_t wh_requested_ie_list; /**< WH-IE header list to message. */
|
||||||
|
wp_nested_ie_sub_list_t wp_requested_nested_ie_list; /**< WP-IE Nested IE list to message. */
|
||||||
|
struct mlme_security_s security; /**< Request MAC security paramaters */
|
||||||
|
struct channel_list_s channel_list; /**< Channel List. */
|
||||||
|
} asynch_request_t;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief LLC neighbour info request parameters
|
||||||
|
*/
|
||||||
|
typedef struct llc_neighbour_req {
|
||||||
|
struct mac_neighbor_table_entry *neighbor; /**< Generic Link Layer Neighbor information entry. */
|
||||||
|
struct ws_neighbor_class_entry *ws_neighbor; /**< Wi-sun Neighbor information entry. */
|
||||||
|
} llc_neighbour_req_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ws_asynch_ind ws asynch data indication
|
||||||
|
* @param interface Interface pointer
|
||||||
|
* @param data MCPS-DATA.indication specific values
|
||||||
|
* @param ie_ext Information element list
|
||||||
|
*/
|
||||||
|
typedef void ws_asynch_ind(struct protocol_interface_info_entry *interface, const struct mcps_data_ind_s *data, const struct mcps_data_ie_list *ie_ext, uint8_t message_type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ws_asynch_confirm ws asynch data confirmation to asynch message request
|
||||||
|
* @param api The API which handled the response
|
||||||
|
* @param data MCPS-DATA.confirm specific values
|
||||||
|
* @param user_id MPX user ID
|
||||||
|
*/
|
||||||
|
typedef void ws_asynch_confirm(struct protocol_interface_info_entry *interface, uint8_t asynch_message);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ws_asynch_confirm ws asynch data confirmation to asynch message request
|
||||||
|
* @param interface The interface pointer
|
||||||
|
* @param mac_64 Neighbor 64-bit address
|
||||||
|
* @param neighbor_buffer Buffer where neighbor infor is buffered
|
||||||
|
* @param request_new true if is possible to allocate new entry
|
||||||
|
*
|
||||||
|
* @return true when neighbor info is available
|
||||||
|
* @return false when no neighbor info
|
||||||
|
*/
|
||||||
|
typedef bool ws_neighbor_info_request(struct protocol_interface_info_entry *interface, const uint8_t *mac_64, llc_neighbour_req_t *neighbor_buffer, bool request_new);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ws_llc_create ws LLC module create
|
||||||
|
* @param interface Interface pointer
|
||||||
|
* @param asynch_ind_cb Asynch indication
|
||||||
|
* @param ie_ext Information element list
|
||||||
|
*
|
||||||
|
* Function allocate and init LLC class and init it 2 supported 2 API: ws asynch and MPX user are internally registered.
|
||||||
|
*/
|
||||||
|
int8_t ws_llc_create(struct protocol_interface_info_entry *interface, ws_asynch_ind *asynch_ind_cb, ws_asynch_confirm *asynch_cnf_cb, ws_neighbor_info_request *ws_neighbor_info_request_cb);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ws_llc_reset Reset ws LLC parametrs and clean messages
|
||||||
|
* @param interface Interface pointer
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void ws_llc_reset(struct protocol_interface_info_entry *interface);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ws_llc_delete Delete LLC interface. ONLY for Test purpose.
|
||||||
|
* @param interface Interface pointer
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int8_t ws_llc_delete(struct protocol_interface_info_entry *interface);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ws_llc_mpx_api_get Get MPX api for registration purpose.
|
||||||
|
* @param interface Interface pointer
|
||||||
|
*
|
||||||
|
* @return NULL when MPX is not vailabale
|
||||||
|
* @return Pointer to MPX API
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
mpx_api_t *ws_llc_mpx_api_get(struct protocol_interface_info_entry *interface);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ws_llc_asynch_request ws asynch message request to all giving channels
|
||||||
|
* @param interface Interface pointer
|
||||||
|
* @param request Asynch message parameters: type, IE and channel list
|
||||||
|
*
|
||||||
|
* @return 0 Asynch message pushed to MAC
|
||||||
|
* @return -1 memory allocate problem
|
||||||
|
* @return -2 Parameter problem
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int8_t ws_llc_asynch_request(struct protocol_interface_info_entry *interface, asynch_request_t *request);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ws_llc_set_vendor_header_data Configure WS vendor Header data information (Data of WH_IE_VH_TYPE IE element)
|
||||||
|
* @param interface Interface pointer
|
||||||
|
* @param vendor_header pointer to vendor header this pointer must keep alive when it is configured to LLC
|
||||||
|
* @param vendor_header_length configured vendor header length
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void ws_llc_set_vendor_header_data(struct protocol_interface_info_entry *interface, uint8_t *vendor_header, uint8_t vendor_header_length);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ws_llc_set_vendor_payload_data Configure WS vendor payload data information (Data of WP_PAYLOAD_IE_VP_TYPE IE element)
|
||||||
|
* @param interface Interface pointer
|
||||||
|
* @param vendor_payload pointer to vendor payload this pointer must keep alive when it is configured to LLC
|
||||||
|
* @param vendor_payload_length configured vendor payload length
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void ws_llc_set_vendor_payload_data(struct protocol_interface_info_entry *interface, uint8_t *vendor_payload, uint8_t vendor_payload_length);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ws_llc_set_network_name Configure WS Network name (Data of WP_PAYLOAD_IE_NETNAME_TYPE IE element)
|
||||||
|
* @param interface Interface pointer
|
||||||
|
* @param name_length configured network name length
|
||||||
|
* @param name pointer to network name this pointer must keep alive when it is configured to LLC
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void ws_llc_set_network_name(struct protocol_interface_info_entry *interface, uint8_t *name, uint8_t name_length);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ws_llc_set_gtkhash Configure WS GTK hash information (Data of WP_PAYLOAD_IE_GTKHASH_TYPE IE element)
|
||||||
|
* @param interface Interface pointer
|
||||||
|
* @param gtkhash pointer to GTK hash which length is 32 bytes this pointer must keep alive when it is configured to LLC
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void ws_llc_set_gtkhash(struct protocol_interface_info_entry *interface, uint8_t *gtkhash);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ws_llc_set_pan_information_pointer Configure WS PAN information (Data of WP_PAYLOAD_IE_PAN_TYPE IE element)
|
||||||
|
* @param interface Interface pointer
|
||||||
|
* @param pan_information_pointer pointer to Pan information this pointer must keep alive when it is configured to LLC
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void ws_llc_set_pan_information_pointer(struct protocol_interface_info_entry *interface, struct ws_pan_information_s *pan_information_pointer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ws_llc_hopping_schedule_config Configure channel hopping
|
||||||
|
* @param interface Interface pointer
|
||||||
|
* @param hopping_schedule pointer to Channel hopping schedule
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void ws_llc_hopping_schedule_config(struct protocol_interface_info_entry *interface, struct ws_hopping_schedule_s *hopping_schedule);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* WS_LLC_H_ */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,262 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2019, 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 <string.h>
|
||||||
|
#include "nsconfig.h"
|
||||||
|
#include "ns_types.h"
|
||||||
|
#include "ns_trace.h"
|
||||||
|
#include <ns_list.h>
|
||||||
|
#include <nsdynmemLIB.h>
|
||||||
|
#include "NWK_INTERFACE/Include/protocol.h"
|
||||||
|
#include "6LoWPAN/ws/ws_common.h"
|
||||||
|
#include "6LoWPAN/ws/ws_bootstrap.h"
|
||||||
|
|
||||||
|
#include "ws_management_api.h"
|
||||||
|
|
||||||
|
#define TRACE_GROUP "wsmg"
|
||||||
|
|
||||||
|
#ifdef HAVE_WS
|
||||||
|
|
||||||
|
int ws_management_node_init(
|
||||||
|
int8_t interface_id,
|
||||||
|
uint8_t regulatory_domain,
|
||||||
|
char *network_name_ptr,
|
||||||
|
fhss_timer_t *fhss_timer_ptr)
|
||||||
|
{
|
||||||
|
protocol_interface_info_entry_t *cur;
|
||||||
|
|
||||||
|
cur = protocol_stack_interface_info_get_by_id(interface_id);
|
||||||
|
if (!cur || !ws_info(cur)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!network_name_ptr || !fhss_timer_ptr) {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
cur->ws_info->hopping_schdule.regulatory_domain = regulatory_domain;
|
||||||
|
if (ws_common_regulatory_domain_config(cur) < 0) {
|
||||||
|
// Invalid regulatory domain set
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
strncpy(cur->ws_info->network_name, network_name_ptr, 32);
|
||||||
|
cur->ws_info->fhss_timer_ptr = fhss_timer_ptr;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ws_management_regulatory_domain_set(
|
||||||
|
int8_t interface_id,
|
||||||
|
uint8_t regulatory_domain,
|
||||||
|
uint8_t operating_class,
|
||||||
|
uint8_t operating_mode)
|
||||||
|
{
|
||||||
|
uint8_t regulatory_domain_saved;
|
||||||
|
uint8_t operating_class_saved;
|
||||||
|
uint8_t operating_mode_saved;
|
||||||
|
protocol_interface_info_entry_t *cur;
|
||||||
|
|
||||||
|
cur = protocol_stack_interface_info_get_by_id(interface_id);
|
||||||
|
if (!cur || !ws_info(cur)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
regulatory_domain_saved = cur->ws_info->hopping_schdule.regulatory_domain;
|
||||||
|
operating_class_saved = cur->ws_info->hopping_schdule.operating_mode;
|
||||||
|
operating_mode_saved = cur->ws_info->hopping_schdule.operating_class;
|
||||||
|
if (regulatory_domain != 255) {
|
||||||
|
cur->ws_info->hopping_schdule.regulatory_domain = regulatory_domain;
|
||||||
|
}
|
||||||
|
if (operating_mode != 255) {
|
||||||
|
cur->ws_info->hopping_schdule.operating_mode = operating_mode;
|
||||||
|
}
|
||||||
|
if (operating_class != 255) {
|
||||||
|
cur->ws_info->hopping_schdule.operating_class = operating_class;
|
||||||
|
}
|
||||||
|
if (ws_common_regulatory_domain_config(cur) != 0) {
|
||||||
|
// Restore old config on failure
|
||||||
|
//tr_error("unsupported regulatory domain: %d class: %d, mode: %d", regulatory_domain, operating_class, operating_mode);
|
||||||
|
cur->ws_info->hopping_schdule.regulatory_domain = regulatory_domain_saved;
|
||||||
|
cur->ws_info->hopping_schdule.operating_mode = operating_mode_saved;
|
||||||
|
cur->ws_info->hopping_schdule.operating_class = operating_class_saved;
|
||||||
|
ws_common_regulatory_domain_config(cur);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// if settings change reset_restart for the settings needed
|
||||||
|
if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) {
|
||||||
|
// bootstrap active need to restart
|
||||||
|
ws_bootstrap_restart(interface_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ws_management_network_size_set(
|
||||||
|
int8_t interface_id,
|
||||||
|
uint8_t network_size)
|
||||||
|
{
|
||||||
|
protocol_interface_info_entry_t *cur;
|
||||||
|
|
||||||
|
cur = protocol_stack_interface_info_get_by_id(interface_id);
|
||||||
|
if (!cur || !ws_info(cur)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (network_size > NETWORK_SIZE_LARGE) {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
ws_info(cur)->network_size_config = network_size;
|
||||||
|
|
||||||
|
if (network_size == NETWORK_SIZE_LARGE) {
|
||||||
|
ws_common_network_size_configure(cur, 5000);
|
||||||
|
} else {
|
||||||
|
ws_common_network_size_configure(cur, 10);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ws_management_channel_mask_set(
|
||||||
|
int8_t interface_id,
|
||||||
|
uint32_t channel_mask[8])
|
||||||
|
{
|
||||||
|
protocol_interface_info_entry_t *cur;
|
||||||
|
|
||||||
|
cur = protocol_stack_interface_info_get_by_id(interface_id);
|
||||||
|
if (!cur || !ws_info(cur)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memcpy(cur->ws_info->fhss_channel_mask, channel_mask, sizeof(uint32_t) * 8);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ws_management_channel_plan_set(
|
||||||
|
int8_t interface_id,
|
||||||
|
uint8_t channel_plan,
|
||||||
|
uint8_t uc_channel_function,
|
||||||
|
uint8_t bc_channel_function,
|
||||||
|
uint32_t ch0_freq, // Stack can not modify this
|
||||||
|
uint8_t channel_spacing,// Stack can not modify this
|
||||||
|
uint8_t number_of_channels)
|
||||||
|
{
|
||||||
|
protocol_interface_info_entry_t *cur;
|
||||||
|
|
||||||
|
cur = protocol_stack_interface_info_get_by_id(interface_id);
|
||||||
|
if (!cur || !ws_info(cur)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
cur->ws_info->hopping_schdule.channel_plan = channel_plan;
|
||||||
|
cur->ws_info->hopping_schdule.uc_channel_function = uc_channel_function;
|
||||||
|
cur->ws_info->hopping_schdule.bc_channel_function = bc_channel_function;
|
||||||
|
cur->ws_info->hopping_schdule.ch0_freq = ch0_freq;
|
||||||
|
cur->ws_info->hopping_schdule.channel_spacing = channel_spacing;
|
||||||
|
cur->ws_info->hopping_schdule.number_of_channels = number_of_channels;
|
||||||
|
|
||||||
|
// TODO update fields to llc
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ws_management_fhss_timing_configure(
|
||||||
|
int8_t interface_id,
|
||||||
|
uint8_t fhss_uc_dwell_interval,
|
||||||
|
uint32_t fhss_broadcast_interval,
|
||||||
|
uint8_t fhss_bc_dwell_interval)
|
||||||
|
{
|
||||||
|
protocol_interface_info_entry_t *cur;
|
||||||
|
|
||||||
|
cur = protocol_stack_interface_info_get_by_id(interface_id);
|
||||||
|
if (!cur || !ws_info(cur)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (fhss_uc_dwell_interval > 0) {
|
||||||
|
cur->ws_info->fhss_uc_dwell_interval = fhss_uc_dwell_interval;
|
||||||
|
}
|
||||||
|
if (fhss_broadcast_interval > 0) {
|
||||||
|
cur->ws_info->fhss_bc_interval = fhss_broadcast_interval;
|
||||||
|
|
||||||
|
}
|
||||||
|
if (fhss_bc_dwell_interval > 0) {
|
||||||
|
cur->ws_info->fhss_bc_dwell_interval = fhss_bc_dwell_interval;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// if settings change reset_restart for the settings needed
|
||||||
|
if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) {
|
||||||
|
// bootstrap active need to restart
|
||||||
|
ws_bootstrap_restart(interface_id);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ws_management_fhss_unicast_channel_function_configure(
|
||||||
|
int8_t interface_id,
|
||||||
|
uint8_t channel_function,
|
||||||
|
uint16_t fixed_channel,
|
||||||
|
uint8_t dwell_interval)
|
||||||
|
{
|
||||||
|
protocol_interface_info_entry_t *cur;
|
||||||
|
|
||||||
|
cur = protocol_stack_interface_info_get_by_id(interface_id);
|
||||||
|
if (!cur || !ws_info(cur)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (channel_function != WS_FIXED_CHANNEL &&
|
||||||
|
channel_function != WS_VENDOR_DEF_CF &&
|
||||||
|
channel_function != WS_DH1CF &&
|
||||||
|
channel_function != WS_TR51CF) {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
cur->ws_info->fhss_uc_channel_function = channel_function;
|
||||||
|
cur->ws_info->fhss_uc_fixed_channel = fixed_channel;
|
||||||
|
cur->ws_info->fhss_uc_dwell_interval = dwell_interval;
|
||||||
|
|
||||||
|
// if settings change reset_restart for the settings needed
|
||||||
|
if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) {
|
||||||
|
// bootstrap active need to restart
|
||||||
|
ws_bootstrap_restart(interface_id);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int ws_management_fhss_broadcast_channel_function_configure(
|
||||||
|
int8_t interface_id,
|
||||||
|
uint8_t channel_function,
|
||||||
|
uint16_t fixed_channel,
|
||||||
|
uint8_t dwell_interval,
|
||||||
|
uint32_t broadcast_interval)
|
||||||
|
{
|
||||||
|
protocol_interface_info_entry_t *cur;
|
||||||
|
|
||||||
|
cur = protocol_stack_interface_info_get_by_id(interface_id);
|
||||||
|
if (!cur || !ws_info(cur)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (channel_function != WS_FIXED_CHANNEL &&
|
||||||
|
channel_function != WS_VENDOR_DEF_CF &&
|
||||||
|
channel_function != WS_DH1CF &&
|
||||||
|
channel_function != WS_TR51CF) {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
cur->ws_info->fhss_bc_channel_function = channel_function;
|
||||||
|
cur->ws_info->fhss_bc_fixed_channel = fixed_channel;
|
||||||
|
cur->ws_info->fhss_bc_dwell_interval = dwell_interval;
|
||||||
|
cur->ws_info->fhss_bc_interval = broadcast_interval;
|
||||||
|
|
||||||
|
// if settings change reset_restart for the settings needed
|
||||||
|
if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) {
|
||||||
|
// bootstrap active need to restart
|
||||||
|
ws_bootstrap_restart(interface_id);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif // HAVE_WS
|
|
@ -0,0 +1,146 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2019, 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"
|
||||||
|
#include <string.h>
|
||||||
|
#include "ns_types.h"
|
||||||
|
#include "ns_list.h"
|
||||||
|
#include "ns_trace.h"
|
||||||
|
#include "nsdynmemLIB.h"
|
||||||
|
#include "common_functions.h"
|
||||||
|
#include "mac_common_defines.h"
|
||||||
|
#include "ws_mpx_header.h"
|
||||||
|
|
||||||
|
bool ws_llc_mpx_header_frame_parse(uint8_t *ptr, uint16_t length, mpx_msg_t *msg)
|
||||||
|
{
|
||||||
|
if (!length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
memset(msg, 0, sizeof(mpx_msg_t));
|
||||||
|
bool fragmented_number_present = false;
|
||||||
|
bool multiplex_id_present = false;
|
||||||
|
bool fragment_total_size = false;
|
||||||
|
|
||||||
|
msg->transfer_type = *ptr & 7;
|
||||||
|
msg->transaction_id = ((*ptr++ & 0xf8) >> 3);
|
||||||
|
length--;
|
||||||
|
|
||||||
|
|
||||||
|
switch (msg->transfer_type) {
|
||||||
|
case MPX_FT_FULL_FRAME:
|
||||||
|
multiplex_id_present = true;
|
||||||
|
break;
|
||||||
|
case MPX_FT_FULL_FRAME_SMALL_MULTILEX_ID:
|
||||||
|
break;
|
||||||
|
case MPX_FT_FIRST_OR_SUB_FRAGMENT:
|
||||||
|
case MPX_FT_LAST_FRAGMENT:
|
||||||
|
fragmented_number_present = true;
|
||||||
|
if (length < 2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MPX_FT_ABORT:
|
||||||
|
if (length == 2) {
|
||||||
|
fragment_total_size = true;
|
||||||
|
} else if (length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fragmented_number_present) {
|
||||||
|
|
||||||
|
msg->fragment_number = *ptr++;
|
||||||
|
length--;
|
||||||
|
if (msg->fragment_number == 0) { //First fragment
|
||||||
|
fragment_total_size = true;
|
||||||
|
multiplex_id_present = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fragment_total_size) {
|
||||||
|
if (length < 2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
msg->total_upper_layer_size = common_read_16_bit_inverse(ptr);
|
||||||
|
ptr += 2;
|
||||||
|
length -= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (multiplex_id_present) {
|
||||||
|
if (length < 3) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
msg->multiplex_id = common_read_16_bit_inverse(ptr);
|
||||||
|
ptr += 2;
|
||||||
|
length -= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg->frame_ptr = ptr;
|
||||||
|
msg->frame_length = length;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t *ws_llc_mpx_header_write(uint8_t *ptr, const mpx_msg_t *msg)
|
||||||
|
{
|
||||||
|
|
||||||
|
bool fragmented_number_present = false;
|
||||||
|
bool multiplex_id_present = false;
|
||||||
|
bool fragment_total_size = false;
|
||||||
|
|
||||||
|
*ptr = msg->transfer_type;
|
||||||
|
*ptr++ |= ((msg->transaction_id << 3) & 0xf8);
|
||||||
|
|
||||||
|
switch (msg->transfer_type) {
|
||||||
|
case MPX_FT_FULL_FRAME:
|
||||||
|
multiplex_id_present = true;
|
||||||
|
break;
|
||||||
|
case MPX_FT_FULL_FRAME_SMALL_MULTILEX_ID:
|
||||||
|
break;
|
||||||
|
case MPX_FT_FIRST_OR_SUB_FRAGMENT:
|
||||||
|
case MPX_FT_LAST_FRAGMENT:
|
||||||
|
fragmented_number_present = true;
|
||||||
|
if (msg->fragment_number == 0) {
|
||||||
|
fragment_total_size = true;
|
||||||
|
multiplex_id_present = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MPX_FT_ABORT:
|
||||||
|
if (msg->total_upper_layer_size) {
|
||||||
|
fragment_total_size = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fragmented_number_present) {
|
||||||
|
*ptr++ = msg->fragment_number;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fragment_total_size) {
|
||||||
|
ptr = common_write_16_bit_inverse(msg->total_upper_layer_size, ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (multiplex_id_present) {
|
||||||
|
ptr = common_write_16_bit_inverse(msg->multiplex_id, ptr);
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2019, 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 WS_MPX_HEADER_H_
|
||||||
|
#define WS_MPX_HEADER_H_
|
||||||
|
|
||||||
|
#define MPX_FT_FULL_FRAME 0
|
||||||
|
#define MPX_FT_FULL_FRAME_SMALL_MULTILEX_ID 1
|
||||||
|
#define MPX_FT_FIRST_OR_SUB_FRAGMENT 2
|
||||||
|
#define MPX_FT_LAST_FRAGMENT 4
|
||||||
|
#define MPX_FT_ABORT 6
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned transfer_type: 3;
|
||||||
|
unsigned transaction_id: 5;
|
||||||
|
uint8_t fragment_number;
|
||||||
|
uint16_t total_upper_layer_size;
|
||||||
|
uint16_t multiplex_id;
|
||||||
|
uint8_t *frame_ptr;
|
||||||
|
uint16_t frame_length;
|
||||||
|
} mpx_msg_t;
|
||||||
|
|
||||||
|
bool ws_llc_mpx_header_frame_parse(uint8_t *ptr, uint16_t length, mpx_msg_t *msg);
|
||||||
|
uint8_t *ws_llc_mpx_header_write(uint8_t *ptr, const mpx_msg_t *msg);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* WS_MPX_HEADER_H_ */
|
|
@ -0,0 +1,188 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2019, 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"
|
||||||
|
#include <string.h>
|
||||||
|
#include "ns_types.h"
|
||||||
|
#include "ns_list.h"
|
||||||
|
#include "ns_trace.h"
|
||||||
|
#include "nsdynmemLIB.h"
|
||||||
|
#include "fhss_config.h"
|
||||||
|
#include "6LoWPAN/ws/ws_config.h"
|
||||||
|
#include "6LoWPAN/ws/ws_neighbor_class.h"
|
||||||
|
#include "6LoWPAN/ws/ws_common.h"
|
||||||
|
#include "ws_management_api.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_WS
|
||||||
|
|
||||||
|
|
||||||
|
#define TRACE_GROUP "wsne"
|
||||||
|
|
||||||
|
|
||||||
|
bool ws_neighbor_class_alloc(ws_neighbor_class_t *class_data, uint8_t list_size)
|
||||||
|
{
|
||||||
|
|
||||||
|
class_data->neigh_info_list = ns_dyn_mem_alloc(sizeof(ws_neighbor_class_entry_t) * list_size);
|
||||||
|
if (!class_data->neigh_info_list) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
class_data->list_size = list_size;
|
||||||
|
ws_neighbor_class_entry_t *list_ptr = class_data->neigh_info_list;
|
||||||
|
for (uint8_t i = 0; i < list_size; i++) {
|
||||||
|
memset(list_ptr, 0, sizeof(ws_neighbor_class_entry_t));
|
||||||
|
list_ptr->rsl_in = RSL_UNITITIALIZED;
|
||||||
|
list_ptr->rsl_out = RSL_UNITITIALIZED;
|
||||||
|
list_ptr++;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ws_neighbor_class_dealloc(ws_neighbor_class_t *class_data)
|
||||||
|
{
|
||||||
|
ns_dyn_mem_free(class_data->neigh_info_list);
|
||||||
|
class_data->neigh_info_list = NULL;
|
||||||
|
class_data->list_size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ws_neighbor_class_entry_t *ws_neighbor_class_entry_get(ws_neighbor_class_t *class_data, uint8_t attribute_index)
|
||||||
|
{
|
||||||
|
if (!class_data->neigh_info_list || attribute_index >= class_data->list_size) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ws_neighbor_class_entry_t *entry = class_data->neigh_info_list + attribute_index;
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t ws_neighbor_class_entry_index_get(ws_neighbor_class_t *class_data, ws_neighbor_class_entry_t *entry)
|
||||||
|
{
|
||||||
|
if (!class_data->neigh_info_list) {
|
||||||
|
return 0xff;
|
||||||
|
}
|
||||||
|
return entry - class_data->neigh_info_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ws_neighbor_class_entry_remove(ws_neighbor_class_t *class_data, uint8_t attribute_index)
|
||||||
|
{
|
||||||
|
ws_neighbor_class_entry_t *entry = ws_neighbor_class_entry_get(class_data, attribute_index);
|
||||||
|
if (entry) {
|
||||||
|
memset(entry, 0, sizeof(ws_neighbor_class_entry_t));
|
||||||
|
entry->rsl_in = RSL_UNITITIALIZED;
|
||||||
|
entry->rsl_out = RSL_UNITITIALIZED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ws_neighbor_class_neighbor_unicast_time_info_update(ws_neighbor_class_entry_t *ws_neighbor, ws_utt_ie_t *ws_utt, uint32_t timestamp)
|
||||||
|
{
|
||||||
|
ws_neighbor->fhss_data.uc_timing_info.utt_rx_timestamp = timestamp;
|
||||||
|
ws_neighbor->fhss_data.uc_timing_info.ufsi = ws_utt->ufsi;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ws_neighbor_class_neighbor_unicast_schedule_set(ws_neighbor_class_entry_t *ws_neighbor, ws_us_ie_t *ws_us)
|
||||||
|
{
|
||||||
|
ws_neighbor->fhss_data.uc_timing_info.unicast_channel_function = ws_us->channel_function;
|
||||||
|
if (ws_us->channel_function == WS_FIXED_CHANNEL) {
|
||||||
|
ws_neighbor->fhss_data.uc_timing_info.fixed_channel = ws_us->function.zero.fixed_channel;
|
||||||
|
ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels = 1;
|
||||||
|
} else {
|
||||||
|
if (ws_us->channel_plan == 0) {
|
||||||
|
ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels = ws_common_channel_number_calc(ws_us->plan.zero.regulator_domain, ws_us->plan.zero.operation_class);
|
||||||
|
} else if (ws_us->channel_plan == 1) {
|
||||||
|
ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels = ws_us->plan.one.number_of_channel;
|
||||||
|
} else {
|
||||||
|
ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ws_neighbor->fhss_data.uc_timing_info.unicast_dwell_interval = ws_us->dwell_interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ws_neighbor_class_neighbor_broadcast_time_info_update(ws_neighbor_class_entry_t *ws_neighbor, ws_bt_ie_t *ws_bt_ie, uint32_t timestamp)
|
||||||
|
{
|
||||||
|
ws_neighbor->broadcast_timing_info_stored = true;
|
||||||
|
ws_neighbor->fhss_data.bc_timing_info.bt_rx_timestamp = timestamp;
|
||||||
|
ws_neighbor->fhss_data.bc_timing_info.broadcast_slot = ws_bt_ie->broadcast_slot_number;
|
||||||
|
ws_neighbor->fhss_data.bc_timing_info.broadcast_interval_offset = ws_bt_ie->broadcast_interval_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ws_neighbor_class_neighbor_broadcast_schedule_set(ws_neighbor_class_entry_t *ws_neighbor, ws_bs_ie_t *ws_bs_ie)
|
||||||
|
{
|
||||||
|
ws_neighbor->broadcast_shedule_info_stored = true;
|
||||||
|
ws_neighbor->fhss_data.bc_timing_info.broadcast_channel_function = ws_bs_ie->channel_function;
|
||||||
|
if (ws_bs_ie->channel_function == WS_FIXED_CHANNEL) {
|
||||||
|
ws_neighbor->fhss_data.bc_timing_info.fixed_channel = ws_bs_ie->function.zero.fixed_channel;
|
||||||
|
}
|
||||||
|
ws_neighbor->fhss_data.bc_timing_info.broadcast_dwell_interval = ws_bs_ie->dwell_interval;
|
||||||
|
ws_neighbor->fhss_data.bc_timing_info.broadcast_interval = ws_bs_ie->broadcast_interval;
|
||||||
|
ws_neighbor->fhss_data.bc_timing_info.broadcast_schedule_id = ws_bs_ie->broadcast_schedule_identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t ws_neighbor_class_rssi_from_dbm_calculate(int8_t dbm_heard)
|
||||||
|
{
|
||||||
|
if (DEVICE_MIN_SENS > dbm_heard) {
|
||||||
|
// We are hearing packet with lower than min_sens dynamically learn the sensitivity
|
||||||
|
tr_info("heard packet below min sensitivity");
|
||||||
|
DEVICE_MIN_SENS = dbm_heard;
|
||||||
|
}
|
||||||
|
return dbm_heard - DEVICE_MIN_SENS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ws_neighbor_class_parent_set_analyze(ws_neighbor_class_entry_t *ws_neighbor)
|
||||||
|
{
|
||||||
|
if (ws_neighbor->rsl_in == RSL_UNITITIALIZED ||
|
||||||
|
ws_neighbor->rsl_out == RSL_UNITITIALIZED) {
|
||||||
|
ws_neighbor->candidate_parent = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ws_neighbor_class_rsl_in_get(ws_neighbor) < (CAND_PARENT_THRESHOLD - CAND_PARENT_HYSTERISIS) &&
|
||||||
|
ws_neighbor_class_rsl_out_get(ws_neighbor) < (CAND_PARENT_THRESHOLD - CAND_PARENT_HYSTERISIS)) {
|
||||||
|
ws_neighbor->candidate_parent = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ws_neighbor_class_rsl_in_get(ws_neighbor) > (CAND_PARENT_THRESHOLD + CAND_PARENT_HYSTERISIS) &&
|
||||||
|
ws_neighbor_class_rsl_out_get(ws_neighbor) > (CAND_PARENT_THRESHOLD + CAND_PARENT_HYSTERISIS)) {
|
||||||
|
ws_neighbor->candidate_parent = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ws_neighbor_class_rsl_in_calculate(ws_neighbor_class_entry_t *ws_neighbor, int8_t dbm_heard)
|
||||||
|
{
|
||||||
|
uint8_t rssi = ws_neighbor_class_rssi_from_dbm_calculate(dbm_heard);
|
||||||
|
if (ws_neighbor->rsl_in == RSL_UNITITIALIZED) {
|
||||||
|
ws_neighbor->rsl_in = rssi << WS_RSL_SCALING;
|
||||||
|
}
|
||||||
|
ws_neighbor->rsl_in = ws_neighbor->rsl_in + rssi - (ws_neighbor->rsl_in >> WS_RSL_SCALING);
|
||||||
|
ws_neighbor_class_parent_set_analyze(ws_neighbor);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ws_neighbor_class_rsl_out_calculate(ws_neighbor_class_entry_t *ws_neighbor, uint8_t rsl_reported)
|
||||||
|
{
|
||||||
|
if (ws_neighbor->rsl_out == RSL_UNITITIALIZED) {
|
||||||
|
ws_neighbor->rsl_out = rsl_reported << WS_RSL_SCALING;
|
||||||
|
}
|
||||||
|
ws_neighbor->rsl_out = ws_neighbor->rsl_out + rsl_reported - (ws_neighbor->rsl_out >> WS_RSL_SCALING);
|
||||||
|
ws_neighbor_class_parent_set_analyze(ws_neighbor);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HAVE_WS */
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
* Copyright (c) 2018-2019, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -0,0 +1,603 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2019, 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"
|
||||||
|
#include <string.h>
|
||||||
|
#include "ns_types.h"
|
||||||
|
#include "ns_list.h"
|
||||||
|
#include "ns_trace.h"
|
||||||
|
#include "nsdynmemLIB.h"
|
||||||
|
#include "fhss_config.h"
|
||||||
|
#include "eventOS_event.h"
|
||||||
|
#include "eventOS_scheduler.h"
|
||||||
|
#include "eventOS_event_timer.h"
|
||||||
|
#include "ns_address.h"
|
||||||
|
#include "NWK_INTERFACE/Include/protocol.h"
|
||||||
|
#include "6LoWPAN/ws/ws_config.h"
|
||||||
|
#include "Security/kmp/kmp_addr.h"
|
||||||
|
#include "Security/kmp/kmp_api.h"
|
||||||
|
#include "Security/kmp/kmp_socket_if.h"
|
||||||
|
#include "Security/protocols/sec_prot_certs.h"
|
||||||
|
#include "Security/protocols/sec_prot_keys.h"
|
||||||
|
#include "Security/protocols/key_sec_prot/key_sec_prot.h"
|
||||||
|
#include "Security/protocols/eap_tls_sec_prot/auth_eap_tls_sec_prot.h"
|
||||||
|
#include "Security/protocols/tls_sec_prot/tls_sec_prot.h"
|
||||||
|
#include "Security/protocols/fwh_sec_prot/auth_fwh_sec_prot.h"
|
||||||
|
#include "Security/protocols/gkh_sec_prot/auth_gkh_sec_prot.h"
|
||||||
|
#include "6LoWPAN/ws/ws_pae_controller.h"
|
||||||
|
#include "6LoWPAN/ws/ws_pae_auth.h"
|
||||||
|
#include "6LoWPAN/ws/ws_pae_lib.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_WS
|
||||||
|
#ifdef HAVE_PAE_AUTH
|
||||||
|
|
||||||
|
#define TRACE_GROUP "wspa"
|
||||||
|
|
||||||
|
#define PAE_TASKLET_INIT 1
|
||||||
|
#define PAE_TASKLET_EVENT 2
|
||||||
|
#define PAE_TASKLET_TIMER 3
|
||||||
|
|
||||||
|
// Wait for for supplicant to indicate activity (e.g. to send a message)
|
||||||
|
#define WAIT_FOR_AUTHENTICATION_TICKS 5 * 60 * 10 // 5 minutes
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ns_list_link_t link; /**< Link */
|
||||||
|
kmp_service_t *kmp_service; /**< KMP service */
|
||||||
|
protocol_interface_info_entry_t *interface_ptr; /**< Interface pointer */
|
||||||
|
supp_list_t active_supp_list; /**< List of active supplicants */
|
||||||
|
supp_list_t inactive_supp_list; /**< List of inactive supplicants */
|
||||||
|
arm_event_storage_t *timer; /**< Timer */
|
||||||
|
sec_prot_gtk_keys_t *gtks; /**< GTKs */
|
||||||
|
const sec_prot_certs_t *certs; /**< Certificates */
|
||||||
|
bool timer_running; /**< Timer is running */
|
||||||
|
} pae_auth_t;
|
||||||
|
|
||||||
|
static void ws_pae_auth_free(pae_auth_t *pae_auth);
|
||||||
|
static pae_auth_t *ws_pae_auth_get(protocol_interface_info_entry_t *interface_ptr);
|
||||||
|
static pae_auth_t *ws_pae_auth_by_kmp_service_get(kmp_service_t *service);
|
||||||
|
static int8_t ws_pae_auth_event_send(kmp_service_t *service, void *data);
|
||||||
|
static void ws_pae_auth_tasklet_handler(arm_event_s *event);
|
||||||
|
static int8_t ws_pae_auth_timer_if_start(kmp_service_t *service, kmp_api_t *kmp);
|
||||||
|
static int8_t ws_pae_auth_timer_if_stop(kmp_service_t *service, kmp_api_t *kmp);
|
||||||
|
static int8_t ws_pae_auth_timer_start(pae_auth_t *pae_auth);
|
||||||
|
static int8_t ws_pae_auth_timer_stop(pae_auth_t *pae_auth);
|
||||||
|
static bool ws_pae_auth_timer_running(pae_auth_t *pae_auth);
|
||||||
|
static void ws_pae_auth_kmp_service_addr_get(kmp_service_t *service, kmp_api_t *kmp, kmp_addr_t *local_addr, kmp_addr_t *remote_addr);
|
||||||
|
static kmp_api_t *ws_pae_auth_kmp_service_api_get(kmp_service_t *service, kmp_api_t *kmp, kmp_type_e type);
|
||||||
|
static kmp_api_t *ws_pae_auth_kmp_incoming_ind(kmp_service_t *service, kmp_type_e type, const kmp_addr_t *addr);
|
||||||
|
static void ws_pae_auth_kmp_api_create_confirm(kmp_api_t *kmp, kmp_result_e result);
|
||||||
|
static void ws_pae_auth_kmp_api_create_indication(kmp_api_t *kmp, kmp_type_e type, kmp_addr_t *addr);
|
||||||
|
static void ws_pae_auth_kmp_api_finished_indication(kmp_api_t *kmp, kmp_result_e result, kmp_sec_keys_t *sec_keys);
|
||||||
|
static kmp_api_t *ws_pae_auth_kmp_create_and_start(kmp_service_t *service, kmp_type_e type, supp_entry_t *supp_entry);
|
||||||
|
static void ws_pae_auth_kmp_api_finished(kmp_api_t *kmp);
|
||||||
|
|
||||||
|
static int8_t tasklet_id = -1;
|
||||||
|
static NS_LIST_DEFINE(pae_auth_list, pae_auth_t, link);
|
||||||
|
|
||||||
|
int8_t ws_pae_auth_init(protocol_interface_info_entry_t *interface_ptr, sec_prot_gtk_keys_t *gtks, const sec_prot_certs_t *certs)
|
||||||
|
{
|
||||||
|
if (!interface_ptr || !gtks || !certs) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ws_pae_auth_get(interface_ptr) != NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pae_auth_t *pae_auth = ns_dyn_mem_alloc(sizeof(pae_auth_t));
|
||||||
|
if (!pae_auth) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pae_auth->interface_ptr = interface_ptr;
|
||||||
|
ws_pae_lib_supp_list_init(&pae_auth->active_supp_list);
|
||||||
|
ws_pae_lib_supp_list_init(&pae_auth->inactive_supp_list);
|
||||||
|
pae_auth->timer = NULL;
|
||||||
|
|
||||||
|
pae_auth->gtks = gtks;
|
||||||
|
pae_auth->certs = certs;
|
||||||
|
|
||||||
|
pae_auth->kmp_service = kmp_service_create();
|
||||||
|
if (!pae_auth->kmp_service) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kmp_service_cb_register(pae_auth->kmp_service, ws_pae_auth_kmp_incoming_ind, ws_pae_auth_kmp_service_addr_get, ws_pae_auth_kmp_service_api_get)) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kmp_service_event_if_register(pae_auth->kmp_service, ws_pae_auth_event_send)) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kmp_service_timer_if_register(pae_auth->kmp_service, ws_pae_auth_timer_if_start, ws_pae_auth_timer_if_stop)) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key_sec_prot_register(pae_auth->kmp_service) < 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auth_eap_tls_sec_prot_register(pae_auth->kmp_service) < 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (server_tls_sec_prot_register(pae_auth->kmp_service) < 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auth_fwh_sec_prot_register(pae_auth->kmp_service) < 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auth_gkh_sec_prot_register(pae_auth->kmp_service) < 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tasklet_id < 0) {
|
||||||
|
tasklet_id = eventOS_event_handler_create(ws_pae_auth_tasklet_handler, PAE_TASKLET_INIT);
|
||||||
|
if (tasklet_id < 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ws_pae_auth_timer_stop(pae_auth) < 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
ns_list_add_to_end(&pae_auth_list, pae_auth);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
ws_pae_auth_free(pae_auth);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t ws_pae_auth_addresses_set(protocol_interface_info_entry_t *interface_ptr, uint16_t local_port, const uint8_t *remote_addr, uint16_t remote_port)
|
||||||
|
{
|
||||||
|
if (!interface_ptr || !remote_addr) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pae_auth_t *pae_auth = ws_pae_auth_get(interface_ptr);
|
||||||
|
if (!pae_auth) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!pae_auth->kmp_service) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kmp_socket_if_register(pae_auth->kmp_service, local_port, remote_addr, remote_port) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t ws_pae_auth_delete(protocol_interface_info_entry_t *interface_ptr)
|
||||||
|
{
|
||||||
|
if (!interface_ptr) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pae_auth_t *pae_auth = ws_pae_auth_get(interface_ptr);
|
||||||
|
if (!pae_auth) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ws_pae_auth_free(pae_auth);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ws_pae_auth_free(pae_auth_t *pae_auth)
|
||||||
|
{
|
||||||
|
if (!pae_auth) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ws_pae_lib_supp_list_delete(&pae_auth->active_supp_list);
|
||||||
|
ws_pae_lib_supp_list_delete(&pae_auth->inactive_supp_list);
|
||||||
|
|
||||||
|
kmp_socket_if_unregister(pae_auth->kmp_service);
|
||||||
|
|
||||||
|
kmp_service_delete(pae_auth->kmp_service);
|
||||||
|
|
||||||
|
ns_list_remove(&pae_auth_list, pae_auth);
|
||||||
|
ns_dyn_mem_free(pae_auth);
|
||||||
|
}
|
||||||
|
|
||||||
|
static pae_auth_t *ws_pae_auth_get(protocol_interface_info_entry_t *interface_ptr)
|
||||||
|
{
|
||||||
|
ns_list_foreach(pae_auth_t, entry, &pae_auth_list) {
|
||||||
|
if (entry->interface_ptr == interface_ptr) {
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static pae_auth_t *ws_pae_auth_by_kmp_service_get(kmp_service_t *service)
|
||||||
|
{
|
||||||
|
ns_list_foreach(pae_auth_t, entry, &pae_auth_list) {
|
||||||
|
if (entry->kmp_service == service) {
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int8_t ws_pae_auth_event_send(kmp_service_t *service, void *data)
|
||||||
|
{
|
||||||
|
pae_auth_t *pae_auth = ws_pae_auth_by_kmp_service_get(service);
|
||||||
|
if (!pae_auth) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
arm_event_s event = {
|
||||||
|
.receiver = tasklet_id,
|
||||||
|
.sender = 0,
|
||||||
|
.event_id = pae_auth->interface_ptr->id,
|
||||||
|
.data_ptr = data,
|
||||||
|
.event_type = PAE_TASKLET_EVENT,
|
||||||
|
.priority = ARM_LIB_LOW_PRIORITY_EVENT,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (eventOS_event_send(&event) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ws_pae_auth_tasklet_handler(arm_event_s *event)
|
||||||
|
{
|
||||||
|
if (event->event_type == PAE_TASKLET_INIT) {
|
||||||
|
|
||||||
|
} else if (event->event_type == PAE_TASKLET_EVENT) {
|
||||||
|
pae_auth_t *pae_auth = NULL;
|
||||||
|
|
||||||
|
ns_list_foreach(pae_auth_t, entry, &pae_auth_list) {
|
||||||
|
if (entry->interface_ptr->id == event->event_id) {
|
||||||
|
pae_auth = entry;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pae_auth) {
|
||||||
|
kmp_service_event_if_event(pae_auth->kmp_service, event->data_ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ws_pae_auth_timer(uint16_t ticks)
|
||||||
|
{
|
||||||
|
ns_list_foreach(pae_auth_t, pae_auth, &pae_auth_list) {
|
||||||
|
if (!ws_pae_auth_timer_running(pae_auth)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Updates KMP timers
|
||||||
|
bool running = ws_pae_lib_supp_list_timer_update(&pae_auth->active_supp_list, &pae_auth->inactive_supp_list, ticks, kmp_service_timer_if_timeout);
|
||||||
|
if (!running) {
|
||||||
|
ws_pae_auth_timer_stop(pae_auth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int8_t ws_pae_auth_timer_if_start(kmp_service_t *service, kmp_api_t *kmp)
|
||||||
|
{
|
||||||
|
pae_auth_t *pae_auth = ws_pae_auth_by_kmp_service_get(service);
|
||||||
|
if (!pae_auth) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ws_pae_auth_timer_start(pae_auth) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
supp_entry_t *supp_entry = kmp_api_data_get(kmp);
|
||||||
|
if (!supp_entry) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
kmp_entry_t *entry = ws_pae_lib_kmp_list_entry_get(&supp_entry->kmp_list, kmp);
|
||||||
|
if (!entry) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ws_pae_lib_supp_list_to_active(&pae_auth->active_supp_list, &pae_auth->inactive_supp_list, supp_entry);
|
||||||
|
|
||||||
|
ws_pae_lib_kmp_timer_start(&supp_entry->kmp_list, entry);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int8_t ws_pae_auth_timer_if_stop(kmp_service_t *service, kmp_api_t *kmp)
|
||||||
|
{
|
||||||
|
(void) service;
|
||||||
|
|
||||||
|
supp_entry_t *supp_entry = kmp_api_data_get(kmp);
|
||||||
|
|
||||||
|
kmp_entry_t *entry = ws_pae_lib_kmp_list_entry_get(&supp_entry->kmp_list, kmp);
|
||||||
|
if (!entry) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ws_pae_lib_kmp_timer_stop(&supp_entry->kmp_list, entry);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int8_t ws_pae_auth_timer_start(pae_auth_t *pae_auth)
|
||||||
|
{
|
||||||
|
pae_auth->timer_running = true;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int8_t ws_pae_auth_timer_stop(pae_auth_t *pae_auth)
|
||||||
|
{
|
||||||
|
pae_auth->timer_running = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ws_pae_auth_timer_running(pae_auth_t *pae_auth)
|
||||||
|
{
|
||||||
|
return pae_auth->timer_running;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ws_pae_auth_kmp_service_addr_get(kmp_service_t *service, kmp_api_t *kmp, kmp_addr_t *local_addr, kmp_addr_t *remote_addr)
|
||||||
|
{
|
||||||
|
(void) service;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// Get own EUI-64
|
||||||
|
link_layer_address_s mac_params;
|
||||||
|
if (arm_nwk_mac_address_read(pae_auth->interface_ptr->id, &mac_params) >= 0) {
|
||||||
|
kmp_address_eui_64_set(local_addr, mac_params.mac_long);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// For now fixed since not yet support for EA-IE in supplicants
|
||||||
|
uint8_t addr[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
|
||||||
|
kmp_address_eui_64_set(local_addr, addr);
|
||||||
|
|
||||||
|
// Get supplicant address
|
||||||
|
supp_entry_t *entry = kmp_api_data_get(kmp);
|
||||||
|
if (entry && entry->addr) {
|
||||||
|
kmp_address_copy(remote_addr, entry->addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static kmp_api_t *ws_pae_auth_kmp_service_api_get(kmp_service_t *service, kmp_api_t *kmp, kmp_type_e type)
|
||||||
|
{
|
||||||
|
(void) service;
|
||||||
|
|
||||||
|
supp_entry_t *supp_entry = kmp_api_data_get(kmp);
|
||||||
|
if (!supp_entry) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ws_pae_lib_kmp_list_type_get(&supp_entry->kmp_list, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
static kmp_api_t *ws_pae_auth_kmp_incoming_ind(kmp_service_t *service, kmp_type_e type, const kmp_addr_t *addr)
|
||||||
|
{
|
||||||
|
pae_auth_t *pae_auth = ws_pae_auth_by_kmp_service_get(service);
|
||||||
|
if (!pae_auth) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find supplicant from list of active supplicants
|
||||||
|
supp_entry_t *supp_entry = ws_pae_lib_supp_list_entry_eui_64_get(&pae_auth->active_supp_list, kmp_address_eui_64_get(addr));
|
||||||
|
|
||||||
|
if (!supp_entry) {
|
||||||
|
// Find supplicant from list of inactive supplicants
|
||||||
|
supp_entry = ws_pae_lib_supp_list_entry_eui_64_get(&pae_auth->inactive_supp_list, kmp_address_eui_64_get(addr));
|
||||||
|
if (supp_entry) {
|
||||||
|
// Move supplicant to active list
|
||||||
|
ws_pae_lib_supp_list_to_active(&pae_auth->active_supp_list, &pae_auth->inactive_supp_list, supp_entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If does not exists add it to list
|
||||||
|
if (!supp_entry) {
|
||||||
|
supp_entry = ws_pae_lib_supp_list_add(&pae_auth->active_supp_list, addr);
|
||||||
|
if (!supp_entry) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
sec_prot_keys_init(&supp_entry->sec_keys, pae_auth->gtks, pae_auth->certs);
|
||||||
|
} else {
|
||||||
|
// Updates relay address
|
||||||
|
kmp_address_copy(supp_entry->addr, addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Increases waiting time for supplicant authentication
|
||||||
|
ws_pae_lib_supp_timer_ticks_set(supp_entry, WAIT_FOR_AUTHENTICATION_TICKS);
|
||||||
|
|
||||||
|
// Get KMP for supplicant
|
||||||
|
kmp_api_t *kmp = ws_pae_lib_kmp_list_type_get(&supp_entry->kmp_list, type);
|
||||||
|
if (kmp) {
|
||||||
|
return kmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new KMP for initial eapol-key
|
||||||
|
kmp = kmp_api_create(service, type + IEEE_802_1X_INITIAL_KEY);
|
||||||
|
|
||||||
|
if (!kmp) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
kmp_api_data_set(kmp, supp_entry);
|
||||||
|
// Sets address to KMP
|
||||||
|
kmp_api_addr_set(kmp, supp_entry->addr);
|
||||||
|
|
||||||
|
// Sets security keys to KMP
|
||||||
|
kmp_api_sec_keys_set(kmp, &supp_entry->sec_keys);
|
||||||
|
|
||||||
|
if (ws_pae_lib_kmp_list_add(&supp_entry->kmp_list, kmp) == NULL) {
|
||||||
|
kmp_api_delete(kmp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
kmp_api_cb_register(kmp,
|
||||||
|
ws_pae_auth_kmp_api_create_confirm,
|
||||||
|
ws_pae_auth_kmp_api_create_indication,
|
||||||
|
ws_pae_auth_kmp_api_finished_indication,
|
||||||
|
ws_pae_auth_kmp_api_finished);
|
||||||
|
|
||||||
|
if (kmp_api_start(kmp) < 0) {
|
||||||
|
ws_pae_lib_kmp_list_delete(&supp_entry->kmp_list, kmp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return kmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ws_pae_auth_kmp_api_create_confirm(kmp_api_t *kmp, kmp_result_e result)
|
||||||
|
{
|
||||||
|
(void) kmp;
|
||||||
|
(void) result;
|
||||||
|
// If KMP-CREATE.request has failed, authentication error, just stop for now
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ws_pae_auth_kmp_api_create_indication(kmp_api_t *kmp, kmp_type_e type, kmp_addr_t *addr)
|
||||||
|
{
|
||||||
|
(void) type;
|
||||||
|
(void) addr;
|
||||||
|
// For now, accept every KMP-CREATE.indication
|
||||||
|
kmp_api_create_response(kmp, KMP_RESULT_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ws_pae_auth_kmp_api_finished_indication(kmp_api_t *kmp, kmp_result_e result, kmp_sec_keys_t *sec_keys)
|
||||||
|
{
|
||||||
|
(void) sec_keys;
|
||||||
|
|
||||||
|
// For now, just ignore if not ok
|
||||||
|
if (result != KMP_RESULT_OK) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
supp_entry_t *supp_entry = kmp_api_data_get(kmp);
|
||||||
|
if (!supp_entry) {
|
||||||
|
// Should not be possible
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets type
|
||||||
|
kmp_type_e type = kmp_api_type_get(kmp);
|
||||||
|
|
||||||
|
if (type > IEEE_802_1X_INITIAL_KEY) {
|
||||||
|
// For EAPOL-key, start EAP-TLS towards supplicant
|
||||||
|
type = IEEE_802_1X_MKA;
|
||||||
|
tr_debug("PAE start EAP-TLS, eui-64: %s", trace_array(kmp_address_eui_64_get(supp_entry->addr), 8));
|
||||||
|
} else if (type == IEEE_802_1X_MKA) {
|
||||||
|
// After EAP-TLS start 4WH towards supplicant
|
||||||
|
type = IEEE_802_11_4WH;
|
||||||
|
// Insert GTK0
|
||||||
|
sec_prot_keys_gtk_insert_index_set(supp_entry->sec_keys.gtks, 0);
|
||||||
|
tr_debug("PAE start 4WH, eui-64: %s", trace_array(kmp_address_eui_64_get(supp_entry->addr), 8));
|
||||||
|
} else if (type == IEEE_802_11_4WH) {
|
||||||
|
// After 4WH start GKH towards supplicant
|
||||||
|
type = IEEE_802_11_GKH;
|
||||||
|
// Insert GTK1
|
||||||
|
sec_prot_keys_gtk_insert_index_set(supp_entry->sec_keys.gtks, 1);
|
||||||
|
tr_debug("PAE start GKH, eui-64: %s", trace_array(kmp_address_eui_64_get(supp_entry->addr), 8));
|
||||||
|
} else if (type == IEEE_802_11_GKH) {
|
||||||
|
tr_debug("PAE authenticated, eui-64: %s", trace_array(kmp_address_eui_64_get(supp_entry->addr), 8));
|
||||||
|
// After GKH end
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Increases waiting time for supplicant authentication
|
||||||
|
ws_pae_lib_supp_timer_ticks_set(supp_entry, WAIT_FOR_AUTHENTICATION_TICKS);
|
||||||
|
|
||||||
|
kmp_service_t *service = kmp_api_service_get(kmp);
|
||||||
|
pae_auth_t *pae_auth = ws_pae_auth_by_kmp_service_get(service);
|
||||||
|
if (!pae_auth) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create new instance
|
||||||
|
kmp_api_t *new_kmp = ws_pae_auth_kmp_create_and_start(pae_auth->kmp_service, type, supp_entry);
|
||||||
|
if (!new_kmp) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For EAP-TLS create also TLS in addition to EAP-TLS
|
||||||
|
if (type == IEEE_802_1X_MKA) {
|
||||||
|
if (ws_pae_lib_kmp_list_type_get(&supp_entry->kmp_list, TLS_PROT) != NULL) {
|
||||||
|
// TLS already exists, wait for it to be deleted
|
||||||
|
ws_pae_lib_kmp_list_delete(&supp_entry->kmp_list, new_kmp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Create TLS instance */
|
||||||
|
if (ws_pae_auth_kmp_create_and_start(service, TLS_PROT, supp_entry) == NULL) {
|
||||||
|
ws_pae_lib_kmp_list_delete(&supp_entry->kmp_list, new_kmp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
kmp_api_create_request(new_kmp, type, supp_entry->addr, &supp_entry->sec_keys);
|
||||||
|
}
|
||||||
|
|
||||||
|
static kmp_api_t *ws_pae_auth_kmp_create_and_start(kmp_service_t *service, kmp_type_e type, supp_entry_t *supp_entry)
|
||||||
|
{
|
||||||
|
// Create KMP instance for new authentication
|
||||||
|
kmp_api_t *kmp = kmp_api_create(service, type);
|
||||||
|
|
||||||
|
if (!kmp) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ws_pae_lib_kmp_list_add(&supp_entry->kmp_list, kmp) == NULL) {
|
||||||
|
kmp_api_delete(kmp);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
kmp_api_cb_register(kmp,
|
||||||
|
ws_pae_auth_kmp_api_create_confirm,
|
||||||
|
ws_pae_auth_kmp_api_create_indication,
|
||||||
|
ws_pae_auth_kmp_api_finished_indication,
|
||||||
|
ws_pae_auth_kmp_api_finished);
|
||||||
|
|
||||||
|
kmp_api_data_set(kmp, supp_entry);
|
||||||
|
|
||||||
|
if (kmp_api_start(kmp) < 0) {
|
||||||
|
ws_pae_lib_kmp_list_delete(&supp_entry->kmp_list, kmp);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return kmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ws_pae_auth_kmp_api_finished(kmp_api_t *kmp)
|
||||||
|
{
|
||||||
|
supp_entry_t *supp_entry = kmp_api_data_get(kmp);
|
||||||
|
if (!supp_entry) {
|
||||||
|
// Should not be possible
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete KMP
|
||||||
|
ws_pae_lib_kmp_list_delete(&supp_entry->kmp_list, kmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HAVE_PAE_AUTH */
|
||||||
|
#endif /* HAVE_WS */
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2019, 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 WS_PAE_AUTH_H_
|
||||||
|
#define WS_PAE_AUTH_H_
|
||||||
|
|
||||||
|
#ifdef HAVE_PAE_AUTH
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Authenticator port access entity controls key security protocols using KMP API.
|
||||||
|
*
|
||||||
|
* Configures KMP service network access and provides timing and callback services
|
||||||
|
* for it. Registers needed security protocols to KMP service.
|
||||||
|
*
|
||||||
|
* PAE Maintains security keys that are internal to port access entity for
|
||||||
|
* each supplicant and maintains supplicant security registration state.
|
||||||
|
*
|
||||||
|
* Autenticator PAE controls network access keys and provides new network
|
||||||
|
* access keys to supplicants when they are changed. When supplicant
|
||||||
|
* network keys are updated, also other keys (master key, pairwise key)
|
||||||
|
* are updated as needed.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ws_pae_auth_init initializes PAE authenticator
|
||||||
|
*
|
||||||
|
* \param interface_ptr interface
|
||||||
|
* \param local_port local port
|
||||||
|
* \param remote_addr remote address
|
||||||
|
* \param remote_port remote port
|
||||||
|
* \param gtks group keys
|
||||||
|
* \param cert_chain certificate chain
|
||||||
|
*
|
||||||
|
* \return < 0 failure
|
||||||
|
* \return >= 0 success
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int8_t ws_pae_auth_init(protocol_interface_info_entry_t *interface_ptr, sec_prot_gtk_keys_t *gtks, const sec_prot_certs_t *certs);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ws_pae_auth_addresses_set set relay addresses
|
||||||
|
*
|
||||||
|
* \param interface_ptr interface
|
||||||
|
* \param local_port local port
|
||||||
|
* \param remote_addr remote address
|
||||||
|
* \param remote_port remote port
|
||||||
|
*
|
||||||
|
* \return < 0 failure
|
||||||
|
* \return >= 0 success
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int8_t ws_pae_auth_addresses_set(protocol_interface_info_entry_t *interface_ptr, uint16_t local_port, const uint8_t *remote_addr, uint16_t remote_port);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ws_pae_auth_delete deletes PAE authenticator
|
||||||
|
*
|
||||||
|
* \param interface_ptr interface
|
||||||
|
*
|
||||||
|
* \return < 0 failure
|
||||||
|
* \return >= 0 success
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int8_t ws_pae_auth_delete(protocol_interface_info_entry_t *interface_ptr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ws_pae_auth_timer PAE authenticator timer call
|
||||||
|
*
|
||||||
|
* \param ticks elapsed ticks
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void ws_pae_auth_timer(uint16_t ticks);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define ws_pae_auth_init(interface_ptr, gtks, certs) 1
|
||||||
|
#define ws_pae_auth_addresses_set(interface_ptr, local_port, remote_addr, remote_port) 1
|
||||||
|
#define ws_pae_auth_delete NULL
|
||||||
|
#define ws_pae_auth_timer NULL
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* WS_PAE_AUTH_H_ */
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue