EthernetNative 和 android_net_ethernet.cpp

来源:互联网 发布:阿里云的机房 编辑:程序博客网 时间:2024/04/30 23:48

Lamdoc船长的宝藏http://blog.csdn.net/lamdoc/article/details/7690230

除了android_net_netutils.cpp 外 还有一个JNI : android_net_ethernet.cpp

1. frameworks/base/ethernet/java/android/net/ethernet/EthernetNative.java 代码会调用这个JNI

[java] view plaincopyprint?
  1. package android.net.ethernet;  
  2.   
  3. /** 
  4.  * Native calls for sending requests to the kernel, 
  5.  * {@hide} 
  6.  */  
  7. public class EthernetNative {  
  8.     public native static String getInterfaceName(int i); //get eth0, sit0  
  9.     public native static int getInterfaceCnt();  //  
  10.     public native static int initEthernetNative();   
  11.     public native static String waitForEvent();  
  12. }  

2. JNINativeMethod gEthernetMethods[]:

[cpp] view plaincopyprint?
  1. static JNINativeMethod gEthernetMethods[] = {  
  2.     {"waitForEvent""()Ljava/lang/String;",  
  3.      (void *)android_net_ethernet_waitForEvent},  
  4.     {"getInterfaceName""(I)Ljava/lang/String;",  
  5.      (void *)android_net_ethernet_getInterfaceName},  
  6.     {"initEthernetNative""()I",  
  7.      (void *)android_net_ethernet_initEthernetNative},  
  8.     {"getInterfaceCnt","()I",  
  9.      (void *)android_net_ethernet_getInterfaceCnt}  
  10. };  

3. AndroidRuntime 运行时,会注册 这个NativeMethod:

[cpp] view plaincopyprint?
  1.     int register_android_net_ethernet_EthernetManager(JNIEnv* env)  
  2.     {  
  3.         jclass eth = env->FindClass(ETH_PKG_NAME);  
  4.         LOGI("Loading ethernet jni class");  
  5.         LOG_FATAL_IF(eth == NULL, "Unable to find class " ETH_PKG_NAME);  
  6.         dhcpInfoFieldIds.dhcpInfoClass =  
  7.             env->FindClass("android/net/DhcpInfo");  
  8.   
  9.         if (dhcpInfoFieldIds.dhcpInfoClass != NULL) {  
  10.             dhcpInfoFieldIds.constructorId =  
  11.                 env->GetMethodID(dhcpInfoFieldIds.dhcpInfoClass,  
  12.                                  "<init>""()V");  
  13.             dhcpInfoFieldIds.ipaddress =  
  14.                 env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass,  
  15.                                 "ipAddress""I");  
  16.             dhcpInfoFieldIds.gateway =  
  17.                 env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass,  
  18.                                 "gateway""I");  
  19.             dhcpInfoFieldIds.netmask =  
  20.                 env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass,  
  21.                                 "netmask""I");  
  22.             dhcpInfoFieldIds.dns1 =  
  23.                 env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "dns1""I");  
  24.             dhcpInfoFieldIds.dns2 =  
  25.                 env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "dns2""I");  
  26.             dhcpInfoFieldIds.serverAddress =  
  27.                 env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass,  
  28.                                 "serverAddress""I");  
  29.             dhcpInfoFieldIds.leaseDuration =  
  30.                 env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass,  
  31.                                 "leaseDuration""I");  
  32.         }  
  33.   
  34.         //注册gEthernetMethods[]   
  35.         return AndroidRuntime::registerNativeMethods(env,  
  36.                                                      ETH_PKG_NAME,  
  37.                                                      gEthernetMethods,  
  38.                                                      NELEM(gEthernetMethods));  
  39.     }<SPAN style="COLOR: #ff0000"><STRONG><SPAN style="FONT-SIZE: 16px">  
  40. </SPAN></STRONG></SPAN>  

4. waitForEvent():

