5 votes

Comment faire fonctionner Ethernet sur Android via OTG ?

J'essaie d'utiliser un modem LTE connecté à un appareil Android 7 via un câble OTG. Le noyau reconnaît le périphérique et l'enregistre dans le système d'exploitation. cdc_ether mais je ne parviens pas à utiliser la connexion de l'appareil. Est-ce parce qu'il est ensuite monté en tant que stockage USB ?

L'appareil n'apparaît pas comme un appareil dans l'interface utilisateur Android / la barre d'état.

Si je désactive le support MTP, l'appareil ne s'enregistrera pas. cdc_ether du tout.

dmesg :

[10946.408785] usb 1-1.3: new high-speed USB device number 21 using msm_hsusb_host
[10946.525287] usb 1-1.3: New USB device found, idVendor=19d2, idProduct=1225
[10946.525306] usb 1-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[10946.525316] usb 1-1.3: Product: ZTE Mobile Broadband
[10946.525325] usb 1-1.3: Manufacturer: ZTE,Incorporated
[10946.525335] usb 1-1.3: SerialNumber: MF8610ZTED000000
[10946.529662] usb-storage 1-1.3:1.0: USB Mass Storage device detected
[10946.532702] scsi host19: usb-storage 1-1.3:1.0
[10947.538579] scsi 19:0:0:0: CD-ROM            ZTE      USB SCSI CD-ROM  2.31 PQ: 0 ANSI: 2
[10952.740595] usb 1-1.3: USB disconnect, device number 21
[10953.087891] usb 1-1.3: new high-speed USB device number 22 using msm_hsusb_host
[10953.232955] usb 1-1.3: New USB device found, idVendor=19d2, idProduct=1405
[10953.232969] usb 1-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[10953.232977] usb 1-1.3: Product: ZTE Mobile Broadband
[10953.232984] usb 1-1.3: Manufacturer: ZTE,Incorporated
[10953.232991] usb 1-1.3: SerialNumber: MF8610ZTED000000
[10953.260856] cdc_ether 1-1.3:1.0 usb0: register 'cdc_ether' at usb-msm_hsusb_host-1.3, CDC Ethernet Device, 36:4b:50:b7:ef:da
[10953.262322] usb-storage 1-1.3:1.2: USB Mass Storage device detected
[10953.262652] scsi host20: usb-storage 1-1.3:1.2
[10954.261139] scsi 20:0:0:0: CD-ROM            ZTE      USB SCSI CD-ROM  2.31 PQ: 0 ANSI: 2

dmesg avec MTP désactivé :

[10664.987934] usb 1-1.3: new high-speed USB device number 19 using msm_hsusb_host
[10665.105272] usb 1-1.3: New USB device found, idVendor=19d2, idProduct=1225
[10665.105291] usb 1-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[10665.105301] usb 1-1.3: Product: ZTE Mobile Broadband
[10665.105310] usb 1-1.3: Manufacturer: ZTE,Incorporated
[10665.105320] usb 1-1.3: SerialNumber: MF8610ZTED000000
[10665.110339] usb-storage 1-1.3:1.0: USB Mass Storage device detected
[10665.111320] scsi host17: usb-storage 1-1.3:1.0
[10666.110748] scsi 17:0:0:0: CD-ROM            ZTE      USB SCSI CD-ROM  2.31 PQ: 0 ANSI: 2
[10671.223090] usb 1-1.3: USB disconnect, device number 19
[10671.407859] msm_otg 78db000.usb: OTG runtime idle
[10671.407887] msm_otg 78db000.usb: OTG runtime suspend

ifconfig :

TB-8504F:/ # ifconfig                                                                                                                  
wlan0     Link encap:Ethernet  HWaddr 40:a1:08:36:5b:0d
          inet addr:192.168.1.133  Bcast:192.168.1.255  Mask:255.255.255.0 
          inet6 addr: 2605:a601:ab2b:9900:b19e:4f2e:5d28:5fa9/64 Scope: Global
          inet6 addr: fe80::42a1:8ff:fe36:5b0d/64 Scope: Link
          inet6 addr: 2605:a601:ab2b:9900:42a1:8ff:fe36:5b0d/64 Scope: Global
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:27906 errors:0 dropped:4 overruns:0 frame:0 
          TX packets:17795 errors:0 dropped:0 overruns:0 carrier:0 
          collisions:0 txqueuelen:1000 
          RX bytes:14342222 TX bytes:8697917 

