2/23/2020

USB LTE

1. USB LTE 모듈 구조 

USB LTE Module의 경우 구조는 대부분 비슷하며 AT CommandSerial를 통해 설정을 하면 대부분 동작이 가능하다.
각각의 USB LTE Module 마다 조금씩은 다르겠지만 동작방식은 얼추 비슷하다.


  • USB LTE 연결시 사용되어지는 USB CDC Model 
  1. ACM(Abstract Control Model):  AT Command 용 Serial로 연결 PPP사용
  2. ECM (Ethernet Device Model)
  3. NCM (Network Control Model)
  4. RNDIS(Remote NDIS RNDIS):
  5. MBIM(Mobile Broadband Interface Model)

USB-CDC 관련참조 
  https://ahyuo79.blogspot.com/2019/01/jetson-tx2-jetpack33-usb-device.html

  • Kernel  Config 설정 
Device Drivers -> Network device support -> USB Network Adapters ->CDC MBIM support
Device Drivers -> Network device support -> Networking support -> PPP


USB CDC 기반의 RNDIS or ETHERNET을 이용하여 테스트한다고 하면 아래와 같이 DHCP Client 이용하고 확인 후 
직접 network device 설정위치에서 설정진행 
 
$ ifconfig usb0 up 
$ udhcpc -i usb0  //DHCP Client 이용 


1.1  Serial Modem 의 역사

Serial Interface로 이용하여 PPP로 오래전부터 전화기에서 사용하던 방식이다.
이를 전화기 선 4개중 2개를 이용하여 Serial Analog Modem 방식으로 통신하는 방식이지만, 전화기이다보니, 
이전에는 PBX가 별도로 존재하였다 (PBX는 교환기) 

물론 요즘은 세상이 너무 좋아져서 IP-PBX로 변경되고, FTTX로 광통신으로 집으로 Network가 구축이 되어진다. 


PBX 와 PSTN 관련사항 
전화기를 통한 통신과 PBX(교환기)관련정보이며, PBX는 DTMF를 인식

전화선 
요즘은 IP-PBX를 사용하기 때문에 LAN과 전화선의 구분없고 RJ45사용하지만, 이전에는 RJ11로 사용했던것으로 기억한다

  • PBX기반의 Serial Modem
아래 구조는 오래전에 PC통신으로 전화선 2개로 연결하여 PBX를 걸쳐 PPP로 연결되는 방식이며, 아래와 같이 동작한다.
물론 통신 중에는 전화기를 사용하지 못하는 단점이 존재한다.

+-------------+  serial  +---------+  phone wire  +------+  phone wire  +----------+  serial  +----------+
| Development |----------| Modem A |--------------| PABX |--------------| Modem B  |----------| BBS      |
|  Computer   |----------|         |--------------|  X   |--------------| (answer) |----------| Computer |
+-------------+          +---------+              +------+              +----------+          +----------+

  • ADSL Modem
여기서 더 발전한 Modem이 xDSL 모뎀이며 전화선 4개 중 전화용 2개가 아닌 나머지 2개로 이용하여 통신하는 것으로 진행한다.
이 때 인증하는 방식은 오래전 기억으로는 PPPoE 와 PPPoA로 DSLAM을 걸쳐 인증하고 통신하는 방식인 걸로 기억한다. 

  • AT Command 
상위 통신을 할때 사용하던 명령어가 바로 AT Command로 역사가 길다 
  https://en.wikibooks.org/wiki/Serial_Programming/Modems_and_AT_Commands

1.2 LTE 의 DUN (Dial Up Network)


LTE에서는 기존에 사용했던 Serial Interface에서 AT Command 기반으로 Connection 지원하며, 
Serial Interface에서 바로 AT Command와 Modem을 동시에 사용가능하다.

Linux에서는 wvdial의 Phone 설정과 Analog Modem 부분의 설정을 보면 쉽게 이해가 간다.
Dial Commnad 인 ATD 와 *99#를 이용하여 Serial Interface로 Modem으로 연결진행한다.

이를 DUN (Dial Up Network)라고 하며, 이때 사용되어지는 Network Protocol이 PPP를 사용을 하게되는데, 
반드시 Kernel에서 지원을 해줘야 한다. 

