先说BT:
Android KK上已经抛弃bluez改用bluedroid,详细构架请参考官网:https://source.android.com/devices/bluetooth
对于构架官网已经描述的很清楚了,我简单的做个补充:
蓝牙系统服务
蓝牙系统服务蓝牙系统服务(位于 packages/apps/Bluetooth
中)被打包为 Android 应用,并在 Android 框架层实现蓝牙服务和配置文件。该应用通过 JNI 调用 HAL 层。它会编译成为system/app/Bluetooth.apkJNI
JNI
与 android.bluetooth 相关联的 JNI 代码位于 packages/apps/Bluetooth/jni
中。当发生特定蓝牙操作时(例如发现设备时),JNI 代码会调用 HAL 层并从 HAL 接收回调。它会编译成为system/lib/libbluetooth_jni.soHAL
HAL
硬件抽象层定义了 android.bluetooth API 和蓝牙进程会调用的标准接口,并且您必须实现该接口才能使蓝牙硬件正常工作。蓝牙 HAL 的头文件是 hardware/libhardware/include/hardware/bluetooth.h
。另外,请查看所有 hardware/libhardware/include/hardware/bt_*.h
文件。它会编译成为system/lib/libhardware.so,供libbluetooth_jni.so调用. 它会在hw_get_module_by_class函数中,调用bluedroid
………………
snprintf(path, sizeof(path), "%s/%s.default.so", //bluetooth.default.so
HAL_LIBRARY_PATH2, name);
if (access(path, R_OK) == 0) break;
snprintf(path, sizeof(path), "%s/%s.default.so",
HAL_LIBRARY_PATH1, name);
if (access(path, R_OK) == 0) break;
………………
Bluedroid
代码位于 external/bluetooth/bluedroid
。它会编译成bluetooth.default.so供libhardware.so调用。
它自己会在如下代码中调用厂商的最终实现代码:
void init_vnd_if(unsigned char *local_bdaddr)
{
void *dlhandle;
dlhandle = dlopen("libbt-vendor.so", RTLD_NOW);
if (!dlhandle)
{
ALOGE("!!! Failed to load libbt-vendor.so !!!");
return;
}
………………
蓝牙堆栈
蓝牙堆栈系统为您提供了默认蓝牙堆栈(位于 system/bt
中)。该堆栈会实现常规蓝牙 HAL,并通过扩展程序和更改配置对其进行自定义。供应商扩展程序要添加自定义扩展程序和用于跟踪的 HCI 层,您可以创建一个 libbt-vendor 模块并指定这些组件。
再说WIFI:
wifi的HAL代码位于:hardware/libhardware_legacy/wifi/wifi.c,其中最为关键的代码是:int wifi_load_driver()
{
#ifdef WIFI_DRIVER_MODULE_PATH
char driver_status[PROPERTY_VALUE_MAX];
int count = 100; /* wait at most 20 seconds for completion */
if (is_wifi_driver_loaded()) {
return 0;
}
if (insmod(DRIVER_MODULE_PATH, DRIVER_MODULE_ARG) < 0)
return -1;
if (strcmp(FIRMWARE_LOADER,"") == 0) {
/* usleep(WIFI_DRIVER_LOADER_DELAY); */
property_set(DRIVER_PROP_NAME, "ok");
}
else {
property_set("ctl.start", FIRMWARE_LOADER);
}
sched_yield();
while (count-- > 0) {
if (property_get(DRIVER_PROP_NAME, driver_status, NULL)) {
if (strcmp(driver_status, "ok") == 0)
return 0;
else if (strcmp(DRIVER_PROP_NAME, "failed") == 0) {
wifi_unload_driver();
return -1;
}
}
usleep(200000);
}
property_set(DRIVER_PROP_NAME, "timeout");
wifi_unload_driver();
return -1;
#else
property_set(DRIVER_PROP_NAME, "ok");
return 0;
#endif
}
一般的设备厂商都会根据不同的UID和PID来insmod不同的wifi驱动(/sys/bus/usb/devices)。
再说wifi驱动,这个好像没啥说的,按照厂商的说明编译出对应的so,再找个合适的地方insmod即可。
需要注意的是,在Linux上原本可以手工执行并验证的命令在Android上貌似报参数错误:
insmod cfg80211.ko
insmod rtl8723bu.ko
cd ../wpa_tools/
./wpa_supplicant -Dnl80211,wext -iwlan0 -c ./wpa_supplicant_empty.conf -B
./wpa_cli -iwlan0 scan
./wpa_cli -iwlan0 scan_results
./wpa_cli -iwlan0 add_network
./wpa_cli -iwlan0 set_network 0 ssid '"TP-LINK_ABCD"'
./wpa_cli -iwlan0 set_network 0 key_mgmt WPA-PSK
./wpa_cli -iwlan0 set_network 0 psk '"1234567890"'
./wpa_cli -iwlan0 set_network 0 pairwise CCMP
./wpa_cli -iwlan0 set_network 0 group CCMP
./wpa_cli -iwlan0 set_network 0 proto WPA2
./wpa_cli -iwlan0 enable_network 0
udhcpc -iwlan0