2016年12月30日 星期五

Wifi + Ethernet workable at the same time on Android

Android 6.0 + kernel 4.4 on Upboard
(Thank Bruce and Solar for help)
Wifi + Ethernet can't workable at the same time on Android, even we use "ifconfig" to setting.

Upboard Setting:
ip :
eth0    inet addr:192.168.1.20  Bcast:192.168.1.255  Mask:255.255.255.0
wlan0   inet addr:172.20.10.5   Bcast:172.20.10.15   Mask:255.255.255.240
route :
待補

PC(linux) Setting:
ip :
eth0    inet addr:192.168.1.21  Bcast:192.168.1.255  Mask:255.255.255.0
We can use "$ping -I eth0 192.168.1.21" to get response from Upboard to PC, but if we use "$ping 192.168.1.21" it can't get any response.
According the above description here we come to the conclusion. We need to specify the interface so it can transmit the package successfully.

sample code: ref : stackoverflow
(sender.c and listener.c)
#include <netinet/in.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define PORT  12345
#define SERVER_ADDR "192.168.1.20"

int main(int argc, char *argv[])
{
    int fd, nbytes;
    char message[16];
    struct sockaddr_in addr;

    if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
     perror("socket");
  return -1;
    }

    strncpy(message, argv[1], sizeof(message));

    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr(SERVER_ADDR);
    addr.sin_port = htons(PORT);

    const char device[] = "eth0";
    if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, device, sizeof(device)) < 0) {
        perror("SO_BINDTODEVICE");
  return -1;
    }
    while (1) {
        if ((nbytes = sendto(fd, message, strlen(message), 0, 
                   (struct sockaddr *) &addr, sizeof(addr))) < 0) {
         perror("sendto");
   return -1;
     }
     usleep(1000*1000);
    }
}
Android/PC run the program, PC/Android run tcpdump, it should get packages. But...the program need root permission if you want to run Android App. = ="

7 則留言:

  1. 这是一个不错的方法,但是有些Android设备在边上WiFi时会将eth0 down,反之连接上以太网时会将WiFi down,这种情况就不太好办了。

    回覆刪除
    回覆
    1. 我Android6.0剛好就是這樣的問題,請問這會有蹶決方法嗎?

      刪除
    2. 大致思路有两个,一个是连接上WiFi后,自己手动再ifconfig eth0 up,然后设置IP,这样系统不会tear down eth0了,这个eth0也可以使用了。还有一个思路需要改ROM源码,改得系统不再去tear down其它网卡设备,在这里有大致的描述:https://blog.csdn.net/kangear/article/details/14446527

      刪除
    3. 那篇是應用在Android4.2,而我Android6.0架構不一樣了,但我也有在ConnectivityService更改code,所以ifconfig裡的eth0和wlan0都是up的。

      但問題是我無法內外網都能ping ,必須要指定該網段就走該介面。(自行adb更改路由表)

      例如: 可以ping -I eth0 "同eth0的網段"、也可以ping -I wlan0 "同wlan0的網段",但無法同時直接 ping "同eth0的網段"、ping "同wlan0的網段" (只能取其一,這跟連線的先後順序有關)。

      但我adb另外自行下這指令似乎能解決 ip rule add from all lookup main pref 99 。請問還有甚麼好的解決方法嗎?還是只能往底層追呢?謝謝

      刪除
    4. ip rule add from all lookup main pref 99
      > 这个问题还没有遇到
      同时ping内外网
      > 我尝试添加过默认路由表,但是也不行,也是需要加-I才能ping这本身很奇怪,感觉是内核的问题,同一个板子,如要跑纯Linux是可以实现的,Android内核就不行。
      https://blog.csdn.net/kangear/article/details/79908100

      刪除
    5. 还是路由表的问题,Android使用的路由表并不是busybox route命令查看到的那个,这里有记录,已经实现了同时ping通两个网段了。:P
      https://blog.csdn.net/kangear/article/details/80547073

      刪除
  2. 作者已經移除這則留言。

    回覆刪除