USB-драйвер Android-гаджета

Я пытаюсь заставить работать Ethernet через USB для своего Nexus S. Я использую Ice Cream Sandwich v4.0.3 и пересобрал ядро ​​с включенной поддержкой USB-гаджетов. Когда я подключаю телефон к своей машине с Linux и запускаю ifconfig -a, usb0 появляется как на телефоне, так и на машине с Linux. Я запускаю ifconfig для настройки обеих сторон, и все выглядит правильно, но я не могу выполнить ping ни с одной из сторон:

PING 192.168.22.2 (192.168.22.2) 56(84) bytes of data.
From 192.168.22.1 icmp_seq=1 Destination Host Unreachable
From 192.168.22.1 icmp_seq=2 Destination Host Unreachable

У меня также есть N900 с Maemo Linux, который поддерживает Ethernet через USB. Я сравнил вывод ethtool, ifconfig, route и arp между N900 и Nexus S, и все они очень похожи, за исключением вывода arp. Он показывает (неполный) для HWAddress для подключения Android:

Address                  HWtype  HWaddress           Flags Mask            Iface
10.1.3.1                 ether   00:1B:17:05:30:13   C                     eth0
192.168.22.2                     (incomplete)                              usb0

Единственная другая подсказка, которую я имею, это то, что ifconfig показывает на стороне Linux:

usb0      Link encap:Ethernet  HWaddr 66:E4:64:10:D1:A9  
      inet addr:192.168.22.1  Bcast:192.168.22.255  Mask:255.255.255.0
      inet6 addr: fe80::64e4:64ff:fe10:d1a9/64 Scope:Link
      UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
      RX packets:0 errors:0 dropped:0 overruns:0 frame:0
      TX packets:42 errors:0 dropped:0 overruns:0 carrier:0
      collisions:0 txqueuelen:1000 
      RX bytes:0 (0.0 b)  TX bytes:9039 (8.8 KiB)

и на стороне Android:

usb0      Link encap:Ethernet  HWaddr 7A:78:28:52:9C:A0
      inet addr:192.168.22.2 Bcast:192.168.22.255 Mask:255.255.255.0
      inet6 addr: fe80::7878:28ff:fe52:9ca0/64 Scope:Link
      UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
      RX packets:202 errors:0 dropped:202 overruns:0 frame:0
      TX packets:36 errors:0 dropped:0 overruns:0 carrier:0
      collisions:0 txqueuelen:1000
      RX bytes:47294 (46.1 KiB)  TX bytes:1728 (1.6 KiB)

Обратите внимание на отброшенные пакеты на стороне Android.

Кажется, я почти у цели... какие-нибудь предложения?

РЕДАКТИРОВАТЬ:

Я пересобрал ядро ​​с помощью модуля ядра гаджета (я пробовал и g_cdc, и g_ether) вместо встроенной поддержки. Я не уверен, связано ли следующее с этим или просто не синхронизировано в моем предыдущем посте. Если я запускаю ping с любой стороны, номера TX и RX фактически совпадают с обеих сторон, но сторона Android по какой-то причине их отбрасывает.

Хост-сторона ifconfig:

usb0      Link encap:Ethernet  HWaddr 12:23:34:45:56:67  
      inet addr:192.168.22.1  Bcast:192.168.22.255  Mask:255.255.255.0
      inet6 addr: fe80::1023:34ff:fe45:5667/64 Scope:Link
      UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
      RX packets:33 errors:0 dropped:0 overruns:0 frame:0
      TX packets:734 errors:0 dropped:0 overruns:0 carrier:0
      collisions:0 txqueuelen:1000 
      RX bytes:1140 (1.1 KiB)  TX bytes:37684 (36.8 KiB)

Сторона Android ifconfig:

usb0      Link encap:Ethernet  HWaddr 5E:89:C6:D8:BC:08  
      inet addr:192.168.22.2  Bcast:192.168.22.255  Mask:255.255.255.0
      inet6 addr: fe80::5c89:c6ff:fed8:bc08/64 Scope:Link
      UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
      RX packets:734 errors:0 dropped:734 overruns:0 frame:0
      TX packets:33 errors:0 dropped:0 overruns:0 carrier:0
      collisions:0 txqueuelen:1000 
      RX bytes:27408 (26.7 KiB)  TX bytes:1602 (1.5 KiB)

ЕЩЕ ОДНА РЕДАКЦИЯ!!

После использования arp на стороне хоста и ip на стороне Android для ручного добавления записей ошибки Destination Host Unreachable исчезли, но по-прежнему нет ответа на ping. Я запустил Wireshark на хосте, и сообщения с устройства неверны. Отображаемые MAC-адреса выглядят неправильно, а протокол неизвестен, поэтому просто отображается как 0x7aab. После просмотра фактических данных в сообщении оказывается, что к сообщению добавлены два нулевых байта. Если бы их убрать, вроде бы все заработало. Кто-нибудь когда-либо видел это или знает, где в коде это можно исправить?

ЕЩЕ ОДНА РЕДАКЦИЯ!!!

После загрузки всего этим утром я не стал создавать фальшивые записи ARP и снова запустил ping. Согласно Wireshark, от хоста пришло сообщение ARP, а от Droid пришло неизвестное сообщение, но они были одинаковой длины. Изучив содержимое сообщений, Droid также отправил то, что выглядело как действительное сообщение ARP, но оно было сдвинуто на 2 байта — два дополнительных байта в начале и два последних обрезанных.

Какова топология между устройствами? устройство-устройство? или ты переходишь через коммутатор? если это устройство к устройству, какой кабель вы используете?
Я использую стандартный кабель micro-usb, который шел в комплекте с телефоном, поэтому устройство-устройство.

Ответы (1)

Похоже, есть проблема с выравниванием байтов. Я нашел этот пост:

http://www.mail-archive.com/linux-omap@vger.kernel.org/msg20797.html

и исходя из этого внес следующие изменения в drivers/usb/gadget/u_ether.c:

257,258c257
< 
<   //skb_reserve(skb, NET_IP_ALIGN);
---
>   skb_reserve(skb, NET_IP_ALIGN);
513d511
<         int                     i=0;
599,606d596
< 
< if ((int)skb->data & 0x2) {
<   skb_push(skb, 2);
<   for (i=0; i<length; i++) {
<     skb->data[i] = skb->data[i+2];
<   }
< }
< 

Теперь я могу пинговать в обоих направлениях через USB. Если кто-нибудь знает лучший способ решить эту проблему, пожалуйста, дайте мне знать, иначе я пойду с этим.