#!/bin/bash # # Copyright (c) 2020, 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. # # Test build and run otbr dbus server # set -euxo pipefail OTBR_DBUS_SERVER_CONF=otbr-test-agent.conf readonly OTBR_DBUS_SERVER_CONF on_exit() { local status=$? sudo systemctl stop test-otbr-agent || true if [[ -v LEADER_PID ]]; then kill "$LEADER_PID" || true fi if [[ -v CHILD_PID ]]; then kill "$CHILD_PID" || true fi sudo killall dbus-monitor || true sudo rm "/etc/dbus-1/system.d/${OTBR_DBUS_SERVER_CONF}" || true sed -n "/$TEST_HELLO/,\$p" /var/log/syslog | grep 'ot-cli\|otbr' return "${status}" } ot_ctl() { sudo "${CMAKE_BINARY_DIR}"/third_party/openthread/repo/src/posix/ot-ctl "$@" } otbr_factoryreset() { ot_ctl factoryreset timeout 2 bash -c "while ! ot_ctl state; do sleep 1; done" } scan_meshcop_service() { if command -v dns-sd; then timeout 5 dns-sd -Z _meshcop._udp local. || true else avahi-browse -aprt || true fi } update_meshcop_txt_and_check() { sudo gdbus call --system --dest io.openthread.BorderRouter.wpan0 --method=io.openthread.BorderRouter.UpdateVendorMeshCopTxtEntries --object-path /io/openthread/BorderRouter/wpan0 "[('nn',[97])]" || true sleep 5 service="$(scan_meshcop_service)" grep --binary-files=text "nn=OpenThread" <<<"${service}" sudo gdbus call --system --dest io.openthread.BorderRouter.wpan0 --method=io.openthread.BorderRouter.UpdateVendorMeshCopTxtEntries --object-path /io/openthread/BorderRouter/wpan0 "[('vn',[118,101,110,100,111,114])]" sleep 5 service="$(scan_meshcop_service)" grep --binary-files=text "vn=vendor" <<<"${service}" sudo gdbus call --system --dest io.openthread.BorderRouter.wpan0 --method=io.openthread.BorderRouter.UpdateVendorMeshCopTxtEntries --object-path /io/openthread/BorderRouter/wpan0 "[]" sleep 5 service="$(scan_meshcop_service)" grep --binary-files=text "vn=OpenThread" <<<"${service}" sudo gdbus call --system --dest io.openthread.BorderRouter.wpan0 --method=io.openthread.BorderRouter.UpdateVendorMeshCopTxtEntries --object-path /io/openthread/BorderRouter/wpan0 "[('A',[97,98,99]),('B',[49,50])]" sleep 5 service="$(scan_meshcop_service)" grep --binary-files=text "A=abc" <<<"${service}" grep --binary-files=text "B=12" <<<"${service}" sudo gdbus call --system --dest io.openthread.BorderRouter.wpan0 --method=io.openthread.BorderRouter.Reset --object-path /io/openthread/BorderRouter/wpan0 sleep 5 service="$(scan_meshcop_service)" grep --binary-files=text "A=abc" <<<"${service}" grep --binary-files=text "B=12" <<<"${service}" sudo gdbus call --system --dest io.openthread.BorderRouter.wpan0 --method=io.openthread.BorderRouter.UpdateVendorMeshCopTxtEntries --object-path /io/openthread/BorderRouter/wpan0 "[('A',[97,99]),('B',[49,50])]" sleep 5 service="$(scan_meshcop_service)" grep --binary-files=text "A=ac" <<<"${service}" grep --binary-files=text "B=12" <<<"${service}" } test_get_properties() { local ot_version local rcp_version local thread_version ot_version=$(ot_ctl version | grep -oE '^OPENTHREAD.*$' | tr -d '\r\n') rcp_version=$(ot_ctl rcp version | grep -oE '^OPENTHREAD.*$' | tr -d '\r\n') thread_version=$(ot_ctl thread version | grep -oE '^[0-9]+' | tr -d '\r\n') local property_names="array:string:" property_names+="OtHostVersion," property_names+="OtRcpVersion," property_names+="ThreadVersion," property_names+="Uptime," property_names+="RadioCoexMetrics," property_names+="RadioSpinelMetrics," property_names+="RcpInterfaceMetrics" local result_pattern="\s+variant\s+string\s+\"${ot_version}\"" result_pattern+="\s+variant\s+string\s+\"${rcp_version}\"" result_pattern+="\s+variant\s+uint16\s+${thread_version}" result_pattern+="\s+variant\s+uint64\s+\d+" # Uptime result_pattern+="\s+variant\s+struct\s+{(\s+uint32\s+\d+){18}\s+boolean\s+(true|false)\s+}" # RadioCoexMetrics result_pattern+="\s+variant\s+struct\s+{(\s+uint32\s+\d+){4}\s+}" # RadioSpinelMetrics result_pattern+="\s+variant\s+struct\s+{\s+byte\s+\d+(\s+uint64\s+\d+){7}\s+}" # RcpInterfaceMetrics sudo dbus-send --system --dest=io.openthread.BorderRouter.wpan0 --print-reply \ /io/openthread/BorderRouter/wpan0 \ io.openthread.BorderRouter.GetProperties \ "${property_names}" \ | grep -oPz "${result_pattern}" } otbr_agent_service_start() { local -r EXIT_CODE_SHOULD_RESTART=7 sudo systemd-run --collect --no-ask-password -u test-otbr-agent -p "RestartForceExitStatus=$EXIT_CODE_SHOULD_RESTART" "${CMAKE_BINARY_DIR}"/src/agent/otbr-agent -d7 -I wpan0 -B lo "spinel+hdlc+forkpty://$(command -v ot-rcp)?forkpty-arg=1" timeout 2 bash -c "while ! ot_ctl state; do sleep 1; done" } suite_setup() { TEST_HELLO="$(basename "$0") started at $(date +%s)" logger "$TEST_HELLO" [[ -f /etc/dbus-1/system.d/"${OTBR_DBUS_SERVER_CONF}" ]] || { local CONFIG_FILE_PATH="third_party/openthread/repo/src/posix/platform" mkdir -p "${PWD}/${CONFIG_FILE_PATH}" && cp "${PROJECT_SOURCE_DIR}/${CONFIG_FILE_PATH}/openthread.conf.example" "${PWD}/${CONFIG_FILE_PATH}" sudo rm -rf tmp sudo install -m 644 "${CMAKE_BINARY_DIR}"/src/agent/otbr-agent.conf /etc/dbus-1/system.d/"${OTBR_DBUS_SERVER_CONF}" sudo service dbus reload } trap on_exit EXIT sudo systemctl start avahi-daemon export -f ot_ctl } test_ready_signal() { # Because we do want to run the command as root but redirect as the normal user. # shellcheck disable=SC2024 sudo expect <&1 || true) | grep NotFound # Verify Eui64 property. 0x18b4300000000001 = 1780100529276321793 sudo dbus-send --system --dest=io.openthread.BorderRouter.wpan0 --print-reply /io/openthread/BorderRouter/wpan0 org.freedesktop.DBus.Properties.Get string:io.openthread.BorderRouter string:Eui64 \ | grep '1780100529276321793' # The ot-cli-ftd node is used to test Thread attach. expect <