그리고, 이 통신 내부에도 인증이 존재하며, PPP로 LCP 와 PAP/CHAP를 통해 인증하며, IPCP로 연결설정을 완료한다. 

설정종료시에는 Serial 의 DTR Pin을 이용하여 종료를 진행하는데, 거의 잘 사용하지 않는 것 같다. 

$ cat /etc/wvdial.conf
.........
Dial Command = ATD
Modem Type = Analog Modem
ISDN = 0
Phone = *99#
#
#Modem = /dev/ttymxc3
Modem = /dev/ttyACM0
Username = 1
Password = 1
Baud = 115200
New PPPD = yes
Stupid Mode = 1



  • PPP의 기본구조 



  • PPPD 와 CHAT으로만 연결

$ vi /home/root/at_com_zte
TIMEOUT   5
ECHO      ON   
ABORT     BUSY
ABORT     ERROR
ABORT     'NO CARRIER'
ABORT     VOICE
ABORT     'NO DIALTONE'
ABORT     'NO DIAL TONE'
ABORT     'NO ANSWER'
ABORT     DELAYED
''     AT
OK     AT
OK     AT
OK 'AT+CGDCONT=1,"IP","lte150.ktfwing.com"'
OK        ATD*99***1#
TIMEOUT   30
CONNECT   ''


$ pppd /dev/ttyACM0 115200  unit 1 linkname datakey crtscts usepeerdns \
    noauth user guest password guest defaultroute noipdefault ipcp-accept-local \
    ipcp-accept-remote ipcp-max-failure 30 lcp-echo-interval 5 lcp-echo-failure 30 \
    modem dump debug kdebug 8 \
    connect "/usr/sbin/chat -v -t 500 -T *99# -f /home/root/at_com_zte"

상위 미동작확인 (추후 분석)

ATINOUT Program 


1.3  USB CDC-ACM 의 WVDIAL 설정 

UART가 존재하지 않고, USC-CDC의 ACM만 존재한다면, 이를  Serial Interface로 이용하여 상위와 동일하게 구성가능하다. 
Linux에서 wvdial 기반으로 쉽게 설정 및 접속가능하다 (pppd도 필요)


오래전에 사용하던 전화기 모뎀을 생각을 하면 될 것 같으며, 동작방식은 다음과 같다.
우선 Serial 설정 후 init의 AT Command를 한 후 pppd를 이용하여 Serial로 접속진행한다.

  https://wiki.archlinux.org/index.php/Wvdial
  https://wiki.archlinux.org/index.php/USB_3G_Modem
  https://en.wikibooks.org/wiki/Serial_Programming/Modems_and_AT_Commands
  https://en.wikibooks.org/wiki/Serial_Programming/Modems_and_AT_Commands/Commands_A_-_M
  https://www.developershome.com/sms/atCommandsIntro.asp
  https://m2msupport.net/m2msupport/at-commands-to-get-device-information/
  https://m2msupport.net/m2msupport/atcgdcont-define-pdp-context/

AT Command
   https://www.rfwireless-world.com/Terminology/modem-AT-commands.html

$ vi /etc/wvdial.conf  // ~/.wvdialrc
[Dialer Defaults]
Init1 = ATZ
#Check USIM 
Init2 = AT+CPIN?
#KT 
Init3 = AT+CGDCONT=1,"IP","lte150.ktfwing.com","",0,0
#SKT 
#Init3 = AT+CGDCONT=1,"IP","lte.sktelecom.com" 
Modem Type = Analog Modem
ISDN = 0
Phone = *99#
Modem = /dev/ttyACM0
Username = 1
Password = 1
Baud = 115200
New PPPD = yes
Stupid Mode = 1

[Dialer SKnet]
Init1 = ATZ
Init2 = AT+CPIN?
Init3 = AT+CGDCONT=1,"IP","lte.sktelecom.com" 
Modem Type = Analog Modem
ISDN = 0
Phone = *99#
Modem = /dev/ttyACM0
Username = 1
Password = 1
Baud = 115200
New PPPD = yes
Stupid Mode = 1

