Рейтинг:1

Настройка USB-сети между Android и встроенным Linux

флаг lk

Сейчас я работаю над проектом, в котором у нас есть встроенная система Linux с некоторыми функциями управления датчиками/двигателями, и мы создаем приложение с графическим интерфейсом, позволяющее пользователю управлять системой. В будущем мы можем запускать оба приложения в одной системе, но на данный момент мы хотим иметь возможность установить это как обновление для существующих машин, а существующие платы контроллеров не имеют возможности запускать графический интерфейс как он разработан, поэтому он будет работать на отдельном SBC (в настоящее время мы создаем прототип с ODroid C4 под управлением Android 9)

Мы разработали API связи между двумя системами, и я провел начальное тестирование, запустив прямое соединение Ethernet между двумя системами со статическими IP-адресами, однако из-за требований к развертыванию и ограничений Android мне нужно выяснить другой метод подключения для фактического развертывания продукта. Нам нужно, чтобы клиент мог подключаться к Интернету в системе с графическим интерфейсом через Wi-Fi или Ethernet, поэтому встроенный порт Ethernet на ODroid не может использоваться для этой цели, и, кроме того, ядро ​​​​Android имеет некоторое внутреннее поведение. это позволяет только одному сетевому соединению быть активным в любой момент времени.

Исключением из правил определения приоритетов сети Android являются сетевые интерфейсы USB. И система контроллера Linux, и само устройство Android могут отображаться как сетевой интерфейс для удаленного хоста — в системе контроллера у нас есть доступный USB-порт для гаджета, и я включил g_эфир модуль ядра в нашем образе системы, а в системе с графическим интерфейсом у нас есть порт USB OTG, и я могу включить USB-модем в настройках системы Android.

Мне удалось установить связь между любой из этих систем и моей системой разработки Windows, используя их соответствующие интерфейсы, но я до сих пор не понял, как заставить одно решение взаимодействовать с другим.

Система Linux в качестве удаленного интерфейса (USB-гаджет с драйвером g_ether)

  • Загрузка модуля ядра g_ether в системе Linux создает usb0 интерфейс:
# modprobe g_ether
# есликонфиг
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
        инет 10.42.128.107 сетевая маска 255.255.255.0 широковещательная рассылка 10.42.128.255
        inet6 fe80::206:cff:fe01:1027 prefixlen 64 scopeid 0x20<ссылка>
        эфир 00:06:0c:01:10:27 txqueuelen 1000 (Ethernet)
        RX-пакеты 500 байт 54062 (52,7 КиБ)
        Ошибки RX 0 отброшено 46 переполнение 0 кадр 0
        Пакеты TX 0 байт 24423 (23,8 КиБ)
        Ошибки передачи 0 отброшено 0 превышение пропускной способности 0 несущей 0 коллизий 0

lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
        инет 127.0.0.1 сетевая маска 255.0.0.0
        inet6 ::1 prefixlen 128 scopeid 0x10<хост>
        loop txqueuelen 0 (локальная петля)
        Пакеты RX 0 байт 0 (0,0 Б)
        Ошибки RX 0 отброшено 0 переполнение 0 кадр 0
        Пакеты TX 0 байт 0 (0,0 Б)
        Ошибки передачи 0 отброшено 0 превышение пропускной способности 0 несущей 0 коллизий 0

usb0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
        inet6 fe80::24b:5bfc:8a9e:b148 prefixlen 64 scopeid 0x20<ссылка>
        эфир 9a:8c:fa:85:ec:a1 txqueuelen 1000 (Ethernet)
        Пакеты RX 0 байт 0 (0,0 Б)
        Ошибки RX 0 отброшено 0 переполнение 0 кадр 0
        Пакеты TX 1 байт 96 (96,0 Б)
        Ошибки передачи 0 отброшено 0 превышение пропускной способности 0 несущей 0 коллизий 0
  • Подключение USB-кабеля от порта гаджета в системе Linux к хост-порту в системе Android немедленно создает usb0 интерфейс на Android и генерирует IP-адрес для usb0 интерфейс в линуксе:

Андроид:

odroidc4:/ # ifconfig usb0
usb0 Link encap:Ethernet HWaddr fa:4c:95:c0:8d:18 Драйвер cdc_subset
          МУЛЬТИКАНСИРОВАННАЯ ТРАНСЛЯЦИЯ MTU: 1500 Метрика: 1
          Пакеты RX: 0 ошибки: 0 отброшены: 0 переполнение: 0 кадр: 0
          Пакеты TX: 0 ошибки: 0 отброшены: 0 переполнения: 0 оператор: 0
          коллизии: 0 txqueuelen: 1000
          Байты RX:0 Байты TX:0

Линукс:

# если конфиг usb0
usb0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
        инет 169.254.119.94 сетевая маска 255.255.0.0 широковещательная рассылка 169.254.255.255
        inet6 fe80::24b:5bfc:8a9e:b148 prefixlen 64 scopeid 0x20<ссылка>
        эфир 9a:8c:fa:85:ec:a1 txqueuelen 1000 (Ethernet)
        Пакеты RX 0 байт 0 (0,0 Б)
        Ошибки RX 0 отброшено 0 переполнение 0 кадр 0
        Пакеты TX 1 байт 96 (96,0 Б)
        Ошибки передачи 0 отброшено 0 превышение пропускной способности 0 несущей 0 коллизий 0
  • При открытии интерфейса в системе Android не назначается IP-адрес, поэтому мне приходится назначать его вручную, используя пространство 169.254/16, которое система Linux назначает самостоятельно.
odroidc4:/ # ifconfig usb0 up
odroidc4:/ # ifconfig usb0
usb0 Link encap:Ethernet HWaddr fa:4c:95:c0:8d:18 Драйвер cdc_subset
          адрес inet6: fe80::f84c:95ff:fec0:8d18/64 Область действия: ссылка
          ВВЕРХ ТРАНСЛЯЦИЯ РАБОТАЕТ MULTICAST MTU:1500 Метрика:1
          Пакеты RX: 117, ошибки: 4, отброшенные: 75, переполнение: 0, кадр: 4.
          Пакеты TX: 27, ошибки: 0, отброшенные: 0, превышения: 0, носитель: 0.
          коллизии: 0 txqueuelen: 1000
          Байты RX: 5080 Байты TX: 4897

odroidc4:/ # ip addr add 169.254.1.1/16 широковещательный 169.254.255.255 dev usb0
odroidc4:/ # ifconfig usb0
usb0 Link encap:Ethernet HWaddr fa:4c:95:c0:8d:18 Драйвер cdc_subset
          инет адрес: 169.254.1.1 Bcast: 169.254.255.255 Маска: 255.255.0.0
          адрес inet6: fe80::f84c:95ff:fec0:8d18/64 Область действия: ссылка
          ВВЕРХ ТРАНСЛЯЦИЯ РАБОТАЕТ MULTICAST MTU:1500 Метрика:1
          Пакеты RX: 117, ошибки: 4, отброшенные: 75, переполнение: 0, кадр: 4.
          Пакеты TX: 44 ошибки: 0 отброшены: 0 переполнены: 0 перевозчик: 0
          коллизии: 0 txqueuelen: 1000
          Байты RX: 5080 Байты TX: 8528

На данный момент у меня есть 2 проблемы: во-первых, пинг любого устройства с другого не дает ответа. Глядя на количество пакетов на стороне Android, создается впечатление, что он получает эхо-запросы со стороны Linux, но не отвечает, что может быть вызвано второй проблемой, заключающейся в том, что таблицы маршрутизации не работают должным образом. на стороне андроида. Учитывая, что мне нужно, чтобы это работало, когда в системе Android также есть активное подключение к Интернету, у меня одновременно подключен Ethernet, и это то, что я вижу при просмотре маршрутизации:

odroidc4:/ # список маршрутов ip
169.254.0.0/16 dev usb0 ссылка на область ядра proto src 169.254.1.1
10.42.128.0/24 dev eth0 прото-область ядра ссылка src 10.42.128.166
odroidc4:/ # ip route get 169.254.119.94
169.254.119.94 через 10.42.128.2 dev eth0 таблица eth0 src 10.42.128.166 uid 0
    тайник
