hikey970自己build android image,开始使用android-9.0-r8
build completed image之后烧机发现wifi无法连接,于是开始查询原因,发现在hikey github的device code中,对于init.common.rc设置如下:
service wpa_supplicant /system/vendor/bin/hw/wpa_supplicant \
-iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf \
-g@android:wpa_wlan0
socket wpa_wlan0 dgram 660 wifi wifi
class main
disabled
oneshot
其中设置
-iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf
应该要替换成
interface android.hardware.wifi.supplicant@1.0::ISupplicant default interface android.hardware.wifi.supplicant@1.1::ISupplicant default
原因是在/data/misc/wifi目录下并没有创建wpa_supplicant.conf
根据代码可以看出系统将wpa_supplicant.conf存储在以下位置
PRODUCT_COPY_FILES += \
frameworks/native/data/etc/android.hardware.wifi.xml:system/etc/permissions/android.hardware.wifi.xml \
frameworks/native/data/etc/android.hardware.bluetooth.xml:system/etc/permissions/android.hardware.bluetooth.xml \
frameworks/native/data/etc/android.hardware.bluetooth_le.xml:system/etc/permissions/android.hardware.bluetooth_le.xml \
device/linaro/hikey/wpa_supplicant.conf:system/etc/wifi/wpa_supplicant.conf
而android.hardware.wifi.supplicant@1.x::ISupplicant 函数
代码在/external/wpa_supplicant_8/wpa_supplicant/hidl/1.0/supplicant.cpp
constexpr char kStaIfaceConfPath[] =
"/data/misc/wifi/wpa_supplicant.conf";
constexpr char kP2pIfaceConfPath[] =
"/data/misc/wifi/p2p_supplicant.conf";
// Migrate conf files for existing devices.
constexpr char kTemplateConfPath[] =
"/vendor/etc/wifi/wpa_supplicant.conf";
可以看到conf文件主要有以上路径
而路径中/vendor/etc/wifi/wpa_supplicant.conf的生成是在
/external/wpa_supplicant_8/wpa_supplicant/wpa_supplicant_conf.mk
include $(CLEAR_VARS)
LOCAL_MODULE := wpa_supplicant.conf
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc/wifi
因此通过代码/external/wpa_supplicant_8/wpa_supplicant/hidl/1.0/supplicant.cpp
bool Supplicant::ensureConfigFileExists()
{
// To support Android P Wifi framework, make sure the config file exists.
if (copyTemplateConfigFileIfNotExists(
kStaIfaceConfPath, kTemplateConfPath) != 0) {
wpa_printf(MSG_ERROR, "Conf file does not exists: %s",
kStaIfaceConfPath);
return false;
}
// P2P configuration file is not madatory but required for some devices.
if (copyTemplateConfigFileIfNotExists(
kP2pIfaceConfPath, kTemplateConfPath) != 0) {
wpa_printf(MSG_INFO, "Conf file does not exists: %s",
kP2pIfaceConfPath);
}
return true;
}
int copyTemplateConfigFileIfNotExists(
const std::string& config_file_path,
const std::string& template_config_file_path)
{
int ret = access(config_file_path.c_str(), R_OK | W_OK);
if (ret == 0) {
return 0;
}
if (errno == EACCES) {
ret = chmod(config_file_path.c_str(), kConfigFileMode);
if (ret == 0) {
return 0;
} else {
wpa_printf(
MSG_ERROR, "Cannot set RW to %s. Errno: %s",
config_file_path.c_str(), strerror(errno));
return -1;
}
} else if (errno != ENOENT) {
wpa_printf(
MSG_ERROR, "Cannot acces %s. Errno: %s",
config_file_path.c_str(), strerror(errno));
return -1;
}
ret = copyFileIfItExists(template_config_file_path, config_file_path);
if (ret == 0) {
wpa_printf(
MSG_INFO, "Copied template conf file from %s to %s",
template_config_file_path.c_str(), config_file_path.c_str());
return 0;
} else if (ret == -1) {
unlink(config_file_path.c_str());
return -1;
}
// Did not create the conf file.
return -1;
}
} // namespace
int copyFileIfItExists(
const std::string& src_file_path, const std::string& dest_file_path)
{
int ret = access(src_file_path.c_str(), R_OK);
if ((ret != 0) && (errno == ENOENT)) {
return 1;
}
ret = copyFile(src_file_path, dest_file_path);
if (ret != 0) {
wpa_printf(
MSG_ERROR, "Failed copying %s to %s.",
src_file_path.c_str(), dest_file_path.c_str());
return -1;
}
return 0;
}
int copyFile(
const std::string& src_file_path, const std::string& dest_file_path)
{
std::string file_contents;
if (!android::base::ReadFileToString(src_file_path, &file_contents)) {
wpa_printf(
MSG_ERROR, "Failed to read from %s. Errno: %s",
src_file_path.c_str(), strerror(errno));
return -1;
}
if (!android::base::WriteStringToFile(
file_contents, dest_file_path, kConfigFileMode, getuid(),
getgid())) {
wpa_printf(
MSG_ERROR, "Failed to write to %s. Errno: %s",
dest_file_path.c_str(), strerror(errno));
return -1;
}
return 0;
}
完成了将/vendor/etc/wifi/wpa_supplicant.conf复制到/data/misc/wifi/wpa_supplicant.conf
在/external/wpa_supplicant_8/wpa_supplicant/hidl目录下有分1.0 1.1两个版本,而选择版本的代码应该在
/external/wpa_supplicant_8/wpa_supplicant/Android.mk
include $(CLEAR_VARS)
LOCAL_MODULE := libwpa_hidl
LOCAL_VENDOR_MODULE := true
LOCAL_CPPFLAGS := $(L_CPPFLAGS)
LOCAL_CFLAGS := $(L_CFLAGS)
LOCAL_C_INCLUDES := $(INCLUDES)
HIDL_INTERFACE_VERSION = 1.0
LOCAL_SRC_FILES := \
hidl/$(HIDL_INTERFACE_VERSION)/hidl.cpp \
hidl/$(HIDL_INTERFACE_VERSION)/hidl_manager.cpp \
hidl/$(HIDL_INTERFACE_VERSION)/iface_config_utils.cpp \
hidl/$(HIDL_INTERFACE_VERSION)/p2p_iface.cpp \
hidl/$(HIDL_INTERFACE_VERSION)/p2p_network.cpp \
hidl/$(HIDL_INTERFACE_VERSION)/sta_iface.cpp \
hidl/$(HIDL_INTERFACE_VERSION)/sta_network.cpp \
hidl/$(HIDL_INTERFACE_VERSION)/supplicant.cpp
因此当我从r8升级到r12时,wifi又出了问题,无法连接,再次查看发现r12使用了hidl 1.1
在hidl 1.1不在使用路径/data/misc/wifi/wpa_supplicant.conf而是替换如下
if (ensureConfigFileExists(
kStaIfaceConfPath, kOldStaIfaceConfPath) != 0) {
wpa_printf(
MSG_ERROR, "Conf file does not exists: %s",
kStaIfaceConfPath);
return {{SupplicantStatusCode::FAILURE_UNKNOWN,
"Conf file does not exist"},
{}};
}
constexpr char kStaIfaceConfPath[] =
"/data/vendor/wifi/wpa/wpa_supplicant.conf";
但是hikey目录中并没有wpa文件夹,这就会造成文件复制失败,因此,需要在init.common.rc中创建这个文件夹
mkdir /data/vendor/wifi/wpa 0777 wifi wifi
现在wifi可以正常使用,但是图标仍然会显示无连接,这是因为,手机连上wifi后,会去访问谷歌服务器以判断wifi是否可用,但是国内网已经屏蔽谷歌服务器,因此访问必然失败,这就需要修改一下访问服务器网址,可以参考如下
/frameworks/base/services/core/java/com/android/server/connectivity/NetworkMonitor.java
// Default configuration values for captive portal detection probes.
// TODO: append a random length parameter to the default HTTPS url.
// TODO: randomize browser version ids in the default User-Agent String.
private static final String DEFAULT_HTTPS_URL = "https://connect.rom.miui.com/generate_204";
private static final String DEFAULT_HTTP_URL =
"http://connect.rom.miui.com/generate_204";
private static final String DEFAULT_FALLBACK_URL = "http://connect.rom.miui.com/generate_204";
private static final String DEFAULT_OTHER_FALLBACK_URLS =
"http://connect.rom.miui.com/generate_204";
private static final String DEFAULT_USER_AGENT = "Mozilla/5.0 (X11; Linux x86_64) "
+ "AppleWebKit/537.36 (KHTML, like Gecko) "
+ "Chrome/60.0.3112.32 Safari/537.36";