Мы используем модем Telit LE910B1 на встроенном устройстве с ядром Linux 5.1.0. У нас есть только один UART, доступный для модема, поэтому мы используем линейную дисциплину n_gsm с CMUX на модеме. Когда все настроено, наше приложение создает два виртуальных ttys, использует одно для получения информации о модеме, а другое передается pppd для запуска сеанса PPP. Затем мы можем запустить данные RX / TX через TCP / IP. Все это работает хорошо в течение короткого времени, с небольшими передачами данных, но когда мы пытаемся передать большие объемы данных, соединение PPP блокируется, и единственный способ возобновить работу - это отключить pppd, выключить и включить модем и перезапустите приложение.
Telit смогла воспроизвести проблему с двумя разными версиями Ubuntu (18.04 и) и смогла получить информацию о трассировке от модема, которую они передали Intel для дальнейшей диагностики. Ответ Intel был что они думают, что «сторона приложения хоста», возможно, не делает правильные кадры CMUX или не учитывает максимальный размер кадра. Вот некоторые выдержки, предоставленные нам Telit из анализа трассировки модема:
<-- Packet discarded because of flag("0xF9") missing in CMUX frame.
<-- Packet discarded because of dlc is not valid in frame.
<-- Packet discarded because of length size more then RD_BUF_SIZE = 1510
<-- Packet dropped because of in PPP frame FCS is not valid
В моем случае «сторона приложения хоста» - это драйвер n_gsm в Linux, и я могу установить только размеры mru и mtu, которые я установил в то, что Telit говорит по умолчанию для модема (т.е. 121).
Код, который я использую для настройки модема, довольно прост (проверка ошибок для краткости):
struct termios tio;
int serial_fd;
serial_fd = open("/dev/ttyS1", O_RDWR | O_NOCTTY | O_NDELAY);
tcgetattr(serial_fd, &tio);
tio.c_iflag = 0;
tio.c_oflag = 0;
tio.c_cflag = CS8 | CREAD | CLOCAL;
tio.c_cflag |= CRTSCTS;
tio.c_lflag = 0;
tio.c_cc[VMIN] = 1;
tio.c_cc[VTIME] = 0;
cfsetospeed(&tio, B115200);
cfsetispeed(&tio, B115200);
tcsetattr(serial_fd, TCSANOW, &tio);
Для настройки модема я использую следующее:
send_at_command(serial_fd, "ATE0V1&K3&D2\r");
send_at_command(serial_fd, "AT#CMUXMODE=5\r");
send_at_command(serial_fd, "AT+CMUX=0,0\r");
После этого я включаю дисциплину n_gsm
struct gsm_config gsm;
int ldisc = N_GSM0710;
ioctl(serial_fd, TIOCSETD, &ldisc);
ioctl(serial_fd, GSMIOC_GETCONF, &gsm) ;
gsm.initiator = 1;
gsm.encapsulation = 0;
gsm.mru = 121;
gsm.mtu = 121;
ioctl(serial_fd, GSMIOC_SETCONF, &gsm);
/* Create /dev/ttyGSM1 and /dev/ttyGSM2. Do not close /dev/ttyS1 */
кто-нибудь еще использовал модем LE910 * с линейной дисциплиной CMUX и n_gsm в ядре Linux 5.1.0 или новее? Были ли у вас проблемы? Есть ли проблемы с кодом, который я показал, или вы можете предложить что-то, что я мог бы попробовать?
РЕДАКТИРОВАТЬ
Я посмотрел на код драйвера n_gsm. c и обнаружил, что есть 3 уровня трассировки, которые вы можете включить. Я начал с включения уровней 4 и 2:
echo "6" > /sys/module/n_gsm/parameters/debug
, и это будет регистрировать пакеты по мере их сборки и отправки в tty. Я обнаружил, что Intel правильно сказала. Драйвер отправляет мусор на модем. Журнал показывает, что нормальные пакеты выходят, но затем это:
Jan 19 18:09:51 ZFG0000805 kern.debug kernel: gsm_data_kick: 00000000: f9 0b ef f3 21 45 10 05 74 aa 6a 40 00 40 06 d1 ....!E..t.j@.@..
Jan 19 18:09:51 ZFG0000805 kern.debug kernel: gsm_data_kick: 00000010: a5 46 19 8e 6f cc 65 18 76 00 16 0b 58 5b e6 da .F..o.e.v...X[..
Jan 19 18:09:51 ZFG0000805 kern.debug kernel: gsm_data_kick: 00000020: 55 bd 3e 38 ad 80 18 1f 4a 4d dc 00 00 01 01 08 U.>8....JM......
Jan 19 18:09:51 ZFG0000805 kern.debug kernel: gsm_data_kick: 00000030: 0a 65 3c e5 73 7b 9d 4c 86 f8 53 e4 9f ff a4 9e .e<.s{.L..S.....
Jan 19 18:09:51 ZFG0000805 kern.debug kernel: gsmld_output: 00000060: 27 3c ee ab 28 29 51 e7 4e 04 f4 70 ce d4 e3 f2 '<..()Q.N..p....
Jan 19 18:09:51 ZFG0000805 kern.debug kernel: gsmld_output: 00000070: 93 ed 71 30 c7 1e 93 d8 b3 4a 90 88 e7 f9 ..q0.....J....
Обычно вы видите пинок, сопровождаемый выводом, где пакет точно такой же, но не здесь. Пакеты CMUX должны начинаться и заканчиваться байтом 0xf9, но «выходной» пакет выглядит поврежденным. После этого все записи в пике показывают завершенные пакеты, но следующая трассировка вывода начинается на один байт от символа начала кадра.
Jan 19 18:09:52 ZFG0000805 kern.debug kernel: gsm_data_kick: 00000000: f9 0b ef f3 87 8d e0 d0 db 2a 22 96 92 80 b6 a4 .........*".....
Jan 19 18:09:52 ZFG0000805 kern.debug kernel: gsm_data_kick: 00000010: 31 33 43 f0 13 e9 f3 79 13 d9 b4 13 8a 85 10 15 13C....y........
Jan 19 18:09:52 ZFG0000805 kern.debug kernel: gsm_data_kick: 00000020: 26 0d ab c2 89 f2 ad a2 6f cd 5d a9 15 f2 fe e8 &.......o.].....
Jan 19 18:09:52 ZFG0000805 kern.debug kernel: gsm_data_kick: 00000030: 6a 90 06 ef f3 d2 4c c1 65 4e 3c 22 f5 db f8 66 j.....L.eN<"...f
Jan 19 18:09:52 ZFG0000805 kern.debug kernel: gsm_data_kick: 00000040: d5 d7 70 fa f5 47 03 09 52 d3 1f 30 91 55 20 ce ..p..G..R..0.U .
Jan 19 18:09:52 ZFG0000805 kern.debug kernel: gsm_data_kick: 00000050: bc 71 51 b5 f7 ac f4 2a 7d 5d 1d 47 8d 30 73 22 .qQ....*}].G.0s"
Jan 19 18:09:52 ZFG0000805 kern.debug kernel: gsm_data_kick: 00000060: 38 fa 39 f4 64 9f f6 7d 5d 7d 5d 2a ab b6 a6 cf 8.9.d..}]}]*....
Jan 19 18:09:52 ZFG0000805 kern.debug kernel: gsm_data_kick: 00000070: 76 dd 8f 0a fd 27 8f 09 b2 78 99 da f8 e7 f9 v....'...x.....
Jan 19 18:09:52 ZFG0000805 kern.debug kernel: gsmld_output: 00000000: 0b ef f3 87 8d e0 d0 db 2a 22 96 92 80 b6 a4 31 ........*".....1
Jan 19 18:09:52 ZFG0000805 kern.debug kernel: gsmld_output: 00000010: 33 43 f0 13 e9 f3 79 13 d9 b4 13 8a 85 10 15 26 3C....y........&
Jan 19 18:09:52 ZFG0000805 kern.debug kernel: gsmld_output: 00000020: 0d ab c2 89 f2 ad a2 6f cd 5d a9 15 f2 fe e8 6a .......o.].....j
Jan 19 18:09:52 ZFG0000805 kern.debug kernel: gsmld_output: 00000030: 90 06 ef f3 d2 4c c1 65 4e 3c 22 f5 db f8 66 d5 .....L.eN<"...f.
Jan 19 18:09:52 ZFG0000805 kern.debug kernel: gsmld_output: 00000040: d7 70 fa f5 47 03 09 52 d3 1f 30 91 55 20 ce bc .p..G..R..0.U ..
Jan 19 18:09:52 ZFG0000805 kern.debug kernel: gsmld_output: 00000050: 71 51 b5 f7 ac f4 2a 7d 5d 1d 47 8d 30 73 22 38 qQ....*}].G.0s"8
Jan 19 18:09:52 ZFG0000805 kern.debug kernel: gsmld_output: 00000060: fa 39 f4 64 9f f6 7d 5d 7d 5d 2a ab b6 a6 cf 76 .9.d..}]}]*....v
Jan 19 18:09:52 ZFG0000805 kern.debug kernel: gsmld_output: 00000070: dd 8f 0a fd 27 8f 09 b2 78 99 da f8 e7 f9 ....'...x.....
Теперь действительно странная часть. Когда я включаю ведение журнала пакетов,
echo "7" > /sys/module/n_gsm/parameters/debug
Пакеты регистрируются непосредственно перед отправкой в очередь для отправки. Это замедляет работу всей системы, но, что бы я ни пытался, я не мог заставить сетевую сессию зависать. Казалось, все работало нормально, хотя было ужасно медленно.