X270へEM7430の搭載チャレンジ

## 環境
・X270 (Type 20HN, 20HM) Laptop (ThinkPad) - Type 20HM　BIOS ver 1.45
・SIMはpovo
・M.2 NGFF ワイヤレスWWAN USBアダプターカード
・Aliexpressで購入した、EM7430のDELL版

・windows10 21H2 の環境（X270じゃなくてもいい）
・lubuntu-20.04.4-desktop-amd64 の環境（X270じゃなくてもいい）

ちなみに、EM7430は3種類存在するらしい。
|EM7430|vid|pid|
|:-:|:-:|:-:|
|generic Sierra|1199|9071|
|Lenovo |1199|907b|
|Dell(Dw5816e)|413c|81cc|

https://radenku.com/setting-modem-sierra-em7430-cat-6-openwrt/#42_Setting_Sierra_EM7430_Pertama_Kali

## やること
簡単に言うとEM7430のVID,PID,BIDを変更し、BIOSのホワイトリストを騙す。

#### 0.前提
ワイヤレスWWAN USBアダプターカードにEM7430を搭載して、windows環境に接続する。

#### 1.ドライバの用意（windows10）
以下URLのnz3wm10w.exeをダウンロード＆インストールする。

https://support.lenovo.com/jp/ja/downloads/ds500384-sierra-wireless-em7430-software-for-windows-10-64-bit-thinkpad

#### 2.ファームウェアアップデート（windows10）
以下URLの7430→Genericをダウンロード&実行する。
※デバイスマネージャーで認識していないとうまくいかない。
※autoflash-7455.shでもファームウェアアップデートできるが何故かうまくいかない。

https://source.sierrawireless.com/resources/airprime/minicard/74xx/em_mc74xx-approved-fw-packages/#sthash.NAcMibyB.dpbs

#### 3.スクリプトの修正（windows10）
以下URLのautoflash-7455.shを参考に修正する。

https://github.com/danielewood/sierra-wireless-modems/blob/master/autoflash-7455.sh

