• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/expect -f
2#
3#  Copyright (c) 2024, 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
30proc wait_for {command success {failure {[\r\n]FAILURE_NOT_EXPECTED[\r\n]}}} {
31    set timeout 1
32    for {set i 0} {$i < 40} {incr i} {
33        if {$command != ""} {
34            send "$command\n"
35        }
36
37        expect {
38            -re $success {
39                return 0
40            }
41            -re $failure {
42                fail "Failed due to '$failure' found"
43            }
44            timeout {
45                # Do nothing
46            }
47        }
48    }
49    fail "Failed due to '$success' not found"
50}
51
52proc expect_line {line} {
53    set timeout 10
54    expect -re "\[\r\n \]($line)(?=\[\r\n>\])"
55    return $expect_out(1,string)
56}
57
58# type: The type of the node.
59#   Possible values:
60#   1. cli: The cli app. ot-cli-ftd or ot-cli-mtd
61#   2. otbr: The otbr-agent.
62#
63# sim_app: The path of the simulation app to start the node.
64#   If type is 'cli', sim_app is the path of the cli app.
65#   If type is 'otbr', sim_app is the path of the coprocessor. It could be 'ot-rcp', 'ot-ncp-ftd'
66#     or 'ot-ncp-mtd'.
67proc spawn_node {id type sim_app} {
68    global spawn_id
69    global spawn_ids
70    global argv0
71
72    send_user "\n# ${id} ${type} ${sim_app}\n"
73
74    switch -regexp ${type} {
75        cli {
76            spawn $sim_app $id
77            send "factoryreset\n"
78            wait_for "state" "disabled"
79            expect_line "Done"
80            send "routerselectionjitter 1\n"
81            expect_line "Done"
82
83            expect_after {
84                timeout { fail "Timed out" }
85            }
86        }
87        otbr-docker {
88            spawn docker exec -it $sim_app bash
89            expect "app#"
90        }
91        otbr {
92            spawn $::env(EXP_OTBR_AGENT_PATH) -I $::env(EXP_TUN_NAME) -d7 "spinel+hdlc+forkpty://${sim_app}?forkpty-arg=${id}"
93        }
94    }
95
96    set spawn_ids($id) $spawn_id
97
98    return $spawn_id
99}
100
101proc create_socat {id} {
102    global socat_pid
103    spawn socat -d -d pty,raw,echo=0 pty,raw,echo=0
104    set socat_pid [exp_pid]
105    set pty1 ""
106    set pty2 ""
107    expect {
108        -re {PTY is (\S+).*PTY is (\S+)} {
109            set pty1 $expect_out(1,string)
110            set pty2 $expect_out(2,string)
111        }
112        timeout {
113            fail "Timed out"
114        }
115    }
116    set spawn_ids($id) $spawn_id
117    return [list $pty1 $pty2]
118}
119
120proc start_otbr_docker {name sim_app sim_id pty1 pty2} {
121    exec $sim_app $sim_id <$pty1 >$pty1 &
122    exec docker run -d \
123        --name $name \
124        --network backbone1 \
125        --cap-add=NET_ADMIN \
126        --privileged \
127        --sysctl net.ipv6.conf.all.disable_ipv6=0 \
128        --sysctl net.ipv4.conf.all.forwarding=1 \
129        --sysctl net.ipv6.conf.all.forwarding=1 \
130        -v $pty2:/dev/ttyUSB0 \
131        $::env(EXP_OTBR_DOCKER_IMAGE)
132}
133
134proc switch_node {id} {
135    global spawn_ids
136    global spawn_id
137
138    send_user "\n# ${id}\n"
139    set spawn_id $spawn_ids($id)
140}
141
142proc dispose_node {id} {
143    switch_node $id
144    send "\x04"
145    expect eof
146}
147proc dispose_socat {} {
148    global socat_pid
149    if { [info exists socat_pid] } {
150        exec kill $socat_pid
151    }
152}
153proc dispose_all {} {
154    global spawn_ids
155    set max_node [array size spawn_ids]
156    for {set i 1} {$i <= $max_node} {incr i} {
157        if { [info exists spawn_ids($i)] } {
158            dispose_node $i
159        }
160    }
161    array unset spawn_ids
162    dispose_socat
163}
164
165proc get_ipaddr {type} {
166    send "ipaddr $type\n"
167    expect "ipaddr $type"
168    set rval [expect_line {([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}}]
169    expect_line "Done"
170
171    return $rval
172}
173
174proc get_omr_addr {} {
175    send "ipaddr -v\r\n"
176    expect -re {(?:[0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}(?= origin:slaac)}
177    return $expect_out(0,string)
178}
179