dummy0    Link encap:Ethernet  HWaddr c6:b9:c8:82:8f:7e
          inet6 addr: fe80::c4b9:c8ff:fe82:8f7e/64 Scope: Link
          UP BROADCAST RUNNING NOARP  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0 
          TX packets:3 errors:0 dropped:0 overruns:0 carrier:0 
          collisions:0 txqueuelen:0 
          RX bytes:0 TX bytes:210 

p2p0      Link encap:Ethernet  HWaddr 42:a1:08:36:5b:0d
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0 
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 
          collisions:0 txqueuelen:1000 
          RX bytes:0 TX bytes:0 

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0 
          inet6 addr: ::1/128 Scope: Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0 
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 
          collisions:0 txqueuelen:0 
          RX bytes:0 TX bytes:0 

ip l :

255|TB-8504F:/ # ip l
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: dummy0: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN mode DEFAULT group default 
    link/ether c6:b9:c8:82:8f:7e brd ff:ff:ff:ff:ff:ff
3: sit0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN mode DEFAULT group default 
    link/sit 0.0.0.0 brd 0.0.0.0
20: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DORMANT group default qlen 1000
    link/ether 40:a1:08:36:5b:0d brd ff:ff:ff:ff:ff:ff
21: p2p0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN mode DORMANT group default qlen 1000
    link/ether 42:a1:08:36:5b:0d brd ff:ff:ff:ff:ff:ff
31: usb0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 36:4b:50:b7:ef:da brd ff:ff:ff:ff:ff:ff

L'appareil apparaît comme usb0 avec l'adresse MAC qui était listée dans dmesg .

12voto

Irfan Latif Points 16863

Il existe une longue liste de questions relatives à l'Ethernet, mais aucune n'a de réponse complète couvrant tous les aspects. Je généralise votre question afin de partager mes connaissances en la matière.

Voici ce que vous devez faire pour qu'Ethernet fonctionne sur Android :

  • Assurez-vous que le support OTG est disponible
  • Le noyau doit être construit avec le support Ethernet (et USB Ethernet)
  • Gérer le changement de mode USB et le chargement des modules du noyau (le cas échéant).
  • Faire en sorte que le framework Android s'occupe de la configuration du réseau ou la faire manuellement

Note : Tout ce qui est décrit ci-dessous nécessite un appareil enraciné ou au moins celui avec un bootloader déverrouillé.
Vous devez être familier avec l'interface en ligne de commande.


SUPPORT OTG

Votre appareil doit être capable de fonctionner en mode hôte USB. EthernetService es a commencé uniquement si le périphérique prend en charge la fonction hôte USB ( android.hardware.usb.host ) ou Ethernet ( android.hardware.ethernet ). Vous pouvez également avoir besoin d'utiliser un hub USB alimenté si l'alimentation USB d'Android n'est pas suffisante pour le périphérique connecté. Question connexe :

CONFIGURATION DU NOYAU

Afin d'utiliser Ethernet sur USB (adaptateurs ou dispositifs de type modem) le noyau doit être construit avec CONFIG_USB_USBNET et d'autres configurations comme USB_NET_CDCETHER , USB_NET_HUAWEI_CDC_NCM , USB_NET_CDC_MBIM etc., en fonction du type de périphérique connecté et du protocole qu'il utilise. Questions connexes :

CHANGEMENT DE MODE USB ET CHARGEMENT DU MODULE DU NOYAU

De nombreux périphériques réseau USB sont multi-modes ou flip-flop appareils. Ils se présentent comme des périphériques de stockage de masse USB (également appelés ZeroCD ) lorsqu'il est inséré et doit être commuté en mode Ethernet/PPP. USB_ModeSwitch est un outil Linux couramment utilisé à cette fin. Voir quelques détails aquí comment cela fonctionne. Vous devez construire cet outil pour votre appareil, ou vous pouvez le télécharger. ce binaire para aarch64 . Obtenir la base de données des appareils à partir de aquí .

Afin de changer automatiquement de mode chaque fois que l'appareil est connecté à Android, nous devons écouter le noyau USB. uevents soit par aide hotplug ou un démon en espace utilisateur (comme udev sur Linux et ueventd sur Android). En outre, le module du noyau peut également être chargé/déchargé automatiquement. Je suis définir un init service ici pour y parvenir, vous pouvez aussi le faire manuellement.

