M35/SIM900B Linux下CMUX协议实现


作者:lingyun 来源:凌云物网智科实验室 时间:2014-09-24

Author: Guo Wenxue <guowenxue@gmail.com>
Date: 2011.10.11

Modify by guowenxue
Date: 2011.10.26 Add patch for Linux-3.0 to support auto create device node in /dev

Modify by guowenxue
Date: 2012.12.12 Add new test on Linux-3.4 for M35 GPRS module
————–
The ldattach program used to open a serial device and attach a line discipline on it, in order
to implement GSM0701 multiplexer protocol on SIMCOM SIM900 GPRS module, I modify it to support
GSM0701 discipline as the guide of “linux-3.0/Documentation/serial/n_gsm.txt”.

Orignal ldattach program source code can get from follow sites:
ftp://ftp.irisa.fr/pub/OpenBSD/src/sbin/ldattach/ldattach.c
https://laas.mine.nu/uclibc/util-linux-ng-2.14.2/sys-utils/ldattach.c
Another GSM0701 Implement source code named gsmmux+ussp can refer to:
http://koti.mbnet.fi/toukka/

Follow content will introduce how to implement the GSM0701 multiplexer in Linux-3.0 Kernel on
AT91SAM9260 board with GSM Module SIM900:
————–

1. Choose follow option when do “make menuconfig” before cross compile linux kernel:
Device Drivers —>
Character devices —>
<*> GSM MUX line discipline support (EXPERIMENTAL)
The GSM0701 Multiplexer driver is linux-3.0/drivers/tty/n_gsm.c

/***********************************************************************************************
*
* Linux-3.0 on AT91SAM9260 with SIM900 module driver test log
*
**********************************************************************************************/

2. In Linux Kernel, apply follow patch to let linux kernel auto create device node when system
start:
diff -Nuar linux-3.0/drivers/tty/n_gsm.c linux-3.0-concentrator/drivers/tty/n_gsm.c
— linux-3.0/drivers/tty/n_gsm.c 2011-07-22 02:17:23.000000000 +0000
+++ linux-3.0-concentrator/drivers/tty/n_gsm.c 2011-10-21 15:43:50.407109928 +0000
@@ -249,6 +249,7 @@
#define MAX_MUX 4 /* 256 minors */
static struct gsm_mux *gsm_mux[MAX_MUX]; /* GSM muxes */
static spinlock_t gsm_mux_lock;
+static struct class *dev_class = NULL; /* Add by guowenxue */

/*
* This section of the driver logic implements the GSM encodings
@@ -2751,6 +2752,8 @@

static int __init gsm_init(void)
{
+ int i, result; /* add by guowenxue */
+
/* Fill in our line protocol discipline, and register it */
int status = tty_register_ldisc(N_GSM0710, &tty_ldisc_packet);
if (status != 0) {
@@ -2787,17 +2790,47 @@
pr_err(“gsm_init: tty registration failed.\n”);
return -EBUSY;
}
+
+ /* Add by guowenxue */
+ dev_class = class_create(THIS_MODULE, gsm_tty_driver->name);
+ if(IS_ERR(dev_class))
+ {
+ printk(“%s driver create class failture\n”, gsm_tty_driver->name);
+ result = -ENOMEM;
+ goto ERROR;
+ }
+
+ for(i=gsm_tty_driver->minor_start; i<MAX_MUX; i++)
+ {
+ device_create(dev_class, NULL, MKDEV(gsm_tty_driver->major, i), NULL, “%s%u”, gsm_tty_driver->name, i);
+ }
+ /* Add by guowenxue end */
+
pr_debug(“gsm_init: loaded as %d,%d.\n”,
gsm_tty_driver->major, gsm_tty_driver->minor_start);
return 0;
+
+ERROR:
+ tty_unregister_driver(gsm_tty_driver);
+ put_tty_driver(gsm_tty_driver);
+ return result;
}

static void __exit gsm_exit(void)
{
int status = tty_unregister_ldisc(N_GSM0710);
+ int i;
if (status != 0)
pr_err(“n_gsm: can’t unregister line discipline (err = %d)\n”,
status);
+ /* Add by guowenxue */
+ for(i=gsm_tty_driver->minor_start; i<MAX_MUX; i++)
+ {
+ device_destroy(dev_class, MKDEV(gsm_tty_driver->major, i));
+ }
+ class_destroy(dev_class);
+ /* Add end */
+
tty_unregister_driver(gsm_tty_driver);
put_tty_driver(gsm_tty_driver);
}
3. When Linux system start up, if the n_gsm driver is build in the kernel, then we can skip
this step goto 4, or we should install the driver first(or in the system init script).
/tmp >: insmod n_gsm.ko debug=1
/tmp >: cat /proc/devices | grep gsm
248 gsmtty
/tmp >: ls /dev/gsmtty*
/dev/gsmtty0 /dev/gsmtty1 /dev/gsmtty2 /dev/gsmtty3

