How to determine if a tty belonging to a gsm / 3g modem is a data or control port?

I am currently writing a small tool for a linux router that establishes a wwan (gsm / 3g) connection when I connect the corresponding modem to its USB port. When a device is connected to several ttys, they are registered, and currently I maintain a list of manufacturers and devices, and of their registered ttys, a management / data port.

If possible, I want to get rid of this list and find a way to somehow test the registered ttys directly to see if they are a management port or a data port.

I studied the wvdial and modem-manager source code to find out how these tools find the correct port, but could not find the right information. I also tried to find information in sysfs to distinguish between ports, but that also failed.

+5
source share
3 answers

You cannot detect this by external means. It is common practice to either establish udev rules for a particular modem manufacturer and model. Or you can connect to each tty sequentially and check with the AT command what type of port.

In the case of udev rules, you can follow this process:

1) Detecting vid and pid modem 2) Based on vid / pid, create symbolic links in / dev / serial / by -id

For example, a Sierra Wireless MC8795V modem with vid = 1199 and pid 683c. I know that port 3 is always an AT command channel. So you can create a symlink fixed with -AT at the end.

If detected using AT commands, a better and more general approach is to run the AT command to see if tty responds at all. You should receive an echo or OK if you did not configure your modem to echo.

For instance:

AT AT OK 

If you get a response, it means that you found either the AT management port or the PPP port. To verify this, simply issue the ATI command. If the response contains APP1, APP2, APP3, then you get to the PPP port. Otherwise, you found your AT control port.

For example, the AT management port:

 ATI Manufacturer: Sierra Wireless, Incorporated Model: MC8795V Revision: K2_0_7_46AP C:/WS/FW/K2_0_7_46AP/MSM6290/SRC 2010/10/27 22:15:30 IMEI: XXXXXXXXXXXXXXX IMEI SV: 20 FSN: D9A2160146410 3GPP Release 6 +GCAP: +CGSM,+DS,+ES OK 

For example, PPP port:

 ATI Sierra Wireless, Incorporated MC8795V APP1 OK 

A word of warning though. In the case of Sierra Wireless modules, they clearly show which port is. For other manufacturers, you will need to check the USB manual to see if ATI can use this approach.

+1
source

I use this script to get data and control ports for the 3rd USB dongle.

 #!/bin/sh . /usr/share/libubox/jshn.sh for a in `ls /sys/bus/usb/devices`; do local vendor product [ -z "$usb" -a -f /sys/bus/usb/devices/$a/idVendor -a -f /sys/bus/usb/devices/$a/idProduct ] || continue vendor=$(cat /sys/bus/usb/devices/$a/idVendor) product=$(cat /sys/bus/usb/devices/$a/idProduct) echo Vendor $vendor, Product $product [ -f /lib/network/wwan/$vendor:$product ] && { usb=/lib/network/wwan/$vendor:$product devicename=$a echo usb: $usb devicename: $devicename } done [ -n "$usb" ] && { local old_cb control data json_set_namespace wwan old_cb json_init json_load "$(cat $usb)" echo "$(cat $usb)" json_select json_get_vars desc control data json_set_namespace $old_cb [ -n "$control" -a -n "$data" ] && { ttys=$(ls -d /sys/bus/usb/devices/$devicename/${devicename}*/tty* | sed "s/.*\///g" | tr "\n" " ") ctl_device=$(echo $ttys | cut -d" " -f $((control + 1))) [ -n "$ctl_device" ] && ctl_device=/dev/$ctl_device dat_device=$(echo $ttys | cut -d" " -f $((data + 1))) [ -n "$dat_device" ] && dat_device=/dev/$dat_device echo control_device: $ctl_device, data_device: $dat_device } } 

Selective Outputs:

Connected ZTE MF667

 Vendor 1a40, Product 0101 #this is usb hub Vendor 19d2, Product 0016 usb: /lib/network/wwan/19d2:0016 devicename: 1-1.2 { "desc": "ONDA MF110/ZTE", "control": 1, "data": 2 }} control_device: /dev/ttyUSB1, data_device: /dev/ttyUSB2 

Connected Huawei E3131

 Vendor 1a40, Product 0101 #this is usb hub Vendor 12d1, Product 1506 usb: /lib/network/wwan/12d1:1506 devicename: 1-1.2 { "desc": "Huawei E367/E398", "control": 2, "data": 0 }} control_device: /dev/ttyUSB2, data_device: /dev/ttyUSB0 
+1
source

This works for me:

 for device in $(mmcli -L | grep ModemManager | awk '{print $1}'); do cport=$(mmcli -m $device | awk '/primary port:/{ print $NF }' | tr -d \') ldevices=($(mmcli -m $device | grep "ports:" | pcregrep -o1 "(\w+) \(at\)")) dport=$(echo "/dev/${ldevices[@]##$cport}") [ -c $dport ] && echo $dport done 
0
source

Source: https://habr.com/ru/post/1345775/


All Articles