Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / third_party / ot-br-posix / repo / tests / scripts / meshcop
1 #!/bin/bash
2 #
3 #  Copyright (c) 2017, The OpenThread Authors.
4 #  All rights reserved.
5 #
6 #  Redistribution and use in source and binary forms, with or without
7 #  modification, are permitted provided that the following conditions are met:
8 #  1. Redistributions of source code must retain the above copyright
9 #     notice, this list of conditions and the following disclaimer.
10 #  2. Redistributions in binary form must reproduce the above copyright
11 #     notice, this list of conditions and the following disclaimer in the
12 #     documentation and/or other materials provided with the distribution.
13 #  3. Neither the name of the copyright holder nor the
14 #     names of its contributors may be used to endorse or promote products
15 #     derived from this software without specific prior written permission.
16 #
17 #  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 #  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 #  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 #  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21 #  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 #  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 #  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 #  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 #  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 #  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 #  POSSIBILITY OF SUCH DAMAGE.
28 #
29 # Test thread commissioning along with openthread.
30 #
31 # Usage:
32 #   ./meshcop         # test with latest openthread.
33 #   NO_CLEAN=1 ./meshcop # test with existing binaries in ${TEST_BASE}.
34 set -euxo pipefail
35
36 # Get our starting directory and remember it
37 readonly ORIGIN_PWD="$(pwd)"
38 readonly SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
39
40 #---------------------------------------
41 # Configurations
42 #---------------------------------------
43 readonly OT_RCP="ot-rcp"
44 readonly OT_CLI="${OT_CLI:-ot-cli-ftd}"
45 readonly ABS_TOP_BUILDDIR="$(cd "${top_builddir:-"${SCRIPT_DIR}"/../../}" && pwd)"
46 readonly ABS_TOP_SRCDIR="$(cd "${top_srcdir:-"${SCRIPT_DIR}"/../../}" && pwd)"
47 readonly NO_CLEAN="${NO_CLEAN:-1}"
48 readonly IGNORE_INSTALLED="${IGNORE_INSTALLED:-0}"
49 readonly OTBR_USE_WEB_COMMISSIONER="${USE_WEB_COMMISSIONER:-0}"
50
51 #----------------------------------------
52 # Test constants
53 #----------------------------------------
54 readonly TEST_BASE=/tmp/test-otbr
55
56 readonly OTBR_AGENT=otbr-agent
57 readonly OTBR_WEB=otbr-web
58 readonly OT_COMMISSIONER_CLI=commissioner-cli
59
60 readonly STAGE_DIR="${TEST_BASE}/stage"
61 readonly BUILD_DIR="${TEST_BASE}/build"
62 readonly OTBR_PSKC_PATH="${ABS_TOP_BUILDDIR}/tools/pskc"
63 readonly OTBR_AGENT_PATH="${ABS_TOP_BUILDDIR}/src/agent/${OTBR_AGENT}"
64 readonly OTBR_DBUS_CONF="${ABS_TOP_BUILDDIR}/src/agent/otbr-agent.conf"
65 readonly OTBR_WEB_PATH="${ABS_TOP_BUILDDIR}/src/web/${OTBR_WEB}"
66
67 # The node ids
68 readonly LEADER_NODE_ID=1
69 readonly JOINER_NODE_ID=2
70
71 # Web GUI
72 readonly OTBR_WEB_HOST=127.0.0.1
73 readonly OTBR_WEB_PORT=8773
74 readonly OTBR_WEB_URL="http://${OTBR_WEB_HOST}:${OTBR_WEB_PORT}"
75
76 #
77 # NOTE Joiner pass phrase:
78 #   Must be at least 6 bytes long
79 #   And this example has: J ZERO ONE N E R
80 #   We cannot use letter O and I because Q O I Z are not allowed per spec
81 readonly OT_JOINER_PASSPHRASE=J01NER
82
83 # 18b430 is the nest EUI prefix.
84 readonly OT_JOINER_EUI64="18b430000000000${JOINER_NODE_ID}"
85
86 # The border agent, and ncp needs a pass phrase.
87 readonly OT_AGENT_PASSPHRASE=MYPASSPHRASE
88
89 # The network needs a name.
90 readonly OT_NETWORK_NAME=MyTestNetwork
91
92 # The TUN device for OpenThread border router.
93 readonly TUN_NAME=wpan0
94
95 echo "ORIGIN_PWD: ${ORIGIN_PWD}"
96 echo "TEST_BASE: ${TEST_BASE}"
97 echo "ABS_TOP_SRCDIR=${ABS_TOP_SRCDIR}"
98 echo "ABS_TOP_BUILDDIR=${ABS_TOP_BUILDDIR}"
99
100 #----------------------------------------
101 # Helper functions
102 #----------------------------------------
103
104 die()
105 {
106     exit_message="$*"
107     echo " *** ERROR: $*"
108     exit 1
109 }
110
111 exists_or_die()
112 {
113     [[ -f $1 ]] || die "Missing file: $1"
114 }
115
116 executable_or_die()
117 {
118     [[ -x $1 ]] || die "Missing executable: $1"
119 }
120
121 random_channel()
122 {
123     echo $((11 + "${RANDOM}" % 16))
124 }
125
126 random_panid()
127 {
128     printf "0x%04x" "${RANDOM}"
129 }
130
131 random_xpanid()
132 {
133     printf "%04x%04x%04x%04x" "${RANDOM}" "${RANDOM}" "${RANDOM}" "${RANDOM}"
134 }
135
136 random_masterkey()
137 {
138     printf "%04x%04x%04x%04x%04x%04x%04x%04x" "${RANDOM}" "${RANDOM}" "${RANDOM}" "${RANDOM}" "${RANDOM}" "${RANDOM}" "${RANDOM}" "${RANDOM}"
139 }
140
141 write_syslog()
142 {
143     logger -s -p syslog.alert "OPENTHREAD_TEST: $*"
144 }
145
146 output_logs()
147 {
148     write_syslog 'All apps should be dead now'
149
150     # part 1
151     # ------
152     #
153     # On travis (the CI server), we can't see what went into the
154     # syslog.  So this is here so we can see the output.
155     #
156     # part 2
157     # ------
158     #
159     # If we run locally, it is sometimes helpful for our victim (you
160     # the developer) to have logs split upto various files to help
161     # that victim, we'll GREP the log files according.
162     #
163     # Wait 5 seconds for the "logs to flush"
164     sleep 5
165
166     cd "${ORIGIN_PWD}"
167     echo 'START_LOG: SYSLOG ==================='
168     tee complete-syslog.log </var/log/syslog
169     echo 'START_LOG: BR-AGENT ================='
170     grep "${OTBR_AGENT}" /var/log/syslog | tee otbr-agent.log
171     echo 'START_LOG: OT-COMISSIONER ========='
172     cat "${OT_COMMISSIONER_LOG}"
173     echo 'START_LOG: OT-RCP ==================='
174     grep "${OT_RCP}" /var/log/syslog | tee "${OT_RCP}.log"
175     echo 'START_LOG: OT-CLI ==================='
176     grep "${OT_CLI}" /var/log/syslog | tee "${OT_CLI}.log"
177     echo '====================================='
178     echo 'Hint, for each log Search backwards for: "START_LOG: <NAME>"'
179     echo '====================================='
180 }
181
182 build_dependencies()
183 {
184     # Clean up old stuff
185     if [[ ${NO_CLEAN} != 1 ]]; then
186         [[ ! -d ${STAGE_DIR} ]] || rm -rf "${STAGE_DIR}"
187         [[ ! -d ${BUILD_DIR} ]] || rm -rf "${BUILD_DIR}"
188     fi
189
190     [[ -d ${STAGE_DIR} ]] || mkdir -p "${STAGE_DIR}"
191     [[ -d ${BUILD_DIR} ]] || mkdir -p "${BUILD_DIR}"
192
193     # As above, these steps are broken up
194     ot_cli=$(command -v "${OT_CLI}")
195     ot_rcp=$(command -v "${OT_RCP}")
196
197     if [[ ${OTBR_USE_WEB_COMMISSIONER} != 1 ]]; then
198         ot_commissioner_build
199     fi
200
201     write_syslog "TEST: BUILD COMPLETE"
202 }
203
204 test_setup()
205 {
206     # message for general failures
207     exit_message="JOINER FAILED"
208
209     executable_or_die "${OTBR_AGENT_PATH}"
210     executable_or_die "${OTBR_WEB_PATH}"
211
212     # Remove flashes
213     sudo rm -vrf "${TEST_BASE}/tmp"
214     # OPENTHREAD_POSIX_DAEMON_SOCKET_LOCK
215     sudo rm -vf "/tmp/openthread.lock"
216
217     build_dependencies
218
219     # We will be creating a lot of log information
220     # Rotate logs so we have a clean and empty set of logs uncluttered with other stuff
221     if [[ -f /etc/logrotate.conf ]]; then
222         sudo logrotate -f /etc/logrotate.conf || true
223     fi
224
225     # From now on - all exits are TRAPPED
226     # When they occur, we call the function: output_logs'.
227     trap test_teardown EXIT
228 }
229
230 test_teardown()
231 {
232     # Capture the exit code so we can return it below
233     readonly EXIT_CODE=$?
234     write_syslog "EXIT ${EXIT_CODE} - output logs"
235
236     sudo pkill -f "${OTBR_AGENT}" || true
237     sudo pkill -f "${OTBR_WEB}" || true
238     sudo pkill -f "${OT_COMMISSIONER_CLI}" || true
239     sudo pkill -f "${OT_CLI}" || true
240     wait
241
242     if [[ ${NO_CLEAN} != 1 ]]; then
243         echo 'clearing all'
244         sudo rm /etc/dbus-1/system.d/otbr-agent.conf || true
245         sudo rm -rf "${STAGE_DIR}" || true
246         sudo rm -rf "${BUILD_DIR}" || true
247
248         output_logs
249     fi
250
251     echo "EXIT ${EXIT_CODE}: MESSAGE: ${exit_message}"
252     exit ${EXIT_CODE}
253 }
254
255 ba_start()
256 {
257     exists_or_die "${OTBR_DBUS_CONF}"
258     sudo cp "${OTBR_DBUS_CONF}" /etc/dbus-1/system.d
259
260     write_syslog "AGENT: kill old"
261     sudo killall "${OTBR_AGENT}" || true
262     write_syslog "AGENT: starting"
263
264     # we launch this in the background
265     (
266         set -e
267         set -x
268
269         cd "${ORIGIN_PWD}"
270
271         # check version
272         sudo "${OTBR_AGENT_PATH}" -V
273         # check invalid arguments
274         sudo "${OTBR_AGENT_PATH}" -x && exit $?
275
276         [[ ! -d tmp ]] || sudo rm -rf tmp
277         sudo "${OTBR_AGENT_PATH}" -I "${TUN_NAME}" -v -d 6 "spinel+hdlc+forkpty://${ot_rcp}?forkpty-arg=${LEADER_NODE_ID}" &
278     )
279
280     # wait for it to complete
281     sleep 10
282
283     pidof ${OTBR_AGENT} || die "AGENT: failed to start"
284     write_syslog "AGENT: start complete"
285 }
286
287 web_start()
288 {
289     write_syslog "WEB: kill old"
290     sudo killall "${OTBR_WEB}" || true
291     write_syslog "WEB: starting"
292     (
293         set -e
294         set -x
295
296         cd "${ORIGIN_PWD}"
297         sudo "${OTBR_WEB_PATH}" -I "${TUN_NAME}" -p "${OTBR_WEB_PORT}" -a "${OTBR_WEB_HOST}" &
298     )
299     sleep 15
300
301     pidof ${OTBR_WEB} || die "WEB: failed to start"
302     write_syslog "WEB: start complete"
303 }
304
305 network_form()
306 {
307     readonly OT_PANID="$(random_panid)"
308     readonly OT_XPANID="$(random_xpanid)"
309     readonly OT_MASTER_KEY="$(random_masterkey)"
310     readonly OT_CHANNEL="$(random_channel)"
311
312     curl --header "Content-Type: application/json" --request POST --data "{\"masterKey\":\"${OT_MASTER_KEY}\",\"prefix\":\"fd11:22::\",\"defaultRoute\":true,\"extPanId\":\"${OT_XPANID}\",\"panId\":\"${OT_PANID}\",\"passphrase\":\"${OT_AGENT_PASSPHRASE}\",\"channel\":${OT_CHANNEL},\"networkName\":\"${OT_NETWORK_NAME}\"}" "${OTBR_WEB_URL}"/form_network | grep "success" || die "WEB: form failed"
313     sleep 15
314     # verify mDNS is working as expected.
315     local mdns_result="${TEST_BASE}"/mdns_result.log
316     avahi-browse -aprt | tee "${mdns_result}"
317     grep -q "${OT_NETWORK_NAME}" "${mdns_result}"
318     rm "${mdns_result}"
319 }
320
321 ot_commissioner_build()
322 {
323     readonly OT_COMMISSIONER_PATH=${BUILD_DIR}/ot-commissioner/build/src/app/cli/commissioner-cli
324     readonly OT_COMMISSIONER_CONFIG=${BUILD_DIR}/ot-commissioner/src/app/etc/commissioner/non-ccm-config.json
325
326     if [[ -x ${OT_COMMISSIONER_PATH} ]]; then
327         return 0
328     fi
329
330     (mkdir -p "${BUILD_DIR}/ot-commissioner" \
331         && cd "${BUILD_DIR}/ot-commissioner" \
332         && (git --git-dir=.git rev-parse --is-inside-work-tree || git --git-dir=.git init .) \
333         && git fetch --depth 1 https://github.com/openthread/ot-commissioner.git master \
334         && git checkout FETCH_HEAD \
335         && ./script/bootstrap.sh \
336         && mkdir build && cd build \
337         && cmake -GNinja -DCMAKE_BUILD_TYPE=Release .. \
338         && ninja)
339 }
340
341 ot_commissioner_start()
342 {
343     write_syslog "COMMISSIONER: kill old"
344     sudo killall "${OT_COMMISSIONER_CLI}" || true
345
346     readonly OT_PSKC="$("${OTBR_PSKC_PATH}" "${OT_AGENT_PASSPHRASE}" "${OT_XPANID}" "${OT_NETWORK_NAME}")"
347     readonly OT_COMMISSIONER_LOG="${TEST_BASE}"/commissioner.log
348
349     local commissioner_config_file="${TEST_BASE}"/ot-commissioner.json
350
351     sed "s/3aa55f91ca47d1e4e71a08cb35e91591/${OT_PSKC}/g" "${OT_COMMISSIONER_CONFIG}" >"${commissioner_config_file}"
352
353     expect -f- <<EOF &
354 spawn ${OT_COMMISSIONER_PATH} ${commissioner_config_file}
355 set timeout 1
356 expect_after {
357     timeout { exit 1 }
358 }
359 send "start :: 49191\n"
360 expect "done"
361 sleep 5
362 send "active\n"
363 expect "true"
364 send "joiner enable meshcop 0x${OT_JOINER_EUI64} ${OT_JOINER_PASSPHRASE}\n"
365 expect "done"
366 wait
367 EOF
368
369     sleep 10
370 }
371
372 web_commissioner_start()
373 {
374     curl --header "Content-Type: application/json" --request POST --data "{\"pskd\":\"${OT_JOINER_PASSPHRASE}\", \"passphrase\":\"${OT_AGENT_PASSPHRASE}\"}" "${OTBR_WEB_URL}"/commission
375     sleep 15
376 }
377
378 joiner_start()
379 {
380     write_syslog 'JOINER START'
381     cd ${TEST_BASE}
382     sudo expect -f- <<EOF || die 'JOINER FAILED'
383 spawn ${ot_cli} ${JOINER_NODE_ID}
384 send "ifconfig up\r\n"
385 expect "Done"
386 send "joiner start ${OT_JOINER_PASSPHRASE}\r\n"
387 set timeout 20
388 expect {
389   "Join success" {
390     send_user "succeeded to find join success"
391     send "exit\r\n"
392   }
393   timeout {
394     send_user "Failed to find join success"
395     exit 1
396   }
397 }
398 EOF
399     exit_message="JOINER SUCCESS COMPLETE"
400 }
401
402 main()
403 {
404     test_setup
405     ba_start
406     web_start
407     network_form
408     if [[ ${OTBR_USE_WEB_COMMISSIONER} == 1 ]]; then
409         web_commissioner_start
410     else
411         ot_commissioner_start
412     fi
413     joiner_start
414 }
415
416 main "$@"