[cpp] view plaincopyprint?
  1. static jstring android_net_ethernet_waitForEvent(JNIEnv *env, jobject clazz)  
  2. {  
  3.     char *buff;  
  4.     struct nlmsghdr *nh;  
  5.     struct ifinfomsg *einfo;  
  6.     struct iovec iov;  
  7.     struct msghdr msg;  
  8.     char *result = NULL;  
  9.     char rbuf[4096];  
  10.     unsigned int left;  
  11.     interface_info_t *info;  
  12.     int len;  
  13.   
  14.     LOGV("Poll events from ethernet devices");  
  15.     /* 
  16.      *wait on uevent netlink socket for the ethernet device 
  17.      */  
  18.     buff = (char *)malloc(NL_POLL_MSG_SZ);  
  19.     if (!buff) {  
  20.         LOGE("Allocate poll buffer failed");  
  21.         goto error;  
  22.     }  
  23.   
  24.     iov.iov_base = buff;  
  25.     iov.iov_len = NL_POLL_MSG_SZ;  
  26.     msg.msg_name = (void *)&addr_msg;  
  27.     msg.msg_namelen =  sizeof(addr_msg);  
  28.     msg.msg_iov =  &iov;  
  29.     msg.msg_iovlen =  1;  
  30.     msg.msg_control =  NULL;  
  31.     msg.msg_controllen =  0;  
  32.     msg.msg_flags =  0;  
  33.   
  34.     if ((len = recvmsg(nl_socket_poll, &msg, 0)) >= 0) {  
  35.         LOGV("recvmsg get data");  
  36.         result = rbuf;  
  37.         left = 4096;  
  38.         rbuf[0] = '\0';  
  39.         for (nh = (struct nlmsghdr *) buff; NLMSG_OK (nh, len);  
  40.              nh = NLMSG_NEXT (nh, len)) {  
  41.   
  42.             if (nh->nlmsg_type == NLMSG_DONE) {  
  43.                 LOGE("Did not find useful eth interface information");  
  44.                 goto error;  
  45.             }  
  46.   
  47.             if (nh->nlmsg_type == NLMSG_ERROR) {  
  48.                 /* Do some error handling. */  
  49.                 LOGE("Read device name failed");  
  50.                 goto error;  
  51.             }  
  52.   
  53.             LOGV(" event :%d  found", nh->nlmsg_type);  
  54.             einfo = (struct ifinfomsg *)NLMSG_DATA(nh);  
  55.             LOGV("the device flag :%X", einfo->ifi_flags);  
  56.             if (nh->nlmsg_type == RTM_DELLINK ||  
  57.                 nh->nlmsg_type == RTM_NEWLINK ||  
  58.                 nh->nlmsg_type == RTM_DELADDR ||  
  59.                 nh->nlmsg_type == RTM_NEWADDR) {  
  60.                 int type = nh->nlmsg_type;  
  61.                 if (type == RTM_NEWLINK &&  
  62.                     (!(einfo->ifi_flags & IFF_LOWER_UP))) {  
  63.                     type = RTM_DELLINK;  
  64.                 }  
  65.                 if ((info = find_info_by_index  
  66.                       (((struct ifinfomsg*) NLMSG_DATA(nh))->ifi_index)) != NULL)  
  67.                     snprintf(result,left, "%s:%d:",info->name,type);  
  68.                 left = left - strlen(result);  
  69.                 result =(char *)(result+ strlen(result));  
  70.             }  
  71.   
  72.         }  
  73.         LOGV("Done parsing");  
  74.         rbuf[4096 - left] = '\0';  
  75.         LOGV("poll state :%s, left:%d", rbuf, left);  
  76.     }  
  77.   
  78.   
  79. error:  
  80.     free(buff);  
  81.     return env->NewStringUTF(rbuf);  
  82. }  