4. Power on the SIM900 GPRS module:
/tmp >: comport -ioctl /dev/gprs 1074028593 1
ioctl (/dev/gprs, 1074028593, 1) returned 0
/usr/sbin >: comport -d /dev/ttyS3
aatt++ccggmmmm

SIMCOM_SIM900

OK

5. Run the ldattach program on background:
tmp >: ldattach -8n1 -s 115200 GSM0701 /dev/ttyS3
/tmp >: ps | grep ldattach
23512 root 580 S ./ldattach -8n1 -s 115200 GSM0701 /dev/ttyS3
23556 root 1276 S grep ldattachd

“ldattach -8n1 -s 115200 GSM0701 /dev/ttyS3” Description:
/dev/ttyS3: The GPRS module physical TTY channel
-8n1 -s 115200: configure ttyS3 line mode as 115200,8N1
GSM0701: This is the line discipline I added based on original ldattach program.

6. Now we can use the virtual TTY channel to chat with GPRS module now.
/usr/sbin >: comport -d /dev/gsmtty0
Failed to open /dev/gsmtty0 with baudrate 115200, . RetCode [0x05]
/usr/sbin >: comport -d /dev/gsmtty1
aatt++ccggmmmm

SIMCOM_SIM900

OK
/usr/sbin >: comport -d /dev/gsmtty2
aatt++ccggmmmm

SIMCOM_SIM900

OK
/usr/sbin >: comport -d /dev/gsmtty3
aatt++ccggmmmm

SIMCOM_SIM900

OK

7. GSM0701 Test Result:

~ >: comport -ioctl /dev/gprs 1074028593 1 #Power On GPRS module
ioctl (/dev/gprs, 1074028593, 1) returned 0
~ >: ldattach -8n1 -s 115200 GSM0701 /dev/ttyS3
~ >: sh /etc/ppp/ppp-on
~ >: ps | grep pppd
790 root 872 S /usr/sbin/pppd debug /dev/gsmtty3 115200 nocrtscts modem lock user cmnet noipdefault defaultroute 0.0.0.
~ >: ifconfig ppp0
ppp0 Link encap:Point-to-Point Protocol
inet addr:10.215.173.220 P-t-P:192.200.1.21 Mask:255.255.255.255
UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1
RX packets:6 errors:1 dropped:0 overruns:0 frame:0
TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:3
RX bytes:208 (208.0 B) TX bytes:245 (245.0 B)
~ >: ping 4.2.2.2
PING 4.2.2.2 (4.2.2.2): 56 data bytes
64 bytes from 4.2.2.2: seq=0 ttl=45 time=898.685 ms
^C
— 4.2.2.2 ping statistics —
2 packets transmitted, 1 packets received, 50% packet loss
round-trip min/avg/max = 898.685/898.685/898.685 ms

~ >: comport -d /dev/gsmtty2
Open device “/dev/gsmtty2″
aattee00

OK
at+cmgf=1

OK
at+cscs=”GSM”

OK
at+cmgs=”13554373241″

> Hello Guo Wenxue^Z

+CMGS: 62

