From e68e86317e3525b398d2769cae3d6d0a08646948 Mon Sep 17 00:00:00 2001 From: Yakun Xu Date: Sat, 2 Feb 2019 08:08:43 +0800 Subject: [PATCH] [ci] test with time sync and header ie (#3514) This commit adds the missing test with ie present by enabling TIME_SYNC feature, so that IE code are covered. --- .travis.yml | 4 ++ examples/common-switches.mk | 4 ++ examples/platforms/posix/Makefile.am | 2 +- examples/platforms/posix/sim/alarm-sim.c | 12 ++++++ examples/platforms/posix/sim/radio-sim.c | 44 ++++++++++++++++++++++ include/openthread/platform/time.h | 6 +-- tests/scripts/thread-cert/config.py | 5 ++- tests/scripts/thread-cert/mac802154.py | 41 +++++++++++++++++++- tests/scripts/thread-cert/mle.py | 25 ++++++++++++ tests/scripts/thread-cert/network_layer.py | 13 +++++++ tests/unit/test_platform.cpp | 16 ++++++++ 11 files changed, 166 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index d3780b2e7..288459c64 100644 --- a/.travis.yml +++ b/.travis.yml @@ -73,6 +73,10 @@ matrix: os: linux compiler: gcc python: "2.7" + - env: BUILD_TARGET="posix-32-bit" VERBOSE=1 VIRTUAL_TIME=1 TIME_SYNC=1 + os: linux + compiler: gcc + python: "2.7" - env: BUILD_TARGET="posix-ncp" VERBOSE=1 VIRTUAL_TIME=1 os: linux compiler: gcc diff --git a/examples/common-switches.mk b/examples/common-switches.mk index fb680f932..211493c6f 100644 --- a/examples/common-switches.mk +++ b/examples/common-switches.mk @@ -131,6 +131,10 @@ ifeq ($(SNTP_CLIENT),1) configure_OPTIONS += --enable-sntp-client endif +ifeq ($(TIME_SYNC),1) +COMMONCFLAGS += -DPENTHREAD_CONFIG_ENABLE_TIME_SYNC=1 +endif + ifeq ($(UDP_FORWARD),1) configure_OPTIONS += --enable-udp-forward endif diff --git a/examples/platforms/posix/Makefile.am b/examples/platforms/posix/Makefile.am index f9f64c0cd..90e73224b 100644 --- a/examples/platforms/posix/Makefile.am +++ b/examples/platforms/posix/Makefile.am @@ -54,7 +54,7 @@ PLATFORM_SOURCES = \ $(NULL) libopenthread_posix_a_SOURCES = \ - $(PLATFORM_SOURCES) \ + $(PLATFORM_SOURCES) \ $(NULL) noinst_HEADERS = \ diff --git a/examples/platforms/posix/sim/alarm-sim.c b/examples/platforms/posix/sim/alarm-sim.c index 66da3e26b..fe309d01e 100644 --- a/examples/platforms/posix/sim/alarm-sim.c +++ b/examples/platforms/posix/sim/alarm-sim.c @@ -181,4 +181,16 @@ void platformAlarmProcess(otInstance *aInstance) #endif // OPENTHREAD_CONFIG_ENABLE_PLATFORM_USEC_TIMER } +#if OPENTHREAD_CONFIG_ENABLE_TIME_SYNC +uint64_t otPlatTimeGet(void) +{ + return platformAlarmGetNow(); +} + +uint16_t otPlatTimeGetXtalAccuracy(void) +{ + return 0; +} +#endif // OPENTHREAD_CONFIG_ENABLE_TIME_SYNC + #endif // OPENTHREAD_POSIX_VIRTUAL_TIME diff --git a/examples/platforms/posix/sim/radio-sim.c b/examples/platforms/posix/sim/radio-sim.c index d22b9db51..f15f79aa3 100644 --- a/examples/platforms/posix/sim/radio-sim.c +++ b/examples/platforms/posix/sim/radio-sim.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "utils/code_utils.h" @@ -107,6 +108,11 @@ static otRadioFrame sReceiveFrame; static otRadioFrame sTransmitFrame; static otRadioFrame sAckFrame; +#if OPENTHREAD_CONFIG_HEADER_IE_SUPPORT +static otRadioIeInfo sTransmitIeInfo; +static otRadioIeInfo sReceivedIeInfo; +#endif + static uint8_t sExtendedAddress[OT_EXT_ADDRESS_SIZE]; static uint16_t sShortAddress; static uint16_t sPanid; @@ -376,6 +382,13 @@ void platformRadioInit(void) sReceiveFrame.mPsdu = sReceiveMessage.mPsdu; sTransmitFrame.mPsdu = sTransmitMessage.mPsdu; sAckFrame.mPsdu = sAckMessage.mPsdu; +#if OPENTHREAD_CONFIG_HEADER_IE_SUPPORT + sTransmitFrame.mIeInfo = &sTransmitIeInfo; + sReceiveFrame.mIeInfo = &sReceivedIeInfo; +#else + sTransmitFrame.mIeInfo = NULL; + sReceiveFrame.mIeInfo = NULL; +#endif } bool otPlatRadioIsEnabled(otInstance *aInstance) @@ -494,6 +507,9 @@ void platformRadioReceive(otInstance *aInstance, uint8_t *aBuf, uint16_t aBufLen sReceiveFrame.mInfo.mRxInfo.mUsec = 0; // Don't support microsecond timer for now. } +#if OPENTHREAD_CONFIG_ENABLE_TIME_SYNC + sReceiveFrame.mIeInfo->mTimestamp = otPlatTimeGet(); +#endif sReceiveFrame.mLength = (uint8_t)(aBufLength - 1); if (sState == OT_RADIO_STATE_TRANSMIT && sAckWait && !isAckRequested(sTransmitFrame.mPsdu) && @@ -544,6 +560,34 @@ void platformRadioReceive(otInstance *aInstance, uint8_t *aBuf, uint16_t aBufLen void radioSendMessage(otInstance *aInstance) { +#if OPENTHREAD_CONFIG_HEADER_IE_SUPPORT + bool notifyFrameUpdated = false; + +#if OPENTHREAD_CONFIG_ENABLE_TIME_SYNC + if (sTransmitFrame.mIeInfo->mTimeIeOffset != 0) + { + uint8_t *timeIe = sTransmitFrame.mPsdu + sTransmitFrame.mIeInfo->mTimeIeOffset; + uint64_t time = (uint64_t)((int64_t)otPlatTimeGet() + sTransmitFrame.mIeInfo->mNetworkTimeOffset); + + *timeIe = sTransmitFrame.mIeInfo->mTimeSyncSeq; + + *(++timeIe) = (uint8_t)(time & 0xff); + for (uint8_t i = 1; i < sizeof(uint64_t); i++) + { + time = time >> 8; + *(++timeIe) = (uint8_t)(time & 0xff); + } + + notifyFrameUpdated = true; + } +#endif // OPENTHREAD_CONFIG_ENABLE_TIME_SYNC + + if (notifyFrameUpdated) + { + otPlatRadioFrameUpdated(aInstance, &sTransmitFrame); + } +#endif // OPENTHREAD_CONFIG_HEADER_IE_SUPPORT + sTransmitMessage.mChannel = sTransmitFrame.mChannel; otPlatRadioTxStarted(aInstance, &sTransmitFrame); diff --git a/include/openthread/platform/time.h b/include/openthread/platform/time.h index 113dc4b82..eecb34b84 100644 --- a/include/openthread/platform/time.h +++ b/include/openthread/platform/time.h @@ -32,8 +32,8 @@ * This file includes the platform abstraction for the time service. */ -#ifndef TIME_H_ -#define TIME_H_ +#ifndef OPENTHREAD_PLATFORM_TIME_H_ +#define OPENTHREAD_PLATFORM_TIME_H_ #include @@ -76,4 +76,4 @@ uint16_t otPlatTimeGetXtalAccuracy(void); } // extern "C" #endif -#endif // TIME_H_ +#endif // OPENTHREAD_PLATFORM_TIME_H_ diff --git a/tests/scripts/thread-cert/config.py b/tests/scripts/thread-cert/config.py index 5d4c8430b..825d28909 100644 --- a/tests/scripts/thread-cert/config.py +++ b/tests/scripts/thread-cert/config.py @@ -177,7 +177,9 @@ def create_default_mle_tlvs_factories(): mle.TlvType.PENDING_TIMESTAMP: mle.PendingTimestampFactory(), mle.TlvType.ACTIVE_OPERATIONAL_DATASET: mle.ActiveOperationalDatasetFactory(), mle.TlvType.PENDING_OPERATIONAL_DATASET: mle.PendingOperationalDatasetFactory(), - mle.TlvType.THREAD_DISCOVERY: mle.ThreadDiscoveryFactory() + mle.TlvType.THREAD_DISCOVERY: mle.ThreadDiscoveryFactory(), + mle.TlvType.TIME_REQUEST: mle.TimeRequestFactory(), + mle.TlvType.TIME_PARAMETER: mle.TimeParameterFactory(), } @@ -205,6 +207,7 @@ def create_deafult_network_tlvs_factories(): network_layer.TlvType.ND_OPTION: network_layer.NdOptionFactory(), network_layer.TlvType.ND_DATA: network_layer.NdDataFactory(), network_layer.TlvType.THREAD_NETWORK_DATA: network_layer.ThreadNetworkDataFactory(create_default_network_data_tlvs_factory()), + network_layer.TlvType.XTAL_ACCURACY: network_layer.XtalAccuracyFactory(), # Routing information are distributed in a Thread network by MLE Routing TLV # which is in fact MLE Route64 TLV. Thread specificaton v1.1. - Chapter 5.20 diff --git a/tests/scripts/thread-cert/mac802154.py b/tests/scripts/thread-cert/mac802154.py index 8e9eef3f4..a8897a90c 100644 --- a/tests/scripts/thread-cert/mac802154.py +++ b/tests/scripts/thread-cert/mac802154.py @@ -32,6 +32,7 @@ """ import io +import binascii import struct import config @@ -115,6 +116,13 @@ class MacFrame: """Class representing 802.15.4 MAC frame.""" + IEEE802154_HEADER_IE_TYPE_MASK = 0x8000 + IEEE802154_HEADER_IE_ID_MASK = 0x7f80 + IEEE802154_HEADER_IE_LENGTH_MASK = 0x007f + + IEEE802154_HEADER_IE_HT1 = 0x7e + IEEE802154_HEADER_IE_HT2 = 0x7f + def parse(self, data): mhr_start = data.tell() @@ -128,6 +136,7 @@ class MacFrame: dest_addr_mode = (fc & 0x0c00) >> 10 frame_version = (fc & 0x3000) >> 12 source_addr_mode = (fc & 0xc000) >> 14 + ie_present = bool(fc & 0x0200) if frame_type == MacHeader.FrameType.ACK: fcs = self._parse_fcs(data, data.tell()) @@ -140,7 +149,21 @@ class MacFrame: dest_address = self._parse_address(data, dest_addr_mode) - if not panid_compression: + src_pan_present = not panid_compression + while src_pan_present: + if frame_version < 2: + break + if frame_version == 3: + assert(false) + if dest_addr_mode == 0: + break + if dest_addr_mode == 2: + break + if dest_addr_mode == 3 and source_addr_mode == 2: + break + src_pan_present = False + + if src_pan_present: src_pan_id = struct.unpack("> 7) + header_ie_length = (header_ie & MacFrame.IEEE802154_HEADER_IE_LENGTH_MASK) + if header_ie_length: + data.read(header_ie_length) + + if header_ie_id in [MacFrame.IEEE802154_HEADER_IE_HT1, MacFrame.IEEE802154_HEADER_IE_HT2]: + break + header_ie_end = data.tell() + # Check end of MAC frame if frame_type == MacHeader.FrameType.COMMAND: command_type = ord(data.read(1)) @@ -196,6 +232,9 @@ class MacFrame: non_payload_fields = bytearray([]) + if ie_present: + data.seek(header_ie_start) + non_payload_fields += data.read(header_ie_end - header_ie_start) if command_type is not None: non_payload_fields.append(command_type) diff --git a/tests/scripts/thread-cert/mle.py b/tests/scripts/thread-cert/mle.py index 24135dde6..b63465664 100644 --- a/tests/scripts/thread-cert/mle.py +++ b/tests/scripts/thread-cert/mle.py @@ -58,6 +58,7 @@ class CommandType(IntEnum): ANNOUNCE = 15 DISCOVERY_REQUEST = 16 DISCOVERY_RESPONSE = 17 + TIME_SYNC = 99 class TlvType(IntEnum): @@ -86,6 +87,8 @@ class TlvType(IntEnum): ACTIVE_OPERATIONAL_DATASET = 24 PENDING_OPERATIONAL_DATASET = 25 THREAD_DISCOVERY = 26 + TIME_REQUEST = 252 + TIME_PARAMETER = 253 class SourceAddress(object): @@ -1018,6 +1021,28 @@ class ThreadDiscoveryFactory: def parse(self, data, message_info): return ThreadDiscovery() +class TimeRequest: + # TODO: Not implemented yet + + def __init__(self): + print("TimeRequest is not implemented yet.") + +class TimeRequestFactory: + + def parse(self, data, message_info): + return TimeRequest() + +class TimeParameter: + # TODO: Not implemented yet + + def __init__(self): + print("TimeParameter is not implemented yet.") + + +class TimeParameterFactory: + + def parse(self, data, message_info): + return TimeParameter() class MleCommand(object): diff --git a/tests/scripts/thread-cert/network_layer.py b/tests/scripts/thread-cert/network_layer.py index c6eb6301a..d4cde02ab 100644 --- a/tests/scripts/thread-cert/network_layer.py +++ b/tests/scripts/thread-cert/network_layer.py @@ -48,6 +48,7 @@ class TlvType(IntEnum): ND_DATA = 9 THREAD_NETWORK_DATA = 10 MLE_ROUTING = 11 + XTAL_ACCURACY = 254 class StatusValues(IntEnum): @@ -274,6 +275,18 @@ class NdDataFactory(object): def parse(self, data, message_info): raise NotImplementedError("TODO: Not implemented yet") +class XtalAccuracy: + # TODO: Not implemented yet + + def __init__(self): + print("XtalAccuracy is not implemented yet.") + + +class XtalAccuracyFactory: + + def parse(self, data, message_info): + return XtalAccuracy() + class ThreadNetworkData(object): diff --git a/tests/unit/test_platform.cpp b/tests/unit/test_platform.cpp index 268c156e7..9c2273034 100644 --- a/tests/unit/test_platform.cpp +++ b/tests/unit/test_platform.cpp @@ -571,4 +571,20 @@ void otPlatSettingsWipe(otInstance *aInstance) (void)aInstance; } +#if OPENTHREAD_CONFIG_ENABLE_TIME_SYNC +uint64_t otPlatTimeGet(void) +{ + struct timeval tv; + + gettimeofday(&tv, NULL); + + return (uint64_t)tv.tv_sec * 1000000 + (uint64_t)tv.tv_usec; +} + +uint16_t otPlatTimeGetXtalAccuracy(void) +{ + return 0; +} +#endif // OPENTHREAD_CONFIG_ENABLE_TIME_SYNC + } // extern "C"