0001 ==============================
0002 GSM 0710 tty multiplexor HOWTO
0003 ==============================
0004
0005 .. contents:: :local:
0006
0007 This line discipline implements the GSM 07.10 multiplexing protocol
0008 detailed in the following 3GPP document:
0009
0010 https://www.3gpp.org/ftp/Specs/archive/07_series/07.10/0710-720.zip
0011
0012 This document give some hints on how to use this driver with GPRS and 3G
0013 modems connected to a physical serial port.
0014
0015 How to use it
0016 =============
0017
0018 Config Initiator
0019 ----------------
0020
0021 #. Initialize the modem in 0710 mux mode (usually ``AT+CMUX=`` command) through
0022 its serial port. Depending on the modem used, you can pass more or less
0023 parameters to this command.
0024
0025 #. Switch the serial line to using the n_gsm line discipline by using
0026 ``TIOCSETD`` ioctl.
0027
0028 #. Configure the mux using ``GSMIOC_GETCONF``/``GSMIOC_SETCONF`` ioctl.
0029
0030 #. Obtain base gsmtty number for the used serial port.
0031
0032 Major parts of the initialization program
0033 (a good starting point is util-linux-ng/sys-utils/ldattach.c)::
0034
0035 #include <stdio.h>
0036 #include <stdint.h>
0037 #include <linux/gsmmux.h>
0038 #include <linux/tty.h>
0039
0040 #define DEFAULT_SPEED B115200
0041 #define SERIAL_PORT /dev/ttyS0
0042
0043 int ldisc = N_GSM0710;
0044 struct gsm_config c;
0045 struct termios configuration;
0046 uint32_t first;
0047
0048 /* open the serial port connected to the modem */
0049 fd = open(SERIAL_PORT, O_RDWR | O_NOCTTY | O_NDELAY);
0050
0051 /* configure the serial port : speed, flow control ... */
0052
0053 /* send the AT commands to switch the modem to CMUX mode
0054 and check that it's successful (should return OK) */
0055 write(fd, "AT+CMUX=0\r", 10);
0056
0057 /* experience showed that some modems need some time before
0058 being able to answer to the first MUX packet so a delay
0059 may be needed here in some case */
0060 sleep(3);
0061
0062 /* use n_gsm line discipline */
0063 ioctl(fd, TIOCSETD, &ldisc);
0064
0065 /* get n_gsm configuration */
0066 ioctl(fd, GSMIOC_GETCONF, &c);
0067 /* we are initiator and need encoding 0 (basic) */
0068 c.initiator = 1;
0069 c.encapsulation = 0;
0070 /* our modem defaults to a maximum size of 127 bytes */
0071 c.mru = 127;
0072 c.mtu = 127;
0073 /* set the new configuration */
0074 ioctl(fd, GSMIOC_SETCONF, &c);
0075 /* get first gsmtty device node */
0076 ioctl(fd, GSMIOC_GETFIRST, &first);
0077 printf("first muxed line: /dev/gsmtty%i\n", first);
0078
0079 /* and wait for ever to keep the line discipline enabled */
0080 daemon(0,0);
0081 pause();
0082
0083 #. Use these devices as plain serial ports.
0084
0085 For example, it's possible:
0086
0087 - to use *gnokii* to send / receive SMS on ``ttygsm1``
0088 - to use *ppp* to establish a datalink on ``ttygsm2``
0089
0090 #. First close all virtual ports before closing the physical port.
0091
0092 Note that after closing the physical port the modem is still in multiplexing
0093 mode. This may prevent a successful re-opening of the port later. To avoid
0094 this situation either reset the modem if your hardware allows that or send
0095 a disconnect command frame manually before initializing the multiplexing mode
0096 for the second time. The byte sequence for the disconnect command frame is::
0097
0098 0xf9, 0x03, 0xef, 0x03, 0xc3, 0x16, 0xf9
0099
0100 Config Requester
0101 ----------------
0102
0103 #. Receive ``AT+CMUX=`` command through its serial port, initialize mux mode
0104 config.
0105
0106 #. Switch the serial line to using the *n_gsm* line discipline by using
0107 ``TIOCSETD`` ioctl.
0108
0109 #. Configure the mux using ``GSMIOC_GETCONF``/``GSMIOC_SETCONF`` ioctl.
0110
0111 #. Obtain base gsmtty number for the used serial port::
0112
0113 #include <stdio.h>
0114 #include <stdint.h>
0115 #include <linux/gsmmux.h>
0116 #include <linux/tty.h>
0117 #define DEFAULT_SPEED B115200
0118 #define SERIAL_PORT /dev/ttyS0
0119
0120 int ldisc = N_GSM0710;
0121 struct gsm_config c;
0122 struct termios configuration;
0123 uint32_t first;
0124
0125 /* open the serial port */
0126 fd = open(SERIAL_PORT, O_RDWR | O_NOCTTY | O_NDELAY);
0127
0128 /* configure the serial port : speed, flow control ... */
0129
0130 /* get serial data and check "AT+CMUX=command" parameter ... */
0131
0132 /* use n_gsm line discipline */
0133 ioctl(fd, TIOCSETD, &ldisc);
0134
0135 /* get n_gsm configuration */
0136 ioctl(fd, GSMIOC_GETCONF, &c);
0137 /* we are requester and need encoding 0 (basic) */
0138 c.initiator = 0;
0139 c.encapsulation = 0;
0140 /* our modem defaults to a maximum size of 127 bytes */
0141 c.mru = 127;
0142 c.mtu = 127;
0143 /* set the new configuration */
0144 ioctl(fd, GSMIOC_SETCONF, &c);
0145 /* get first gsmtty device node */
0146 ioctl(fd, GSMIOC_GETFIRST, &first);
0147 printf("first muxed line: /dev/gsmtty%i\n", first);
0148
0149 /* and wait for ever to keep the line discipline enabled */
0150 daemon(0,0);
0151 pause();
0152
0153 11-03-08 - Eric Bénard - <eric@eukrea.com>