GSM 0710 tty 多路複用器 HOWTO¶
此線路規程實現了以下 3GPP 文件中詳細介紹的 GSM 07.10 多路複用協議
本文件提供了一些關於如何將此驅動程式與連線到物理序列埠的 GPRS 和 3G 調變解調器一起使用的提示。
如何使用它¶
配置啟動器¶
透過其序列埠將調變解調器初始化為 0710 mux 模式(通常是
AT+CMUX=命令)。 根據所使用的調變解調器,您可以將或多或少的引數傳遞給此命令。透過使用
TIOCSETDioctl 將序列線路切換為使用 n_gsm 線路規程。如果需要,使用
GSMIOC_GETCONF_EXT/GSMIOC_SETCONF_EXTioctl 配置 mux。使用
GSMIOC_GETCONF/GSMIOC_SETCONFioctl 配置 mux。對於非預設值,使用
GSMIOC_GETCONF_DLCI/GSMIOC_SETCONF_DLCIioctl 配置 DLC。獲取所用序列埠的基本 gsmtty 編號。
初始化程式的主要部分(一個好的起點是 util-linux-ng/sys-utils/ldattach.c)
#include <stdio.h> #include <stdint.h> #include <linux/gsmmux.h> #include <linux/tty.h> #define DEFAULT_SPEED B115200 #define SERIAL_PORT /dev/ttyS0 int ldisc = N_GSM0710; struct gsm_config c; struct gsm_config_ext ce; struct gsm_dlci_config dc; struct termios configuration; uint32_t first; /* open the serial port connected to the modem */ fd = open(SERIAL_PORT, O_RDWR | O_NOCTTY | O_NDELAY); /* configure the serial port : speed, flow control ... */ /* send the AT commands to switch the modem to CMUX mode and check that it's successful (should return OK) */ write(fd, "AT+CMUX=0\r", 10); /* experience showed that some modems need some time before being able to answer to the first MUX packet so a delay may be needed here in some case */ sleep(3); /* use n_gsm line discipline */ ioctl(fd, TIOCSETD, &ldisc); /* get n_gsm extended configuration */ ioctl(fd, GSMIOC_GETCONF_EXT, &ce); /* use keep-alive once every 5s for modem connection supervision */ ce.keep_alive = 500; /* set the new extended configuration */ ioctl(fd, GSMIOC_SETCONF_EXT, &ce); /* get n_gsm configuration */ ioctl(fd, GSMIOC_GETCONF, &c); /* we are initiator and need encoding 0 (basic) */ c.initiator = 1; c.encapsulation = 0; /* our modem defaults to a maximum size of 127 bytes */ c.mru = 127; c.mtu = 127; /* set the new configuration */ ioctl(fd, GSMIOC_SETCONF, &c); /* get DLC 1 configuration */ dc.channel = 1; ioctl(fd, GSMIOC_GETCONF_DLCI, &dc); /* the first user channel gets a higher priority */ dc.priority = 1; /* set the new DLC 1 specific configuration */ ioctl(fd, GSMIOC_SETCONF_DLCI, &dc); /* get first gsmtty device node */ ioctl(fd, GSMIOC_GETFIRST, &first); printf("first muxed line: /dev/gsmtty%i\n", first); /* and wait for ever to keep the line discipline enabled */ daemon(0,0); pause();將這些裝置用作普通序列埠。
例如,可能
使用 *gnokii* 在
ttygsm1上傳送/接收 SMS使用 *ppp* 在
ttygsm2上建立資料鏈路
在關閉物理埠之前,首先關閉所有虛擬埠。
請注意,關閉物理埠後,調變解調器仍處於多路複用模式。 這可能會阻止以後成功重新開啟埠。 為了避免這種情況,如果您的硬體允許,請重置調變解調器,或者在第二次初始化多路複用模式之前手動傳送斷開連線命令幀。 斷開連線命令幀的位元組序列為
0xf9, 0x03, 0xef, 0x03, 0xc3, 0x16, 0xf9
配置請求者¶
透過其序列埠接收
AT+CMUX=命令,初始化 mux 模式配置。透過使用
TIOCSETDioctl 將序列線路切換為使用 *n_gsm* 線路規程。如果需要,使用
GSMIOC_GETCONF_EXT/GSMIOC_SETCONF_EXTioctl 配置 mux。使用
GSMIOC_GETCONF/GSMIOC_SETCONFioctl 配置 mux。對於非預設值,使用
GSMIOC_GETCONF_DLCI/GSMIOC_SETCONF_DLCIioctl 配置 DLC。獲取所用序列埠的基本 gsmtty 編號
#include <stdio.h> #include <stdint.h> #include <linux/gsmmux.h> #include <linux/tty.h> #define DEFAULT_SPEED B115200 #define SERIAL_PORT /dev/ttyS0 int ldisc = N_GSM0710; struct gsm_config c; struct gsm_config_ext ce; struct gsm_dlci_config dc; struct termios configuration; uint32_t first; /* open the serial port */ fd = open(SERIAL_PORT, O_RDWR | O_NOCTTY | O_NDELAY); /* configure the serial port : speed, flow control ... */ /* get serial data and check "AT+CMUX=command" parameter ... */ /* use n_gsm line discipline */ ioctl(fd, TIOCSETD, &ldisc); /* get n_gsm extended configuration */ ioctl(fd, GSMIOC_GETCONF_EXT, &ce); /* use keep-alive once every 5s for peer connection supervision */ ce.keep_alive = 500; /* set the new extended configuration */ ioctl(fd, GSMIOC_SETCONF_EXT, &ce); /* get n_gsm configuration */ ioctl(fd, GSMIOC_GETCONF, &c); /* we are requester and need encoding 0 (basic) */ c.initiator = 0; c.encapsulation = 0; /* our modem defaults to a maximum size of 127 bytes */ c.mru = 127; c.mtu = 127; /* set the new configuration */ ioctl(fd, GSMIOC_SETCONF, &c); /* get DLC 1 configuration */ dc.channel = 1; ioctl(fd, GSMIOC_GETCONF_DLCI, &dc); /* the first user channel gets a higher priority */ dc.priority = 1; /* set the new DLC 1 specific configuration */ ioctl(fd, GSMIOC_SETCONF_DLCI, &dc); /* get first gsmtty device node */ ioctl(fd, GSMIOC_GETFIRST, &first); printf("first muxed line: /dev/gsmtty%i\n", first); /* and wait for ever to keep the line discipline enabled */ daemon(0,0); pause();
11-03-08 - Eric Bénard - <eric@eukrea.com>