odroidc4:/ # ip route show table 0
по умолчанию через 10.42.128.2 dev eth0 table eth0 proto static
...

Система Android в качестве удаленного интерфейса (USB-модем с портом OTG)

Этот сценарий, кажется, немного приближает меня, поскольку я могу заставить работать одностороннюю связь.

  • После добавления необходимых драйверов в мой образ Linux, подключение кабеля от порта Android OTG к порту хоста Linux показывает, что система распознает USB-устройство в dmesg:
[235.710937] usb 1-2.3: новое полноскоростное USB-устройство номер 7 с использованием at91_ohci
[ 235.862304] rndis_host 1-2.3:1.0 usb0: зарегистрируйте 'rndis_host' на usb-at91-2.3, устройство RNDIS, 32:1d:e8:fc:dd:8
  • А usb0 интерфейс немедленно создается и ему назначается IP-адрес на стороне Linux:
# если конфиг usb0
usb0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
        инет 169.254.249.80 сетевая маска 255.255.0.0 широковещательная рассылка 169.254.255.255
        inet6 fe80::e341:f9b1:b676:99b7 prefixlen 64 scopeid 0x20<ссылка>
        эфир 32:1d:e8:fc:dd:80 txqueuelen 1000 (Ethernet)
        RX-пакеты 69 байт 13572 (13,2 КиБ)
        Ошибки RX 0 отброшено 0 переполнение 0 кадр 0
        Пакеты TX 73 байта 18251 (17,8 КиБ)
        Ошибки передачи 8 отброшено 0 превышение пропускной способности 0 несущей 0 коллизий 0
  • На стороне Android с включенным USB-модемом в настройках появляется интерфейс usb0, но начинается вниз. Поднятие этого не дает ему IP-адрес, поэтому я назначил его вручную, но, как и в первом сценарии, таблица маршрутизации не работает должным образом:
odroidc4:/ # ifconfig usb0
usb0 Link encap:Ethernet HWaddr de:75:5c:41:2a:e6
          МУЛЬТИКАНСИРОВАННАЯ ТРАНСЛЯЦИЯ MTU: 1500 Метрика: 1
          Пакеты RX: 0 ошибки: 0 отброшены: 0 переполнение: 0 кадр: 0
          Пакеты TX: 0 ошибки: 0 отброшены: 0 переполнения: 0 оператор: 0
          коллизии: 0 txqueuelen: 1000
          Байты RX:0 Байты TX:0
odroidc4:/ # ifconfig usb0 up
odroidc4:/ # ifconfig usb0
usb0 Link encap:Ethernet HWaddr de:75:5c:41:2a:e6
          адрес inet6: fe80::dc75:5cff:fe41:2ae6/64 Область действия: ссылка
          ВВЕРХ ТРАНСЛЯЦИЯ РАБОТАЕТ MULTICAST MTU:1500 Метрика:1
          RX-пакетов: 10 ошибок: 0 отброшено: 0 превышено: 0 кадр: 0
          Пакеты TX: 12, ошибки: 0, отброшенные: 0, переполнение: 0, носитель: 0.
          коллизии: 0 txqueuelen: 1000
          Байты RX: 1090 Байты TX: 2751
odroidc4:/ # ip addr add 169.254.1.1/16 широковещательный 169.254.255.255 dev usb0
odroidc4:/ # ip-маршрут
10.42.128.0/24 dev eth0 прото-область ядра ссылка src 10.42.128.166
169.254.0.0/16 dev usb0 ссылка на область ядра proto src 169.254.1.1
odroidc4:/ # ip route get 169.254.249.80
169.254.249.80 через 10.42.128.2 dev eth0 таблица eth0 src 10.42.128.166 uid 0
    тайник
  • Однако в этом случае я могу получить успешную связь со стороны Android, вручную указав интерфейс:
odroidc4:/ # ping -c 5 -I usb0 169.254.249.80
PING 169.254.249.80 (169.254.249.80) от 169.254.1.1 usb0: 56(84) байт данных.
64 байта от 169.254.249.80: icmp_seq=1 ttl=64 время=1,56 мс
64 байта от 169.254.249.80: icmp_seq=2 ttl=64 время=1,89 мс
64 байта от 169.254.249.80: icmp_seq=3 ttl=64 время=1,71 мс
64 байта от 169.254.249.80: icmp_seq=4 ttl=64 время=1,75 мс
64 байта от 169.254.249.80: icmp_seq=5 ttl=64 время=1,85 мс