修正したファイル
```shell:autoflash-7455v2.sh
#!/bin/bash
# shellcheck disable=SC2059
#
#.USAGE
# To start, run:
# wget https://raw.githubusercontent.com/danielewood/sierra-wireless-modems/master/autoflash-7455.sh && sudo bash autoflash-7455.sh

#.SYNOPSIS
# - Only for use on Ubuntu 20.04 (or later) LiveUSB
# - Changes all models of EM7455/MC7455 Modems to the Generic Sierra Wireless VID/PID
# - Flashes the Current Generic Firmware

#.DESCRIPTION
# - Only for use on Ubuntu 20.04 (or later) LiveUSB
# - All Needed Packages will Auto-Install
# - Sets MBIM Mode with AT Commands Access
# - Changes all models of EM74XX/MC74XX Modems to the Generic Sierra Wireless VID/PID
# - Clears Band Restrictions and Places Modem in LTE only mode.
# - Flashes the Current Generic Firmware
# - Sets PCOFFEN=2 to tell the modem to ignore the W_DISABLE pin sent by many laptop's internal M2 slots.
# - Sets FASTENUMEN=2 to skip bootloader on warm-boots.
#   - This, combined with PCOFFEN enables these modems to work in the X1G6/T470 and newer laptops.

#.NOTES
# License: The Unlicense / CCZero / Public Domain
# Author: Daniel Wood / https://github.com/danielewood

#.LINK
# https://github.com/danielewood/sierra-wireless-modems

#.VERSION
# Version: 20210405

##################
### Pre-Checks ###
##################

if [ "$EUID" -ne 0 ]
    then echo "Please run with sudo"
    exit
fi

if [[ $(lsb_release -r | awk '{print ($2 >= "20.04")}') -eq 0 ]]; then 
    echo "Please run on Ubuntu 20.04 (Focal Fossa) or later"
    lsb_release -a
    exit
fi

#########################
### Variables & Input ###
#########################

CYAN='\033[0;36m'
NC='\033[0m' # No Color

function display_usage() {
  printf "${CYAN}Usage:${NC} $0\n"
  printf "\n"
  printf "${CYAN}Modem Modes:${NC}\n"
  printf " -h    Display usage instructions\n"
  printf " -u    Set AT!USBSPEED\n"
  printf "         0 - High Speed USB 2 ${CYAN}[Default]${NC}\n"
  printf "         1 - SuperSpeed USB 3\n"
  printf " -m    Set AT!USBCOMP\n"
  printf "         8 - MBIM mode (diag,nmea,modem,mbim) ${CYAN}[Default]${NC}\n"
  printf "         6 - QMI mode (diag,nmea,modem,rmnet0)\n"
  printf " -b    Set AT!SELRAT and AT!BAND\n"
  printf "         9 - LTE Only ${CYAN}[Default]${NC}\n"
  printf "         0 - All Bands\n"  
  printf " -e    Set AT!FASTENUMEN\n"
  printf "         0 - Disable fast enumeration\n"
  printf "         1 - Enable fast enumeration for cold boot and disable for warm boot\n"
  printf "         2 - Enable fast enumeration for warm boot and disable for cold boot ${CYAN}[Default]${NC}\n"
  printf "         3 - Enable fast enumeration for warm and cold boot\n"
  printf "\n"
  printf "${CYAN}Script Modes:${NC}\n"
  printf " -a    Enable All Script Functions ${CYAN}[Default]${NC}\n"
  printf "         Same as: $0 -Mgcdfs\n"
  printf " -M    Use swi_setusbcomp.pl to set modem composition\n"
  printf " -g    Display Modem Settings\n"
  printf " -c    Clear Existing Modem Firmwares\n"
  printf " -d    Download and Unpack Modem Firmware from Sierra Wireless\n"
  printf " -f    Flash Modem Firmware\n"
  printf " -s    Change Modem Settings/Modes\n"
  printf " -l    Legacy Stable Firmware\n"
  printf "         Set SWI9X30C_ZIP=\"SWI9X30C_02.38.00.00_Generic_002.082_000.zip\"\n"
  printf " -q    Quiet Mode -- suppress most output\n"
  printf " -v    Verbose/Debug Mode\n"
  printf "\n"
  exit 0
}

while getopts hu:m:b:e:Mgcdfsalqv option
do
 case "${option}"
 in
 h) display_usage
      exit 0;;
 u) AT_USBSPEED=${OPTARG};;
 m) AT_USBCOMP=${OPTARG};;
 b) AT_SELRAT=${OPTARG};;
 e) AT_FASTENUMEN=${OPTARG};;
 M) set_swi_setusbcomp_trigger=1;;
 g) get_modem_settings_trigger=1;;
 c) clear_modem_firmware_trigger=1;;
 d) download_modem_firmware_trigger=1;;
 f) flash_modem_firmware_trigger=1;;
 s) set_modem_settings_trigger=1;;
 a) all_functions_trigger=1;;
 l) SWI9X30C_ZIP='SWI9X30C_02.38.00.00_Generic_002.082_000.zip';;
 q) quiet_trigger=1;;
 v) verbose_trigger=1;;
 *) display_usage>&2
      exit 1;;
  esac
done


#################
### Functions ###
#################

# If no options are set, use defaults of -Mgcdfs
if [[ -z $get_modem_settings_trigger && -z $clear_modem_firmware_trigger \
    && -z $download_modem_firmware_trigger && -z $flash_modem_firmware_trigger \
    && -z $set_modem_settings_trigger && -z $set_swi_setusbcomp_trigger ]]; then
        all_functions_trigger=1
fi

if [[ all_functions_trigger -eq 1 ]]; then
  get_modem_settings_trigger=1
  clear_modem_firmware_trigger=1
  download_modem_firmware_trigger=1
  flash_modem_firmware_trigger=1
  set_modem_settings_trigger=1
  set_swi_setusbcomp_trigger=1
fi

function display_variables() {
    echo "AT_USBSPEED=$AT_USBSPEED"
    echo "AT_USBCOMP=$AT_USBCOMP"
    echo "AT_SELRAT=$AT_SELRAT"
    echo "AT_FASTENUMEN=$AT_FASTENUMEN"
    echo "all_functions_trigger=$all_functions_trigger"
    echo "get_modem_settings_trigger=$get_modem_settings_trigger"
    echo "clear_modem_firmware_trigger=$clear_modem_firmware_trigger"
    echo "download_modem_firmware_trigger=$download_modem_firmware_trigger"
    echo "flash_modem_firmware_trigger=$flash_modem_firmware_trigger"
    echo "set_modem_settings_trigger=$set_modem_settings_trigger"
    echo "set_swi_setusbcomp_trigger=$set_swi_setusbcomp_trigger"
    echo "SWI9X30C_CWE=$SWI9X30C_CWE"
    echo "SWI9X30C_NVU=$SWI9X30C_NVU"
    echo "AT_PRIID_STRING=$AT_PRIID_STRING"
    echo "AT_PRIID_PN=$AT_PRIID_PN"
    echo "AT_PRIID_REV=$AT_PRIID_REV"
}

function set_options() {
    # See if QMI desired, otherwise default to MBIM
    if [[ ${AT_USBCOMP^^} =~ ^QMI$|^6$ ]]; then
        echo 'Setting QMI Mode for Modem'
        echo 'Interface bitmask: 0000010D (diag,nmea,modem,rmnet0)'
        AT_USBCOMP="1,1,0000010D"
        swi_usbcomp='6'
    else
        echo 'Setting MBIM Mode for Modem'
        echo 'Interface bitmask: 0000100D (diag,nmea,modem,mbim)'
        AT_USBCOMP="1,1,0000100D"
        swi_usbcomp='8'
    fi

    # Check for ALL/00 bands and set correct SELRAT/BAND, otherwise default to LTE
    if [[ ${AT_SELRAT^^} =~ ^ALL$|^0$|^00$ ]]; then
        AT_SELRAT='00'
        AT_BAND='00'
    else
        AT_SELRAT='06'
        AT_BAND='09'
    fi

    # Check if valid FASTENUMEN mode, otherwise default to 2
    if [[ ! $AT_FASTENUMEN =~ ^[0-3]$ ]]; then
        AT_FASTENUMEN=2
    fi

    #FASTENUMEN_MODES="0 = Disable fast enumeration [Default]
    #1 = Enable fast enumeration for cold boot and disable for warm boot
    #2 = Enable fast enumeration for warm boot and disable for cold boot
    #3 = Enable fast enumeration for warm and cold boot"
    #echo '"FASTENUMEN"—Enable/disable fast enumeration for warm/cold boot.'
    #echo -n 'Set mode: ' && echo "$FASTENUMEN_MODES" | grep -E "^$AT_FASTENUMEN"

    # Check desired USB interface mode, otherwise default to 0 (USB 2.0)
    if [[ ${AT_USBSPEED^^} =~ SUPER|USB3|1 ]]; then
        AT_USBSPEED=1
    else
        AT_USBSPEED=0
    fi
}

function get_modem_deviceid() {
    deviceid=''
    while [ -z $deviceid ]
    do
        echo 'Waiting for modem to reboot...'
        sleep 3
        deviceid=$(lsusb | grep -i -E '1199:9071|1199:9079|413C:81B6|413C:81CC|1199:907b' | awk '{print $6}')
    done
    sleep 3
    ttyUSB=$(dmesg | grep '.3: Qualcomm USB modem converter detected' -A1 | grep -Eo 'ttyUSB[0-9]$' | tail -1)
    devpath=$(find /dev -maxdepth 1 -regex '/dev/cdc-wdm[0-9]' -o -regex '/dev/qcqmi[0-9]')
}

function get_modem_bootloader_deviceid() {
    deviceid=''
    while [ -z $deviceid ]
    do
        echo 'Waiting for modem in boothold mode...'
        sleep 2
        deviceid=$(lsusb | grep -i -E '1199:9070|1199:9078|413C:81B5|413C:81CC|1199:907b' | awk '{print $6}')
    done
    echo "Found $deviceid"
}

function reset_modem {
    get_modem_deviceid

    # Reset Modem
    printf "${CYAN}---${NC}\n"
    echo 'Reseting modem...'
    ./swi_setusbcomp.pl --usbreset --device="$devpath" &>/dev/null
}

function get_modem_settings() {
    # cat the serial port to monitor output and commands. cat will exit when AT!RESET kicks off.
    sudo cat /dev/"$ttyUSB" 2>&1 | tee -a modem.log &  

    # Display current modem settings
    printf "${CYAN}---${NC}\n"
    echo 'Current modem settings:'
    echo 'send AT
send ATE1
sleep 1
send ATI
sleep 1
send AT!ENTERCND=\"A710\"
sleep 1
send AT!IMPREF?
sleep 1
send AT!GOBIIMPREF?
sleep 1
send AT!USBSPEED?
sleep 1
send AT!USBSPEED=?
sleep 1
send AT!USBCOMP?
sleep 1
send AT!USBCOMP=?
sleep 1
send AT!USBVID?
sleep 1
send AT!USBPID?
sleep 1
send AT!USBPRODUCT?
sleep 1
send AT!PRIID?
sleep 1
send AT!SELRAT?
sleep 1
send AT!BAND?
sleep 1
send AT!BAND=?
sleep 1
send AT!PCINFO?
sleep 1
send AT!PCOFFEN?
sleep 1
send AT!CUSTOM?
sleep 1
send AT!IMAGE?
sleep 1
send AT!GSTATUS?
sleep 1
send AT!PCFCCAUTH?
sleep 1
! pkill cat
sleep 1
! pkill minicom
' > script.txt
    sudo minicom -b 115200 -D /dev/"$ttyUSB" -S script.txt &>/dev/null
}

function clear_modem_firmware() {
    # cat the serial port to monitor output and commands. cat will exit when AT!RESET kicks off.
    sudo cat /dev/"$ttyUSB" 2>&1 | tee -a modem.log &  
    # Clear Previous PRI/FW Entries
    echo 'send AT
send AT!IMAGE=0
sleep 1
send AT!IMAGE?
sleep 1
! pkill cat
sleep 1
! pkill minicom
' > script.txt
    sudo minicom -b 115200 -D /dev/"$ttyUSB" -S script.txt &>/dev/null
}

function download_modem_firmware() {
	#Find latest 7455 firmware and download it
	if [[ -z $SWI9X30C_ZIP ]]; then
		SWI9X30C_URL=$(curl https://source.sierrawireless.com/resources/airprime/minicard/74xx/airprime-em_mc74xx-approved-fw-packages/ 2> /dev/null | grep PTCRB -B1 | sed 's/,-d-,/./g' | grep -iPo 'href="\K.+/swi9x30c[_0-9.]+_generic_[_0-9.]+' | tail -n1)
		SWI9X30C_ZIP=${SWI9X30C_URL##*/}
		SWI9X30C_ZIP="${SWI9X30C_ZIP^^}"'zip'
	fi
	SWI9X30C_URL="https://source.sierrawireless.com${SWI9X30C_URL}zip"
	SWI9X30C_LENGTH=$(curl -sI "$SWI9X30C_URL" | grep -iPo '^Content-Length[^0-9]+\K[0-9]+')
	
	# If remote file size is less than 40MiB, something went wrong, exit.
	if [[ $SWI9X30C_LENGTH -lt 40000000 ]]; then
		printf "${CYAN}---${NC}\n"
		printf "Download of ${CYAN}$SWI9X30C_ZIP${NC} failed.\nFile size on server is too small, something is wrong, exiting...\n"
		printf "Attempted download URL was: $SWI9X30C_URL\n"
		printf "curl info:\n"
		curl -sI "$SWI9X30C_URL"
		printf "${CYAN}---${NC}\n"
		exit
	fi
	
	if [[ $SWI9X30C_LENGTH -eq $(stat --printf="%s" "$SWI9X30C_ZIP" 2>/dev/null) ]]; then
		echo "Already downloaded $SWI9X30C_ZIP..."
	else
		echo "Downloading $SWI9X30C_URL"
		curl -o "$SWI9X30C_ZIP" "$SWI9X30C_URL"
	fi
	
	# If download size does not match what server says, exit:
	if [[ $SWI9X30C_LENGTH -ne $(stat --printf="%s" "$SWI9X30C_ZIP" 2>/dev/null) ]]; then
		printf "${CYAN}---${NC}\n"
		printf "Download of ${CYAN}$SWI9X30C_ZIP${NC} failed.\nDownloaded file size is inconsistent with server, exiting...\n"
		printf "${CYAN}---${NC}\n"
		exit
	fi

    # Cleanup old CWE/NVUs
    rm -f ./*.cwe ./*.nvu 2>/dev/null

    # Unzip SWI9X30C, force overwrite
    unzip -o "$SWI9X30C_ZIP"
}

function flash_modem_firmware() {
    # Kill cat processes used for monitoring status, if it hasnt already exited
    sudo pkill -9 cat &>/dev/null

    printf "${CYAN}---${NC}\n"
    echo "Flashing $SWI9X30C_CWE onto Generic Sierra Modem..."
	echo "$deviceid" "$SWI9X30C_CWE" "$SWI9X30C_NVU"
    sleep 5
    qmi-firmware-update --reset -d "$deviceid"
    get_modem_bootloader_deviceid
    qmi-firmware-update --update-download -d "$deviceid" "$SWI9X30C_CWE" "$SWI9X30C_NVU"
    rc=$?
    if [[ $rc != 0 ]]
    then
        echo "Firmware Update failed, exiting..."
        exit $rc
    fi
}
function set_modem_settings() {
	# EM7430 = vid 413c,pid 81cc,boot 81cb
    # cat the serial port to monitor output and commands. cat will exit when AT!RESET kicks off.
    sudo cat /dev/"$ttyUSB" 2>&1 | tee -a modem.log &  

    # Set Generic Sierra Wireless VIDs/PIDs
    cat <<EOF > script.txt
send AT
sleep 1
send ATE1
sleep 1
send ATI
sleep 1
send AT!ENTERCND=\"A710\"
sleep 1
send AT!IMPREF=\"GENERIC\"
sleep 1
send AT!GOBIIMPREF=\"GENERIC\"
sleep 1
send AT!USBCOMP=1,1,0000100D
sleep 1
send AT!USBVID=1199
sleep 1
send AT!USBPID=907b,9078
sleep 1
send AT!USBPRODUCT=\"Sierra Wireless EM7430 Qualcomm Snapdragon X7 LTE-A\"
sleep 1
send AT!PRIID=\"9904609\",\"002.030\",\"Lenovo-Storm\"
sleep 1
send AT!SELRAT=06
sleep 1
send AT!BAND=00
sleep 1
send AT!IMAGE?
sleep 1
send AT!PCINFO?
sleep 1
send AT!PCOFFEN=2
sleep 1
send AT!CUSTOM=\"FASTENUMEN\",2
sleep 1
send AT!USBSPEED=0
sleep 1
send AT!RESET
! pkill minicom
EOF
    sudo minicom -b 115200 -D /dev/"$ttyUSB" -S script.txt &>/dev/null
}

function script_prechecks() {
    printf "${CYAN}---${NC}\n"
    echo 'Searching for EM7455/MC7455 USB modems...'
    modemcount=$(lsusb | grep -c -i -E '1199:9071|1199:9079|413C:81B6|413C:81CC|1199:907b')
    while [ "$modemcount" -eq 0 ]
    do
        printf "${CYAN}---${NC}\n"
        echo "Could not find any EM7455/MC7455 USB modems"
        echo 'Unplug and reinsert the EM7455/MC7455 USB connector...'
        modemcount=$(lsusb | grep -c -i -E '1199:9071|1199:9079|413C:81B6|413C:81CC|1199:907b')
        sleep 3
    done

    printf "${CYAN}---${NC}\n"
    echo "Found EM7455/MC7455: 
    $(lsusb | grep -i -E '1199:9071|1199:9079|413C:81B6|413C:81CC|1199:907b')
    "

    if [ "$modemcount" -gt 1 ]
    then 
        printf "${CYAN}---${NC}\n"
        echo "Found more than one EM7455/MC7455, remove the one you dont want to flash and try again."
        exit
    fi

    # Stop modem manager to prevent AT command spam and allow firmware-update
    printf "${CYAN}---${NC}\n"
    echo 'Stoping modem manager to prevent AT command spam and allow firmware-update, this may take a minute...'
    systemctl stop ModemManager &>/dev/null
    systemctl disable ModemManager &>/dev/null

    printf "${CYAN}---${NC}\n"
    echo "Installing all needed prerequisites..."
    add-apt-repository universe -y 1>/dev/null
    apt update -y
    # need make and GCC for compiling perl modules
    apt-get install make gcc curl minicom libqmi-glib5 libqmi-proxy libqmi-utils unzip -y
    # Use cpan to install/compile all dependencies needed by swi_setusbcomp.pl
    yes | cpan install UUID::Tiny IPC::Shareable JSON

    # Install Modem Mode Switcher
    if [ ! -f swi_setusbcomp.pl ]; then
        wget https://git.mork.no/wwan.git/plain/scripts/swi_setusbcomp.pl
    fi
    chmod +x ./swi_setusbcomp.pl

    reset_modem
}

function set_swi_setusbcomp() {
    # Modem Mode Switch to usbcomp=8 (DM   NMEA  AT    MBIM)
    printf "${CYAN}---${NC}\n"
    echo "Running Modem Mode Switch to usbcomp=$swi_usbcomp"
    ./swi_setusbcomp.pl --usbcomp=$swi_usbcomp --device="$devpath"
    reset_modem


    # cat the serial port to monitor output and commands.
    sudo cat /dev/"$ttyUSB" 2>&1 | tee -a modem.log &  

    # Set Generic Sierra Wireless VIDs/PIDs
    cat <<EOF > script.txt
send AT
sleep 1
send AT!ENTERCND=\"A710\"
sleep 1
send AT!USBCOMP=$AT_USBCOMP
sleep 1
send AT!RESET
! pkill cat
sleep 1
! pkill minicom
EOF
    sudo minicom -b 115200 -D /dev/"$ttyUSB" -S script.txt &>/dev/null

   get_modem_deviceid
}

function script_cleanup() {
    # Restart ModemManager
    systemctl enable ModemManager &>/dev/null
    systemctl start ModemManager &>/dev/null

    echo "Done!"

    # Kill cat processes used for monitoring status, if it hasnt already exited
    sudo pkill -9 cat &>/dev/null
}

########################
### Script Execution ###
########################

if [[ $quiet_trigger ]]; then
    script_prechecks &>/dev/null
else
    script_prechecks
fi

set_options

devpath=$(find /dev -maxdepth 1 -regex '/dev/cdc-wdm[0-9]' -o -regex '/dev/qcqmi[0-9]')

if [[ $set_swi_setusbcomp_trigger ]]; then
    set_swi_setusbcomp
fi

get_modem_deviceid

[[ $get_modem_settings_trigger ]] && get_modem_settings

if [[ $clear_modem_firmware_trigger ]]; then
  clear_modem_firmware
  get_modem_deviceid
fi

[[ $download_modem_firmware_trigger ]] && download_modem_firmware

SWI9X30C_CWE=$(find . -maxdepth 1 -type f -iregex '.*SWI9X30C[0-9_.]+\.cwe' | cut -c 3- | tail -n1)
echo $SWI9X30C_CWE
SWI9X30C_NVU=$(find . -maxdepth 1 -type f -iregex '.*SWI9X30C[0-9_.]+generic[0-9_.]+\.nvu' | cut -c 3- | tail -n1)
echo $SWI9X30C_NVU

AT_PRIID_STRING=$(strings "$SWI9X30C_NVU" | grep '^9999999_.*_SWI9X30C_' | sort -u | head -1)
AT_PRIID_PN="$(echo "$AT_PRIID_STRING" | awk -F'_' '{print $2}')"
AT_PRIID_REV="$(echo "$AT_PRIID_STRING" | grep -Eo '[0-9]{3}\.[0-9]{3}')"

[[ $flash_modem_firmware_trigger ]] && flash_modem_firmware
[[ $set_modem_settings_trigger ]] && set_modem_settings
[[ $verbose_trigger ]] && display_variables

script_cleanup

# Done

```