[cpp] view plaincopyprint?
  1. <SPAN style="COLOR: #ff0000"><STRONG><SPAN style="FONT-SIZE: 16px">  
  2. 5. initEthernetNative():</SPAN></STRONG></SPAN><PRE class=java name="code">    static jint android_net_ethernet_initEthernetNative(JNIEnv *env,  
  3.                                                         jobject clazz)  
  4.     {  
  5.         int ret = -1;  
  6.   
  7.     LOGI("==>%s",__FUNCTION__);  
  8.         memset(&addr_msg, 0, sizeof(sockaddr_nl));  
  9.         addr_msg.nl_family = AF_NETLINK;  
  10.         memset(&addr_poll, 0, sizeof(sockaddr_nl));  
  11.         addr_poll.nl_family = AF_NETLINK;  
  12.         addr_poll.nl_pid = 0;//getpid();   
  13.         addr_poll.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR;  
  14.   
  15.         /* 
  16.          *Create connection to netlink socket 
  17.          */  
  18.         nl_socket_msg = socket(AF_NETLINK,SOCK_RAW,NETLINK_ROUTE);  
  19.         if (nl_socket_msg <= 0) {  
  20.             LOGE("Can not create netlink msg socket");  
  21.             goto error;  
  22.         }  
  23.         if (bind(nl_socket_msg, (struct sockaddr *)(&addr_msg),  
  24.                  sizeof(struct sockaddr_nl))) {  
  25.             LOGE("Can not bind to netlink msg socket");  
  26.             goto error;  
  27.         }  
  28.   
  29.         nl_socket_poll = socket(AF_NETLINK,SOCK_RAW,NETLINK_ROUTE);  
  30.         if (nl_socket_poll <= 0) {  
  31.             LOGE("Can not create netlink poll socket");  
  32.             goto error;  
  33.         }  
  34.   
  35.         errno = 0;  
  36.         if (bind(nl_socket_poll, (struct sockaddr *)(&addr_poll),  
  37.                 sizeof(struct sockaddr_nl))) {  
  38.             LOGE("Can not bind to netlink poll socket,%s", strerror(errno));  
  39.   
  40.             goto error;  
  41.         }  
  42.   
  43.         if ((ret = netlink_init_interfaces_list()) < 0) {  
  44.             LOGE("Can not collect the interface list");  
  45.             goto error;  
  46.         }  
  47.         LOGE("%s exited with success", __FUNCTION__);  
  48.         return ret;  
  49.   
  50.     error:  
  51.         LOGE("%s exited with error", __FUNCTION__);  
  52.         if (nl_socket_msg > 0)  
  53.             close(nl_socket_msg);  
  54.         if (nl_socket_poll > 0)  
  55.             close(nl_socket_poll);  
  56.         return ret;  
  57.     }  
  58. </PRE><SPAN style="COLOR: #ff0000; FONT-SIZE: 16px"><STRONG><BR>  
  59. 6. getInterfaceName() 和 getInterfaceCnt():</STRONG></SPAN><BR>  
  60. <PRE class=cpp name="code">    static jstring android_net_ethernet_getInterfaceName(JNIEnv *env,  
  61.                                                          jobject clazz,  
  62.                                                          jint index)  
  63.     {  
  64.         int i = 0;  
  65.         interface_info_t *info;  
  66.         LOGI("User ask for device name on %d, list:%X, total:%d",  
  67.              index, (unsigned int)interfaces, total_int);  
  68.         info = interfaces;  
  69.         if (total_int != 0 && index <= (total_int - 1)) {  
  70.             while (info) {  
  71.                 if (index == i) {  
  72.                     LOGV("Found: %s", info->name);  
  73.                     return env->NewStringUTF(info->name);  
  74.                 }  
  75.                 info = info->next;  
  76.                 i++;  
  77.             }  
  78.         }  
  79.         LOGI("No device name found");  
  80.         return env->NewStringUTF(NULL);  
  81.     }  
  82.   
  83.   
  84.     static jint android_net_ethernet_getInterfaceCnt()  
  85.     {  
  86.         return total_int;  
  87.     }  
  88. </PRE><BR>  
  89. <BR>  
  90. <PRE></PRE>  
  91. <P></P>  
  92. <P></P>  
  93. <PRE></PRE>  
  94. <SPAN style="COLOR: #ff0000"><STRONG><SPAN style="FONT-SIZE: 16px"><BR>  
  95. </SPAN></STRONG></SPAN>  
  96. <P></P>  
  97. <PRE></PRE>  
  98. <PRE></PRE>  
  99. <PRE></PRE>  

 

检测 android ethernet 支持 IPV6 否

如果路由器或交换机不支持IPv6, 则把开发板与PC直连。现在的phy应该都支持直连,不许要特定交叉或直连线了。

1. busybox ifconfig -a  : 查看本地IPV6 地址

