D7net
Home
Console
Upload
information
Create File
Create Folder
About
Tools
:
/
usr
/
share
/
ModemManager
/
fcc-unlock.available.d
/
Filename :
8086:7360
back
Copy
#!/bin/bash # SPDX-License-Identifier: CC0-1.0 # 2024 Thomas Vogt # # RPC-powered Intel XMM7360 (8086:7360) FCC unlock if [[ "$FCC_UNLOCK_DEBUG_LOG" == '1' ]]; then exec 3>&1 4>&2 trap 'exec 2>&4 1>&3' 0 1 2 3 exec 1>>/var/log/mm-xmm7360-fcc.log 2>&1 fi # require program name and at least 2 arguments [ $# -lt 2 ] && exit 1 # first argument is DBus path, not needed here shift # second and next arguments are control port names for PORT in "$@"; do # support for XMM7360 has been added in 5.18 # match port type, assuming Linux 5.14 and newer grep -q XMMRPC "/sys/class/wwan/$PORT/type" 2>/dev/null && { XMMRPC_PORT=$PORT break } done # fail if no XMMRPC port exposed [ -n "$XMMRPC_PORT" ] || exit 2 DEVICE=/dev/${XMMRPC_PORT} log() { echo "$1" } error() { echo "$1" >&2 } reverseHexEndianness() { num="$1" printf "%s" "${num:6:2}${num:4:2}${num:2:2}${num:0:2}" } littleEndianToDec() { printf "%d" "0x$1" } bigEndianToDec() { littleEndianToDec "$(reverseHexEndianness "$1")" } readNBytesAsHex() { data=$(head "-c$1" <&99 | xxd -p -c0 | tr -d '\n') printf "%s" "$data" } writeHexAsBinary() { printf "%s" "$1" | xxd -r -p >&99 } readResponseAsHex() { length_hex=$(readNBytesAsHex 4) length=$(bigEndianToDec "$length_hex") content=$(readNBytesAsHex $length) printf "%s" "$length_hex$content" } rpc_command() { exec 99<>"$DEVICE" writeHexAsBinary $1 answer=$(readResponseAsHex) # ignore "async-ack" response answer=$(readResponseAsHex) printf "%s" "$answer" exec 99>&- } VENDOR_ID_HASH="3df8c719" for i in {1..3}; do log "Attempt #${i} to unlock WWAN modem" log "Requesting FCC lock state from modem" # --> (async) csi-fcc-lock-query-req RESP=$(rpc_command "1c00000002040000001c02040000018e11000101020411000101020400000000") MODE=$(littleEndianToDec "${RESP: -8}") STATE=$(littleEndianToDec "${RESP: -20:8}") log "Got response from modem: state=$STATE, mode=$MODE" if [ "$MODE" = "0" ]; then log "FCC lock is deactivated, nothing to do." exit 0 fi if [ "$STATE" != "0" ]; then log "FCC already unlocked, nothing to do." exit 0 fi log "Requesting challenge from modem" # --> (async) csi-fcc-lock-gen-challenge-req RESP=$(rpc_command "1c00000002040000001c02040000019011000101020411000101020400000000") HEX_CHALLENGE=$(printf "%s" "${RESP: -8}") log "Got challenge from modem: $HEX_CHALLENGE" REVERSE_HEX_CHALLENGE=$(reverseHexEndianness "${HEX_CHALLENGE}") COMBINED_CHALLENGE="${REVERSE_HEX_CHALLENGE}${VENDOR_ID_HASH}" RESPONSE_HASH=$(printf "%s" "$COMBINED_CHALLENGE" | xxd -r -p | sha256sum | cut -d ' ' -f 1) REVERSED_RESPONSE=$(reverseHexEndianness "${RESPONSE_HASH:0:8}") log "Sending hash to modem: $REVERSED_RESPONSE" # --> (async) csi-fcc-lock-ver-challenge-req RESP=$(rpc_command "1c00000002040000001c020400000192110001010204110001010204${REVERSED_RESPONSE}") UNLOCK_RESPONSE=$(littleEndianToDec "${RESP: -8}") if [ "$UNLOCK_RESPONSE" = "0" ]; then error "Unlock failed." else log "FCC unlock successful (response $UNLOCK_RESPONSE)" exit 0 fi sleep 0.5 done exit 2