7

我目前正在为 linux 路由器编写一个小工具,当我将适当的调制解调器插入其 USB 端口时,它会设置 wwan (gsm/3g) 连接。当设备插入时,注册了几个 tty,我目前维护一个制造商和设备的列表,以及他们注册的 tty 中的哪个是控制/数据端口。

如果可能的话,我想摆脱这个列表并找到一种方法来以某种方式直接探测已注册的 tty 以检查它们是控制端口还是数据端口。

我检查了 wvdial 和 modem-manager 的源代码,以了解这些工具如何检测正确的端口,但无法找到合适的信息。我还尝试在 sysfs 中查找信息以区分端口,但这也没有成功。

4

3 回答 3

1

您无法通过外部方式检测到这一点。通常的做法是为特定的调制解调器制造商和型号设置 udev 规则。或者您可以顺序连接到每个 tty 并通过 AT 命令验证它是什么类型的端口。

对于 udev 规则,您可以遵循以下过程:

1) 检测调制解调器 vid 和 pid 2) 基于 vid/pid 在 /dev/serial/by-id 创建符号链接

例如,具有 vid = 1199 和 pid 683c 的 Sierra Wireless MC8795V 调制解调器。我知道端口 3 始终是 AT 命令通道。因此,您可以在末尾创建一个带有 -AT 的符号链接。

在通过 AT 命令检测的情况下,最好和更常见的方法是执行 AT 命令以查看 tty 是否有响应。如果您将调制解调器配置为不回显,您应该得到回显或 OK。

例如:

AT
AT
OK

如果您收到响应,这意味着您找到了 AT 控制端口或 PPP 端口。要检查这一点,只需执行 ATI 命令。如果响应包含 APP1、APP2、APP3,那么您点击了 PPP 端口。否则你找到了你的 AT 控制端口。

例如一个 AT 控制端口:

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

例如一个 PPP 端口:

ATI
Sierra Wireless, Incorporated
MC8795V
APP1

OK

一句警告的话。对于 Sierra Wireless 模块,它们清楚地显示哪个端口是哪个。对于其他制造商,您需要查看 USB 接口指南,看看是否可以通过 ATI 采用这种方法。

于 2014-05-24T16:04:12.593 回答
1

我使用这个脚本来获取 3g 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
    }
}

示例输出:

连接中兴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

连接华为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
于 2015-05-22T11:38:10.733 回答
0

这对我有用:

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
于 2018-06-02T01:50:10.787 回答