[python] view plaincopyprint?
  1. root@android:/ # busybox ifconfig -a                                             
  2. eth0      Link encap:Ethernet  HWaddr 00:80:E1:12:64:5F    
  3.           inet6 addr: fec0:1111:2222:3333:280:e1ff:fe12:645f/64 Scope:Site  
  4.           inet6 addr: fe80::280:e1ff:fe12:645f/64 Scope:Link  
  5.           UP BROADCAST MULTICAST  MTU:1500  Metric:1  
  6.           RX packets:223 errors:0 dropped:0 overruns:0 frame:0  
  7.           TX packets:31 errors:0 dropped:0 overruns:0 carrier:0  
  8.           collisions:0 txqueuelen:1000   
  9.           RX bytes:39851 (38.9 KiB)  TX bytes:8561 (8.3 KiB)  
  10.           Interrupt:179   
  11.   
  12. lo        Link encap:Local Loopback    
  13.           inet addr:127.0.0.1  Mask:255.0.0.0  
  14.           inet6 addr: ::1/128 Scope:Host  
  15.           UP LOOPBACK RUNNING  MTU:16436  Metric:1  
  16.           RX packets:464 errors:0 dropped:0 overruns:0 frame:0  
  17.           TX packets:464 errors:0 dropped:0 overruns:0 carrier:0  
  18.           collisions:0 txqueuelen:0   
  19.           RX bytes:34144 (33.3 KiB)  TX bytes:34144 (33.3 KiB)  
  20.   
  21. sit0      Link encap:IPv6-in-IPv4    
  22.           NOARP  MTU:1480  Metric:1  
  23.           RX packets:0 errors:0 dropped:0 overruns:0 frame:0  
  24.           TX packets:0 errors:0 dropped:0 overruns:0 carrier:0  
  25.           collisions:0 txqueuelen:0   
  26.           RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)  

inet6 addr : 就是IPv6 IP地址. 如果没有安装radvd, 第一行inet6 addr 是不会出现的。


2. ping6 -I eth0 fe80::280:e1ff:fe12:645f

或 ping6 fe80::280:e1ff:fe12:645f%eth0  

检查是否能ping通,如果ping通了,就可以进行下一步了。

这里ping6时,需指定eth0 接口,要不然是ping6不通的。


3. 在unbuntu PC上安装apache:

sudo apt-get install apache2 :安装apache。

sudo /etc/init.d/apache2 restart   :启动apache。

sudo vim /var/www/index.html   : 修改网页内容。


在firefox中打开网页

http://localhost/

http://本地ipv4地址/ 

可以检测apache是否工作正常

这时用 http://本地ipv6地址/ 是不能打开网页的,还需要以下几步。


4. 安装dhcpv6 server 和 client:

sudo apt-get install wide-dhcpv6-client wide-dhcpv6-server

这里client应该可以不装。


5. 安装玩 radvd:

这里安装玩 dhcpv6还不够,还需要安装radvd.

a. sudo apt-get install radvd

b. vi /etc/radvd.conf(需新建该文件),如下面几行: 

[python] view plaincopyprint?
  1. interface eth0 {  
  2.    MinRtrAdvInterval 3;  
  3.    MaxRtrAdvInterval 10;  
  4.    AdvLinkMTU 1280;  
  5.    AdvSendAdvert on;  
  6.    prefixfec0:1111:2222:3333::/64 {  
  7.     AdvOnLinkon;  
  8.    AdvAutonomous on;  
  9.    AdvValidLifetime 86400;  
  10.    AdvPreferredLifetime 86400;  
  11.    AdvRouterAddr on;  
  12.    };  
  13. };  

c. 在/etc/sysctl.conf 中打开 net.ipv6.conf.all.forwarding=1

d. sudo /etc/init.d/radvd start

(如果在 radvd 运行状态下重启机器,radvd 会在开机后自动运行)


6. 这时在PC 的 firefox  中打开 apache 网页内容就可以了。

http://[fec0:1111:2222:3333:baac:6fff:fe3e:5af8]/

在 开发板的 web browser 中也可以通过IPv6打开PC apache内容, 地址栏同样是:

http://[fec0:1111:2222:3333:baac:6fff:fe3e:5af8]/

 
 
原创粉丝点击