[Dialer KTnet]
Init1 = ATZ
Init2 = AT+CPIN?
Init3 = AT+CGDCONT=2,"IP","lte150.ktfwing.com"
#Init3 = AT+CGDCONT=2,"IP","lte.ktfwing.com"
Modem Type = Analog Modem
ISDN = 0
Phone = *99#
Modem = /dev/ttyACM0
Username = 1
Password = 1
Baud = 115200
New PPPD = yes
Stupid Mode = 1

Init은 최대 9까지만 되는것으로 파악됨

각 APN 주소 
  https://nemos.tistory.com/763


1.4 WVDIAL 테스트 

상위와 같이 설정을 하면, wvdial 실행 or wvdial SKnet or wvdial KTnet 이런식으로 실행을 진행하면 된다. 

$ wvdial & // default 실행 ( wvdial KTnet , wvdial SKnet ) 다양하게 설정가능 
--> WvDial: Internet dialer version 1.61
--> Initializing modem.
--> Sending: ATZ
ATZ
OK
--> Sending: AT+CGDCONT=2,"IP","lte150.ktfwing.com","",0,0
AT+CGDCONT=2,"IP","lte150.ktfwing.com","",0,0
OK
--> Modem initialized.
--> Sending: ATDT*99#
--> Waiting for carrier.
ATDT*99#
CONNECT
--> Carrier detected.  Starting PPP immediately.
--> Starting pppd at Fri Jun 12 11:42:01 2020
--> Pid of pppd: 980
--> Using interface ppp0
--> local  IP address 28.179.152.168
--> remote IP address 28.179.152.168
--> primary   DNS address 211.219.86.1
--> secondary DNS address 168.126.63.1

$ ifconfig   // PPPoE로 통신가능 
eth0      Link encap:Ethernet  HWaddr 26:E1:2C:C4:C7:C6
          inet addr:192.168.1.17  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::24e1:2cff:fec4:c7c6/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:9 errors:0 dropped:0 overruns:0 frame:0
          TX packets:18 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:2020 (1.9 KiB)  TX bytes:2867 (2.7 KiB)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

ppp0      Link encap:Point-to-Point Protocol
          inet addr:28.179.152.168  P-t-P:28.179.152.168  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1430  Metric:1
          RX packets:7 errors:0 dropped:0 overruns:0 frame:0
          TX packets:11 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:3
          RX bytes:184 (184.0 B)  TX bytes:400 (400.0 B)



1.5 WVDIAL 분석 및 Route Table 문제

wvdial에서 ppp를 실행할때 마다 설정환경이 다른이유 분석 

ppp0만 존재한다면, route table에 ppp0이 기본으로 default로 설정이 되지만, 기존에 default route가 존재한다면, 이야기가 달라진다.

$ cat /etc/ppp/peers/wvdial  // ETH0이 이미 존재하여, default route를 진행못함 (route 확인)
noauth
name wvdial
usepeerdns


$ cat /etc/ppp/peers/wvdial  // ETH0이 default route로 설정되지 못하여 route table 에서 default 설정 
noauth
name wvdial
usepeerdns
defaultroute
replacedefaultroute

$ cat /etc/ppp/chap-secrets
# Secrets for authentication using CHAP
# client        server  secret                  IP addresses
1       *       1
1       *       1
1       *       1
1       *       1
1       *       1
1       *       1
1       *       1
1       *       1


  https://bugs.launchpad.net/ubuntu/+source/ppp/+bug/608372
  https://superuser.com/questions/949520/wvdial-ppp0-and-setting-default-route-automatically
  https://linux.die.net/man/1/wvdial


$ cat /var/run/resolv.conf
$ cat /etc/resolv.conf

$ ls /etc/ppp/  //pppd 
chap-secrets  ip-down.d     ip-up.d       pap-secrets   ppp_on_boot
ip-down       ip-up         options       peers

