1# Copyright (C) 2013-2016 Free Software Foundation, Inc. 2# 3# This file is part of DejaGnu. 4# 5# DejaGnu is free software; you can redistribute it and/or modify it 6# under the terms of the GNU General Public License as published by 7# the Free Software Foundation; either version 2 of the License, or 8# (at your option) any later version. 9# 10# DejaGnu is distributed in the hope that it will be useful, but 11# WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13# General Public License for more details. 14# 15# You should have received a copy of the GNU General Public License 16# along with DejaGnu; if not, write to the Free Software Foundation, 17# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 19# 20# Get serial number in case of multiple devices 21# 22proc adb_serial {} { 23 # If the user has ADB_SERIAL set, use that, otherwise default to the 24 # only device. 25 set serial "[getenv ADB_SERIAL]" 26 if { $serial eq "" } { 27 set status [catch "exec adb devices |& wc -l" output] 28 if { $output > 3 } { 29 perror "Set ADB_SERIAL in your environment to specify the correct target device!" 30 } 31 return "" 32 } else { 33 return "-s $serial" 34 } 35} 36 37# 38# Connect to hostname using adb 39# 40proc adb_open { hostname } { 41 global spawn_id 42 43 set tries 0 44 set result -1 45 46 if {[board_info $hostname exists shell_prompt]} { 47 set shell_prompt [board_info $hostname shell_prompt] 48 } else { 49 set shell_prompt "root@android:/ # " 50 } 51 52 if {[board_info $hostname exists fileid]} { 53 unset board_info($hostname,fileid) 54 } 55 56 set serial [adb_serial] 57 if { $serial ne "" } { 58 spawn adb [adb_serial] shell 59 } else { 60 spawn adb shell 61 } 62 if { $spawn_id < 0 } { 63 perror "invalid spawn id from adb" 64 return -1 65 } 66 67 send "\r\n" 68 while { $tries <= 3 } { 69 expect { 70 -re ".*$shell_prompt.*$" { 71 verbose "Got prompt\n" 72 set result 0 73 break 74 } 75 timeout { 76 warning "adb shell: timed out trying to connect." 77 } 78 eof { 79 perror "adb shell: got EOF while trying to connect." 80 break 81 } 82 } 83 incr tries 84 } 85 86 if { $result < 0 } { 87 # perror "adb shell: couldn't connect after $tries tries." 88 catch "close -i $spawn_id" 89 set spawn_id -1 90 } else { 91 set board_info($hostname,fileid) $spawn_id 92 } 93 94 return $spawn_id 95} 96 97# 98# Download $srcfile to $destfile on $desthost. 99# 100 101proc adb_download {desthost srcfile destfile} { 102 set serial [adb_serial] 103 verbose "Removing old executable: adb $serial shell rm $destfile" 3 104 set status [catch "exec adb $serial shell rm $destfile |& cat" output] 105 verbose "Downloading: adb $serial shell push $srcfile $destfile" 3 106 set status [catch "exec adb $serial push $srcfile $destfile |& cat" output] 107 if { $status == 0 } { 108 verbose "Copied $srcfile to $destfile" 2 109 return $destfile 110 } else { 111 verbose "Download to target failed, $output." 112 return "" 113 } 114} 115 116proc adb_file {dest op args} { 117 set file [lindex $args 0] 118 verbose "Executing command: $op $args" 2 119 switch -- $op { 120 exists { 121 set status [catch "exec adb [adb_serial] shell ls |& cat" out] 122 } 123 delete { 124 set status [catch "exec adb [adb_serial] shell rm $file |& cat" rmout] 125 } 126 } 127 return [eval remote_raw_file \"$dest\" \"$op\" $args] 128} 129 130proc adb_upload {desthost srcfile destfile} { 131 set status [catch "exec adb [adb_serial] pull $srcfile $destfile |& cat" output] 132 if { $status == 0 } { 133 verbose "Copied $srcfile to $destfile" 2 134 return $destfile 135 } else { 136 verbose "Upload from $desthost failed, $output." 137 return "" 138 } 139} 140 141# 142# Execute "$cmd $args[0]" on $boardname. 143# 144proc adb_exec { boardname cmd args } { 145 global remove_test 146 147 if { [llength $args] > 0 } { 148 set pargs [lindex $args 0] 149 if { [llength $args] > 1 } { 150 set inp [lindex $args 1] 151 } else { 152 set inp "" 153 } 154 } else { 155 set pargs "" 156 set inp "" 157 } 158 159 # If CMD sends any output to stderr, exec will think it failed. More often 160 # than not that will be true, but it doesn't catch the case where there is 161 # no output but the exit code is non-zero. 162 if { $inp eq "" } { 163 set inp "/dev/null" 164 } 165 166 verbose "Executing on $boardname: $cmd $pargs < $inp" 167 168 # Execute commands only from temporary folder, therefore do "cd" first 169 global android_tmp_dir 170 set status [catch "exec cat $inp | adb [adb_serial] shell cd $android_tmp_dir \&\& \( $cmd $pargs \) \\; echo XYZ\\\$\\\{\?\\\}ZYX |& cat" output] 171 172 # `status' doesn't mean much here other than adb worked ok. 173 # What we want is whether $cmd ran ok. 174 if { $status != 0 } { 175 regsub "XYZ(\[0-9\]*)ZYX\n?" $output "" output 176 return [list -1 "adb to $boardname failed for $cmd, $output"] 177 } 178 179 regexp "XYZ(\[0-9\]*)ZYX" $output junk status 180 verbose "adb_exec: status:$status text:$output" 4 181 if { $status eq "" } { 182 return [list -1 "Couldn't parse adb output, $output."] 183 } 184 regsub "XYZ(\[0-9\]*)ZYX\n?" $output "" output 185 # Delete one trailing \n because that is what `exec' will do and we want 186 # to behave identical to it. 187 regsub "\n$" $output "" output 188 return [list [expr {$status != 0}] $output] 189} 190