| #!/bin/sh |
| |
| # Copyright (c) 2013 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| . "$(dirname "$0")/common.sh" || exit 1 |
| |
| # A local die function to print the message and then exit |
| die() { |
| echo -e "$@" |
| exit 1 |
| } |
| |
| # Assert inside chroot |
| assert_inside_chroot |
| |
| # Read command flags |
| . /usr/share/misc/shflags |
| DEFINE_string board '' 'which board the firmware is for' 'b' |
| DEFINE_boolean clean false 'clean up all temporary files' 'c' |
| DEFINE_boolean debug false 'debug flag' 'd' |
| DEFINE_string infile '' 'the input (zip) file' 'f' |
| DEFINE_string issue '' 'the issue number on the issue tracker' 'i' |
| DEFINE_string revision '' 'the revision number of the firmware' 'r' |
| |
| PROG=$0 |
| FLAGS_HELP="USAGE: $PROG [flags]" |
| |
| FLAGS "$@" || exit 1 |
| eval set -- "${FLAGS_ARGV}" |
| set -e |
| |
| # Set global variables |
| infile="$FLAGS_infile" |
| FW_PATH="opt/google/touchpad/firmware" |
| FW_MODE=755 |
| FW_OWN="root:root" |
| TMP_DIR="/tmp/touch_fw" |
| TMP_RESULT="${TMP_DIR}/login.result" |
| COOKIE_FILE="${TMP_DIR}/login.cookie" |
| |
| # Some URLs to set up credentials |
| AUTH_URL="https://accounts.google.com/ServiceLoginAuth?hl=en&continue=" |
| TRACKER_URL="https%3A%2F%2Fcode.google.com%2Fp%2Fchrome-os-partner"\ |
| "%2Fissues%2Fdetail%3Fid%3D" |
| issue_auth_url="$AUTH_URL$TRACKER_URL$FLAGS_issue" |
| |
| # Per board definitions |
| # Only works for lumpy/cypress for now. |
| # TODO: work on other boards too. |
| FW_UPDATE_TOOL_CYPRESS="/sbin/cyapa_fw_update" |
| CYPRESS_TOOLS="cypress-tools" |
| |
| # Print the message when debug flag is set. |
| debug_print() { |
| if [ $FLAGS_debug = "$FLAGS_TRUE" ]; then |
| local name=$1 |
| local value=${!name} |
| echo " (DEBUG) $name: $value" |
| fi |
| } |
| |
| # Print the usage and examples, and then exit. |
| usage_and_exit() { |
| flags_help |
| die "\nExamples: |
| Specify the issue # and download the firmware from the remote server. |
| \$ $PROG -i 12345 -b lumpy \n |
| Convert the iic file in a local zip file to bin file. |
| \$ $PROG -f /tmp/CYTRA-116001-00-v11.26-Testdrop.zip -b lumpy \n |
| Specify that it is revision 'r2' and also enable the debug flag. |
| \$ $PROG -i 12345 -b lumpy -r r2 -d \n |
| Clean up all temporary files after finished. |
| \$ $PROG -c \n" |
| } |
| |
| # Make sure that exactly an issue number or an local zip file is specified. |
| check_argument() { |
| if [ -z "$FLAGS_issue" -a -z "$FLAGS_infile" -o \ |
| "$FLAGS_issue" -a "$FLAGS_infile" ]; then |
| echo -e "Specify exactly either an issue number or a local zip file.\n" |
| usage_and_exit |
| elif [ -z "$FLAGS_board" ]; then |
| echo -e "You need to specify a board.\n" |
| usage_and_exit |
| fi |
| } |
| |
| # Set up a temporary directory that only the owner could access. |
| setup_tmp_dir() { |
| mkdir -p -m 0700 $TMP_DIR |
| } |
| |
| # Prompt the user to type chromium email account and password. |
| read_user_and_password() { |
| # Read the user email address and password if not yet. |
| if [ -z $USR -o -z $PASS ]; then |
| echo Please type your user name of chromium account. |
| read -p "Username (without @chromium.org): " USR |
| read -s -p "Password: " PASS |
| fi |
| USR_PASS="Email=${USR}@chromium.org&Passwd=${PASS}" |
| } |
| |
| # Get dsh and GALX |
| get_credential() { |
| # Try to get dsh and GALX values. |
| if ! curl -s -c "$COOKIE_FILE" -L -d $USR_PASS $issue_auth_url > \ |
| "$TMP_RESULT"; then |
| die "Error: curl failed to get $issue_auth_url" |
| fi |
| |
| # The dsh value looks like |
| # name="dsh" id="dsh" value="3039562716843903054" |
| dsh=`grep -i "dsh" "$TMP_RESULT" | \ |
| sed -n "s/.*value=\"\(-*[0-9]*\)\"/\1/p"` |
| |
| # The GALX value looks like |
| # name="GALX" |
| # value="Bfr17SQrDe4"> |
| galx=`grep -i -A1 "GALX" "$TMP_RESULT" | \ |
| sed -n "s/.*value=\"\(.*\)\".*/\1/p"` |
| |
| if [ -z dsh -o -z galx ]; then |
| die "Error: fail to get dsh or galx." |
| fi |
| } |
| |
| # Get the firmware attachment URL from the specified tracker issue. |
| # And then download the firmware zip file. |
| download_fw_file() { |
| # The returned attachment syntax looks like |
| # <a href="//chrome-os-partner.googlecode.com/issues/attachment? |
| # aid=172300000000&name=CYTRA-116001-00-v11.27-Testdrop.zip& |
| # token=E9jFSVjVX9abUmyCrGm0ms0YuBI%3A1359083647918">Download</a> |
| local attach_str=`curl -s -b "$COOKIE_FILE" -L -d \ |
| "GALX=${galx}&bgresponse=js_disabled&dsh=${dsh}&$USR_PASS" \ |
| $issue_auth_url | \ |
| grep "href=.*CYTRA.*\.zip.*Download" | \ |
| sed -n 's/.*href=\"\(.*\)\">Download.*/\1/p'` |
| attachment_url="https:"`echo $attach_str | sed 's/\&/\&/g'` |
| |
| fw_zipfile="${TMP_DIR}/`echo $attachment_url | \ |
| sed -n 's/http.*name=\(CYTRA.*\.zip\)\&token=.*/\1/p'`" |
| |
| if [ "$attachment_url" = "https:" -a "$fw_zipfile" = "${TMP_DIR}/" ]; then |
| die "\n Error: either the firmware url or the firmware zip name |
| cannot be found |
| \n firmware url: $attachment_url |
| \n firmware name: $fw_zipfile" |
| else |
| echo Downloading the firmware: $fw_zipfile |
| curl -s -o "$fw_zipfile" "$attachment_url" |
| fi |
| } |
| |
| # Check the existence of the file |
| check_file_existence() { |
| local target_file="$1" |
| if [ ! -f "$target_file" ]; then |
| die "File does not exist: $target_file" |
| fi |
| } |
| |
| # Get the firmware version from infile. |
| get_fw_version() { |
| # The following command will extract the firmware version number from a |
| # firmware zip file. |
| # |
| # "CYTRA-116001-00-v11.26-Testdrop.zip" => 11.26 |
| # "CYTR-116001-00-V11.2.6.zip" => 11.2.6 |
| # "CYTRA-116001-00-v27.zip" => 27 |
| # "CYTRA_103002_00 FW_V1.9.zip.zip" => 1.9 |
| # |
| # Note: |
| # A in "CYTRA" is optional |
| # Either v or V is acceptable |
| # The firmware version could be something like 11, or 11.26, or 11.2.5, etc. |
| fw_version=`echo $infile | sed -nr 's/.*CYTRA?.*v([0-9]+[\.0-9]*).*/\1/pi'` |
| if [ -z $fw_version ]; then |
| die "Failed to extract the firmware version number from $infile" |
| fi |
| echo Firmware version: $fw_version |
| } |
| |
| # Get the correct firmware .bin file name. |
| # It converts any incorrect dashes and underscores to the correct format. |
| # |
| # Example: it makes the following name conversion |
| # from ".../CYTRA_116001_00_v11.27.iic" |
| # to ".../CYTRA-116001-00_11.27.bin" |
| # |
| # Note that the correct format of a bin file should look like |
| # ${product_id}_${version_number}.bin |
| # where $product_id is "CYTRA-116001-00", and |
| # $version_number is "11.27" |
| # Also note that there is a '_" between $product_id and $version_number. |
| get_fw_bin_name() { |
| sed_script="s/(.*)(CYTRA?)[-_]([0-9]+)[-_]([0-9]+)[-_].*\.iic"\ |
| "/\1\2-\3-\4_${fw_version}.bin/pi" |
| bin_name=`echo $1 | sed -nr $sed_script` |
| } |
| |
| # Convert an iic file to a bin file. |
| convert_iic_to_bin() { |
| local iic_file="${TMP_DIR}/$1" |
| get_fw_bin_name $iic_file |
| test "$FLAGS_revision" && rev="-$FLAGS_revision" |
| # A top_dir looks like "chromeos-touch-firmware-lumpy-11.27-r1" |
| top_dir="chromeos-touch-firmware-${FLAGS_board}-${fw_version}${rev}" |
| relative_bin_file="${top_dir}/${FW_PATH}/$(basename $bin_name)" |
| bin_file="$(dirname $bin_name)/$relative_bin_file" |
| mkdir -p "$(dirname $bin_file)" |
| |
| # Get the firmware update tool ready. |
| local FW_UPDATE_TOOL="$FW_UPDATE_TOOL_CYPRESS" |
| # If the firmware upate tool does not exist in the host yet, we need to |
| # unmerge the package, and then run update_chroot to get the firmware |
| # update tool installed through the virtual/target-sdk package. |
| if [ ! -f $FW_UPDATE_TOOL ]; then |
| echo $CYPRESS_TOOLS does not exist. |
| echo We will unmerge $CYPRESS_TOOLS and then run update_chroot. |
| sudo emerge --unmerge $CYPRESS_TOOLS || \ |
| die "Failed to unmerge '$CYPRESS_TOOLS'" |
| ~/trunk/src/scripts/update_chroot || die "Failed to run 'update_chroot'" |
| echo "Compile and install $FW_UPDATE_TOOL successfully." |
| fi |
| |
| # Convert the iic file to the bin file. Set the proper mode and owner/group. |
| sudo "$FW_UPDATE_TOOL" -c "$iic_file" -o "$bin_file" > /dev/null |
| sudo chmod "$FW_MODE" "$bin_file" |
| sudo chown "$FW_OWN" "$bin_file" |
| |
| debug_print iic_file |
| debug_print bin_name |
| echo "Firmware bin file: $bin_file" |
| } |
| |
| # Get the firmware file in .bin format |
| get_bin_fw_file() { |
| local zipfile="$1" |
| local FILE_TYPE=$(file "$zipfile") |
| # Convert it to lower case for comparison |
| FILE_TYPE=${FILE_TYPE,,} |
| |
| if [[ "$FILE_TYPE" = *"zip archive"* ]]; then |
| # Try to find if there exists the .bin file. |
| # Otherwise, try to locate the .iic file. |
| local fw_file=`zipinfo -1 $zipfile | grep .bin` |
| if [ $fw_file ]; then |
| echo Find firmware bin file: $fw_file |
| unzip -q -o -d "$TMP_DIR" $zipfile $fw_file |
| else |
| local fw_file=`zipinfo -1 $zipfile | grep .iic` |
| if [ $fw_file ]; then |
| unzip -q -o -d "$TMP_DIR" $zipfile $fw_file |
| convert_iic_to_bin $fw_file |
| else |
| echo Neither .bin nor .iic file could be found in $zipfile |
| fi |
| fi |
| else |
| die "Error: '$zipfile' is not a zip file." |
| fi |
| } |
| |
| create_tbz2() { |
| local target_file="$1" |
| local tarball_name="chromeos-touch-firmware" |
| local work_dir=$PWD |
| |
| tarball="${TMP_DIR}/${tarball_name}-${FLAGS_board}-${fw_version}${rev}.tbz2" |
| debug_print target_file |
| cd "$TMP_DIR" |
| sudo tar --owner=root --group=root --mode="$FW_MODE" -cjf "$tarball" \ |
| "$target_file" |
| cd $work_dir |
| echo -e "\nTarball created: ${tarball}" |
| echo -e "You could upload this tarball to the Binary Components Server:" |
| echo -e " https://www.google.com/chromeos/partner/fe/ \n" |
| echo -e "Type '$PROG -c' to clean up all temporary files" \ |
| "after uploading the files.\n" |
| } |
| |
| # Clean up unnecessary files in the tmp directory. |
| # This function is invoked automatically after the tarball is created. |
| clean_up_tmp_files() { |
| # Keep only .tbz2 and .bin files. |
| find "$TMP_DIR" -type f -not -iregex ".*tbz2\|.*bin" | xargs rm |
| } |
| |
| # Clean up the whole tmp directory. |
| # This function is invoked when '-c' clean up flag is specified. |
| clean_up_tmp_dir() { |
| rm -fr "$TMP_DIR" |
| die "Clean up all temporary files in '$TMP_DIR'." |
| } |
| |
| |
| # main program begins here. |
| # ------------------------- |
| |
| if [ $FLAGS_clean = $FLAGS_TRUE ]; then |
| clean_up_tmp_dir |
| fi |
| |
| check_argument |
| setup_tmp_dir |
| |
| # If an issue number is given, get the firmware zip file from a remote server. |
| # This is executed only when '-i' command flag is specified. |
| # If '-f' command flag is specified, skip this block. |
| if [ $FLAGS_issue ]; then |
| read_user_and_password |
| get_credential |
| download_fw_file |
| infile=$fw_zipfile |
| fi |
| |
| # Now we have the local zip file. |
| debug_print infile |
| check_file_existence $infile |
| get_fw_version |
| get_bin_fw_file $infile |
| create_tbz2 "$relative_bin_file" |
| |
| # Clean up some unnecessary temporary files. |
| # Keep the created tarball and the .bin firmware file. |
| clean_up_tmp_files |