OK
^C
~ >: ping 4.2.2.2
PING 4.2.2.2 (4.2.2.2): 56 data bytes
64 bytes from 4.2.2.2: seq=0 ttl=45 time=673.468 ms
^C
— 4.2.2.2 ping statistics —
2 packets transmitted, 1 packets received, 50% packet loss
round-trip min/avg/max = 673.468/673.468/673.468 ms
~ >: uname -a
Linux localhost 3.0.0 #27 Fri Oct 21 14:44:47 UTC 2011 armv5tejl GNU/Linux
WARNNING:
I. Don’t know why does virtaul TTY channel0 created by n_gsm.c is not avialable on SIM900;
II. We must close the virtual TTY (/dev/gsmtty*) device before close Modem TTY channel
/dev/ttyS3(by kill ldattach program).
If kill ldattach before /dev/gsmtty*, then all the program who hold /dev/gsmtty*, dropbear,
console precesses will goes to “deep sleep”, and system seems hang up.
B.T.W: PPP connect shell script:
~ >: cat /etc/ppp/ppp-on
#!/bin/sh
#
# Script to initiate a ppp connection. This is the first part of the
# pair of scripts. This is not a secure pair of scripts as the codes
# are visible with the ‘ps’ command. However, it is simple.
#
# These are the parameters. Change as needed.
TELEPHONE=*99***1# # The telephone number for the connection
ACCOUNT= # The account name for logon (as in ‘George Burns’)
PASSWORD= # The password for this account (and ‘Gracie Allen’)
LOCAL_IP=0.0.0.0 # Local IP address if known. Dynamic = 0.0.0.0
REMOTE_IP=0.0.0.0 # Remote IP address if desired. Normally 0.0.0.0
NETMASK=255.255.255.0 # The proper netmask if needed
#
# Export them so that they will be available at ‘ppp-on-dialer’ time.
export TELEPHONE ACCOUNT PASSWORD
#
# This is the location of the script which dials the phone and logs
# in. Please use the absolute file name as the $PATH variable is not
# used on the connect option. (To do so on a ‘root’ account would be
# a security hole so don’t ask.)
#
DIALER_SCRIPT=/etc/ppp/ppp-on-dialer
#
# Initiate the connection
#

# I put most of the common options on this command. Please, don’t
# forget the ‘lock’ option or some programs such as mgetty will not
# work. The asyncmap and escape will permit the PPP link to work with
# a telnet or rlogin connection. You are welcome to make any changes
# as desired. Don’t use the ‘defaultroute’ option if you currently
# have a default route to an ethernet gateway.
#
#exec /usr/sbin/pppd debug lock nocrtscts modem /dev/ttyS3 115200 \
# asyncmap 20A0000 escape FF kdebug 0 $LOCAL_IP:$REMOTE_IP \
# noipdefault netmask $NETMASK defaultroute connect $DIALER_SCRIPT

#exec /usr/sbin/pppd debug /dev/ttyS3 115200 nocrtscts modem lock \

exec /usr/sbin/pppd debug /dev/gsmtty3 115200 nocrtscts modem lock \
user “cmnet” noipdefault defaultroute $LOCAL_IP:$REMOTE_IP \
connect $DIALER_SCRIPT
~ >: cat /etc/ppp/ppp-on-dialer
#!/bin/sh
#
# This is part 2 of the ppp-on script. It will perform the connection
# protocol for the desired connection.
# OK ATDT$TELEPHONE \
#
exec chat -v \
TIMEOUT 3 \
ABORT “ERROR” \
ABORT “NO DIALTONE” \
ABORT “NO CARRIER” \
ABORT ‘\nBUSY\r’ \
ABORT ‘\nNO ANSWER\r’ \
ABORT ‘\nRINGING\r\n\r\nRINGING\r’ \
TIMEOUT 30 \
” \rAT \
‘OK’ ATH0 \
‘OK’ ATE0 \
OK ‘AT+CGDCONT=1,”IP”,”CMNET”‘ \
OK ATDT*99***1#
CONNECT ” \
# ogin:–ogin: $ACCOUNT \
# assword: $PASSWORD

/***********************************************************************************************
*
* Linux-3.4 on AT91SAM9260 with M35 module driver changelog
*
**********************************************************************************************/
2, For Linux-3.4, it will auto create the gsmtty Device when we run ldattach program in follos step,
so we no need create the device node in the driver like upside linux-3.0 do, now we just need
change the device node number from 64 to 5, for gsmtty0 can not use and we can only use gsmtty[1…4],

diff -Nuar linux-3.4/drivers/tty/n_gsm.c linux-3.4-radi-mon/drivers/tty/n_gsm.c
— linux-3.4/drivers/tty/n_gsm.c 2012-05-21 06:29:13.000000000 +0800
+++ linux-3.4-radi-mon/drivers/tty/n_gsm.c 2012-12-12 23:22:00.767811462 +0800
@@ -164,7 +164,7 @@

/* DLCI 0, 62/63 are special or reseved see gsmtty_open */

-#define NUM_DLCI 64
+#define NUM_DLCI 5 /* Modify from 64 to 5 by guowenxue, only gsmtty[1-4] can be used */