#### 4.Lubuntuの起動　(lubuntu-20.04　ライブ環境）
USBメモリからライブ環境で起動する。
エラーが発生するため、言語は日本語にはしないで英語のまま進めること。
ワイヤレスWWAN USBアダプターカードにEM7430を搭載してLubuntu環境に接続する。

#### 5. 項番3で用意したファイルを実行する　(lubuntu-20.04　ライブ環境）
ゴニョゴニョ動いて、doneとなればOK
-s で設定、-gで現状の取得を行う。
引数なしで、実行するとファームウェアダウンロードでエラーがおきる。

```bash 
sudo bash autoflash-7455v2.sh -s
```

#### 6. X270での認識確認
①BIOSでのホワイトリストチェックに引っかからないか？
→1802エラーが発生した場合は失敗、項番5のやり直し。

②windows10で認識しているか？
→ドライバ入れる。SIM入れる。

③windows10で電波つかむ？
→EM7430のファームウェアによっては電波掴まないことがあった。
→APN設定する。

## 参考サイト

https://www.kenti.jp/archives/604

https://radenku.com/setting-modem-sierra-em7430-cat-6-openwrt

https://github.com/danielewood/sierra-wireless-modems#bypass-lenovo-whitelist-for-t470carbon-x1-g6-and-other-newer-lenovo-laptops