--- Статистика пинга 169.254.249.80 ---
5 пакетов передано, 5 получено, 0% потери пакетов, время 4006 мс
2|odroidc4:/ # ping6 -c5 ff02::1%usb0
PING ff02::1%usb0(ff02::1) 56 байт данных
64 байта из fe80::dc75:5cff:fe41:2ae6: icmp_seq=1 ttl=64 time=0,202 мс
64 байта от fe80::e341:f9b1:b676:99b7: icmp_seq=1 ttl=64 time=1,91 мс (DUP!)
64 байта из fe80::dc75:5cff:fe41:2ae6: icmp_seq=2 ttl=64 time=0,196 мс
64 байта из fe80::e341:f9b1:b676:99b7: icmp_seq=2 ttl=64 time=1,80 мс (DUP!)
64 байта от fe80::dc75:5cff:fe41:2ae6: icmp_seq=3 ttl=64 time=0,199 мс
64 байта из fe80::e341:f9b1:b676:99b7: icmp_seq=3 ttl=64 time=1,37 мс (DUP!)
64 байта от fe80::dc75:5cff:fe41:2ae6: icmp_seq=4 ttl=64 time=0,199 мс
64 байта из fe80::e341:f9b1:b676:99b7: icmp_seq=4 ttl=64 time=1,85 мс (DUP!)
64 байта из fe80::dc75:5cff:fe41:2ae6: icmp_seq=5 ttl=64 time=0,205 мс

--- статистика пинга ff02::1%usb0 ---
5 пакетов передано, 5 получено, +4 дубликата, 0% потери пакетов, время 4004 мс
rtt min/avg/max/mdev = 0,196/0,883/1,914/0,776 мс
  • Я все еще не могу заставить работать трафик, исходящий со стороны Linux, предположительно из-за проблемы маршрутизации на стороне Android, препятствующей правильной маршрутизации обратного трафика:
# ping -c 5 -I usb0 169.254.1.1
PING 169.254.1.1 (169.254.1.1) от 169.254.249.80 usb0: 56 (84) байт данных.

--- Статистика пинга 169.254.1.1 ---
5 пакетов передано, 0 получено, 100% потери пакетов, время 4295 мс
# ping6 -c 5 ff02::1%usb0
PING ff02::1%usb0(ff02::1) 56 байт данных
64 байта из fe80::e341:f9b1:b676:99b7: icmp_seq=1 ttl=64 time=0,522 мс
64 байта из fe80::e341:f9b1:b676:99b7: icmp_seq=2 ttl=64 time=0,302 мс
64 байта из fe80::e341:f9b1:b676:99b7: icmp_seq=3 ttl=64 time=0,376 мс
64 байта из fe80::e341:f9b1:b676:99b7: icmp_seq=4 ttl=64 time=0,383 мс
64 байта из fe80::e341:f9b1:b676:99b7: icmp_seq=5 ttl=64 time=0,385 мс

--- статистика пинга ff02::1%usb0 ---
5 пакетов передано, 5 получено, 0% потери пакетов, время 4009 мс
rtt min/avg/max/mdev = 0,302/0,393/0,522/0,074 мс

В обоих сценариях похоже, что корень проблемы заключается в том, что таблица маршрутизации на стороне Android неправильно маршрутизирует трафик через интерфейс USB, а сторона Android не назначает IP-адрес автоматически, в то время как сторона Linux делает это. С интерфейсом гаджета Linux / хостом Android я могу в некоторой степени понять эти проблемы, но с привязкой порта Android OTG / хостом Linux я ожидаю, что он будет правильно маршрутизироваться, поскольку система Android контролирует подключение модема.

Рейтинг:0
флаг um

Привет @rdowell,

Чтобы решить эту проблему, необходимо добавить основную таблицу маршрутов на Android-устройство:

ip правило добавить из всего поиска main pref 1

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.