2022年3月15日 星期二

Get IP for PLS83-W on linux

Notice:
1. PLS83-W has two modes ECM and QMI(RMNET) respectively, the default mode is ECM.
2. No additional driver installation required on Ubuntu 20.04 and 18.04
3. Press the Power button on the DevKit board
4. Android手機中, rndis幾乎是標配(cdc-ecm)
5. ECM mode supports suspending and automatically connecting to the Internet after waking up(QMI mode,好像會無法自動連線)
6. PPP (ttyUSB or cdc-acm), RNDIS (cdc-ecm), QMI (cdc-wdm),  MBIM (cdc-mbim)
    ref: Cellular technology with Embedded Linux

ip4
Get IP for PLS83-W
這方法寫,記得把ModemManager關掉
#!/bin/bash

function cecho
{
    if [ $1 == "red" ]; then
        echo -e "\033[31m$2\033[0m"
    elif [ $1 == "blue" ]; then
        echo -e "\033[34m$2\033[0m"
    else
        echo $2
    fi
    return 0
}

function send_command 
{
    sleep 1 #Avoid running AT command too fast to hung
    echo -e "\n"
    echo -e "AT cmd:$1"
    echo -n -e $1 > $ATinterface
    if [ $? -eq 1 ]; then
        cecho "red" "Error Code: -1005, Can't write command to $ATinterface"
        exit 1
    fi
    while read line < $ATinterface;
    do
        ##echo -n -e "$line" | grep 'ERROR'
        ##if [ $? -eq 0 ]; then
        ##    cecho "red" "Error Code: -1002, Invalid AT command"
        ##    exit 1
        ##fi
        ##echo "$line" | grep -v 'OK'
        ##echo "$line" | grep 'OK'
        ##if [ $? -eq 0 ]; then
        ##    return 0
        ##fi
        ###########################################
        echo -n -e "$line" | grep 'ERROR'
        if [ $? -eq 0 ]; then
            echo "Error Code: -1002, Invalid AT command"
            exit 1
        else
            echo "$line"
            echo "$line" | grep -i "ok"
            if [ $? -eq 0 ]; then
                return 0
            fi
        fi
    done
    ##while IFS= read line
    ##do
    ##    echo ---
    ##    if [ "$line" = "OK*" ]; then
    ##        echo exit
    ##        break
    ##    else
    ##        echo yyy
    ##        if [ "$line" == "OK*" ]; then
    ##            echo exit
    ##            break
    ##        fi
    ##        echo 11"$line"11
    ##    fi
    ##done < $ATinterface
}

function check_ATinterface
{
    if [ -e "$ATinterface" ];
    then
        cecho "blue" "Using $ATinterface"
    else
        cecho "red" "$ATinterface is not found, turn on the modem"
    fi
}

function isPID_69or6F
{
    vid=$(lsusb | grep "1e2d" | awk -F " " '{printf $6}' | awk -F ":" '{printf $1}')
    if [ "$vid" != "1e2d" ]; then
        cecho "red" "Can't found the PLS83 device"
        exit 1
    fi
    pid=$(lsusb | grep "1e2d" | awk -F " " '{printf $6}' | awk -F ":" '{printf $2}')
    if [ "$pid" == $1 ]; then
        if [ $1 == "0069" ];then
            cecho "red" "ECM mode"
            return 0
        elif [ $1 == "006f" ]; then
            cecho "red" "QMI mode"
            return 0
        fi
    else
        if [ "$1" == "0069" ];then
            send_command "at^ssrvset=actSrvset,1\r"
            cecho "red" "rebooting...., switch to ECM mode, run the script again after 15s"
        elif [ "$1" == "006f" ]; then
            send_command "at^ssrvset=actSrvset,11\r"
            cecho "red" "rebooting...., switch to QMI mode, run the script again after 15s"
        fi
        
        sleep 2
        send_command "at+cfun=1,1\r" #reboot for PLS83 device
        exit 1
    fi
}

function ping_test
{
    #test
    sync
    sleep 3
    echo "Ping a Network for Testing Connectivity"
    ping -c 5 1.1.1.1
    if [ "$?" -eq 0 ];then
        cecho "blue" "ping 1.1.1.1 successed"
    else
        cecho "red" "ping 1.1.1.1 failed"
        return 1
    fi
    ping -c 5 tw.yahoo.com
    if [ "$?" -eq 0 ];then
        cecho "blue" "ping tw.yahoo.com successed"
    else
        cecho "red" "ping tw.yahoo.com failed"
        return 1
    fi
    return 0
}

function get_wwx_interface_dhcp
{
    wwan0=$(ls /sys/class/net | grep wwx)
    if [ $? -gt 1 ]; then
        cecho "red" "error code: -1004, invalid wwan0 interface"
        exit 1
    fi

    ifconfig $wwan0 up
    sleep 3
    sync
    cecho "red" "try to get IP with dhclient"
    dhclient  $wwan0

    if [ $? -eq 0 ];
    then
        cecho "blue" "Get the IP successfully"
    else
        cecho "red" "Failed to get IP :("
    fi

    #ping
    ping_test

}



#--ECM mode-----------------------------------------------------------------

function Main_ECM_mode
{
    #Check SIM card (PIN 1)
    send_command "AT+CPIN?\r"
    send_command "AT+COPS?\r"
    
    
    #Check the ACM0 device if exists
    isPID_69or6F "0069"
    #check_ATinterface
    if [ $? -gt 1 ]; then
        cecho "red" "error code: -1001, invalid path $ATinterface"
        exit 1
    fi
    
    #AT+CGPADDR Show PDP Address
    send_command "AT+CGPADDR=?\r"
    send_command "AT+CGPADDR\r"
    send_command "AT+CGPADDR=1,1\r"
    
    
    #AT^SWWAN PDP Context Activate or Deactivate
    send_command "AT^SWWAN=?\r"
    send_command "AT^SWWAN?\r"
    send_command "AT^SWWAN=1,1,1\r"
    
    
    #Prepare wwan0 to get IP address
    get_wwx_interface_dhcp
}


