diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..3f3dd2aa --- /dev/null +++ b/.clang-format @@ -0,0 +1,113 @@ +--- +Language: Cpp +# BasedOnStyle: LLVM +AccessModifierOffset: -4 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: true +AlignConsecutiveDeclarations: true +AlignEscapedNewlines: Left +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: true +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: false +BinPackArguments: true +BinPackParameters: false +BraceWrapping: + AfterCaseLabel: true + AfterClass: true + AfterControlStatement: true + AfterEnum: true + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: true + AfterUnion: true + BeforeCatch: false + BeforeElse: true + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Custom +BreakBeforeInheritanceComma: false +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeComma +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 120 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeCategories: + - Regex: '^ + -*, + bugprone-argument-comment, + bugprone-too-small-loop-variable, + google-explicit-constructor, + google-readability-casting, + misc-unused-using-decls, + modernize-loop-convert, + modernize-use-bool-literals, + modernize-use-equals-default, + modernize-use-equals-delete, + modernize-use-nullptr, + readability-avoid-const-params-in-decls, + readability-else-after-return, + readability-inconsistent-declaration-parameter-name, + readability-make-member-function-const, + readability-redundant-control-flow, + readability-redundant-member-init, + readability-simplify-boolean-expr, + readability-static-accessed-through-instance +WarningsAsErrors: '*' +HeaderFilterRegex: '(examples|include|src).*(? oldTime { reEvaluateTime, isUpdated := node.failureCtrl.OnTimeAdvanced(oldTime) if isUpdated { diff --git a/dispatcher/dispatcher.go b/dispatcher/dispatcher.go index d95af622..2ce00913 100644 --- a/dispatcher/dispatcher.go +++ b/dispatcher/dispatcher.go @@ -406,7 +406,7 @@ func (d *Dispatcher) handleRecvEvent(evt *Event) { switch evt.Type { case EventTypeAlarmFired: d.Counters.AlarmEvents += 1 - if evt.MsgId == node.msgId { // if OT-node has seen my last sent event (so is done processing) + if evt.MsgId == node.msgId { // if OT-node has seen my last sent event (so it is done processing) d.setSleeping(node.Id) } d.alarmMgr.SetTimestamp(nodeid, d.CurTime+delay) // schedule future wake-up of node @@ -443,8 +443,9 @@ func (d *Dispatcher) handleRecvEvent(evt *Event) { case EventTypeUdpFromHost, EventTypeIp6FromHost: d.Counters.HostEvents += 1 - evt.MustDispatch = true // asap resend again to the target (BR) node. - d.eventQueue.Add(evt) + evt2 := evt.Copy() + evt2.MustDispatch = true // asap resend again to the target (BR) node. + d.eventQueue.Add(&evt2) default: d.Counters.OtherEvents += 1 d.cbHandler.OnRfSimEvent(node.Id, evt) @@ -909,7 +910,7 @@ func (d *Dispatcher) syncAliveNodes() { return } - logger.Warnf("syncing %d alive nodes: %v", len(d.aliveNodes), d.aliveNodes) + logger.Warnf("syncing %d non-responding (alive) nodes: %v at simtime=%v", len(d.aliveNodes), d.aliveNodes, d.CurTime) for nodeid := range d.aliveNodes { d.advanceNodeTime(d.nodes[nodeid], d.CurTime, true) } diff --git a/etc/ot-registrar/credentials_registrar.p12 b/etc/ot-registrar/credentials_registrar.p12 new file mode 100644 index 00000000..42c1feb0 Binary files /dev/null and b/etc/ot-registrar/credentials_registrar.p12 differ diff --git a/event/event.go b/event/event.go index 262e01ff..e9e3f45b 100644 --- a/event/event.go +++ b/event/event.go @@ -28,12 +28,10 @@ package event import ( "encoding/binary" + "encoding/hex" "fmt" "math" "net" - "strings" - "unicode" - "net/netip" "github.com/openthread/ot-ns/logger" @@ -240,7 +238,7 @@ func (e *Event) Deserialize(data []byte) int { } data2 := make([]byte, datalen-payloadOffset) - copy(data2, e.Data[payloadOffset:payloadOffset+datalen]) + copy(data2, e.Data[payloadOffset:datalen]) e.Data = data2 // e.Timestamp is not in the event, so set to invalid initially. @@ -316,12 +314,13 @@ func (e *Event) Copy() Event { func (e *Event) String() string { paylStr := "" if len(e.Data) > 0 { - paylStr = fmt.Sprintf(",payl=%s", keepPrintableChars(string(e.Data))) + paylStr = fmt.Sprintf(",payl=%s", hex.EncodeToString(e.Data)) } s := fmt.Sprintf("Ev{%2d,nid=%d,mid=%d,dly=%v%s}", e.Type, e.NodeId, e.MsgId, e.Delay, paylStr) return s } +/* func keepPrintableChars(s string) string { return strings.Map(func(r rune) rune { if unicode.IsPrint(r) { @@ -330,3 +329,4 @@ func keepPrintableChars(s string) string { return -1 }, s) } +*/ diff --git a/event/event_test.go b/event/event_test.go index eee42ad2..7942bb33 100644 --- a/event/event_test.go +++ b/event/event_test.go @@ -28,9 +28,8 @@ package event import ( "encoding/hex" - "testing" - "net/netip" + "testing" "github.com/openthread/ot-ns/types" "github.com/stretchr/testify/assert" @@ -304,3 +303,26 @@ func TestEventCopy(t *testing.T) { assert.Equal(t, uint8(types.OT_ERROR_FCS), evCopy.RadioCommData.Error) assert.Equal(t, uint64(11234), evCopy.MsgId) } + +func TestDeserializeEventFromLargerData(t *testing.T) { + data, _ := hex.DecodeString("0403020100000000060c0d0e0f00000000100002b01140e201000000000002102030400809070605040302010000") + ev := Event{} + n := ev.Deserialize(data) + assert.Equal(t, 35, n) + assert.Equal(t, 35-eventMsgHeaderLen-radioCommEventDataHeaderLen, len(ev.Data)) +} + +func TestDeserializeEventFromTooLittleData(t *testing.T) { + // header intact, but incomplete data (i.e. datalen too large) + data, _ := hex.DecodeString("0403020100000000060c0d0e0f00000000100002b01140e201000000000002102030") + ev := Event{} + n := ev.Deserialize(data) + assert.Equal(t, 0, n) + assert.Equal(t, 0, len(ev.Data)) + + data, _ = hex.DecodeString("0403020100000000060c0d0e0f00000000") + ev = Event{} + n = ev.Deserialize(data) + assert.Equal(t, 0, n) + assert.Equal(t, 0, len(ev.Data)) +} diff --git a/openthread b/openthread index d6eb56c3..1c5ad340 160000 --- a/openthread +++ b/openthread @@ -1 +1 @@ -Subproject commit d6eb56c3196acea33f91ecb23a84fa05993e8583 +Subproject commit 1c5ad3403d624c0e57b7a6462aa82d67bf46c690 diff --git a/ot-rfsim/CMakeLists.txt b/ot-rfsim/CMakeLists.txt index 23446b77..ea67eee0 100644 --- a/ot-rfsim/CMakeLists.txt +++ b/ot-rfsim/CMakeLists.txt @@ -41,8 +41,16 @@ if(DEFINED ENV{OT_DIR}) else() set(OT_DIR "${PROJECT_SOURCE_DIR}/../openthread") endif() +if(DEFINED ENV{OTNS_NODE_TYPE}) + set(OTNS_NODE_TYPE "$ENV{OTNS_NODE_TYPE}") + message( "-- [ot-rfsim] Caller has set OTNS_NODE_TYPE to: ${OTNS_NODE_TYPE}") +else() + set(OTNS_NODE_TYPE "custom") +endif() get_filename_component(OT_DIR "${OT_DIR}" REALPATH) -message( "-- [ot-rfsim] Using openthread directory for build: ${OT_DIR}" ) +set(BUILD_DIR "build/ot-rfsim-${OTNS_NODE_TYPE}") +message( "-- [ot-rfsim] Using openthread stack for build : ${OT_DIR}" ) +message( "-- [ot-rfsim] Using openthread build output directory: ${BUILD_DIR}" ) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) @@ -52,7 +60,7 @@ add_definitions( -DRFSIM_SW_VERSION="${CMAKE_PROJECT_VERSION}" ) # an external openthread repo may be defined - its build files are stored in there, so that coverage info # collection will work. -add_subdirectory(${OT_DIR} ${OT_DIR}/build/ot-rfsim) +add_subdirectory(${OT_DIR} ${OT_DIR}/${BUILD_DIR}) target_compile_definitions(ot-config INTERFACE OPENTHREAD_CONFIG_FILE="openthread-core-rfsim-config.h" diff --git a/ot-rfsim/README.md b/ot-rfsim/README.md index a94db17f..e9fe2ab4 100644 --- a/ot-rfsim/README.md +++ b/ot-rfsim/README.md @@ -10,7 +10,7 @@ The easiest way to use this code is just to install OT-NS2, following the [OT-NS This CMake project requires an [openthread](https://github.com/openthread/openthread) repository to build the OT nodes. This can be a custom one, indicated by the environment variable `OT_DIR`, or else the default openthread -repository will be seleted which is a Git submodule located in `../openthread`. If not yet initialized, this submodule +repository will be selected which is a Git submodule located in `../openthread`. If not yet initialized, this submodule will be automatically initialized upon first build. ## Building @@ -19,7 +19,7 @@ For more detailed building instructions see [GUIDE.md](../GUIDE.md). ### Build for use in OT-NS with custom build configuration -Below shows first an example default build for use of the binaries in OT-NS simulation. +Below shows first an example custom build to generate the OT node binaries for an OT-NS simulation. This includes debug logging, for extra debug info that can then be optionally displayed in OT-NS using the `watch` command. The OT debug logging is also stored in a log file, per node. @@ -27,7 +27,10 @@ This includes debug logging, for extra debug info that can then be optionally di $ ./script/build ``` -Below shows an example build for OT-NS with build option OT_FULL_LOGS set to 'OFF', to disable the debug logging. +The new executables will end up in the directory `build/custom/bin` by default. Within 'build', there are subdirectories +for different node type builds, depending on which build scripts are run (see further below). + +Below shows an example custom build for OT-NS with build option OT_FULL_LOGS set to 'OFF', to disable the debug logging. This helps to speed up the simulation because far less socket communication events are then generated. ```bash @@ -42,23 +45,23 @@ reason to disable it for an FTD build. (E.g. because a separate MTD build is don $ ./script/build -DOT_CSL_RECEIVER=OFF ``` -After a successful build, the executable files are found in the directory `./build/bin`. +After a successful build, the executable files are found in the directory `./build/custom/bin`. -### Build default v1.1, v1.2, v1.3, or v1.\ nodes for OT-NS +### Build default v1.1, v1.2, v1.3, v1.\ , or Border Router nodes for OT-NS There are some scripts (`./script/build_*`) for building specific versions of OpenThread nodes for use in OT-NS. There are specific commands in OT-NS to add e.g. v1.1, or v1.2 nodes, all mixed in one simulation. -These build scripts produce executables that are copied into the `ot-versions` directory. The scripts will check out -specific commits in the `openthread` repository. For this reason, these scripts won't work with an openthread -Git repository that is cloned with only depth 1. +These build scripts produce executables that are copied into the `ot-versions` directory. The scripts will use +specific branches of the `openthread` repository, which are included as submodules in the Git OTNS project. +To keep the data size small, each submodule is cloned shallow (depth=1) by default. ## Running -The built executables in `bin` can be briefly tested on the command line as follows: +The built custom executables in `bin` can be briefly tested on the command line as follows: ```bash -$ cd build/bin +$ cd build/custom/bin $ ./ot-cli-ftd Usage: ot-cli-ftd [] $ @@ -69,10 +72,10 @@ This will print a usage message and exit the node. The `ot-cli-ftd` is by default used in the OT-NS simulator for the "router" and "fed" (FTD) node types. The `ot-cli-mtd` is by default used for MED, SED and SSED. The BR uses `ot-cli-ftd_br`. -One way to use the `ot-cli-ftd` is to `cd` to the path where the file is and start OT-NS: +One way (but not recommended) is to use the `ot-cli-ftd` is to `cd` to the path where the file is and start OT-NS: ```bash -$ cd build/bin +$ cd build/custom/bin $ otns > add router x 50 y 50 1 @@ -80,6 +83,8 @@ Done > ``` -Another way is to run OT-NS from the same directory from where it was installed. In this case, it will use +The standard way is to run OT-NS from the same directory from where it was installed. In this case, it will use the binaries that are built into `./ot-rfsim/ot-versions`. These binaries can be -built using the various `./script/build_*` scripts. +built using the various `./script/build_*` scripts. Users can copy their own builds into this folder as well and +refer to the named binaries when starting a new node in OTNS. + diff --git a/ot-rfsim/ot-versions/README.md b/ot-rfsim/ot-versions/README.md index fb6ccd88..2f923d55 100644 --- a/ot-rfsim/ot-versions/README.md +++ b/ot-rfsim/ot-versions/README.md @@ -20,5 +20,9 @@ that version is located as a Git submodule. - br - `openthread` - Same code as 'latest', but builds a Thread Border Router (BR). +- ccm - `openthread-ccm` - (In development) A codebase supporting Thread Commercial Commissioning Mode (CCM). + +- br-ccm - `openthread-ccm` - (In development) A Thread CCM Border Router. + Build scripts: the build scripts to build all of the versions are `../script/build_`. Each of these specific build scripts invokes the general `build` script. The `../script/build_all` builds all versions. diff --git a/ot-rfsim/script/build b/ot-rfsim/script/build index 16693952..c5f30be5 100755 --- a/ot-rfsim/script/build +++ b/ot-rfsim/script/build @@ -31,10 +31,12 @@ set -euxo pipefail OTRFSIM_SRCDIR="$(pwd)" OT_DIR=${OT_DIR:-../openthread} +OT_CMAKE_NINJA_TARGET=${OT_CMAKE_NINJA_TARGET-} readonly OTRFSIM_SRCDIR readonly OT_DIR # OpenThread options that are always added to build first. They can be overridden on the command line. +# Specific build scripts for OT versions can and will override these options (partially). OT_OPTIONS=( "-DCMAKE_BUILD_TYPE=Debug" "-DOT_PLATFORM=external" @@ -55,7 +57,8 @@ readonly OT_OPTIONS build() { - local builddir="${OT_CMAKE_BUILD_DIR:-build}" + local nodetype="${OTNS_NODE_TYPE:-custom}" + local builddir="${OT_CMAKE_BUILD_DIR:-build/${nodetype}}" mkdir -p "${builddir}" cd "${builddir}" @@ -65,14 +68,21 @@ build() old_ot_dir=$(cat OT_DIR.txt) fi if [[ ${OT_DIR} != "${old_ot_dir}" ]]; then - echo "Detected new version build of OpenThread: cleaning build dir." + echo "Detected different OT version build into existing build dir: cleaning build dir." rm -rf ../"${builddir}"/* rm -rf ../"${builddir}"/.ninja* fi echo "${OT_DIR}" >OT_DIR.txt + export OT_CMAKE_BUILD_DIR="${builddir}" + export OTNS_NODE_TYPE="${nodetype}" cmake -GNinja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DOT_COMPILE_WARNING_AS_ERROR=ON "$@" "${OTRFSIM_SRCDIR}" - ninja ot-cli-ftd ot-cli-mtd + if [[ -z ${OT_CMAKE_NINJA_TARGET// /} ]]; then + ninja + else + IFS=' ' read -r -a OT_CMAKE_NINJA_TARGET <<<"${OT_CMAKE_NINJA_TARGET}" + ninja "${OT_CMAKE_NINJA_TARGET[@]}" + fi cd "${OTRFSIM_SRCDIR}" } diff --git a/ot-rfsim/script/build_all b/ot-rfsim/script/build_all index 2116253c..a7533959 100755 --- a/ot-rfsim/script/build_all +++ b/ot-rfsim/script/build_all @@ -27,10 +27,16 @@ # POSSIBILITY OF SUCH DAMAGE. # -printf "\n./script/build_all -- builds only OT node versions for which executables are not found.\n\n" +printf "\n./script/build_all -- builds all OT node versions (that weren't built yet or require an update)\n\n" set -euo pipefail +build_error() +{ + printf '\n****************\n Failed build script: %s - stopping.\n****************\n\n' "$@" + exit 1 +} + main() { local options=() @@ -38,19 +44,16 @@ main() for VER in v11 v12 v13 latest br; do SCRIPTNAME="./script/build_$VER" - FTDNAME="./ot-versions/ot-cli-ftd_$VER" - if [ "$VER" == "latest" ]; then - FTDNAME="./ot-versions/ot-cli-ftd" - fi - if [ -f $FTDNAME ]; then - printf '\n%s: file %s is present, skipping this version build.\n\n' "${VER}" "${FTDNAME}" + printf 'Node %s: building with script %s\n' "${VER}" "${SCRIPTNAME}" + if ${SCRIPTNAME} "${options[@]}" ; then + printf 'Node %s: completed build with script %s\n' "${VER}" "${SCRIPTNAME}" else - printf '%s: building %s' "${VER}" "${FTDNAME}" - ${SCRIPTNAME} "${options[@]}" || printf \ - '\n********************\n Failed build script: %s - skipping.\n********************\n\n' "${SCRIPTNAME}" + build_error "${SCRIPTNAME}" fi done + + printf '\nSuccessfully completed building all OT node versions.\n' } main "$@" diff --git a/ot-rfsim/script/build_br b/ot-rfsim/script/build_br index 78b6095a..edae9453 100755 --- a/ot-rfsim/script/build_br +++ b/ot-rfsim/script/build_br @@ -61,9 +61,9 @@ main() local options=() options+=("${OTBR_OPTIONS[@]}" "$@") - ./script/build "${options[@]}" ot-cli-ftd + OT_DIR="../openthread" OTNS_NODE_TYPE="br" OT_CMAKE_NINJA_TARGET="ot-cli-ftd" ./script/build "${options[@]}" - cp ./build/bin/ot-cli-ftd ./ot-versions/ot-cli-ftd_br + cp ./build/br/bin/ot-cli-ftd ./ot-versions/ot-cli-ftd_br } main "$@" diff --git a/ot-rfsim/script/build_br_ccm b/ot-rfsim/script/build_br_ccm new file mode 100755 index 00000000..f052ba16 --- /dev/null +++ b/ot-rfsim/script/build_br_ccm @@ -0,0 +1,70 @@ +#!/bin/bash +# +# Copyright (c) 2024, The OpenThread Authors. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of the copyright holder nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +set -euxo pipefail + +# OpenThread CCM Border Router (OTBR) specific options. These are superimposed on the standard +# options in './build'. +OTBR_OPTIONS=( + "-DOT_THREAD_VERSION=1.4" + "-DOT_VENDOR_MODEL=RFSIM-CCM-BR-v1.4.0" + "-DOT_BACKBONE_ROUTER=ON" + "-DOT_BACKBONE_ROUTER_MULTICAST_ROUTING=ON" + "-DOT_BORDER_ROUTER=ON" + "-DOT_BORDER_ROUTING=ON" + "-DOT_BORDER_ROUTING_DHCP6_PD=ON" + "-DOT_BORDER_ROUTING_COUNTERS=ON" + "-DOT_NAT64_BORDER_ROUTING=ON" + "-DOT_BORDER_AGENT=ON" + "-DOT_MLR=ON" + "-DOT_UDP_FORWARD=ON" + "-DOT_COAP_BLOCK=ON" + "-DOT_DNSSD_SERVER=ON" + "-DOT_NETDATA_PUBLISHER=ON" + "-DOT_SRP_SERVER=ON" + "-DOT_TREL=OFF" + "-DOT_POWER_SUPPLY=EXTERNAL" + "-DOT_DEVICE_PROP_LEADER_WEIGHT=ON" + "-DOT_MLE_MAX_CHILDREN=32" + "-DOT_HISTORY_TRACKER=ON" + "-DOT_CCM=ON" +) +readonly OTBR_OPTIONS + +main() +{ + local options=() + options+=("${OTBR_OPTIONS[@]}" "$@") + + OT_DIR="../openthread-ccm" OTNS_NODE_TYPE="br-ccm" OT_CMAKE_NINJA_TARGET="ot-cli-ftd" ./script/build "${options[@]}" + + cp ./build/br-ccm/bin/ot-cli-ftd ./ot-versions/ot-cli-ftd_br_ccm +} + +main "$@" diff --git a/ot-rfsim/script/test b/ot-rfsim/script/build_ccm similarity index 62% rename from ot-rfsim/script/test rename to ot-rfsim/script/build_ccm index f4297d9a..558c6891 100755 --- a/ot-rfsim/script/test +++ b/ot-rfsim/script/build_ccm @@ -1,6 +1,6 @@ #!/bin/bash # -# Copyright (c) 2022, The OpenThread Authors. +# Copyright (c) 2024, The OpenThread Authors. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -29,21 +29,39 @@ set -euxo pipefail -OT_BUILDDIR="$(pwd)/build" -readonly OT_BUILDDIR - OT_OPTIONS=( - "-DOT_COMPILE_WARNING_AS_ERROR=ON" + "-DOT_THREAD_VERSION=1.4" + "-DOT_VENDOR_MODEL=RFSIM-CCM-v1.4.0" + "-DOT_BACKBONE_ROUTER=OFF" + "-DOT_BACKBONE_ROUTER_MULTICAST_ROUTING=OFF" + "-DOT_BORDER_ROUTER=ON" + "-DOT_BORDER_ROUTING=OFF" + "-DOT_BORDER_ROUTING_DHCP6_PD=OFF" + "-DOT_BORDER_ROUTING_COUNTERS=OFF" + "-DOT_NAT64_BORDER_ROUTING=OFF" + "-DOT_MLR=ON" + "-DOT_COAP_BLOCK=OFF" + "-DOT_DNSSD_SERVER=OFF" + "-DOT_NETDATA_PUBLISHER=ON" + "-DOT_SRP_SERVER=OFF" + "-DOT_TREL=OFF" + "-DOT_POWER_SUPPLY=EXTERNAL" + "-DOT_DEVICE_PROP_LEADER_WEIGHT=ON" + "-DOT_HISTORY_TRACKER=OFF" + "-DOT_BLE_TCAT=ON" + "-DOT_CCM=ON" ) readonly OT_OPTIONS main() { - export CPPFLAGS="${CPPFLAGS:-} -DNDEBUG" + local options=() + options+=("${OT_OPTIONS[@]}" "$@") - rm -rf "$OT_BUILDDIR" - "$(dirname "$0")"/build "${OT_OPTIONS[@]}" + OT_DIR="../openthread-ccm" OTNS_NODE_TYPE="ccm" OT_CMAKE_NINJA_TARGET="ot-cli-ftd ot-cli-mtd" ./script/build "${options[@]}" + cp ./build/ccm/bin/ot-cli-ftd ./ot-versions/ot-cli-ftd_ccm + cp ./build/ccm/bin/ot-cli-mtd ./ot-versions/ot-cli-mtd_ccm } main "$@" diff --git a/ot-rfsim/script/build_latest b/ot-rfsim/script/build_latest index 56508f38..1592bf91 100755 --- a/ot-rfsim/script/build_latest +++ b/ot-rfsim/script/build_latest @@ -57,9 +57,10 @@ main() local options=() options+=("${OT_OPTIONS[@]}" "$@") - ./script/build "${options[@]}" + OT_DIR="../openthread" OTNS_NODE_TYPE="latest" OT_CMAKE_NINJA_TARGET="ot-cli-ftd ot-cli-mtd" ./script/build "${options[@]}" - cp ./build/bin/ot-cli-?td ./ot-versions/ + cp ./build/latest/bin/ot-cli-ftd ./ot-versions/ + cp ./build/latest/bin/ot-cli-mtd ./ot-versions/ } main "$@" diff --git a/ot-rfsim/script/build_v11 b/ot-rfsim/script/build_v11 index c004787e..e1463fd5 100755 --- a/ot-rfsim/script/build_v11 +++ b/ot-rfsim/script/build_v11 @@ -36,7 +36,15 @@ OT_OPTIONS=( ) readonly OT_OPTIONS -OT_DIR="../openthread-v11" OT_CMAKE_BUILD_DIR="build-v11" ./script/build "${OT_OPTIONS[@]}" +main() +{ + local options=() + options+=("${OT_OPTIONS[@]}" "$@") -cp ./build-v11/bin/ot-cli-ftd ./ot-versions/ot-cli-ftd_v11 -cp ./build-v11/bin/ot-cli-mtd ./ot-versions/ot-cli-mtd_v11 + OT_DIR="../openthread-v11" OTNS_NODE_TYPE="v11" OT_CMAKE_NINJA_TARGET="ot-cli-ftd ot-cli-mtd" ./script/build "${options[@]}" + + cp ./build/v11/bin/ot-cli-ftd ./ot-versions/ot-cli-ftd_v11 + cp ./build/v11/bin/ot-cli-mtd ./ot-versions/ot-cli-mtd_v11 +} + +main "$@" diff --git a/ot-rfsim/script/build_v12 b/ot-rfsim/script/build_v12 index a4c31b0f..831131a1 100755 --- a/ot-rfsim/script/build_v12 +++ b/ot-rfsim/script/build_v12 @@ -37,7 +37,15 @@ OT_OPTIONS=( ) readonly OT_OPTIONS -OT_DIR="../openthread-v12" OT_CMAKE_BUILD_DIR="build-v12" ./script/build "${OT_OPTIONS[@]}" +main() +{ + local options=() + options+=("${OT_OPTIONS[@]}" "$@") -cp ./build-v12/bin/ot-cli-ftd ./ot-versions/ot-cli-ftd_v12 -cp ./build-v12/bin/ot-cli-mtd ./ot-versions/ot-cli-mtd_v12 + OT_DIR="../openthread-v12" OTNS_NODE_TYPE="v12" OT_CMAKE_NINJA_TARGET="ot-cli-ftd ot-cli-mtd" ./script/build "${options[@]}" + + cp ./build/v12/bin/ot-cli-ftd ./ot-versions/ot-cli-ftd_v12 + cp ./build/v12/bin/ot-cli-mtd ./ot-versions/ot-cli-mtd_v12 +} + +main "$@" diff --git a/ot-rfsim/script/build_v13 b/ot-rfsim/script/build_v13 index 878f6e46..8dc2a18c 100755 --- a/ot-rfsim/script/build_v13 +++ b/ot-rfsim/script/build_v13 @@ -48,7 +48,15 @@ OT_OPTIONS=( ) readonly OT_OPTIONS -OT_DIR="../openthread-v13" OT_CMAKE_BUILD_DIR="build-v13" ./script/build "${OT_OPTIONS[@]}" +main() +{ + local options=() + options+=("${OT_OPTIONS[@]}" "$@") -cp ./build-v13/bin/ot-cli-ftd ./ot-versions/ot-cli-ftd_v13 -cp ./build-v13/bin/ot-cli-mtd ./ot-versions/ot-cli-mtd_v13 + OT_DIR="../openthread-v13" OTNS_NODE_TYPE="v13" OT_CMAKE_NINJA_TARGET="ot-cli-ftd ot-cli-mtd" ./script/build "${options[@]}" + + cp ./build/v13/bin/ot-cli-ftd ./ot-versions/ot-cli-ftd_v13 + cp ./build/v13/bin/ot-cli-mtd ./ot-versions/ot-cli-mtd_v13 +} + +main "$@" diff --git a/ot-rfsim/script/make-pretty b/ot-rfsim/script/make-pretty deleted file mode 100755 index 707d6128..00000000 --- a/ot-rfsim/script/make-pretty +++ /dev/null @@ -1,182 +0,0 @@ -#!/bin/bash -# -# Copyright (c) 2019-2024, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -# -# The script to check or format source code of OT-RFSIM. -# -# Format c/c++, markdown, and shell: -# -# script/make-pretty -# -# Format c/c++ only: -# -# script/make-pretty clang-format -# -# Format markdown only: -# -# script/make-pretty markdown -# -# Format shell only: -# -# script/make-pretty shell -# -# Check only: -# -# script/make-pretty check clang-format -# script/make-pretty check markdown -# script/make-pretty check shell -# - -set -euo pipefail - -OT_BUILD_JOBS=$(getconf _NPROCESSORS_ONLN) -readonly OT_BUILD_JOBS - -OT_EXCLUDE_DIRS=(build cmake-build) -readonly OT_EXCLUDE_DIRS - -OT_CLANG_SOURCES=('*.c' '*.cc' '*.cpp' '*.h' '*.hpp') -readonly OT_CLANG_SOURCES - -OT_MARKDOWN_SOURCES=('*.md') -readonly OT_MARKDOWN_SOURCES - -OT_SCRIPT_DIR="$(dirname "$0")"/../../openthread/script -readonly OT_SCRIPT_DIR - -do_clang_format() -{ - echo -e '========================================' - echo -e ' format c/c++ (clang-format)' - echo -e '========================================' - - git ls-files "${OT_CLANG_SOURCES[@]}" | grep -v -E "^($(echo "${OT_EXCLUDE_DIRS[@]}" | tr ' ' '|'))" \ - | xargs -n3 -P"$OT_BUILD_JOBS" "$OT_SCRIPT_DIR"/clang-format -style=file -i -verbose -} - -do_clang_format_check() -{ - echo -e '========================================' - echo -e ' check c/c++ (clang-format)' - echo -e '========================================' - - git ls-files "${OT_CLANG_SOURCES[@]}" | grep -v -E "^($(echo "${OT_EXCLUDE_DIRS[@]}" | tr ' ' '|'))" \ - | xargs -n3 -P"$OT_BUILD_JOBS" "$OT_SCRIPT_DIR"/clang-format-check -} - -do_markdown_format() -{ - echo -e '========================================' - echo -e ' format markdown' - echo -e '========================================' - - git ls-files "${OT_MARKDOWN_SOURCES[@]}" | grep -v -E "^($(echo "${OT_EXCLUDE_DIRS[@]}" | tr ' ' '|'))" \ - | xargs -n10 -P"$OT_BUILD_JOBS" npx prettier@2.0.4 --write -} - -do_markdown_check() -{ - echo -e '========================================' - echo -e ' check markdown' - echo -e '========================================' - - git ls-files "${OT_MARKDOWN_SOURCES[@]}" | grep -v -E "^($(echo "${OT_EXCLUDE_DIRS[@]}" | tr ' ' '|'))" \ - | xargs -n10 -P"$OT_BUILD_JOBS" npx prettier@2.0.4 --check -} - -do_shell_format() -{ - echo -e '========================================' - echo -e ' format shell' - echo -e '========================================' - - git ls-files | xargs shfmt -f | grep -v -E "^($(echo "${OT_EXCLUDE_DIRS[@]}" | tr ' ' '|'))" \ - | xargs -n10 -P"$OT_BUILD_JOBS" shfmt -i 4 -bn -ci -fn -s -w -} - -do_shell_check() -{ - echo -e '========================================' - echo -e ' check shell' - echo -e '========================================' - - git ls-files | xargs shfmt -f | grep -v -E "^($(echo "${OT_EXCLUDE_DIRS[@]}" | tr ' ' '|'))" \ - | xargs -n10 -P"$OT_BUILD_JOBS" shfmt -i 4 -bn -ci -fn -s -d - - git ls-files | xargs shfmt -f | grep -v -E "^($(echo "${OT_EXCLUDE_DIRS[@]}" | tr ' ' '|'))" \ - | xargs -n10 -P"$OT_BUILD_JOBS" shellcheck -} - -do_check() -{ - if [ $# == 0 ]; then - do_clang_format_check - do_markdown_check - do_shell_check - elif [ "$1" == 'clang' ]; then - do_clang_format_check - elif [ "$1" == 'clang-format' ]; then - do_clang_format_check - elif [ "$1" == 'markdown' ]; then - do_markdown_check - elif [ "$1" == 'shell' ]; then - do_shell_check - else - echo >&2 "Unsupported check: $1. Supported: clang-format, markdown, shell" - # 128 for Invalid arguments - exit 128 - fi -} - -main() -{ - if [ $# == 0 ]; then - do_clang_format - do_markdown_format - do_shell_format - elif [ "$1" == 'clang' ]; then - do_clang_format - elif [ "$1" == 'clang-format' ]; then - do_clang_format - elif [ "$1" == 'markdown' ]; then - do_markdown_format - elif [ "$1" == 'shell' ]; then - do_shell_format - elif [ "$1" == 'check' ]; then - shift - do_check "$@" - else - echo >&2 "Unsupported action: $1. Supported: clang-format, markdown, shell" - # 128 for Invalid arguments - exit 128 - fi - -} - -main "$@" diff --git a/ot-rfsim/src/ble.c b/ot-rfsim/src/ble.c index 0df38eba..95098158 100644 --- a/ot-rfsim/src/ble.c +++ b/ot-rfsim/src/ble.c @@ -29,6 +29,7 @@ #if OPENTHREAD_CONFIG_BLE_TCAT_ENABLE #include "platform-rfsim.h" +#include #include #define OT_BLE_ADV_DELAY_MAX_US 10000 @@ -59,6 +60,16 @@ otError otPlatBleDisable(otInstance *aInstance) return OT_ERROR_NONE; } +otError otPlatBleGetAdvertisementBuffer(otInstance *aInstance, uint8_t **aAdvertisementBuffer) +{ + OT_UNUSED_VARIABLE(aInstance); + static uint8_t sAdvertisementBuffer[OT_TCAT_ADVERTISEMENT_MAX_LEN]; + + *aAdvertisementBuffer = sAdvertisementBuffer; + + return OT_ERROR_NONE; +} + otError otPlatBleGapAdvStart(otInstance *aInstance, uint16_t aInterval) { OT_UNUSED_VARIABLE(aInstance); @@ -157,12 +168,12 @@ void platformBleProcess(otInstance *aInstance) { } } -/* -otBleLinkCapabilities otPlatGetBleLinkCapabilities(otInstance *aInstance) +void otPlatBleGetLinkCapabilities(otInstance *aInstance, otBleLinkCapabilities *aBleLinkCapabilities) { OT_UNUSED_VARIABLE(aInstance); - otBleLinkCapabilities dummy = {0}; - return dummy; + aBleLinkCapabilities->mGattNotifications = 1; + aBleLinkCapabilities->mL2CapDirect = 0; + aBleLinkCapabilities->mRsv = 0; } otError otPlatBleGapAdvSetData(otInstance *aInstance, uint8_t *aAdvertisementData, uint16_t aAdvertisementLen) @@ -172,6 +183,11 @@ otError otPlatBleGapAdvSetData(otInstance *aInstance, uint8_t *aAdvertisementDat OT_UNUSED_VARIABLE(aAdvertisementLen); return OT_ERROR_NOT_IMPLEMENTED; } - */ + +bool otPlatBleSupportsMultiRadio(otInstance *aInstance) +{ + OT_UNUSED_VARIABLE(aInstance); + return false; // TODO check +} #endif \ No newline at end of file diff --git a/ot-rfsim/src/openthread-core-rfsim-config.h b/ot-rfsim/src/openthread-core-rfsim-config.h index cb0ac62d..1d458b35 100644 --- a/ot-rfsim/src/openthread-core-rfsim-config.h +++ b/ot-rfsim/src/openthread-core-rfsim-config.h @@ -332,4 +332,14 @@ */ #define OPENTHREAD_CONFIG_OTNS_ENABLE 1 +/** + * @def OPENTHREAD_SIMULATION_VIRTUAL_TIME + * + * MUST be enabled for the RFSIM platform. + * + */ +#ifndef OPENTHREAD_SIMULATION_VIRTUAL_TIME +#define OPENTHREAD_SIMULATION_VIRTUAL_TIME 1 +#endif + #endif // OPENTHREAD_CORE_RFSIM_CONFIG_H_ diff --git a/ot-rfsim/src/platform-rfsim.c b/ot-rfsim/src/platform-rfsim.c index 7a161384..8ccacb20 100644 --- a/ot-rfsim/src/platform-rfsim.c +++ b/ot-rfsim/src/platform-rfsim.c @@ -231,14 +231,16 @@ otError platformUdpFromHostToNode(otInstance *aInstance, const struct MsgToHostE otIp6Address *srcIp6; udp = otUdpNewMessage(aInstance, NULL); - otEXPECT((error = otMessageAppend(udp, aMsg, aMsgLen)) == OT_ERROR_NONE); otEXPECT_ACTION(udp != NULL, error = OT_ERROR_NO_BUFS); + otEXPECT((error = otMessageAppend(udp, aMsg, aMsgLen)) == OT_ERROR_NONE); srcIp6 = (otIp6Address *) aEvData->mSrcIp6; //dstIp6 = (otIp6Address *) aEvData->mDstIp6; otUdpForwardReceive(aInstance, udp, aEvData->mSrcPort, srcIp6, aEvData->mDstPort); exit: + if (error != OT_ERROR_NONE && udp != NULL) + otMessageFree(udp); // only free when otUdpForwardReceive didn't free it. return error; } diff --git a/ot-rfsim/src/radio.c b/ot-rfsim/src/radio.c index bad99f55..327ebdc3 100644 --- a/ot-rfsim/src/radio.c +++ b/ot-rfsim/src/radio.c @@ -1032,10 +1032,23 @@ void radioReceive(otInstance *aInstance, otError aError) if (sTxWait && otMacFrameIsAckRequested(&sTransmitFrame)) { + bool isAwaitedAckReceived = false; otError txDoneError = OT_ERROR_NONE; // TODO: for Enh-Ack, look at address match too. - bool isAwaitedAckReceived = isAck && aError == OT_ERROR_NONE && - otMacFrameGetSequence(&sReceiveFrame) == otMacFrameGetSequence(&sTransmitFrame); + if (isAck && aError == OT_ERROR_NONE) { +#if OPENTHREAD_API_VERSION >= 431 + // this function signature change was in PR #10544, merged very close to API version 431 increase. + uint8_t rxSeqNum; + uint8_t txSeqNum; + if (otMacFrameGetSequence(&sReceiveFrame, &rxSeqNum) == OT_ERROR_NONE) { + if (otMacFrameGetSequence(&sTransmitFrame, &txSeqNum) == OT_ERROR_NONE) { + isAwaitedAckReceived = rxSeqNum == txSeqNum; + } + } +#else + isAwaitedAckReceived = otMacFrameGetSequence(&sReceiveFrame) == otMacFrameGetSequence(&sTransmitFrame); +#endif + } sTxWait = false; if (!isAwaitedAckReceived) { @@ -1048,7 +1061,7 @@ void radioReceive(otInstance *aInstance, otError aError) radioProcessFrame(aInstance, aError); } - exit: +exit: return; } diff --git a/pylibs/otns/cli/OTNS.py b/pylibs/otns/cli/OTNS.py index dc416bc5..f055001f 100644 --- a/pylibs/otns/cli/OTNS.py +++ b/pylibs/otns/cli/OTNS.py @@ -1051,13 +1051,13 @@ def joiner_start(self, nodeid: int, pwd: str) -> None: """ self.node_cmd(nodeid, f"joiner start {pwd}") - def ccm_joiner_start(self, nodeid: int) -> None: + def joiner_startccm(self, nodeid: int) -> None: """ - Start CCM joiner. + Start CCM joiner, using Autonomous Enrollment (AE) with cBRSKI. :param nodeid: joiner node ID """ - self.node_cmd(nodeid, f"joiner ccm") + self.node_cmd(nodeid, f"joiner startccm") def commissioner_joiner_add(self, nodeid: int, usr: str, pwd: str, timeout=None) -> None: """ diff --git a/pylibs/unittests/OTNSTestCase.py b/pylibs/unittests/OTNSTestCase.py index f64c3411..a85aa260 100644 --- a/pylibs/unittests/OTNSTestCase.py +++ b/pylibs/unittests/OTNSTestCase.py @@ -24,6 +24,7 @@ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. + import logging import tracemalloc import unittest diff --git a/pylibs/unittests/test_ccm_commissioning.py b/pylibs/unittests/test_ccm_commissioning.py index 7c7e69cd..1ee40599 100755 --- a/pylibs/unittests/test_ccm_commissioning.py +++ b/pylibs/unittests/test_ccm_commissioning.py @@ -25,48 +25,194 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -import tracemalloc -import unittest import logging +import subprocess +import time +import unittest from OTNSTestCase import OTNSTestCase from otns.cli import OTNS -tracemalloc.start() +class CcmTests(OTNSTestCase): + """ + Thread Commercial Commissioning Mode (CCM) tests. All tests make use of an external server, + OT-Registrar, which runs from a Java JAR file. The Registrar forwards the Voucher, obtained + from the vendor-controlled MASA server, to the Joiner. The Registrar also generates the + final domain identity (LDevID certificate) for the Joiner to use. + See RFC 8995 and IETF ANIMA WG cBRSKI draft for details. + """ -class CommissioningTests(OTNSTestCase): + registrar_process = None def setUp(self) -> None: logging.info("Setting up for test: %s", self.name()) - self.ns = OTNS(otns_args=['-ot-script', 'none', '-log', 'debug']) - self.ns.speed = float('inf') + self.ns = OTNS(otns_args=['-log', 'trace', '-pcap', 'wpan-tap', '-seed', '4']) + self.ns.speed = 1e6 + + def tearDown(self) -> None: + self.stopRegistrar() + super().tearDown() def setFirstNodeDataset(self, n1) -> None: self.ns.node_cmd(n1, "dataset init new") + self.ns.node_cmd(n1, "dataset channel 22") + self.ns.node_cmd(n1, "dataset meshlocalprefix fd00:777e::") self.ns.node_cmd(n1, "dataset networkkey 00112233445566778899aabbccddeeff") # allow easy Wireshark dissecting self.ns.node_cmd(n1, "dataset securitypolicy 672 orcCR 3") # enable CCM-commissioning flag in secpolicy self.ns.node_cmd(n1, "dataset commit active") + def setAlternativeDataset(self, n1) -> None: + self.ns.node_cmd(n1, "dataset init active") + self.ns.node_cmd(n1, "dataset channel 22") + self.ns.node_cmd(n1, "dataset meshlocalprefix fd00:777e::") + self.ns.node_cmd(n1, "dataset securitypolicy 672 orcCR 3") # enable CCM-commissioning flag in secpolicy + self.ns.node_cmd(n1, "dataset commit active") + + def startRegistrar(self): + self.registrar_log_file = open("tmp/ot-registrar.log", 'w') + self.registrar_process = subprocess.Popen(['java', '-jar', './etc/ot-registrar/ot-registrar-0.3-jar-with-dependencies.jar', + '-registrar', '-vv', '-f', './etc/ot-registrar/credentials_registrar.p12'], + stdout = self.registrar_log_file, stderr = subprocess.STDOUT) + self.assertIsNone(self.registrar_process.returncode) + time.sleep(1) # FIXME could detect when Registrar is ready to serve, with process.communicate() + + def stopRegistrar(self): + if self.registrar_process is None: + return + logging.debug("stopping OT Registrar") + self.registrar_process.terminate() + if self.registrar_log_file is not None: + self.registrar_log_file.close() + self.registrar_process = None + self.registrar_log_file = None + + def testAddCcmNodesMixedWithRegular(self): + ns = self.ns + + n1 = ns.add("br", version="ccm") + n2 = ns.add("router", version="ccm") + n2 = ns.add("router", version="ccm") + n2 = ns.add("router") + + ns.go(30) + self.assertFormPartitions(1) + + def testCommissioningOneCcmNode(self): + ns = self.ns + self.startRegistrar() + #ns.web() + ns.coaps_enable() + ns.radiomodel = 'MIDisc' # enforce strict line topologies for testing + + n1 = ns.add("br", x = 100, y = 100, radio_range = 120, version="ccm", script="") + n2 = ns.add("router", x = 100, y = 200, radio_range = 120, version="ccm", script="") + + # configure sim-host server that acts as BRSKI Registrar + # TODO update IPv6 addr + ns.cmd('host add "masa.example.com" "910b::1234" 5684 5684') + + # n1 is a BR out-of-band configured with initial dataset, and becomes leader+ccm-commissioner + self.setFirstNodeDataset(n1) + ns.ifconfig_up(n1) + ns.thread_start(n1) + ns.go(15) + state_n1 = ns.get_state(n1) + self.assertTrue(state_n1 == "leader") + ns.commissioner_start(n1) + ns.go(5) + ns.coaps() # see emitted CoAP events + + # n2 joins as CCM joiner + # because CoAP server is real, let simulation also move in near real time speed. + ns.speed = 50 + ns.commissioner_ccm_joiner_add(n1, "*") + ns.ifconfig_up(n2) + ns.ccm_joiner_start(n2) + ns.go(20) + + # check join result + ns.coaps() # see emitted CoAP events + ns.cmd('host list') + state_n2 = ns.get_state(n2) + self.assertTrue(state_n2 == "router" or state_n2 == "child") + ns.go(20) + + #ns.interactive_cli() + + def testCommissioningOneCcmNodeOneJoinerRouter(self): + ns = self.ns + self.startRegistrar() + #ns.web() + ns.watch_default('debug') + ns.coaps_enable() + ns.radiomodel = 'MIDisc' # enforce strict line topologies for testing + + n1 = ns.add("br", x = 100, y = 100, radio_range = 120, version="ccm") + n2 = ns.add("router", x = 100, y = 200, radio_range = 120, version="ccm") + n3 = ns.add("router", x = 100, y = 300, radio_range = 120, version="ccm", script="") + + # configure sim-host server that acts as BRSKI Registrar + # TODO update IPv6 addr + ns.cmd('host add "masa.example.com" "910b::1234" 5684 5684') + + # n1 is a BR out-of-band configured with initial dataset, and becomes leader+ccm-commissioner + self.setAlternativeDataset(n1) + ns.ifconfig_up(n1) + ns.thread_start(n1) + ns.go(15) + state_n1 = ns.get_state(n1) + self.assertTrue(state_n1 == "leader") + # n1 starts commissioner + ns.commissioner_start(n1) + ns.go(5) + ns.coaps() # see emitted CoAP events + + # n2 also added out-of-band, for Joiner Router role + self.setAlternativeDataset(n2) + ns.ifconfig_up(n2) + ns.thread_start(n2) + ns.go(20) + state_n2 = ns.get_state(n2) + self.assertTrue(state_n2 == "router" or state_n2 == "child") + ns.coaps() # see emitted CoAP events + + # n3 joins as CCM joiner - needs to search channel. + # because CoAP server is real, let simulation also move in near real time speed. + ns.speed = 1 + ns.commissioner_ccm_joiner_add(n1, "*") + ns.ifconfig_up(n3) + ns.node_cmd(n3, 'coaps x509') + ns.joiner_startccm(n3) + ns.go(10) + ns.coaps() # see emitted CoAP events + ns.cmd('host list') + + # n3 automatically has enabled Thread and joined the network + #ns.interactive_cli() + state_n3 = ns.get_state(n3) + self.assertTrue(state_n3 == "router" or state_n3 == "child") + + def testCommissioningOneHop(self): ns = self.ns - # ns.web() + ns.web() ns.coaps_enable() ns.radiomodel = 'MIDisc' # enforce strict line topologies for testing - n1 = ns.add("br", x = 100, y = 100, radio_range = 120) - n2 = ns.add("router", x = 100, y = 200, radio_range = 120) - n3 = ns.add("router", x = 200, y = 100, radio_range = 120) + n1 = ns.add("br", x = 100, y = 100, radio_range = 120, script="", version="ccm") + n2 = ns.add("router", x = 100, y = 200, radio_range = 120, script="") + n3 = ns.add("router", x = 200, y = 100, radio_range = 120, script="", version="ccm") # configure sim-host server that acts as BRSKI Registrar # TODO update IPv6 addr ns.cmd('host add "masa.example.com" "910b::1234" 5683 5683') - # n1 is out-of-band configured with initial dataset, and becomes leader+ccm-commissioner + # n1 is a BR out-of-band configured with initial dataset, and becomes leader+ccm-commissioner self.setFirstNodeDataset(n1) ns.ifconfig_up(n1) ns.thread_start(n1) - self.go(35) + self.go(15) self.assertTrue(ns.get_state(n1) == "leader") ns.commissioner_start(n1) @@ -81,18 +227,20 @@ def testCommissioningOneHop(self): print('counters', c) joins = ns.joins() print('joins', joins) - self.assertFormPartitionsIgnoreOrphans(1) + self.assertFormPartitionsIgnoreOrphans(1) # ignore orphan n3 self.assertTrue(joins and joins[0][1] > 0) # assert join success - # n3 joins as CCM joiner - # because CoAP server is real, let simulation also move in real time. + # n3 joins as CCM joiner + # because CoAP server is real, let simulation also move in near real time speed. ns.speed = 5 ns.commissioner_ccm_joiner_add(n1, "*") ns.ifconfig_up(n3) - ns.ccm_joiner_start(n3) - self.go(10) - #ns.thread_start(n3) - #self.go(100) + ns.joiner_startccm(n3) + self.go(20) + ns.thread_start(n3) + self.go(100) + + ns.node_cmd(n3, 'dataset active') c = ns.counters() print('counters', c) diff --git a/script/check-pretty b/script/check-pretty deleted file mode 100755 index 959f1f7b..00000000 --- a/script/check-pretty +++ /dev/null @@ -1,111 +0,0 @@ -#!/bin/bash -# Copyright (c) 2020, The OTNS Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -# -# The script to check source code of OTNS. -# -# Check all: -# -# script/check-pretty -# -# Check go only: -# -# script/check-pretty go -# -# Check go.mod only: -# -# script/check-pretty go.mod -# -# Check shell only: -# -# script/check-pretty shell -# - -# shellcheck source=script/common.sh -. "$(dirname "$0")"/common.sh - -do_go_mod_check() -{ - echo -e '=====================' - echo -e ' check go.mod' - echo -e '=====================' - - cp go.mod go.mod.orig - go mod tidy - diff go.mod go.mod.orig || die "go.mod is not tidy" - echo "Congratulations! Your go.mod is tidy." -} - -do_go_check() -{ - echo -e '=====================' - echo -e ' check Go' - echo -e '=====================' - - cd "$OTNSDIR" || return 1 - golangci-lint run "${GOLINT_ARGS[@]}" || die "check pretty failed" - echo "Congratulations! Your Go code is pretty." -} - -do_shell_check() -{ - echo -e '=====================' - echo -e ' check shell' - echo -e '=====================' - - shfmt -f . | grep -v -E "^($(echo "${OTNS_EXCLUDE_DIRS[@]}" | tr ' ' '|'))" \ - | xargs -n10 -P"$OTNS_BUILD_JOBS" shfmt -i 4 -bn -ci -fn -s -d - - shfmt -f . | grep -v -E "^($(echo "${OTNS_EXCLUDE_DIRS[@]}" | tr ' ' '|'))" \ - | xargs -n10 -P"$OTNS_BUILD_JOBS" shellcheck -x - - echo "Congratulations! Your shell code is pretty." -} - -main() -{ - install_pretty_tools - - if [ $# == 0 ]; then - do_go_mod_check - do_go_check - do_shell_check - elif [ "$1" == 'go' ]; then - do_go_check - elif [ "$1" == 'shell' ]; then - do_shell_check - elif [ "$1" == 'go.mod' ]; then - do_go_mod_check - else - echo >&2 "Unsupported check: $1. Supported: go, go.mod, shell" - # 128 for Invalid arguments - exit 128 - fi -} - -main "$@" diff --git a/script/common.sh b/script/common.sh index 7f922d8f..1bd2dec9 100644 --- a/script/common.sh +++ b/script/common.sh @@ -40,19 +40,26 @@ fi # shellcheck source=script/utils.sh . "$(dirname "$0")"/utils.sh -export readonly SCRIPTDIR SCRIPTDIR=$(realpathf "$(dirname "$0")") -export readonly OTNSDIR +export readonly SCRIPTDIR + OTNSDIR=$(realpathf "$SCRIPTDIR"/..) -export readonly GOPATH +export readonly OTNSDIR + GOPATH=$(go env GOPATH) +export readonly GOPATH export PATH=$PATH:"$GOPATH"/bin mkdir -p "$GOPATH"/bin -export readonly GOLINT_ARGS=(-E goimports -E whitespace -E goconst -E exportloopref -E unconvert) -export readonly OTNS_BUILD_JOBS +GOLINT_ARGS=(-E goimports -E whitespace -E goconst -E exportloopref -E unconvert) +export readonly GOLINT_ARGS + OTNS_BUILD_JOBS=$(getconf _NPROCESSORS_ONLN) -export readonly OTNS_EXCLUDE_DIRS=(web/site/node_modules/ openthread/ openthread-v11/ openthread-v12/ openthread-v13/ build/ build-v11/ build-v12/ build-v13/) +export readonly OTNS_BUILD_JOBS + +# excluded dirs for make-pretty or similar operations +OTNS_EXCLUDE_DIRS=(build/ web/site/node_modules/ openthread/ openthread-v11/ openthread-v12/ openthread-v13/ openthread-ccm/) +export readonly OTNS_EXCLUDE_DIRS go_install() { @@ -104,14 +111,12 @@ build_openthread() build_openthread_br() { - if [[ ! -f ./ot-rfsim/ot-versions/ot-cli-ftd_br ]]; then - get_openthread - install_openthread_buildtools - ( - cd ot-rfsim - ./script/build_br "$(get_build_options)" - ) - fi + get_openthread + install_openthread_buildtools + ( + cd ot-rfsim + ./script/build_br "$(get_build_options)" + ) } build_openthread_versions() diff --git a/script/install-deps b/script/install-deps index a4367805..a393e846 100755 --- a/script/install-deps +++ b/script/install-deps @@ -25,7 +25,7 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. # -# This script installs OTNS dependencies. +# This script installs OTNS dependencies and is called by 'test'. # shellcheck source=script/common.sh . "$(dirname "$0")"/common.sh @@ -62,7 +62,7 @@ install_grpcwebproxy() install_python_libs() { activate_python_venv - python3 -m pip install setuptools wheel + python3 -m pip install setuptools wheel yapf } main() diff --git a/script/make-pretty b/script/make-pretty index c452aca0..764bfbff 100755 --- a/script/make-pretty +++ b/script/make-pretty @@ -1,35 +1,36 @@ #!/bin/bash -# Copyright (c) 2020, The OTNS Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -# -# The script to format source code of OTNS. -# -# Format all: +# +# Copyright (c) 2019-2024, The OpenThread Authors. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of the copyright holder nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +# +# The script to check or format source code of OTNS. +# +# Format go, c/c++, markdown, python, and shell: # # script/make-pretty # @@ -37,14 +38,48 @@ # # script/make-pretty go # -# Format go.mod only: +# Format c/c++ only: +# +# script/make-pretty clang +# script/make-pretty clang-format +# script/make-pretty clang-tidy +# +# Format markdown only: +# +# script/make-pretty markdown +# +# Format python only: # -# script/make-pretty go.mod +# script/make-pretty python # # Format shell only: # # script/make-pretty shell # +# Check only: +# +# script/make-pretty check go +# script/make-pretty check clang +# script/make-pretty check clang-format +# script/make-pretty check clang-tidy +# script/make-pretty check markdown +# script/make-pretty check python +# script/make-pretty check shell +# + +set -euo pipefail + +OT_CLANG_SOURCES=('*.c' '*.cc' '*.cpp' '*.h' '*.hpp') +readonly OT_CLANG_SOURCES + +OT_MARKDOWN_SOURCES=('*.md') +readonly OT_MARKDOWN_SOURCES + +OT_PYTHON_SOURCES=('*.py') +readonly OT_PYTHON_SOURCES + +OT_CLANG_TIDY_FIX_DIRS=('ot-rfsim/src') +readonly OT_CLANG_TIDY_FIX_DIRS # shellcheck source=script/common.sh . "$(dirname "$0")"/common.sh @@ -59,6 +94,27 @@ do_go_format() golangci-lint run "${GOLINT_ARGS[@]}" --fix || die "make pretty failed" } +do_go_format_check() +{ + echo -e '=====================' + echo -e ' check Go' + echo -e '=====================' + + cd "$OTNSDIR" || return 1 + golangci-lint run "${GOLINT_ARGS[@]}" || die "make pretty failed" +} + +do_go_mod_check() +{ + echo -e '=====================' + echo -e ' check go.mod' + echo -e '=====================' + + cp go.mod go.mod.orig + go mod tidy + diff go.mod go.mod.orig || die "go.mod is not tidy" +} + do_go_mod_format() { echo -e '=====================' @@ -68,16 +124,150 @@ do_go_mod_format() go mod tidy } +do_clang_format() +{ + get_openthread + echo -e '========================================' + echo -e ' format c/c++ (clang-format)' + echo -e '========================================' + + git ls-files "${OT_CLANG_SOURCES[@]}" | grep -v -E "^($(echo "${OTNS_EXCLUDE_DIRS[@]}" | tr ' ' '|'))" \ + | xargs -n3 -P"$OTNS_BUILD_JOBS" openthread/script/clang-format -style=file -i -verbose +} + +do_clang_format_check() +{ + get_openthread + echo -e '========================================' + echo -e ' check c/c++ (clang-format)' + echo -e '========================================' + + git ls-files "${OT_CLANG_SOURCES[@]}" | grep -v -E "^($(echo "${OTNS_EXCLUDE_DIRS[@]}" | tr ' ' '|'))" \ + | xargs -n3 -P"$OTNS_BUILD_JOBS" openthread/script/clang-format-check +} + +do_clang_tidy_fix() +{ + get_openthread + echo -e '========================================' + echo -e ' format c/c++ (clang-tidy)' + echo -e '========================================' + + (cd ./ot-rfsim \ + && ./script/build_latest \ + && cd build/latest \ + && ../../../openthread/script/clang-tidy -j"$OTNS_BUILD_JOBS" "${OT_CLANG_TIDY_FIX_DIRS[@]}" -fix) +} + +do_clang_tidy_check() +{ + get_openthread + echo -e '========================================' + echo -e ' check c/c++ (clang-tidy)' + echo -e '========================================' + + (cd ./ot-rfsim \ + && ./script/build_latest \ + && cd build/latest \ + && ../../../openthread/script/clang-tidy -j"$OTNS_BUILD_JOBS" "${OT_CLANG_TIDY_FIX_DIRS[@]}") +} + +do_markdown_format() +{ + echo -e '========================================' + echo -e ' format markdown' + echo -e '========================================' + + git ls-files "${OT_MARKDOWN_SOURCES[@]}" | grep -v -E "^($(echo "${OTNS_EXCLUDE_DIRS[@]}" | tr ' ' '|'))" \ + | xargs -n10 -P"$OTNS_BUILD_JOBS" npx prettier@2.0.4 --write +} + +do_markdown_check() +{ + echo -e '========================================' + echo -e ' check markdown' + echo -e '========================================' + + git ls-files "${OT_MARKDOWN_SOURCES[@]}" | grep -v -E "^($(echo "${OTNS_EXCLUDE_DIRS[@]}" | tr ' ' '|'))" \ + | xargs -n10 -P"$OTNS_BUILD_JOBS" npx prettier@2.0.4 --check +} + +do_python_format() +{ + echo -e '========================================' + echo -e ' format python' + echo -e '========================================' + + git ls-files "${OT_PYTHON_SOURCES[@]}" | grep -v -E "^($(echo "${OTNS_EXCLUDE_DIRS[@]}" | tr ' ' '|'))" \ + | xargs -n10 -P"$OTNS_BUILD_JOBS" python3 -m yapf --verbose --style '{based_on_style: google, column_limit: 119}' -ipr +} + +do_python_check() +{ + echo -e '========================================' + echo -e ' check python' + echo -e '========================================' + + git ls-files "${OT_PYTHON_SOURCES[@]}" | grep -v -E "^($(echo "${OTNS_EXCLUDE_DIRS[@]}" | tr ' ' '|'))" \ + | xargs -n10 -P"$OTNS_BUILD_JOBS" python3 -m yapf --verbose --style '{based_on_style: google, column_limit: 119}' -dpr +} + do_shell_format() { - echo -e '=====================' + echo -e '========================================' echo -e ' format shell' - echo -e '=====================' + echo -e '========================================' - shfmt -f . | grep -v -E "^($(echo "${OTNS_EXCLUDE_DIRS[@]}" | tr ' ' '|'))" \ + git ls-files | xargs shfmt -f | grep -v -E "^($(echo "${OTNS_EXCLUDE_DIRS[@]}" | tr ' ' '|'))" \ | xargs -n10 -P"$OTNS_BUILD_JOBS" shfmt -i 4 -bn -ci -fn -s -w } +do_shell_check() +{ + echo -e '========================================' + echo -e ' check shell' + echo -e '========================================' + + git ls-files | xargs shfmt -f | grep -v -E "^($(echo "${OTNS_EXCLUDE_DIRS[@]}" | tr ' ' '|'))" \ + | xargs -n10 -P"$OTNS_BUILD_JOBS" shfmt -i 4 -bn -ci -fn -s -d + + git ls-files | xargs shfmt -f | grep -v -E "^($(echo "${OTNS_EXCLUDE_DIRS[@]}" | tr ' ' '|'))" \ + | xargs -n10 -P"$OTNS_BUILD_JOBS" shellcheck +} + +do_check() +{ + if [ $# == 0 ]; then + do_go_format_check + do_go_mod_check + do_clang_format_check + do_clang_tidy_check + do_markdown_check + do_python_check + do_shell_check + elif [ "$1" == 'go' ]; then + do_go_format_check + do_go_mod_check + elif [ "$1" == 'clang' ]; then + do_clang_format_check + do_clang_tidy_check + elif [ "$1" == 'clang-format' ]; then + do_clang_format_check + elif [ "$1" == 'clang-tidy' ]; then + do_clang_tidy_check + elif [ "$1" == 'markdown' ]; then + do_markdown_check + elif [ "$1" == 'python' ]; then + do_python_check + elif [ "$1" == 'shell' ]; then + do_shell_check + else + echo >&2 "Unsupported check: $1. Supported: go, clang, clang-format, clang-tidy, markdown, python, shell" + # 128 for Invalid arguments + exit 128 + fi +} + main() { install_pretty_tools @@ -85,18 +275,36 @@ main() if [ $# == 0 ]; then do_go_format do_go_mod_format + do_clang_tidy_fix + do_clang_format + do_markdown_format + do_python_format do_shell_format elif [ "$1" == 'go' ]; then do_go_format - elif [ "$1" == 'go.mod' ]; then do_go_mod_format + elif [ "$1" == 'clang' ]; then + do_clang_tidy_fix + do_clang_format + elif [ "$1" == 'clang-format' ]; then + do_clang_format + elif [ "$1" == 'clang-tidy' ]; then + do_clang_tidy_fix + elif [ "$1" == 'markdown' ]; then + do_markdown_format + elif [ "$1" == 'python' ]; then + do_python_format elif [ "$1" == 'shell' ]; then do_shell_format + elif [ "$1" == 'check' ]; then + shift + do_check "$@" else - echo >&2 "Unsupported action: $1. Supported: go, go.mod, shell" + echo >&2 "Unsupported action: $1. Supported: go, clang, clang-format, clang-tidy, markdown, python, shell, check" # 128 for Invalid arguments exit 128 fi + } main "$@" diff --git a/script/setup-dev b/script/setup-dev index 0f1ce85c..d3c8e44e 100755 --- a/script/setup-dev +++ b/script/setup-dev @@ -25,7 +25,7 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. # -# This script setup environment for OTNS development. +# This script sets up the environment for OTNS development. # shellcheck source=script/common.sh . "$(dirname "$0")"/common.sh diff --git a/script/utils.sh b/script/utils.sh index 52373b5a..924bc6dd 100644 --- a/script/utils.sh +++ b/script/utils.sh @@ -33,7 +33,7 @@ function die() function realpathf() { - # the Python3 method is a backup. + # the Python3 method is a backup. Used for max portability. realpath -s "$1" || python3 -c "import os; print(os.path.realpath('$1'))" } @@ -109,11 +109,12 @@ install_package() function install_pretty_tools() { + # TODO Known bug: version v1.59.0 won't work with Go 1.23 or higher. Requires version <= 1.22 if ! installed golangci-lint; then curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b "$(go env GOPATH)"/bin v1.59.0 fi - go install mvdan.cc/sh/v3/cmd/shfmt@latest + install_package shfmt --apt shfmt --brew shfmt install_package shellcheck --apt shellcheck --brew shellcheck } diff --git a/simulation/node_config.go b/simulation/node_config.go index 27b84995..62860a54 100644 --- a/simulation/node_config.go +++ b/simulation/node_config.go @@ -284,7 +284,9 @@ func (cfg *ExecutableConfig) FindExecutableBasedOnConfig(nodeCfg *NodeConfig) st } if nodeCfg.IsBorderRouter { exeName = cfg.Br - } else if len(nodeCfg.Version) > 0 && nodeCfg.Version != versionLatestTag { + } + + if len(nodeCfg.Version) > 0 && nodeCfg.Version != versionLatestTag { exeName += "_" + nodeCfg.Version } diff --git a/simulation/sim_hosts.go b/simulation/sim_hosts.go index 81f2aa0d..8d868ca3 100644 --- a/simulation/sim_hosts.go +++ b/simulation/sim_hosts.go @@ -27,7 +27,6 @@ package simulation import ( - "encoding/hex" "errors" "fmt" "io" @@ -218,7 +217,7 @@ func (sh *SimHosts) handleUdpFromSimHost(simConn *SimConn, udpData []byte) { if simConn.Nat66State.SrcIp6Address == netip.IPv6Unspecified() { // send as UDP-event to node itself to handle. ev := &event.Event{ - Delay: 0, + Delay: 0, // FIXME Type: event.EventTypeUdpFromHost, Data: udpData, NodeId: simConn.Node.Id, @@ -230,9 +229,7 @@ func (sh *SimHosts) handleUdpFromSimHost(simConn *SimConn, udpData []byte) { }, } sh.sim.Dispatcher().PostEventAsync(ev) - logger.Debugf("sh.sim.Dispatcher().PostEventAsync(ev) FIXME-UDP path %v, %+v", ev, ev.MsgToHostData) logger.Debugf("simConn.Nat66State UDP-path = %v", simConn.Nat66State) - logger.Debugf("udpData = %s", hex.EncodeToString(udpData)) } else { // send as IPv6-event to node, to let it forward to others on mesh. ip6Datagram := createIp6UdpDatagram(simConn.Nat66State.DstPort, simConn.Nat66State.SrcPort,