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
- package android.net.ethernet;
- /**
- * Native calls for sending requests to the kernel,
- * {@hide}
- */
- public class EthernetNative {
- public native static String getInterfaceName(int i); //get eth0, sit0
- public native static int getInterfaceCnt(); //
- public native static int initEthernetNative();
- public native static String waitForEvent();
- }
package android.net.ethernet;/** * Native calls for sending requests to the kernel, * {@hide} */public class EthernetNative { public native static String getInterfaceName(int i); //get eth0, sit0 public native static int getInterfaceCnt(); // public native static int initEthernetNative(); public native static String waitForEvent();}
2. JNINativeMethod gEthernetMethods[]:
- static JNINativeMethod gEthernetMethods[] = {
- {"waitForEvent", "()Ljava/lang/String;",
- (void *)android_net_ethernet_waitForEvent},
- {"getInterfaceName", "(I)Ljava/lang/String;",
- (void *)android_net_ethernet_getInterfaceName},
- {"initEthernetNative", "()I",
- (void *)android_net_ethernet_initEthernetNative},
- {"getInterfaceCnt","()I",
- (void *)android_net_ethernet_getInterfaceCnt}
- };
static JNINativeMethod gEthernetMethods[] = { {"waitForEvent", "()Ljava/lang/String;", (void *)android_net_ethernet_waitForEvent}, {"getInterfaceName", "(I)Ljava/lang/String;", (void *)android_net_ethernet_getInterfaceName}, {"initEthernetNative", "()I", (void *)android_net_ethernet_initEthernetNative}, {"getInterfaceCnt","()I", (void *)android_net_ethernet_getInterfaceCnt} };
3. AndroidRuntime 运行时,会注册 这个NativeMethod:
- int register_android_net_ethernet_EthernetManager(JNIEnv* env)
- {
- jclass eth = env->FindClass(ETH_PKG_NAME);
- LOGI("Loading ethernet jni class");
- LOG_FATAL_IF(eth == NULL, "Unable to find class " ETH_PKG_NAME);
- dhcpInfoFieldIds.dhcpInfoClass =
- env->FindClass("android/net/DhcpInfo");
- if (dhcpInfoFieldIds.dhcpInfoClass != NULL) {
- dhcpInfoFieldIds.constructorId =
- env->GetMethodID(dhcpInfoFieldIds.dhcpInfoClass,
- "<init>", "()V");
- dhcpInfoFieldIds.ipaddress =
- env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass,
- "ipAddress", "I");
- dhcpInfoFieldIds.gateway =
- env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass,
- "gateway", "I");
- dhcpInfoFieldIds.netmask =
- env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass,
- "netmask", "I");
- dhcpInfoFieldIds.dns1 =
- env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "dns1", "I");
- dhcpInfoFieldIds.dns2 =
- env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "dns2", "I");
- dhcpInfoFieldIds.serverAddress =
- env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass,
- "serverAddress", "I");
- dhcpInfoFieldIds.leaseDuration =
- env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass,
- "leaseDuration", "I");
- }
- //注册gEthernetMethods[]
- return AndroidRuntime::registerNativeMethods(env,
- ETH_PKG_NAME,
- gEthernetMethods,
- NELEM(gEthernetMethods));
- }<SPAN style="COLOR: #ff0000"><STRONG><SPAN style="FONT-SIZE: 16px">
- </SPAN></STRONG></SPAN>
int register_android_net_ethernet_EthernetManager(JNIEnv* env) { jclass eth = env->FindClass(ETH_PKG_NAME); LOGI("Loading ethernet jni class"); LOG_FATAL_IF(eth == NULL, "Unable to find class " ETH_PKG_NAME); dhcpInfoFieldIds.dhcpInfoClass = env->FindClass("android/net/DhcpInfo"); if (dhcpInfoFieldIds.dhcpInfoClass != NULL) { dhcpInfoFieldIds.constructorId = env->GetMethodID(dhcpInfoFieldIds.dhcpInfoClass, "<init>", "()V"); dhcpInfoFieldIds.ipaddress = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "ipAddress", "I"); dhcpInfoFieldIds.gateway = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "gateway", "I"); dhcpInfoFieldIds.netmask = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "netmask", "I"); dhcpInfoFieldIds.dns1 = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "dns1", "I"); dhcpInfoFieldIds.dns2 = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "dns2", "I"); dhcpInfoFieldIds.serverAddress = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "serverAddress", "I"); dhcpInfoFieldIds.leaseDuration = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "leaseDuration", "I"); } //注册gEthernetMethods[] return AndroidRuntime::registerNativeMethods(env, ETH_PKG_NAME, gEthernetMethods, NELEM(gEthernetMethods)); }
4. waitForEvent():
- static jstring android_net_ethernet_waitForEvent(JNIEnv *env, jobject clazz)
- {
- char *buff;
- struct nlmsghdr *nh;
- struct ifinfomsg *einfo;
- struct iovec iov;
- struct msghdr msg;
- char *result = NULL;
- char rbuf[4096];
- unsigned int left;
- interface_info_t *info;
- int len;
- LOGV("Poll events from ethernet devices");
- /*
- *wait on uevent netlink socket for the ethernet device
- */
- buff = (char *)malloc(NL_POLL_MSG_SZ);
- if (!buff) {
- LOGE("Allocate poll buffer failed");
- goto error;
- }
- iov.iov_base = buff;
- iov.iov_len = NL_POLL_MSG_SZ;
- msg.msg_name = (void *)&addr_msg;
- msg.msg_namelen = sizeof(addr_msg);
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_control = NULL;
- msg.msg_controllen = 0;
- msg.msg_flags = 0;
- if ((len = recvmsg(nl_socket_poll, &msg, 0)) >= 0) {
- LOGV("recvmsg get data");
- result = rbuf;
- left = 4096;
- rbuf[0] = '\0';
- for (nh = (struct nlmsghdr *) buff; NLMSG_OK (nh, len);
- nh = NLMSG_NEXT (nh, len)) {
- if (nh->nlmsg_type == NLMSG_DONE) {
- LOGE("Did not find useful eth interface information");
- goto error;
- }
- if (nh->nlmsg_type == NLMSG_ERROR) {
- /* Do some error handling. */
- LOGE("Read device name failed");
- goto error;
- }
- LOGV(" event :%d found", nh->nlmsg_type);
- einfo = (struct ifinfomsg *)NLMSG_DATA(nh);
- LOGV("the device flag :%X", einfo->ifi_flags);
- if (nh->nlmsg_type == RTM_DELLINK ||
- nh->nlmsg_type == RTM_NEWLINK ||
- nh->nlmsg_type == RTM_DELADDR ||
- nh->nlmsg_type == RTM_NEWADDR) {
- int type = nh->nlmsg_type;
- if (type == RTM_NEWLINK &&
- (!(einfo->ifi_flags & IFF_LOWER_UP))) {
- type = RTM_DELLINK;
- }
- if ((info = find_info_by_index
- (((struct ifinfomsg*) NLMSG_DATA(nh))->ifi_index)) != NULL)
- snprintf(result,left, "%s:%d:",info->name,type);
- left = left - strlen(result);
- result =(char *)(result+ strlen(result));
- }
- }
- LOGV("Done parsing");
- rbuf[4096 - left] = '\0';
- LOGV("poll state :%s, left:%d", rbuf, left);
- }
- error:
- free(buff);
- return env->NewStringUTF(rbuf);
- }
static jstring android_net_ethernet_waitForEvent(JNIEnv *env, jobject clazz) { char *buff; struct nlmsghdr *nh; struct ifinfomsg *einfo; struct iovec iov; struct msghdr msg; char *result = NULL; char rbuf[4096]; unsigned int left; interface_info_t *info; int len; LOGV("Poll events from ethernet devices"); /* *wait on uevent netlink socket for the ethernet device */ buff = (char *)malloc(NL_POLL_MSG_SZ); if (!buff) { LOGE("Allocate poll buffer failed"); goto error; } iov.iov_base = buff; iov.iov_len = NL_POLL_MSG_SZ; msg.msg_name = (void *)&addr_msg; msg.msg_namelen = sizeof(addr_msg); msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_control = NULL; msg.msg_controllen = 0; msg.msg_flags = 0; if ((len = recvmsg(nl_socket_poll, &msg, 0)) >= 0) { LOGV("recvmsg get data"); result = rbuf; left = 4096; rbuf[0] = '\0'; for (nh = (struct nlmsghdr *) buff; NLMSG_OK (nh, len); nh = NLMSG_NEXT (nh, len)) { if (nh->nlmsg_type == NLMSG_DONE) { LOGE("Did not find useful eth interface information"); goto error; } if (nh->nlmsg_type == NLMSG_ERROR) { /* Do some error handling. */ LOGE("Read device name failed"); goto error; } LOGV(" event :%d found", nh->nlmsg_type); einfo = (struct ifinfomsg *)NLMSG_DATA(nh); LOGV("the device flag :%X", einfo->ifi_flags); if (nh->nlmsg_type == RTM_DELLINK || nh->nlmsg_type == RTM_NEWLINK || nh->nlmsg_type == RTM_DELADDR || nh->nlmsg_type == RTM_NEWADDR) { int type = nh->nlmsg_type; if (type == RTM_NEWLINK && (!(einfo->ifi_flags & IFF_LOWER_UP))) { type = RTM_DELLINK; } if ((info = find_info_by_index (((struct ifinfomsg*) NLMSG_DATA(nh))->ifi_index)) != NULL) snprintf(result,left, "%s:%d:",info->name,type); left = left - strlen(result); result =(char *)(result+ strlen(result)); } } LOGV("Done parsing"); rbuf[4096 - left] = '\0'; LOGV("poll state :%s, left:%d", rbuf, left); } error: free(buff); return env->NewStringUTF(rbuf); }
- <SPAN style="COLOR: #ff0000"><STRONG><SPAN style="FONT-SIZE: 16px">
- 5. initEthernetNative():</SPAN></STRONG></SPAN><PRE class=java name="code"> static jint android_net_ethernet_initEthernetNative(JNIEnv *env,
- jobject clazz)
- {
- int ret = -1;
- LOGI("==>%s",__FUNCTION__);
- memset(&addr_msg, 0, sizeof(sockaddr_nl));
- addr_msg.nl_family = AF_NETLINK;
- memset(&addr_poll, 0, sizeof(sockaddr_nl));
- addr_poll.nl_family = AF_NETLINK;
- addr_poll.nl_pid = 0;//getpid();
- addr_poll.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR;
- /*
- *Create connection to netlink socket
- */
- nl_socket_msg = socket(AF_NETLINK,SOCK_RAW,NETLINK_ROUTE);
- if (nl_socket_msg <= 0) {
- LOGE("Can not create netlink msg socket");
- goto error;
- }
- if (bind(nl_socket_msg, (struct sockaddr *)(&addr_msg),
- sizeof(struct sockaddr_nl))) {
- LOGE("Can not bind to netlink msg socket");
- goto error;
- }
- nl_socket_poll = socket(AF_NETLINK,SOCK_RAW,NETLINK_ROUTE);
- if (nl_socket_poll <= 0) {
- LOGE("Can not create netlink poll socket");
- goto error;
- }
- errno = 0;
- if (bind(nl_socket_poll, (struct sockaddr *)(&addr_poll),
- sizeof(struct sockaddr_nl))) {
- LOGE("Can not bind to netlink poll socket,%s", strerror(errno));
- goto error;
- }
- if ((ret = netlink_init_interfaces_list()) < 0) {
- LOGE("Can not collect the interface list");
- goto error;
- }
- LOGE("%s exited with success", __FUNCTION__);
- return ret;
- error:
- LOGE("%s exited with error", __FUNCTION__);
- if (nl_socket_msg > 0)
- close(nl_socket_msg);
- if (nl_socket_poll > 0)
- close(nl_socket_poll);
- return ret;
- }
- </PRE><SPAN style="COLOR: #ff0000; FONT-SIZE: 16px"><STRONG><BR>
- 6. getInterfaceName() 和 getInterfaceCnt():</STRONG></SPAN><BR>
- <PRE class=cpp name="code"> static jstring android_net_ethernet_getInterfaceName(JNIEnv *env,
- jobject clazz,
- jint index)
- {
- int i = 0;
- interface_info_t *info;
- LOGI("User ask for device name on %d, list:%X, total:%d",
- index, (unsigned int)interfaces, total_int);
- info = interfaces;
- if (total_int != 0 && index <= (total_int - 1)) {
- while (info) {
- if (index == i) {
- LOGV("Found: %s", info->name);
- return env->NewStringUTF(info->name);
- }
- info = info->next;
- i++;
- }
- }
- LOGI("No device name found");
- return env->NewStringUTF(NULL);
- }
- static jint android_net_ethernet_getInterfaceCnt()
- {
- return total_int;
- }
- </PRE><BR>
- <BR>
- <PRE></PRE>
- <P></P>
- <P></P>
- <PRE></PRE>
- <SPAN style="COLOR: #ff0000"><STRONG><SPAN style="FONT-SIZE: 16px"><BR>
- </SPAN></STRONG></SPAN>
- <P></P>
- <PRE></PRE>
- <PRE></PRE>
- <PRE></PRE>
检测 android ethernet 支持 IPV6 否
如果路由器或交换机不支持IPv6, 则把开发板与PC直连。现在的phy应该都支持直连,不许要特定交叉或直连线了。
1. busybox ifconfig -a : 查看本地IPV6 地址
- root@android:/ # busybox ifconfig -a
- eth0 Link encap:Ethernet HWaddr 00:80:E1:12:64:5F
- inet6 addr: fec0:1111:2222:3333:280:e1ff:fe12:645f/64 Scope:Site
- inet6 addr: fe80::280:e1ff:fe12:645f/64 Scope:Link
- UP BROADCAST MULTICAST MTU:1500 Metric:1
- RX packets:223 errors:0 dropped:0 overruns:0 frame:0
- TX packets:31 errors:0 dropped:0 overruns:0 carrier:0
- collisions:0 txqueuelen:1000
- RX bytes:39851 (38.9 KiB) TX bytes:8561 (8.3 KiB)
- Interrupt:179
- 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:16436 Metric:1
- RX packets:464 errors:0 dropped:0 overruns:0 frame:0
- TX packets:464 errors:0 dropped:0 overruns:0 carrier:0
- collisions:0 txqueuelen:0
- RX bytes:34144 (33.3 KiB) TX bytes:34144 (33.3 KiB)
- sit0 Link encap:IPv6-in-IPv4
- NOARP MTU:1480 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 (0.0 B) TX bytes:0 (0.0 B)
root@android:/ # busybox ifconfig -a eth0 Link encap:Ethernet HWaddr 00:80:E1:12:64:5F inet6 addr: fec0:1111:2222:3333:280:e1ff:fe12:645f/64 Scope:Site inet6 addr: fe80::280:e1ff:fe12:645f/64 Scope:Link UP BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:223 errors:0 dropped:0 overruns:0 frame:0 TX packets:31 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:39851 (38.9 KiB) TX bytes:8561 (8.3 KiB) Interrupt:179 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:16436 Metric:1 RX packets:464 errors:0 dropped:0 overruns:0 frame:0 TX packets:464 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:34144 (33.3 KiB) TX bytes:34144 (33.3 KiB)sit0 Link encap:IPv6-in-IPv4 NOARP MTU:1480 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 (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(需新建该文件),如下面几行:
- interface eth0 {
- MinRtrAdvInterval 3;
- MaxRtrAdvInterval 10;
- AdvLinkMTU 1280;
- AdvSendAdvert on;
- prefixfec0:1111:2222:3333::/64 {
- AdvOnLinkon;
- AdvAutonomous on;
- AdvValidLifetime 86400;
- AdvPreferredLifetime 86400;
- AdvRouterAddr on;
- };
- };
interface eth0 { MinRtrAdvInterval 3; MaxRtrAdvInterval 10; AdvLinkMTU 1280; AdvSendAdvert on; prefixfec0:1111:2222:3333::/64 { AdvOnLinkon; AdvAutonomous on; AdvValidLifetime 86400; AdvPreferredLifetime 86400; AdvRouterAddr on; };};
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]/
- EthernetNative 和 android_net_ethernet.cpp
- .h和.cpp
- .h和.cpp
- .cpp和.h
- hpp和cpp
- .h和.cpp
- .h和.cpp区别
- CPP类和对象
- cpp和c的区别
- Excel.cpp和Excel.h
- .c和.cpp混合使用
- .h和.cpp的概念
- stdAfx.h和stdAfx.cpp
- Excel.cpp和Excel.h
- HEADTAIL.cpp 等值首尾和
- .h和.cpp的区别
- cpp文件和.h文件
- moc_xxxx.cpp 和 xxxx.moc
- 图解框架-android网络设备管理
- 百钱买百鸡
- 从tfs优化看分布式存储系统
- 对生活现状的思考
- POJ 1087 A Plug for UNIX
- EthernetNative 和 android_net_ethernet.cpp
- 使用xmlHttpRequest实现Ajax技术
- ACdream 群赛11.10 Problem J: I can't describe the problem
- Hibernate_一对一双向外键关联
- Objective-C内存管理教程和原理剖析(二)口诀与范式
- 利用ffmpeg解码h264流的代码
- Objective-C内存管理教程和原理剖析(三)@property (retain)和@synthesize的默认实现
- 工作中应该持有的态度
- android ethernet