#!/bin/bash
# This script assumes Verizon SIMS ICCID start with 89148 and is firmware 1.
# This script assumes T-Mobile SIMS start with 8901260 and is firmware 2.

fwsw_modems=(LE910-NA1 LE910C4-NF)
mt_modems=(lna3 l4n1)
readme=/etc/ppp/peers/README.fwswitch
function setactivefirmware
{
    radio-cmd ${RADIOOPTION} --set-active-firmware $1
#   RESULT=$(radio-cmd ${RADIOOPTION} 'AT#FWSWITCH='$1',1' 2>&1)
#   if (($? != 0)) ; then
#       >&2 echo "FW Set failed"
#       return 1
#   fi
#   if [[ $RESULT =~ [Ee][Rr][Rr][Oo][Rr] ]] ; then
#       >&2 echo "FW Set failed"
#       return 1
#   fi
}

function getactivefirmware
{
    /usr/bin/radio-query ${RADIOOPTION} --active-firmware
#   FW=$(/usr/bin/radio-cmd ${RADIOOPTION} 'AT#FWSWITCH?' 2>/dev/null)
#   if (($? != 0)) ; then
#       >&2 echo "FW Query failed"
#       return 1
#   fi
#   [[ $FW =~ \#FWSWITCH:[[:space:]]*([^,]*) ]]
#   echo "${BASH_REMATCH[1]}"
}

# See if string is in array of strings
# parm 1 String
# parm 2 Arrays of strings
function findItem {
    local s check="$1"
    shift
    for s ; do 
        [[ "$s" == "$check" ]] && return 0;
    done
    return 1
}


function usage {
>&2 echo "
Usage: $0 <image_id> [timeout]
    image_id <0|1|2|-1>  : for dual FW image SKU-s, the id of the image to switch to
                       -1 is based on SIM
    timeout            : wait time for radio to come up if set (default : 15 sec)
    
"
    exit 1
}

if [ $# -gt 2 ] ; then
    usage
fi

#
# Check if the radio present
#
MODEL=$(radio-query ${RADIOOPTION} --model 2>&1)
result=$?
if [[ $MCONTEXT =~ [Ee][Rr][Rr][Oo][Rr] ]] ; then
    RADIOOPTION="${RADIOOPTION2}"
    MODEL=$(radio-query ${RADIOOPTION} --model 2>&1)
    result=$?
fi

if ((result != 0)) ; then
  [ "$VERBOSE" ] && >&2 echo "Assume no radio on this device."
  exit 0
fi

#
# Load args (don't wait for the radio by default)
#
FWIMAGE=$1
if ((FWIMAGE < -2)) || ((FWIMAGE > 2)) ; then
    usage
fi
if ! >&2 /usr/sbin/mlinux-cell-radio-ready ; then
    [ "$VERBOSE" ] && >&2 echo Radio is not ready
    [ "$VERBOSE" ] && >&2 echo Try again later
    exit 1
fi
if ((FWIMAGE == -1)) ; then
    iccid=$(radio-query ${RADIOOPTION} --iccid)
    if (($? == 0)); then
        if ((${#iccid} == 0)) ; then
            [ "$VERBOSE" ] && >&2 echo "No carrier.  Maybe no SIM?"
            [ "$VERBOSE" ] && >&2 echo "ERROR: Cannot decide on firmware"
            exit 1
        fi
        if [[ $iccid =~ ^89148.* ]] ; then
            # Verizon
            logger -s -t mlinux-sw-firmware -p daemon.info "Assuming $iccid is a Verizon SIM ICCID using Firmware 1"
            ((FWIMAGE=1))
        elif [[ $iccid =~ ^8901260.* ]] ; then
            # T-Mobile
            logger -s -t mlinux-sw-firmware -p daemon.info "Assuming $iccid is a T-Mobile SIM ICCID using Firmware 2"
            ((FWMAGE=2))
            if [[ $MODEL == LE910-NA1 ]] ; then  # Assume LNA3 has no firmware image 2
                ((FWIMAGE=0))
            fi
        else
            # Everybody else
            logger -s -t mlinux-sw-firmware -p daemon.info "Assuming $iccid is a possibly AT&T SIM using Firmware 0"
            ((FWIMAGE=0))
        fi
    else
       >&2 echo "Cannot get ICCID from SIM"
       >&2 echo "Try again later"
       exit 1
    fi
fi
    

TIMEOUT=${2:-15}
if [ "$VERBOSE" != "yes" ]; then
  VERBOSE=""
fi

[ "$VERBOSE" ] && >&2 echo -n "Switching the radio firmware image: "

#
# Applicable for LTE910-NA1 and LE910C4-NF with dual FW images only
#
if ! findItem "$MODEL" "${fwsw_modems[@]}" ; then
    echo "Firmware switch is not supported on ${MODEL}."
    exit 1
fi

#
# Check if firmware switch is required
#
FWACTIVE=$(getactivefirmware)
if [ $? -ne 0 ] || [ "$FWACTIVE" == "" ]; then
    [ "$VERBOSE" ] && >&2 echo "The $MODEL radio does not support firmware switching."
    exit 0
fi

if (( FWACTIVE == FWIMAGE )); then
    echo "Cellular radio firmware has already been switched to $FWIMAGE image."
    exit 0
fi

# Disable the LNA3 chat script in case of failure.
for f in $mt_modems ; do
    linkf=/etc/ppp/peers/${f}_chat
    if ! [[ -L ${linkf} ]] || [[ $(basename $(readlink -f ${linkf})) != ${readme} ]] ; then
        ln -sf "${readme}" "${linkf}"
        echo "Chat script is now disabled."
    fi
done

#
# Switch the firmware
#
RESULT=$(setactivefirmware "$FWIMAGE")
if [ $? -ne 0 ]; then
  [ "$VERBOSE" ] && >&2 echo "$RESULT"
  exit 1
fi


#
# Exit if no TIMEOUT set
#
# This is somewhat dangerous in that we assume the radio
# will switch.
if ((TIMEOUT == 0)) ; then
   if ((FWIMAGE == 0)) ; then
     [ "$VERBOSE" ] && >&2 echo "Use mlinux-switch-apn to switch the APN when the radio is ready, before dialing"
     exit 0
   fi
fi
# 
#
# Wait for the radio to be ready before continuing
#
COUNTER=0

[ "$VERBOSE" ] && echo -n "Wait..."

#
# Give it some time
#
sleep 5

while [ $COUNTER -lt $TIMEOUT ]; do
  MODEL=$(radio-query ${RADIOOPTION} --model)
  if [ $? -eq 0 ]; then
    echo "Cellular radio firmware has been switched to $FWIMAGE image."
    exit 0
  fi

  let COUNTER=COUNTER+1

  [ "$VERBOSE" ] && echo -n "."

  sleep 1
done

>&2 echo "Cellular radio is not ready."
>&2 echo "When it becomes ready, invoke /usr/sbin/mlinux-switch-apn"
>&2 echo "to set the APN"
exit 1
