Skip to contentSkip to conversation

Usage of the n_gsm line discipline

DISCUSSION Thomas Petazzoni 2 participants 2 messages Mar 4, 2011

lore
Share & tools
lore
#0 lore raw

Hello,

(Sorry for posting on LKML, but there doesn't seem to be any specific list for TTY stuff, according to MAINTAINERS).

I have followed with interest the development of the n_gsm line discipline to multiplex a serial GSM modem. I have a Telit GE865 QUAD GPRS modem [1], for which the datasheet [2] says that it supports 3GPP TS 27.010 for multiplexing.

Therefore, I wanted to use the n_gsm line discipline in order to be able to make data connections and do SMS emission/reception concurrently.

My GSM modem is on /dev/ttyS2 and works fine :

===================================================================

# picocom -e b -b 115200 /dev/ttyS2 
picocom v1.6

port is : /dev/ttyS2
flowcontrol : none
baudrate is : 115200
parity is : none
databits are : 8
[...]

Terminal ready
AT
OK
===================================================================

I am able to send SMS with AT commands and make GPRS data connections using pppd, so the modem seems to be working fine.

As the n_gsm line discipline doesn't seem to have a documentation, I started with the following C program to set the n_gsm line discipline on my modem :

===================================================================
#define N_GSM0710 21 /* GSM 0710 Mux */

int main(void)

{
	int fd, ret;
	struct termios t;
	int ldisc = N_GSM0710;

	fd = open("/dev/ttyS2", O_RDWR);
	assert(fd >= 0);

	tcgetattr(fd, &t);
	cfsetispeed(&t, B115200);
	cfsetospeed(&t, B115200);
	t.c_iflag &= ~(IXON | IXOFF);
	t.c_lflag &= ~CRTSCTS;
	ret = tcsetattr(fd, TCSANOW, &t);
	assert(ret == 0);

	ret = ioctl(fd, TIOCSETD, & ldisc);
	if (ret) {
		printf("Error occured: %s\n", strerror(errno));
		return -1;
	}

	while(1)
		sleep(10);

	return 0;
}

===================================================================

I start this program, with the n_gsm module loaded. Then I create a device node for gsmtty1 :

	mknod /dev/gsmtty1 c 252 1

where 252 is the major of n_gsm :

	# cat /proc/devices | grep gsmtty
	252 gsmtty

(from the code, I understood that gsmtty0 is the control channel, that the multiplexer uses to communicate with the modem, so that gsmtty1 is the first available channel).

Then I start picocom on /dev/gsmtty1, and I expect to be able to send normal AT commands to the modem. Unfortunately, picocom doesn't recognize it as a valid tty :

===================================================================

# picocom -e b -b 115200 /dev/gsmtty1 
picocom v1.6

port is : /dev/gsmtty1
flowcontrol : none
baudrate is : 115200
parity is : none
databits are : 8
[...]

FATAL: term closed
term_exitfunc: reset failed for dev UNKNOWN: Input/output error
===================================================================

strace shows which ioctl() is failing:

===================================================================
open("/dev/gsmtty1", O_RDWR|O_NONBLOCK) = 3
ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 -opost -isig -icanon -echo ...}) = 0
ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 -opost -isig -icanon -echo ...}) = 0
ioctl(3, SNDCTL_TMR_CONTINUE or TCSETSF, {B115200 -opost -isig -icanon -echo ...}) = 0
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(0, SNDCTL_TMR_CONTINUE or TCSETSF, {B38400 -opost -isig -icanon -echo ...}) = 0
[...]
ioctl(3, TCFLSH, 0x2) = -1 EIO (Input/output error)
ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbec9773c) = -1 EIO (Input/output error)
write(2, "term_exitfunc: reset failed for "..., 64term_exitfunc: reset failed for dev UNKNOWN: Input/output error ) = 64
===================================================================

So, maybe I misconfigured n_gsm, or I didn't understand how to use it. Would it be possible to have a few details on how it is supposed to be used ? I haven't been able to find any userspace code that currently makes use of n_gsm. Is it available somewhere ?

If I can get it to work, I am willing to contribute a Documentation/n_gsm.txt document.

Finally, I'm using current git, i.e I have all the latest n_gsm changes that are upstream. I'm at b65a0e0c84cf489bfa00d6aa6c48abc5a237100f.

Thanks a lot,

Thomas Petazzoni

[1] http://www.telit.com/en/products/gsm-gprs.php?p_ac=show&p=47
[2] http://www.telit.com/module/infopool/download.php?id=1484

Signature · 4 lines
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
#1 lore raw
Quoted 4 lines

So, maybe I misconfigured n_gsm, or I didn't understand how to use it. Would it be possible to have a few details on how it is supposed to be used ? I haven't been able to find any userspace code that currently makes use of n_gsm. Is it available somewhere ?

Check dmesg but if your modem doesn't start up in multiplex mode you will need to issue an AT+CMUX command first. So the usual sequence is

write AT+CMUXblah [see GSM spec/modem command info] TIOCSETD
GSMIOC_GETCONF
[modify anything needed]
GSMIOC_SETCONF

The defaults uses are the T1/T2/N2 from the spec, we are not the initiator, and using encoding 1 (ie HDLC/LAP like), 64byte MRU/MTU.

So at the very least you'll want to set initiator to 1 so that we start issuing SABM messages at the modem to enter mux mode.

Quoted 2 lines

If I can get it to work, I am willing to contribute a Documentation/n_gsm.txt document.

That would be good.

Alan