1、setting里面按dhcp获取ip 会调用到/system/core/libnetutils下dhcp_utils.c文件
dhcp_utils.c是负责和dhcpcd守护进程通信的。
2、dhcpcd守护进程是在init.rc里面启动的。相关代码在external/dhcpcd/dhcpcd.c文件里面
3、dhcp_utils.c 里面有个dhcp_do_request,这个就是系统设置里面会调用到的接口
4、dhcp_do_request分析
static const char DAEMON_NAME[] = "dhcpcd";
static const char DAEMON_PROP_NAME[] = "init.svc.dhcpcd";
static const char HOSTNAME_PROP_NAME[] = "net.hostname";
static const char DHCP_PROP_NAME_PREFIX[] = "dhcp";
get_daemon_suffix(interface, daemon_suffix);获取守护进程后缀名 daemon_suffix 是eth0
snprintf(result_prop_name, sizeof(result_prop_name), "%s.%s.result",
DHCP_PROP_NAME_PREFIX,
interface); 给result_prop_name赋值 dhcp.eth0.result
snprintf(daemon_prop_name, sizeof(daemon_prop_name), "%s_%s",
DAEMON_PROP_NAME,
daemon_suffix); 给daemon_prop_name赋值init.svc.dhcpcd_eth0 ;在串口输入getprop 能够看到[init.svc.dhcpcd_eth0]: [running]
/* Erase any previous setting of the dhcp result property */
property_set(result_prop_name, "");设置 dhcp.eth0.result为“”
/* Start the daemon and wait until it's ready */
if (property_get(HOSTNAME_PROP_NAME, prop_value, NULL) && (prop_value[0] != '\0'))//这里不大明白,就是取一个net.hostname的值是否为空
snprintf(daemon_cmd, sizeof(daemon_cmd), "%s_%s:-i %s -h %s %s", DAEMON_NAME,daemon_suffix,DHCP_OPTION60,
prop_value, interface);
给daemon_cmd赋值 dhcpcd_eth0:-i STB -h android-ce2fe875ba037a46 eth0
else
snprintf(daemon_cmd, sizeof(daemon_cmd), "%s_%s:%s", DAEMON_NAME, daemon_suffix, interface);
给daemon_cmd赋值 dhcpcd_eth0: eth0
这个daemon_cmd至关重要
memset(prop_value, '\0', PROPERTY_VALUE_MAX);
property_set(ctrl_prop, daemon_cmd);//向名字为dhcpcd的service,发送"ctrl.start"启动命令字,该service在init.rc中
对property属性功能知道的很少,就理解成像服务发送了一个命令就行了
相当于执行了dhcpc 命令
/*
* Wait for a system property to be assigned a specified value.
* If desired_value is NULL, then just wait for the property to
* be created with any value. maxwait is the maximum amount of
* time in seconds to wait before giving up.
*/
static int wait_for_property(const char *name, const char *desired_value, int maxwait)
/*wait_for_property 等待给一个系统属性赋一个指定的值
* 如果赋值为null,那么就等待属性被任意赋值创建
maxwait是最长等待时间,以秒为单位*/
现在的desired_status 是running
if (wait_for_property(daemon_prop_name, desired_status, 10) < 0) {
snprintf(errmsg, sizeof(errmsg), "%s", "Timed out waiting for dhcpcd to start");
return -1;
}
执行完这一步,getprop能够查看到[init.svc.dhcpcd_eth0]: [running],属性值改变了。
/* Wait for the daemon to return a result */
等待给result_prop_name 也就是等待给dhcp.eth0.result 赋值,等待时间15s。
if (wait_for_property(result_prop_name, NULL, 15) < 0) {
snprintf(errmsg, sizeof(errmsg), "%s", "Timed out waiting for DHCP to finish");
return -1;
}
等待有给dhcp.eth0.result赋值了,去获取这个值是什么,查看getprop
[dhcp.eth0.result]: [ok]
if (!property_get(result_prop_name, prop_value, NULL)) {
/* shouldn't ever happen, given the success of wait_for_property() */
snprintf(errmsg, sizeof(errmsg), "%s", "DHCP result property was not set");
return -1;
}
下面也就顺理成章了,如果这个值变为ok,也就是获取到了ip 等信息,给赋值。
if (strcmp(prop_value, "ok") == 0) {
char dns_prop_name[PROPERTY_KEY_MAX];
if (fill_ip_info(interface, ipaddr, gateway, prefixLength, dns1, dns2, server, lease)
== -1) {
return -1;
}
/* copy dns data to system properties - TODO - remove this after we have async
* notification of renewal's */
snprintf(dns_prop_name, sizeof(dns_prop_name), "net.%s.dns1", interface); net.eth0.dns1
property_set(dns_prop_name, *dns1 ? ipaddr_to_string(*dns1) : "");
snprintf(dns_prop_name, sizeof(dns_prop_name), "net.%s.dns2", interface);
property_set(dns_prop_name, *dns2 ? ipaddr_to_string(*dns2) : "");
return 0;
} else {
snprintf(errmsg, sizeof(errmsg), "DHCP result was %s", prop_value);
return -1;
}
完工啦!