5 votos

¿Cómo hacer que Ethernet funcione en Android a través de OTG?

Estoy intentando utilizar un módem LTE conectado a un dispositivo Android 7 a través de un cable OTG. El kernel reconoce el dispositivo y lo registra con cdc_ether pero no puedo utilizar la conexión desde el dispositivo. ¿Esto se debe a que se monta posteriormente como almacenamiento USB?

El dispositivo no aparece como tal en la barra de estado/UI de Android.

Si desactivo el soporte MTP, el dispositivo no se registrará cdc_ether en absoluto.

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 con el MTP desactivado:

[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

El dispositivo aparece como usb0 con la dirección MAC que figuraba en dmesg .

0 votos

pero no puedo utilizar la conexión desde el dispositivo ¿Cómo has probado a usarlo? Android no lo configurará (a menos que se añada una configuración personalizada a alguna de init 's .rc archivos), hay que hacerlo manualmente. ¿Aparece como una interfaz de red (compruebe con ip l o ifconfig )?

0 votos

gracias por la respuesta - he añadido los registros solicitados - ¿tiene un ejemplo de cómo añadir una entrada personalizada a los archivos init.rc? Puedo modificar la partición de arranque en este dispositivo

1 votos

Creo que usb0 es la interfaz. Sin embargo, puedes confirmarlo retirando el dongle. Puede configurar esta interfaz mediante ip comandos (configurar, establecer IP, añadir ruta, etc.). Pero el framework de Android no conocerá esta interfaz, por lo que algunas APIs informarán del dispositivo fuera de línea. Android no configura y gestiona los recursos de hardware directamente, sino a través de las HALs proporcionadas por el proveedor. Así que si quieres añadir un nuevo recurso de hardware, necesitas ejecutar su HAL como un servicio nativo. El framework de Android interactuaría con eso. En palabras sencillas, requiere reconstruir una ROM personalizada.

12voto

Jack Wade Puntos 231

Hay una larga lista de preguntas relacionadas con Ethernet, pero ninguna tiene una respuesta completa que cubra todos los aspectos. Estoy generalizando tu pregunta para compartir mis conocimientos al respecto.

Esto es lo que hay que hacer para que Ethernet funcione en Android:

  • Asegúrate de que el soporte OTG está disponible
  • El kernel debe ser construido con soporte para Ethernet (y USB Ethernet)
  • Manejar el cambio de modo USB y la carga de módulos del kernel (si procede)
  • Hacer que el framework de Android se encargue de la configuración de la red o hacerlo manualmente

Nota: Todo lo que se describe a continuación requiere una dispositivo rooteado o al menos el que tiene el bootloader desbloqueado.
Debe estar familiarizado con la interfaz de línea de comandos.


SOPORTE OTG

Su dispositivo debe ser capaz de funcionar en modo host USB. EthernetService es comenzó sólo si el dispositivo admite la función de host USB ( android.hardware.usb.host ) o Ethernet ( android.hardware.ethernet ). También puede ser necesario utilizar un concentrador USB alimentado si la fuente de alimentación USB de Android no es suficiente para el dispositivo conectado. Pregunta relacionada:

CONFIGURACIÓN DEL KERNEL

Para utilizar Ethernet sobre USB (adaptadores o dispositivos tipo módem) el núcleo debe construirse con CONFIG_USB_USBNET y otras configuraciones como USB_NET_CDCETHER , USB_NET_HUAWEI_CDC_NCM , USB_NET_CDC_MBIM etc. dependiendo del tipo de dispositivo conectado y del protocolo que hable. Preguntas relacionadas:

CAMBIO DE MODO USB Y CARGA DEL MÓDULO DEL KERNEL

Muchos dispositivos de red USB son multimodo o chancleta dispositivos. Aparecen como dispositivo de almacenamiento masivo USB (también llamado ZeroCD modo) cuando se insertan y necesitan ser cambiados al modo Ethernet/PPP. USB_ModeSwitch es una herramienta de Linux comúnmente utilizada para este propósito. Ver algunos detalles aquí cómo funciona. Usted necesita construir esta herramienta para su dispositivo, o puede descargar este binario para aarch64 . Obtener la base de datos de dispositivos de aquí .

Para cambiar automáticamente de modo cada vez que el dispositivo se conecta a Android, necesitamos escuchar el kernel USB uevents , ya sea a través de Ayuda para la conexión en caliente o un demonio del espacio de usuario (como udev en Linux y ueventd en Android). Además, el módulo del kernel también se puede cargar/descargar automáticamente. Yo definir un init servicio aquí para conseguirlo, también puedes hacerlo manualmente.

Nota: Hay una aplicación para Android Widget PPP (por el desarrollador de USB_ModeSwitch, no tengo ninguna afiliación) que maneja el cambio de modo automáticamente y necesita "no hay módulos de controlador del kernel, la implementación del "controlador" se basa en la API del host USB de Android" . También podría interesarle.

# /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

* En el caso de hotplug es necesario definir políticas de SELinux personalizadas para permitir que el kernel realice cambios (ver esta respuesta para más detalles).

#!/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

CONFIGURACIÓN DE LA RED

El marco de trabajo de Android tiene un nombre codificado para la interfaz Ethernet ( por defecto es eth0 , eth1 , ...). Cada vez que aparece una interfaz Ethernet, su el nombre coincide con con el valor codificado. Renombrar la interfaz después no funciona porque sólo núcleo proporcionado El nombre de la interfaz es rastreado .

Así que tienes que hacer que esta convención de nombres sea consistente entre el kernel y AOSP modificando uno de los dos (si es necesario). El nombre proporcionado por el kernel se puede ver usando ip herramienta (como en su caso es usb0 ). Utilice dumpsys o descompilar /system/framework/framework-res.apk utilizando apktool para ver el valor de la AOSP.

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

En cuanto aparece una interfaz Ethernet, Android la configura automáticamente, NetworkMonitor valida la conectividad y ConnectivityService desactiva el WiFi y los datos móviles (si están activados). Otros servicios y componentes que intervienen en la configuración son UsbHostManager , EthernetTracker , EthernetNetworkFactory , IpClient.eth0 , DhcpClient , DnsManager y Netd .

Servicio Ethernet se añadió en Android 5. Antes de eso AOSP fue parcheado para hacer funcionar Ethernet (por ejemplo, ver este y este ). Aún así, Android de serie no proporciona ninguna configuración de interfaz gráfica para Ethernet, pero algunos desarrolladores de ROMs personalizadas y OEMs sí lo hacen (por ejemplo, véase este ). EthernetManager que se utiliza para establecer y guardar configuración manual de IP (para /data/misc/ethernet/ipconfig.txt ) está oculto . Por defecto se utiliza un configuración de código duro (véase el uso de dumpsys ethernet en "Configuraciones IP:") o Configuración proporcionada por DHCP .

CONFIGURACIÓN MANUAL

Es posible que desee hacer la configuración manual de la red, por ejemplo, si:

  • El framework de Android no configura la interfaz Ethernet (en dispositivos antiguos o debido a la inconsistencia del nombre de la interfaz).
  • Desea establecer una dirección IP estática o un servidor DNS diferente.
  • Quieres usar Ethernet junto con WiFi o Datos Móviles, o quieres compartir Internet entre cualquiera de ellos.

Pero en este caso la pila de red Java de Android sigue sin funcionar, por lo que algunas aplicaciones que dependen de las API de Android pueden no comportarse con normalidad. Para obtener detalles relacionados, consulte Conexión a WiFi a través de 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

No olvides establecer los permisos adecuados en .rc y scripts de shell. Una vez configurado, Ethernet funciona tan pronto como se conecta el adaptador USB.

1 votos

@moderadores fusionarlo con alguna otra pregunta similar si es necesario.

0 votos

0 votos

Este parece ser precisamente el problema al que me enfrento. Pero no puedo entender cómo el usbX se ha renombrado como ethX ... ¿Podría dar más detalles?

PreguntAndroid.com

PreguntAndroid es una comunidad de usuarios de Android en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X