/*
* DLCI 0 is used to pass control blocks out of band of the data

3, Power on the M35 GPRS module and check some device:
~ >: comport -ioctl /dev/gprs 24624 1
ioctl (/dev/gprs, 24624, 1) returned 0
~ >: ls -l /dev/ttyS2 #This is the GSM module used serial port
crw-rw—- 1 root root 4, 66 Jan 1 08:00 /dev/ttyS2
~ >: ls -l /dev/gsmtty* #This is the GMUX port, not genrate now
ls: /dev/gsmtty*: No such file or directory
~ >: cat /proc/devices | grep gsmtty #GMUX port device name should be gsmtty* and major number is 254
254 gsmtty
~ >: comport -d /dev/ttyS2 #We can use the original serial port communicate with GSM module
aatt

OK
aattee00

OK

4, Run the ldattach file
~ >: cp ldattach /apps/tools/
~ >: ldattach –help

Usage: ldattach [ -dhV78neo12 ] [ -s <speed> ] <ldisc> <device>

Known <ldisc> names:
GSM0701
TTY
SLIP
MOUSE
PPP
STRIP
AX25
X25
6PACK
R3964
IRDA
HDLC
SYNC_PPP
SYNCPPP
HCI
GIGASET_M101
GIGASET
M101
~ >: ldattach -8n1 -s 115200 GSM0701 /dev/ttyS2
~ >: ps | grep ldattach | grep -v grep
446 root 232 S ldattach -8n1 -s 115200 GSM0701 /dev/ttyS2
~ >:
~ >: ls -l /dev/gsmtty*
crw-rw—- 1 root root 254, 1 Jan 1 08:06 /dev/gsmtty1
crw-rw—- 1 root root 254, 2 Jan 1 08:06 /dev/gsmtty2
crw-rw—- 1 root root 254, 3 Jan 1 08:06 /dev/gsmtty3
crw-rw—- 1 root root 254, 4 Jan 1 08:06 /dev/gsmtty4

~ >: comport -d /dev/gsmtty1
at

OK
at

OK
~ >: comport -d /dev/gsmtty2
aatt

OK
aatt

OK
~ >: comport -d /dev/gsmtty3
at

OK
at

OK
~ >: comport -d /dev/gsmtty4
at

OK
at

OK
at+creg?

+CREG: 0,1

OK
at+csq

+CSQ: 17,0
5 Start PPP dial up and do PPP ping test
~ >: ifup-ppp -h
=================================================================================
ERROR: -h dial up configure file “/apps/etc/network/ifcfg–h” not found!
=================================================================================

ifup-ppp Usage: ifup-ppp [-d /dev/ttyUSB0] [-a apn] [-u username] [-p password] [-v chap/pap] [-i ipaddr] pppXX

This shell script used to do pppd dial up on GPRS/3G modem, if no options gived, it
will use the default configure file “/apps/etc/network/ifcfg-pppXX”. If get options
in this command, it will use the option from the command line, and be careful the -d
option must be given to specify the modem device.

pppXX: Required, specify the dial up generated PPP device, such as ppp10.
-d: Required, if use command line options, specify the modem TTY device.
-a: Option, APN(Access Point Name) for the SIM card provider.
-u: Option, username for the GPRS login if needed.
-p: Option, password for the GPRS login if needed.
-v: Option, authenticate method, pap or chap.
-i: Option, <local_IP_address>:<remote_IP_address> such as 0.0.0.0:0.0.0.0
Example: ifup-ppp -d /dev/ttyUSB0 -a 3gnet -u uid -p pwd ppp10

Copyright (C) 2012 GuoWenxue <guowenxue@gmail.com QQ:281143292>
~ >: ifup-ppp -d /dev/gsmtty1 -a “cmnet” -u “uid” -p “pwd” ppp10
+ pppd /dev/gsmtty1 115200 name uid password pwd unit 10 require-pap idle 86400 refuse-mschap refuse-mschap-v2 refuse-eap nodefaultroute updetach debug lcp-echo-failure 3 lcp-echo-interval 5 ipcp-accept-local ipcp-accept-remote ipcp-restart 50 modem nocrtscts noipdefault noauth novj noccp novjccomp lock connect /usr/sbin/chat -v -E -V -f /etc/ppp/gprs-chat
CONNECT + connected
Script /usr/sbin/chat -v -E -V -f /etc/ppp/gprs-chat finished (pid 504), status = 0x0
Serial connection established.
using channel 2
Using interface ppp10
Connect: ppp10 <–> /dev/gsmtty1
rcvd [LCP ConfReq id=0x1 <asyncmap 0xa0000> <auth pap> <pcomp> <accomp>]
sent [LCP ConfReq id=0x1 <asyncmap 0x0> <magic 0x1797a46d> <pcomp> <accomp>]
sent [LCP ConfAck id=0x1 <asyncmap 0xa0000> <auth pap> <pcomp> <accomp>]
rcvd [LCP ConfNak id=0x1 <asyncmap 0xa0000>]
sent [LCP ConfReq id=0x2 <asyncmap 0xa0000> <magic 0x1797a46d> <pcomp> <accomp>]
rcvd [LCP ConfAck id=0x2 <asyncmap 0xa0000> <magic 0x1797a46d> <pcomp> <accomp>]
sent [LCP EchoReq id=0x0 magic=0x1797a46d]
sent [PAP AuthReq id=0x1 user=”uid” password=<hidden>]
rcvd [LCP EchoRep id=0x0 magic=0x0]
rcvd [PAP AuthAck id=0x1 “”]
PAP authentication succeeded
sent [IPCP ConfReq id=0x1 <addr 0.0.0.0>]
rcvd [IPCP ConfReq id=0x1 <addr 192.168.254.254>]
sent [IPCP ConfAck id=0x1 <addr 192.168.254.254>]
sent [LCP EchoReq id=0x1 magic=0x1797a46d]
rcvd [LCP EchoRep id=0x1 magic=0x0]
sent [LCP EchoReq id=0x2 magic=0x1797a46d]
rcvd [LCP EchoRep id=0x2 magic=0x0]
sent [LCP EchoReq id=0x3 magic=0x1797a46d]
rcvd [LCP EchoRep id=0x3 magic=0x0]
sent [LCP EchoReq id=0x4 magic=0x1797a46d]
rcvd [LCP EchoRep id=0x4 magic=0x0]
sent [LCP EchoReq id=0x5 magic=0x1797a46d]
rcvd [LCP EchoRep id=0x5 magic=0x0]
sent [LCP EchoReq id=0x6 magic=0x1797a46d]
rcvd [LCP EchoRep id=0x6 magic=0x0]
sent [LCP EchoReq id=0x7 magic=0x1797a46d]
rcvd [LCP EchoRep id=0x7 magic=0x0]
sent [LCP EchoReq id=0x8 magic=0x1797a46d]
rcvd [LCP EchoRep id=0x8 magic=0x0]
sent [LCP EchoReq id=0x9 magic=0x1797a46d]
rcvd [LCP EchoRep id=0x9 magic=0x0]
sent [IPCP ConfReq id=0x1 <addr 0.0.0.0>]
sent [LCP EchoReq id=0xa magic=0x1797a46d]
rcvd [LCP EchoRep id=0xa magic=0x0]
sent [LCP EchoReq id=0xb magic=0x1797a46d]
rcvd [LCP EchoRep id=0xb magic=0x0]
sent [LCP EchoReq id=0xc magic=0x1797a46d]
rcvd [LCP EchoRep id=0xc magic=0x0]
rcvd [IPCP ConfNak id=0x1 <addr 10.212.179.145>]
sent [IPCP ConfReq id=0x2 <addr 10.212.179.145>]
rcvd [IPCP ConfAck id=0x2 <addr 10.212.179.145>]
local IP address 10.212.179.145
remote IP address 192.168.254.254
+ route add default ppp10
~ >: ifconfig ppp10
ppp10 Link encap:Point-to-Point Protocol
inet addr:10.212.179.145 P-t-P:192.168.254.254 Mask:255.255.255.255
UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1
RX packets:3 errors:0 dropped:0 overruns:0 frame:0
TX packets:4 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:3
RX bytes:30 (30.0 B) TX bytes:40 (40.0 B)

~ >: ping 4.2.2.2 -c 4 -I ppp10
PING 4.2.2.2 (4.2.2.2): 56 data bytes
64 bytes from 4.2.2.2: seq=0 ttl=51 time=1667.614 ms
64 bytes from 4.2.2.2: seq=1 ttl=51 time=1117.488 ms

— 4.2.2.2 ping statistics —
4 packets transmitted, 2 packets received, 50% packet loss
round-trip min/avg/max = 1117.488/1392.551/1667.614 ms
~ >:
6 Use other serial port do AT command:
~ >: comport -d /dev/gsmtty2
at

OK
at+csq

+CSQ: 17,0

OK
~ >: comport -d /dev/gsmtty3
at

OK
at+creg?

+CREG: 0,1

OK
~ >: comport -d /dev/gsmtty4
at

OK
at+cops?

+COPS: 0,0,”CHINA MOBILE”

OK

在线咨询
微信号
13554373241
联系方式
135-5437-3241
邮箱
guowenxue@aliyun.com
返回顶部