usb_modeswitch & usb modem

Статья в основном для тех, кто использует 3G/4G USB модемы и ее назначение как ознакомительное, так и помочь в решении проблем с подключением этих устройств с помощью usb_modeswitch (при отсутствии в /dev файл-устройств serial port).
Для начала небольшой э́кскурс в usb_modeswitch.
usb_modeswitch - это программа переключающая режимы бистабильных USB устройств, точнее устройств, созданных на основе сотовых чипсетов и имеющих встроенные драйвера (как правило MS Windows). При подключении к компьютеру в первый раз такие устройства ведут себя как флеш-накопители и начинают установку своего программного обеспечения. По окончании установки (и при всех последующих подключениях) драйвер переключает режим такого бистабильного устройства (грубо говоря, вместо одного устройство появляется другое устройство). Если не ошибаюсь, то впервые это применил производитель модемов "Option" и назвал этот механизм "ZeroCD". Ну а по существу бистабильное устройство - это устройство, состоящее из нескольких устройств, например, USB modem содержит виртуальный CD ROM (на котором размещены драйвера) и сам модем (позже к флеш-накопителю стали добавлять Card Rider, а сам модем совершенствовать, в смысле внедрять новые технологии - NDIS, HiLink).
Для понимания работы с usb_modeswitch посмотрим состав этого пакета, привожу самые необходимые файлы, необходимые для управления переключения режимов и сбора информации об устройстве:

/etc/usb_modeswitch.conf - общий (глобальный) конфигурационный файл для включения функции ведения логов при диагностике, для запрета переключения режимов и др.
Например, установим запрет переключения режимов и включим логирование, т.е. установим значения DisableSwitching=1, DisableSwitching=1
Втыкаем модем, запускаем команду ls /dev/ttyUSB* и ..... пусто, а также видим, что появился лог
/var/log/usb_modeswitch_4-1.1 - в последней строке которого написано - Switching globally disabled, что мы и осуществили.
Заодно посмотрим наш модем, как он обзывается по дефолту, без переключения режима
lsusb
Bus 004 Device 046: ID 12d1:15ca Huawei Technologies Co., Ltd. E3131 3G/UMTS/HSPA+ Modem (Mass Storage Mode)
Возвращаем дефолтные значения в DisableSwitching=0, DisableSwitching=0 , перетыкаем модем и смотрим как сработало переключение
ls /dev/ttyUSB*
/dev/ttyUSB0  /dev/ttyUSB1  /dev/ttyUSB2
lsusb
Bus 004 Device 053: ID 12d1:1506 Huawei Technologies Co., Ltd. Modem/Networkcard
И видим, что устройство переключилось в другой режим
было 12d1:15ca (Mass Storage Mode) - стало 12d1:1506 (Modem/Networkcard)
UPD - после изменения параметров и перетыкания модема необходима пауза 10-15с

/etc/usb_modeswitch.d/ - директория для своих файлов конфигурации. Здесь можно добавить новые или измененные файлы конфигурации, которые будут иметь приоритет над набором конфигураций в /usr/share/usb_modeswitch. Сам этого никогда не делал, не представился случай.

/etc/usb_modeswitch.setup - список конфигураций для переключения режимов USB-устройств.
Файл очень содержательный и эта информация очень полезна для использования ручного переключения режимов. Например, посмотрим модем Huawei E1550
cat /etc/usb_modeswitch.setup | grep -C 11 E1550
# Huawei E1550
# Huawei E1750
#
# Contributor: Anders Blomdell, Ahmed Soliman

DefaultVendor=  0x12d1
DefaultProduct= 0x1446

TargetVendor=   0x12d1
TargetProduct=  0x1001