$ cat /etc/ppp/ip-up
#!/bin/sh
#
# $Id: ip-up,v 1.2 1998/02/10 21:25:34 phil Exp $
#
# This script is run by the pppd after the link is established.
# It uses run-parts to run scripts in /etc/ppp/ip-up.d, so to add routes,
# set IP address, run the mailq etc. you should create script(s) there.
#
# Be aware that other packages may include /etc/ppp/ip-up.d scripts (named
# after that package), so choose local script names with that in mind.
#
# This script is called with the following arguments:
#    Arg  Name                          Example
#    $1   Interface name                ppp0
#    $2   The tty                       ttyS1
#    $3   The link speed                38400
#    $4   Local IP number               12.34.56.78
#    $5   Peer  IP number               12.34.56.99
#    $6   Optional ``ipparam'' value    foo

# The  environment is cleared before executing this script
# so the path must be reset
PATH=/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin
export PATH
# These variables are for the use of the scripts run by run-parts
PPP_IFACE="$1"
PPP_TTY="$2"
PPP_SPEED="$3"
PPP_LOCAL="$4"
PPP_REMOTE="$5"
PPP_IPPARAM="$6"
export PPP_IFACE PPP_TTY PPP_SPEED PPP_LOCAL PPP_REMOTE PPP_IPPARAM


# as an additional convenience, $PPP_TTYNAME is set to the tty name,
# stripped of /dev/ (if present) for easier matching.
PPP_TTYNAME=`/usr/bin/basename "$2"`
export PPP_TTYNAME

# Main Script starts here

run-parts /etc/ppp/ip-up.d

# last line

$ cat /etc/ppp/ip-up.d/08setupdns
#!/bin/sh
ACTUALCONF=/var/run/resolv.conf
PPPCONF=/var/run/ppp/resolv.conf
if [ -f $PPPCONF ] ; then
        if [ -f $ACTUALCONF ] ; then
                if [ ! -h $ACTUALCONF -o ! "`readlink $ACTUALCONF 2>&1`" = "$PPPCONF" ] ; then
                        mv $ACTUALCONF $ACTUALCONF.ppporig
                fi
        fi

        ln -sf $PPPCONF $ACTUALCONF
fi

  • Route Table 분석 
아래의 명령으로 default route를 분석하고 다중 network Interface를 가지고 있을 때 default route 를 반드시 관리를 해야한다. 

$ netstat -rn
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface

$ route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface

$ route add default dev ppp0

$ route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         *               0.0.0.0         U     0      0        0 ppp0

$ route add default dev eth0

$ route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         *               0.0.0.0         U     0      0        0 eth0
default         *               0.0.0.0         U     0      0        0 ppp0

$ route del default



2. AT Command 기본 문법(Syntax) 

  • AT Command Syntax
AT Command의 시작은 AT or at로 시작을하며, Command를 종료를 위해서는 CR을 입력하며, 응답은 CR, LF Respone CR, LF 식으로 동작이된다.
AT Command는 일반적으로 아래와 같이 네가지 모드로 동작하게 되며, Command만 안다면, 아래와 같이 응용하여 적용가능하다.

Test command (help 개념으로 보통 동작확인)
AT+CXXX=?    

Read command (대부분 Status 확인용 동작)
AT+CXXX?        

Write command (Command 설정 or 실행, Manual 참조)
AT+CXXX=<...>  

Execution command  (Command 실행 )
AT+CXXX  

2.1 AT 기본Command  


상위 문법에 따라 Commnad 당 4가지 문법이 적용가능하므로, 각각의 기능을 살펴보자

  • AT+CPIN
주로 USIM의 연결상태 및 PIN 암호화 설정가능
  https://m2msupport.net/m2msupport/atcpin-enter-pin/

  • AT+CGDCONT
LTE의 모듈의 PDP type 및 APN 주소 등  설정하는 것으로 각 통신사마다 설정을 해줘야한다.

  • AT+CGACT

  • AT+CEREG


2.2 AT 기본 Command  TEST

가장 기본적으로 테스트 하는 방식은 minicom을 사용하는 방식이며, 좀 편하게 하고 싶다면, 상위 wvdial을 기반으로 테스트를 해도 상관없다.

더불어 Console도 다 Serial 통신이므로, 이 기반으로 직접 다른 UART로 통신을 해도 상관은 없다. 

  • minicom 설정 및 AT Command 사용 