#--QMI mode---------------------------------------------------------------------
function PrepareReq_utils
{
    #install libmbim-utils
    ret=$(whereis mbimcli | cut -f 2 -d " ")
    if [ -z "$ret" ];then
        sudo apt-get install libmbim-utils
    fi
    #install udhcpc
    ret=$(whereis udhcpc | cut -f 2 -d " ")
    if [ -z "$ret" ];then
        sudo apt-get install udhcpc
    fi

    sudo modprobe qmi_wwan
    echo '1e2d 006F' | sudo tee /sys/bus/usb/drivers/qmi_wwan/new_id
}

function qmiCommandtoInternet
{
    #chect if the /dev/cdc-wdm exitis
    if [ -z /dev/cdc-wdm[0-9] ];then
        cecho "red" "/dev/cdc-wdm* is null"
        exit 1
    else
        cdc=$(ls /dev/ | grep cdc)
    fi

    sudo qmicli -d /dev/$cdc -p --dms-get-operating-mode
    sudo qmicli -d /dev/$cdc -p --get-wwan-iface

    wwan0=$(ls /sys/class/net | grep wwan)
    if [ $? -gt 1 ]; then
        cecho "red" "Error Code: -1003, invalid wwan0 interface"
        exit 1
    fi

    sudo ip link set $wwan0 down
    echo 'Y' | sudo tee /sys/class/net/$wwan0/qmi/raw_ip
    sudo ip link set $wwan0 up

    sudo qmicli -p -d /dev/$cdc -p --wds-start-network="apn='Internet',ip-type=4" --client-no-release-cid

    sudo udhcpc -i $wwan0

}

function Main_QMI_mode
{
    send_command "AT+CPIN?\r"
    send_command "AT+COPS?\r"
    isPID_69or6F "006f"
    PrepareReq_utils
    qmiCommandtoInternet
    ping_test
}


#--globle value-----------------------------------------------------------------
ATinterface=
MODE=
MAIN=0
APN_R=0
APN_W=0



#--Help-------------------------------------------------------------------------
function usageExit()
{
  cat >&2 << EOF
    pls83.sh - Quick link to Internet only for test, not offcial

    pls83.sh [options]

    options:
    -h, --help                        Show this menu
    -m, --mode                        Specify ECM mode for PLS83
    -p, --path=_device_path           Specify a device for the PLS83 to be run, such as: /dev/ttyACM*, /dev/ttyUSB*
    -ar, --apnr=1 or 0                Read the APN name from PLS83
    -aw, --apnw=\"APN_NAME\"          Write the APN name into PLS83, it will restart PLS83 module
EOF
    exit 0
}

function checkArgExit() 
{
    if [[ $# -lt 2 ]]; then
        echo "Missing argument for option $1" >&2
        exit 1
    fi
}

function APNRead()
{
    send_command "AT+COPS?\r"
    send_command "AT+CGDCONT?\r"
    exit 0
}

function APNWrite()
{
    send_command "AT+CGDCONT=1,\"IPV4V6\",\"$1\"\r"
    send_command "AT+CFUN=1,1\r"
    exit #reboot, so~exit
}

# Parse arguments
if [ $# -lt 1 ]; then
     echo "Enter paramaters, such as pls83.sh -p /dev/ttyACM0"
         exit
     else
         while [ -n "$1" ]; do
             case "$1" in
                 -h|--help)
                     usageExit
                     ;;
                 -p|--path)
                     checkArgExit $@
                     ATinterface=$2
                     MAIN=1
                     shift 2
                     ;;
                 -m|--mode)
                     checkArgExit $@
                     MODE=$2
                     shift 2
                     ;;
                 -ar|--anpr) #APN Read
                     checkArgExit $@
                     APN_R=1
                     shift 2
                     ;;
                 -aw|--anpw) #APN Write
                     checkArgExit $@
                     APN_W=1
                     aw_p=$2
                     shift 2
                     ;;
                 *)
                     echo "Unknown option $1" >&2
                     echo >&2
                     usageExit
                     ;;
             esac
         done
fi


if [ -z "$ATinterface" ]; then
    cecho "red" "Error Code: -1003, Lost the path, remember to add parameters, -p"
    exit 1
fi
exec <> $ATinterface

if [ "$APN_R" -eq 1 ]; then
    APNRead
    exit
fi
if [ "$APN_W" -eq 1 ]; then
    APNWrite $aw_p
    exit
fi
if [ "$MAIN" -eq 1 ]; then
    if [ "$MODE" == "qmi" ] || [ "$MODE" == "QMI" ]; then
        Main_QMI_mode
    elif [ "$MODE" == "ecm" ] || [ "$MODE" == "ECM" ]; then
        Main_ECM_mode
    else
        cecho "red" "Enter error mode, use the default mode as ECM mode"
        Main_ECM_mode
    fi
fi

exit 
1.cdc-wdm要在QMI mode下才會看得到,如果沒看到的話,再執行一次script或電腦/DevKit board重新開機
2.如果用 minicom 時,看起來一直在印同樣的字串(不會換行),電腦重新開機
ref:
1. els61pls62
2. PLS63/83 QMI/RMNET Setup and Linux qmi_wwan / ModemManager Integration


Andriod Driver:
1. Android_12_kernel_4.19 (ECM mocd, PID and VID: 1e2d 0069, support suspend/wake up)
1. Android_12_Kernel_4.19 (QMI mode, keyword: 1e2d 006f)

沒有留言:

張貼留言