MessageContent="55534243123456780000000000000011060000000000000000000000000000"
Вообщем то все понятно, кроме одного параметра - MessageContent
Default_VID&PID - это VID&PID до переключения устройства
Target_VID&PID - это VID&PID после переключения устройства
MessageContent - это последовательность из 31 байта, на вид не понятное и страшное, но на самом деле эту последовательность можно легко получить (используя сниффер), если прослушать команду хоста устройству в момент переключения, например, я получил для своего устройства E3131 следующее значение (кстати, в этом файле нет информации как для модема E3131, так и для E3531)
55534243123456780000000000000011062000000101000100000000000000
Но будет еще понятнее, если учесть, что согласно спецификации
- смещение 0 - 3 (1-ые 4 байта, 55534243) это сигнатура и она постоянна для наших модемов
- смещение 15 - 30 это SBW (Command Block Wrapper), но нужны только 1-ые 4 байта (в нашем примере это 11062000). НО, в принципе, достаточно в большинстве случаев только знания 1-го байта (код самой команды SCSI), т.е. в нашем случае это будет 11. И в итоге для моего устройства в полне подходит последовательность (проверено, работает)
55534243000000000000000000000011000000000000000000000000000000
В любом случае, если не известен этот код, всегда можно посмотреть эту последовательность для похожего (близкого) модема в файле /etc/usb_modeswitch.setup, а потом уточнить методом проб и ошибок или, для тех кто знаком, применить сниффер.
Сразу же привожу полный формат команды для ручного переключения режимов (практически срабатывает всегда)
sudo usb_modeswitch -v D_VID -p D_PID -V T_VID -P T_PID -M MC
где
D_VID, D_PID - Default VID&PID (берем из lsusb)
T_VID, T_PID - Target VID&PID (берем из /usr/share/usb_modeswitch/D_VID:D_PID
MC - MessageContent, последовательность из 31 байта - код для переключения (берем из /etc/usb_modeswitch.setup), если нет информации, действуем, как описал выше.
UPD - а вообще советую, как только приобрели модем и он нормально переключается, записать значения Default ID, Target ID, MessageContent из указанных файлов, потом может пригодится в случае проблем с usb_modeswitch. Если информации о значении MessageContent нет, установить ее.
Пример моего устройства, E3131 (а вот AT команда показывает E3531) и, как уже подметил, его нет в файле /etc/usb_modeswitch.setup
cat /etc/usb_modeswitch.setup | egrep 'E3131|E1550|0x15ca'
......... пусто .......
но usb_modeswitch переключает и без этого. Но я всеравно нашел для него значение MessageContent (применил сниффер) и если usb_modeswitch по какой то причине глюкнул и не переключает автоматически, я могу выполнить переключение в ручном режиме
sudo usb_modeswitch -v 12d1 -p 15ca -V 12d1 -P 1506 -M 55534243000000000000000000000011000000000000000000000000000000
Кроме того я использую ручное переключение в случае, если автоматичски переключение не работает, а мне нужно пообщаться с модемом, используя AT-команды в Linux, чтобы не запускать для этого винду.

/usr/share/usb_modeswitch/VID:PID - директория, содержащая индивидуальные файлы для каждого устройства в соответствии с их ID. И, как пишут, если имеется файл с даным ID устройства, то имеются все шансы что устройство с данным ID поддерживается, даже если его модель и не совпадает.
Пример для моего устройства (которое, кстати, отсутствует в файле /etc/usb_modeswitch.setup)
cat /usr/share/usb_modeswitch/12d1:15ca
# Huawei E3131
TargetVendor=0x12d1
TargetProduct=0x1506
HuaweiNewMode=1
Если ручное переключение работает и есть желание чтобы это работало автоматически, необходимо создать правило UDEV (как его создавать, не описываю, это уже другая история). Кроме того не описываю и создание своего конфигурационного файла.
И лично мое мнение - я не заморачиваюсь с usb_modeswitch, а с помощью AT команд сразу же перевожу устройство в нужный мне режим, в котором serial port создаются автоматически при наличии нужного модуля (драйвера).
Разумеется все проблемы и нюансы не опишешь, но желательно, в случае проблем с переключением, всегда смотреть появление новых файл-устройств в директории /dev.
Количественное изменение я обычно смотрю командой ls /dev | wc -l
Конкретное появление новых файлов проще узнать так - создаю 2 файла
ls /dev > ~/dev_1 и ls /dev > ~/dev_2 (до и после подключения устройства)
Создаю 2 вертикальных терминала (у меня tilix) и запускаю в каждом из них команду
sed '=' ~/dev_1 | sed 'N;s/\n/\t/' , sed '=' ~/dev_2 | sed 'N;s/\n/\t/'
Сдвигаю их как можно ближе, чтобы легче видеть изменения (ориентируюсь по номерам - после каждого нового появления файла нумерация сдвигается).
Ну вот и все, надеюсь, пригодится.
Ошибки не исчезают с опытом - они просто умнеют
vasek
надеюсь, пригодится.
Спасибо уважаемый , конечно очень пригодится :)
Прочитал в этой теме вот такое утверждение
RusWolf
usb_modeswitch последний в arch не переключает режим автоматом.
Или ручками давай команду, или установи usb_modeswitch предпоследний.
Уже тут обсуждалось это.
и решил проверить.
Установил из реп usb_modeswitch 2.5.1-1 вставляю свой свисток:
Bus 004 Device 023: ID 12d1:1505 Huawei Technologies Co., Ltd. E398 LTE/UMTS/GSM Modem/Networkcard
тишина.
Ладно, копирую /usr/lib/udev/rules.d/40-usb_modeswitch.rules в /etc/udev/rules.d - тишина. Сильно не заморачиваясь тем, что в этом файле написано добавляю перед последней строкой: LABEL="mode..." отсебятину:
ATTRS{idVendor}=="12d1", ATTRS{manufacturer}!="Android", ATTR{idProduct}=="1505", RUN+="/usr/sbin/usb_modeswitch -v12d1 -p1505 -J"
Может это и костыль, но профит:
Bus 004 Device 026: ID 12d1:140c Huawei Technologies Co., Ltd. E180v
после подключения свистка все работает автоматом.

[root@TM8481 udev]# ls /dev|grep USB
ttyUSB0
ttyUSB1
ttyUSB2
anode
вот такое утверждение
Я бы сказал не утверждение, а факт.

https://bugs.archlinux.org/task/56372?project=5&string=usb_modeswitch
https://t.me/arch_linuxru
Вы утверждали, что не работает автоматическое переключение режима, я показал, что работает. Вот это и есть факт :). Может работает для тех, кто нихт фирштейн по английски? )))
anode, проверь, сработает ли эта команда для твоего свистка (значение M взял упрощенное)
sudo usb_modeswitch -v 12d1 -p 1505 -V 12d1 -P 140c -M 55534243000000000000000000000011000000000000000000000000000000
Ошибки не исчезают с опытом - они просто умнеют
anode
я показал, что работает.
После костыля, покажи что бы автоматом работало из коробки, без костылей и рукотворчества, как на предыдущем пакете :)
https://t.me/arch_linuxru
vasek
anode, проверь, сработает ли эта…
Вечером, сейчас не на чем .
RusWolf, все таки это блог - предлагаю флуд перенести в /dev/null. Во-вторых, "костыль" работает в любом дистрибутиве, где есть udev, а он есть везде, независимо от системы инициализации. "Изкаропки" - это не ко мне, я не дистрибьютор Арча. Лучше обратиться к тому, кто сопровождает пакет.
anode
все таки это блог - предлагаю флуд перенести в /dev/null.
Однозначно наш флуд в /dev/null.
https://t.me/arch_linuxru
 
Зарегистрироваться или войдите чтобы оставить сообщение.