blob: ebba57d0b67c8664be0e648103c1d80f78eaf357 [file] [log] [blame]
Maksym Sloyko96342732021-08-03 21:54:28 +00001#!/bin/bash
2# Copyright 2021 Google LLC
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16
17# List of options the script accepts. Trailing column means that the option
18# requires an argument.
19ARGUMENT_LIST=(
20 "help"
21 "product-id:"
22 "product-name:"
23 "host-mac:"
24 "bind-device:"
25 "dev-mac:"
William A. Kennington IIIf8a77742022-02-28 18:05:54 -080026 "dev-type:"
Maksym Sloyko96342732021-08-03 21:54:28 +000027 "gadget-dir-name:"
28 "iface-name:"
29)
30
31print_usage() {
32 cat <<HELP
33$0 [OPTIONS] [stop|start]
34 Create USB Gadget Configuration
35 --product-id USB Product Id for the gadget.
36 --product-name Product name string (en) for the gadget.
37 --host-mac MAC address of the host part of the connection. Optional.
38 --dev-mac MAC address of the device (gadget) part of the connection. Optional.
William A. Kennington IIIf8a77742022-02-28 18:05:54 -080039 --dev-type Type of gadget to instantiate. Default: "eem"
Maksym Sloyko96342732021-08-03 21:54:28 +000040 --bind-device Name of the device to bind, as listed in /sys/class/udc/
William A. Kennington III878454a2022-04-04 17:05:05 -070041 --gadget-dir-name Optional base name for gadget directory. Default: iface-name
William A. Kennington III69ebd2c2022-04-04 17:51:09 -070042 --iface-name name of the network interface.
Maksym Sloyko96342732021-08-03 21:54:28 +000043 --help Print this help and exit.
44HELP
45}
46
47gadget_start() {
William A. Kennington IIIa9de0df2022-02-22 17:11:13 -080048 # Add the gbmcbr configuration if this is a relevant device
49 if (( ID_VENDOR == 0x18d1 && ID_PRODUCT == 0x22b )); then
William A. Kennington IIIe1c8b872022-04-04 17:30:48 -070050 mkdir -p /run/systemd/network || return
William A. Kennington IIIa9de0df2022-02-22 17:11:13 -080051 cat >/run/systemd/network/+-bmc-"${IFACE_NAME}".network <<EOF
52[Match]
53Name=${IFACE_NAME}
54[Network]
55Bridge=gbmcbr
56[Bridge]
57Cost=85
58EOF
William A. Kennington IIIe1c8b872022-04-04 17:30:48 -070059 # Ignore any failures due to systemd being unavailable at boot
William A. Kennington IIIa9de0df2022-02-22 17:11:13 -080060 networkctl reload || true
61 fi
62
Maksym Sloyko96342732021-08-03 21:54:28 +000063 local gadget_dir="${CONFIGFS_HOME}/usb_gadget/${GADGET_DIR_NAME}"
William A. Kennington IIIe1c8b872022-04-04 17:30:48 -070064 mkdir -p "${gadget_dir}" || return
65 echo ${ID_VENDOR} > "${gadget_dir}/idVendor" || return
66 echo ${ID_PRODUCT} > "${gadget_dir}/idProduct" || return
Maksym Sloyko96342732021-08-03 21:54:28 +000067
68 local str_en_dir="${gadget_dir}/strings/0x409"
William A. Kennington IIIe1c8b872022-04-04 17:30:48 -070069 mkdir -p "${str_en_dir}" || return
70 echo ${STR_EN_VENDOR} > "${str_en_dir}/manufacturer" || return
71 echo ${STR_EN_PRODUCT} > "${str_en_dir}/product" || return
Maksym Sloyko96342732021-08-03 21:54:28 +000072
73 local config_dir="${gadget_dir}/configs/c.1"
William A. Kennington IIIe1c8b872022-04-04 17:30:48 -070074 mkdir -p "${config_dir}" || return
75 echo 100 > "${config_dir}/MaxPower" || return
76 mkdir -p "${config_dir}/strings/0x409" || return
77 echo "${DEV_TYPE^^}" > "${config_dir}/strings/0x409/configuration" || return
Maksym Sloyko96342732021-08-03 21:54:28 +000078
William A. Kennington IIIf8a77742022-02-28 18:05:54 -080079 local func_dir="${gadget_dir}/functions/${DEV_TYPE}.${IFACE_NAME}"
William A. Kennington IIIe1c8b872022-04-04 17:30:48 -070080 mkdir -p "${func_dir}" || return
Maksym Sloyko96342732021-08-03 21:54:28 +000081
82 if [[ -n $HOST_MAC_ADDR ]]; then
William A. Kennington IIIe1c8b872022-04-04 17:30:48 -070083 echo ${HOST_MAC_ADDR} >${func_dir}/host_addr || return
Maksym Sloyko96342732021-08-03 21:54:28 +000084 fi
85
86 if [[ -n $DEV_MAC_ADDR ]]; then
William A. Kennington IIIe1c8b872022-04-04 17:30:48 -070087 echo ${DEV_MAC_ADDR} >${func_dir}/dev_addr || return
Maksym Sloyko96342732021-08-03 21:54:28 +000088 fi
89
William A. Kennington IIIe1c8b872022-04-04 17:30:48 -070090 ln -s "${func_dir}" "${config_dir}" || return
Maksym Sloyko96342732021-08-03 21:54:28 +000091
William A. Kennington IIIe1c8b872022-04-04 17:30:48 -070092 echo "${BIND_DEVICE}" >${gadget_dir}/UDC || return
William A. Kennington III8d0f9062022-04-04 17:30:54 -070093 local ifname
94 ifname="$(<"${func_dir}"/ifname)" || return
95 if [ "${IFACE_NAME}" != "$ifname" ]; then
96 # We don't care if downing the interface fails, only the rename
97 ip link set dev "$ifname" down || true
98 ip link set dev "$ifname" name "${IFACE_NAME}" || return
99 fi
William A. Kennington IIIf08c0cc2022-04-04 19:39:58 -0700100 ip link set dev "$IFACE_NAME" up || return
Maksym Sloyko96342732021-08-03 21:54:28 +0000101}
102
103gadget_stop() {
104 local gadget_dir="${CONFIGFS_HOME}/usb_gadget/${GADGET_DIR_NAME}"
William A. Kennington IIIf8a77742022-02-28 18:05:54 -0800105 rm -f ${gadget_dir}/configs/c.1/${DEV_TYPE}.${IFACE_NAME}
William A. Kennington III0ae2b8f2022-03-31 18:02:30 -0700106 rmdir ${gadget_dir}/functions/${DEV_TYPE}.${IFACE_NAME} \
107 ${gadget_dir}/configs/c.1/strings/0x409 \
108 ${gadget_dir}/configs/c.1 \
109 ${gadget_dir}/strings/0x409 \
110 ${gadget_dir} || true
William A. Kennington IIIa9de0df2022-02-22 17:11:13 -0800111
112 rm -f /run/systemd/network/+-bmc-"${IFACE_NAME}".network
William A. Kennington IIIe1c8b872022-04-04 17:30:48 -0700113 networkctl reload || true
Maksym Sloyko96342732021-08-03 21:54:28 +0000114}
115
116opts=$(getopt \
117 --longoptions "$(printf "%s," "${ARGUMENT_LIST[@]}")" \
118 --name "$(basename "$0")" \
119 --options "" \
120 -- "$@"
121)
122
123eval set --$opts
124
125CONFIGFS_HOME=${CONFIGFS_HOME:-/sys/kernel/config}
126ID_VENDOR="0x18d1" # Google
127ID_PRODUCT=""
128STR_EN_VENDOR="Google"
129STR_EN_PRODUCT=""
130DEV_MAC_ADDR=""
William A. Kennington IIIf8a77742022-02-28 18:05:54 -0800131DEV_TYPE="eem"
Maksym Sloyko96342732021-08-03 21:54:28 +0000132HOST_MAC_ADDR=""
133BIND_DEVICE=""
134ACTION="start"
William A. Kennington III878454a2022-04-04 17:05:05 -0700135GADGET_DIR_NAME=""
William A. Kennington III69ebd2c2022-04-04 17:51:09 -0700136IFACE_NAME=""
Maksym Sloyko96342732021-08-03 21:54:28 +0000137while [[ $# -gt 0 ]]; do
138 case "$1" in
139 --product-id)
140 ID_PRODUCT=$2
141 shift 2
142 ;;
143 --product-name)
144 STR_EN_PRODUCT=$2
145 shift 2
146 ;;
147 --host-mac)
148 HOST_MAC_ADDR=$2
149 shift 2
150 ;;
151 --dev-mac)
152 DEV_MAC_ADDR=$2
153 shift 2
154 ;;
William A. Kennington IIIf8a77742022-02-28 18:05:54 -0800155 --dev-type)
156 DEV_TYPE=$2
157 shift 2
158 ;;
Maksym Sloyko96342732021-08-03 21:54:28 +0000159 --bind-device)
160 BIND_DEVICE=$2
161 shift 2
162 ;;
163 --gadget-dir-name)
164 GADGET_DIR_NAME=$2
165 shift 2
166 ;;
167 --iface-name)
168 IFACE_NAME=$2
169 shift 2
170 ;;
171 --help)
172 print_usage
173 exit 0
174 ;;
175 start)
176 ACTION="start"
177 shift 1
178 break
179 ;;
180 stop)
181 ACTION="stop"
182 shift 1
183 break
184 ;;
185 --)
186 shift 1
187 ;;
188 *)
189 break
190 ;;
191 esac
192done
193
William A. Kennington III878454a2022-04-04 17:05:05 -0700194if [ -z "$GADGET_DIR_NAME" ]; then
195 GADGET_DIR_NAME="$IFACE_NAME"
196fi
197
Maksym Sloyko96342732021-08-03 21:54:28 +0000198if [[ $ACTION == "stop" ]]; then
199 gadget_stop
200else
William A. Kennington III69ebd2c2022-04-04 17:51:09 -0700201 if [ -z "$ID_PRODUCT" ]; then
202 echo "Product ID is missing" >&2
203 exit 1
204 fi
205
206 if [ -z "$IFACE_NAME" ]; then
207 echo "Interface name is missing" >&2
208 exit 1
209 fi
210
211 if [ -z "$BIND_DEVICE" ]; then
212 echo "Bind device is missing" >&2
213 exit 1
214 fi
215
William A. Kennington III986d3a62022-03-31 17:58:30 -0700216 rc=0
217 gadget_start || rc=$?
218 (( rc == 0 )) || gadget_stop || true
219 exit $rc
Maksym Sloyko96342732021-08-03 21:54:28 +0000220fi