minicom 에서 연결하여 직접 AT Command를 TEST 간단히 테스트 해도 상관 없지만, 직접 연결도 가능하다. 
이 부분은 minicom Script도 작성가능하므로, 이 부분은 다른 것을 참조하고, 이곳에서는 간단히 AT Command TEST 만 하자 

$ minicom -s   // 설정 
// Serial port setup  -> Serial Device 와 Bps   (직접 Serial Interface 설정)
// ESC Key 로 Menu로 나오면 자동으로 연결된 상태 
or
$ minicom -D /dev/ttymxc5    // UART 접속 (주의 default BPS 와 Console 과 동일)
or
$ minicom -D /dev/ttyACM0    // USB-UART 접속 (주의 default BPS 와 Console과 동일)

Welcome to minicom 2.7.1

OPTIONS: I18n
.....
Press CTRL-A Z for help on special keys

// Ctrl-A 후 Z 입력하면 Help 확인가능 

// Ctrl-A 후 C 입력하면 화면 Clear (반드시 Clear 후 확인)
// Ctrl-A 후 X 입력하면 Minicom 종료 


ATZ  // 직접 입력하며, 결과값 확인 가능 
OK

AT+COPS? // 직접 입력하며, 결과값 확인 가능 
+COPS: 0,0,"KT",7

OK

AT+CGATT?       //GPRS network:
+CGATT: 1

OK

AT+CGDCONT?
+CGDCONT: 1,"IP","","",0,0

+CGDCONT: 2,"IP","","",0,0

OK

AT+CEREG?
+CEREG: 0,1  //

//+CEREG: , [, ][, ][, ]

AT+CGDCONT=1,"IP","lte150.ktfwing.com"
or 
AT+CGDCONT=2,"IP","lte150.ktfwing.com"    // cid  PDPText=IP or "IPV6" or IPV4V6"  APN: Access Point Name 


AT^SWWAN=1,1,1
or
AT^SWWAN=1,2,1  // SWWAN=, [, ]


AT+CEER  // ERROR 확인 


Ctrl A + q   // Exit
  https://wiki.emacinc.com/wiki/Getting_Started_With_Minicom
  https://m2msupport.net/m2msupport/atcimi-request-international-mobile-subscriber-identity/
  https://www.sktiot.com/iot/developer/guide/guide/catM1/menu_02/page_01
  https://doc.qt.io/archives/qtopia4.3/atcommands.html
  https://m2msupport.net/m2msupport/atcgdcont-define-pdp-context/


사용후 반드시 Background Process 강제종료해야함 

이 방법을 사용하기 전에 반드시 /proc/cmdline 에서 본인의 console 속도확인 

$ cat /dev/ttyACM0 &
$ echo -ne "AT+CCID=?\r"  >  /dev/ttyACM0 
$ echo -ne "AT+COPS?\r"  >  /dev/ttyACM0 
$ echo -ne "AT+CGATT?\r"  >  /dev/ttyACM0 
$ echo -ne "AT+CGDCONT=2,\"IP\",\"lte150.ktfwing.com\"\r"  >  /dev/ttyACM0 
$ echo -ne "AT^SWWAN=1,2,1\r"  > /dev/ttyACM0 
$ echo -ne "AT+CGDCONT?\r" > /dev/ttyACM0
$ echo -ne "AT+CPIN?\r" > /dev/ttyACM0
$ ifconfig usb0 up

Linux Serial Communication
  https://www.cyberciti.biz/hardware/5-linux-unix-commands-for-connecting-to-the-serial-console/
  https://wiki.archlinux.org/index.php/Working_with_the_serial_console
 https://unix.stackexchange.com/questions/117037/how-to-send-data-to-a-serial-port-and-see-any-answer


  https://askubuntu.com/questions/474545/minicom-not-recognizing-the-usb-modem
  https://unix.stackexchange.com/questions/97242/how-to-send-at-commands-to-a-modem-in-linux


3. Android RIL 관련 Library 

이 부분을 기반으로 소스를 구현한 적이 없으며, LTE Module은 이 부분이 필요가 없으므로 참고만 하고 있다.

Android RIL 관련소스
  https://android.googlesource.com/platform/hardware/ril/+/3b1530aef62476248825a2092c9aea800395c3b1/libril/ril.cpp