Note : Il existe une application Android Widget PPP (par le développeur de USB_ModeSwitch, je n'ai aucune affiliation) qui gère le changement de mode automatiquement et qui a besoin de "pas de module pilote pour le noyau, l'implémentation du 'pilote' est basée sur l'API hôte USB d'Android". . Cela pourrait vous intéresser aussi.

# /system/etc/init/custom.rc

# kernel hotplug or uevent daemon service
service cust.udevd /system/sbin/busybox uevent /system/sbin/udev.sh
    seclabel u:r:magisk:s0
    disabled
    writepid /dev/cpuset/system-background/tasks

# set kernel hotplug helper or start uevent daemon on boot
on property:sys.boot_completed=1
    #write /proc/sys/kernel/hotplug /system/sbin/udev.sh
    start cust.udevd

* Dans le cas du hotplug, vous devez définir des politiques SELinux personnalisées pour permettre au noyau d'effectuer des modifications (cf. cette réponse pour plus de détails).

#!/system/bin/sh

# /system/sbin/udev.sh script is executed from kernel hotplug or uevent daemon

# set PATH where you placed binaries
export PATH=/system/bin

# save log
exec >>/dev/udev.log 2>&1

# don't execute multiple instances
exec 200<>/dev/udev.lock
flock 200

VID="12d1"          # USB vendor ID of a Huawei devcie
PID_UMS="1f01"      # product ID in ZeroCD mode
PID_ETH="14db"      # product ID in Ethernet mode
MODULE="cdc_ether"  # kernel module for USB Ethernet
IFACE="usb0"        # Ethernet interface name

matches() {
    [ -e "/sys/$DEVPATH/$1" ] || return 1
    [ "$(cat "/sys/$DEVPATH/$1")" = "$2" ] || return 1
    return 0
}

# check if a new USB device is added or removed
if [ "$SUBSYSTEM" = "usb" ]
then
    # check if a USB device is added, then match VID and PID for mode switching
    # also device must belong to UMS class: https://www.usb.org/defined-class-codes#anchor_BaseClass08h
    if [ "$ACTION" = "add" ] && echo "$PRODUCT" | grep -q "$VID/$PID_UMS/" &&
        matches bInterfaceClass 08 && matches bInterfaceNumber 00
    then
        echo "Switching USB mode..."

        # USB mode switching of flip flop devices (USB modems, routers etc.)
        # usb_modeswitch_dispatcher needs /system/sbin/usb_modeswitch binary and configuration files in /etc
        # so you need to modify the hard-coded paths in source code as per your requirement
        usb_modeswitch_dispatcher --switch-mode "$(basename "$DEVPATH")"
    fi

    # match VID and PID for module loading
    # modprobe should be built with the hard-coded path to where you place modules e.g. /system/lib
    if echo "$PRODUCT" | grep -q "$VID/$PID_ETH/"
    then
        if [ "$ACTION" = "add" ] && ! grep -q "^$MODULE " /proc/modules
        then
            echo "Loading $MODULE module..."
            modprobe "$MODULE"

        elif [ "$ACTION" = "remove" ] && grep -q "^$MODULE " /proc/modules
        then
            echo "Removing $MODULE module..."
            modprobe -r "$MODULE"
        fi
    fi
fi

# on network interface event
if [ "$SUBSYSTEM" = "net" ] && [ "$INTERFACE" = "$IFACE" ]
then
    if [ "$ACTION" = "add" ]
    then
        echo "Starting cust.eth_config service..."
        #start cust.eth_config    # uncomment if you want to do manual network configuration
    fi

    if [ "$ACTION" = "remove" ]
    then
        echo "Stopping cust.eth_config service..."
        #stop cust.eth_config    # uncomment if you want to do manual network configuration
    fi
fi

CONFIGURATION DU RÉSEAU

Le cadre Android a un nom codé en dur pour l'interface Ethernet ( par défaut es eth0 , eth1 , ...). Chaque fois qu'une interface Ethernet apparaît, son le nom correspond avec la valeur codée en dur. Renommer l'interface par la suite ne fonctionne pas parce que seule la valeur Noyau fourni le nom de l'interface est traqué .

Vous devez donc rendre cette convention de dénomination cohérente entre le noyau et l'AOSP en modifiant l'un des deux (si nécessaire). Le nom fourni par le noyau peut être vu en utilisant ip (dans votre cas, il s'agit de usb0 ). Utilisez dumpsys ou décompiler /system/framework/framework-res.apk mit apktool pour voir la valeur AOSP.

~$ dumpsys ethernet
...
  Ethernet interface name filter: eth\d
...

Dès qu'une interface Ethernet apparaît, Android la configure automatiquement, NetworkMonitor valide la connectivité et ConnectivityService désactive le WiFi et les données mobiles (s'ils sont activés). Les autres services et composants impliqués dans la configuration sont UsbHostManager , EthernetTracker , EthernetNetworkFactory , IpClient.eth0 , DhcpClient , DnsManager y Netd .

EthernetService a été ajouté dans Android 5. Avant cela, AOSP a été patché pour faire fonctionner Ethernet (voir par exemple este y este ). Android standard ne fournit toujours pas de paramètres GUI pour Ethernet, mais certains développeurs de ROM personnalisées et OEMs le font (voir par exemple este ). EthernetManager qui est utilisée pour régler et sauvegarder configuration IP manuelle (à /data/misc/ethernet/ipconfig.txt ) est caché . Par défaut, on utilise un configuration codée en dur (voir l'utilisation dumpsys ethernet sous "Configurations IP") ou Configuration fournie par DHCP .

CONFIGURATION MANUELLE

Vous pourriez vouloir faire une configuration manuelle du réseau, par exemple si :

  • Le framework Android ne configure pas l'interface Ethernet (sur les anciens appareils ou en raison d'une incohérence dans le nom de l'interface).
  • Vous voulez définir une adresse IP statique ou un serveur DNS différent.
  • Vous voulez utiliser l'Ethernet en même temps que le WiFi ou les données mobiles, ou vous voulez partager l'internet entre tous ces éléments.

Mais dans ce cas, la pile réseau Java d'Android reste hors service, de sorte que certaines applications dépendant des API d'Android peuvent ne pas se comporter normalement. Pour plus de détails, voir Se connecter au WiFi via ADB Shell .

# /system/etc/init/custom.rc

# Ethernet IP configuration service
service cust.eth_config /system/sbin/eth_config.sh
    seclabel u:r:magisk:s0
    disabled
    writepid /dev/cpuset/system-background/tasks

# clear routing and DNS
on property:init.svc.cust.eth_config=stopped
    exec u:r:magisk:s0 -- /system/sbin/eth_config.sh stop

#!/system/bin/sh

# /system/sbin/eth_config.sh script is executed from eth_config init service

# set PATH where you placed binaries
export PATH=/system/bin

IFACE=usb0                    # Ethernet interface name
DIR=/data/local/tmp/ethernet  # temporary directory
mkdir -p $DIR

# save log
exec >$DIR/eth_config.log 2>&1

if [ "$1" = stop ]
then
    echo "Clearing configuration..."
    ip ru del lookup main
    ip r f table main
    ndc resolver setnetdns 0 '' 0.0.0.0
    exit
fi

# destroy set network if any
ndc network default set 0

# turn WiFi and Mobile Data off
svc wifi disable
svc data disable

# set interfaces up
ip link set dev lo up
ip link set dev $IFACE up

# Android doesn't use main table by default
ip rule add lookup main

# set IP, route and DNS manually here
# or add any other IP/routing configuration
# or run a minimal DHCP client as follows

# create 'udhcpc' script
<<-'SCRIPT' cat >$DIR/udhcpc_default.script
#!/system/bin/sh

case $1 in
    bound|renew)
        echo "Setting IP address, gateway route and DNS for $interface..."
        ip address f dev $interface
        ip route f table main
        ip address add $ip/$mask dev $interface
        ip route add default via $router dev $interface
        ndc resolver setnetdns 0 '' $dns
    ;;
    *)
        echo "Ignoring $1"
    ;;
esac
SCRIPT

# start DHCP client to obtain IP from server
chmod 0755 $DIR/udhcpc_default.script
exec busybox udhcpc -v -f -i $IFACE -s $DIR/udhcpc_default.script

N'oubliez pas de définir les permissions appropriées sur .rc et des scripts shell. Une fois installé, Ethernet fonctionne dès que vous connectez l'adaptateur USB.

androidalle.com

AndroidAlle est une communauté de androiders où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X