Android 10 Android 10 Software Integration Guide for the LWB family radios Overview This document explains the steps required to integrate an LWB/LWB5/LWB5+ module into a device running Android 10. Integrating Wi-Fi and Bluetooth into specific Android platforms can be challenging and may require platform specific changes. If the following information is confusing or does not provide the expected results, please visit https://www.ezurio.com/resources/support for further assistance. Ezurio has integrated this radio with an available commercial development kit. Each required change to the AOSP will be shown here. Your system may be different and so these modifications may need further adjustments on your system. Be sure to review the standard Software Integration Guide for the LWB family: sig_LWB_series_radio.pdf Preliminary expectations Familiarity with Android Open Source Project (AOSP) We recommend you have built your development system initially prior to adding support from this document. Required Packages Backports package Sterling Firmware package for the radio you are using https://github.com/LairdCP/Sterling-LWB-and-LWB5-Release-Packages Placement of code and firmware in AOSP Create a directory “laird” as a child of your AOSP’s root directory and place the backports and appropriate firmware packages for the wifi/bt interface combination there. Use tar to expand each package in that directory. For backports, create a symlink named backport which points to the newly expanded backports directory. Examples: (after sourcing your build/envsetup file) $ croot $ mkdir laird $ cp <your download location>/laird-lwb*-firmware-*.tar.bz2 . $ cp <your download location>/backports-laird-*.tar.bz2 . $ tar xf laird-lwb*-firmware-*.tar.bz2 $ tar xf backports-laird-*.tar.bz2 $ ln -sf laird-backport-x.x.x.x/ backport Compiling Backports The backports driver package must be configured for the desired radio and then compiled against the proper Android Linux kernel for your project using the same compiler used for the remainder of the AOSP. The simplest way to accomplish this is to have the Android make system do the compilation. For our AOSP, we edited kernel.mk in the ./device/<company name>/common/build directory diff --git a/common/build/kernel.mk b/common/build/kernel.mk index 9a177b17..bdb1dc0c 100644 --- a/common/build/kernel.mk +++ b/common/build/kernel.mk @@ -150,11 +150,30 @@ define build_dtb dtbs endef $(KERNEL_BIN): $(KERNEL_CONFIG) $(TARGET_KERNEL_SRC) | $(KERNEL_OUT) $(hide) echo "Building $(KERNEL_ARCH) $(KERNEL_VERSION) kernel ..." $(hide) PATH=$$PATH $(MAKE) -C $(TARGET_KERNEL_SRC) mrproper $(call build_kernel,$(KERNEL_NAME)) $(call build_kernel,modules) + $(hide) echo "building LWB module drivers" + $(MAKE) -C laird/backport ARCH=$(KERNEL_ARCH) \ + CROSS_COMPILE="$(KERNEL_CROSS_COMPILE_WRAPPER)" \ + KLIB_BUILD=$(realpath $(KERNEL_OUT)) defconfig-lwb5p + $(MAKE) -C laird/backport ARCH=$(KERNEL_ARCH) \ + CROSS_COMPILE="$(KERNEL_CROSS_COMPILE_WRAPPER)" \ + KLIB_BUILD=$(realpath $(KERNEL_OUT)) + $(call build_dtb); \ for dtsplat in $(TARGET_BOARD_DTS_CONFIG); do \ DTB_NAME=`echo $$dtsplat | cut -d':' -f2`; \ (note that our kernel resides in ./vendor/<devkit vendor name>/kernel_imx. Adjust the KLIB_BUILD parameter as appropriate) The first invocation of make will configure the for appropriate defconfig you specify. The second will actually create the device driver modules. Note when the modules are compiled, both wireless and bt modules are created. compat.ko cfg80211.ko brcmutil.ko brcmfmac.ko Kernel defconfig ensure your kernel is built for using modules: CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y ensure the default cfg80211 is built as a module for the kernel (this version will not be used) CONFIG_CFG80211=m init.rc additions Choose the appropriate 2 digit regulatory domain for the regdomain entry. Example is FCC insmod vendor/lib/modules/compat.ko insmod vendor/lib/modules/cfg80211.ko insmod vendor/lib/modules/brcmutil.ko insmod vendor/lib/modules/brcmfmac.ko regdomain="US" init.rc changes/additional # Prepare for wifi setprop wifi.interface wlan0 setprop wifi.concurrent.interface p2p0 service wpa_supplicant /vendor/bin/hw/wpa_supplicant \ -Dnl80211 -iwlan0 -c/vendor/etc/wifi/wpa_supplicant.conf \ -O/data/vendor/wifi/wpa/sockets \ -e/data/misc/wifi/entropy.bin -g@android:wpa_wlan0 class main socket wpa_wlan0 dgram 660 wifi wifi disabled oneshot service dhcpcd_wlan0 /system/bin/dhcpcd -aABDKL class main disabled oneshot service dhcpcd_p2p /system/bin/dhcpcd -aABKL class main disabled oneshot service iprenew_wlan0 /system/bin/dhcpcd -n class main disabled oneshot service iprenew_p2p /system/bin/dhcpcd -n class main disabled oneshot BoardConfig.mk BOARD_WLAN_DEVICE := bcmdhd BOARD_WPA_SUPPLICANT_PRIVATE_LIB := lib_driver_cmd_bcmdhd BOARD_WPA_HOSTAPD_PRIVATE_LIB := lib_driver_cmd_bcmdhd BOARD_HAVE_BLUETOOTH := true BOARD_HAVE_BLUETOOTH_BCM := true BOARD_VENDOR_KERNEL_MODULES += \ laird/backport/compat/compat.ko \ laird/backport/net/wireless/cfg80211.ko \ laird/backport/drivers/net/wireless/broadcom/brcm80211/brcmutil/brcmutil.ko \ laird/backport/drivers/net/wireless/broadcom/brcm80211/brcmfmac/brcmfmac.ko Your device.mk Add bluetooth options to product_packages PRODUCT_PACKAGES += \ android.hardware.bluetooth@1.0-impl \ android.hardware.bluetooth@1.0-service \ bt_vendor.conf \ libbt-vendor Firmware Each of the LWB family’s firmware files contains several different firmware files, each of which needs to be added to the PRODUCT_COPY_FILES entry. Here is an example showing all the possible firmware files. You should only include the files from your firmware package. In the ‘placement of code and firmware in AOSP’ section above, you un-tared the specific firmware for your usage. add the appropriate firmware files for your radio to the device.mk file: (use the symlink name) (modify the interface as necessary): PRODUCT_COPY_FILES += \ laird/lib/firmware/brcm/BCM4335C0.hcd:$(TARGET_COPY_OUT_VENDOR)/firmware/brcm/BCM4335C0.hcd \ laird/lib/firmware/brcm/BCM43430A1.hcd:$(TARGET_COPY_OUT_VENDOR)/firmware/brcm/BCM43430A1.hcd \ laird/lib/firmware/brcm/brcmfmac4339-sdio.bin:$(TARGET_COPY_OUT_VENDOR)/firmware/brcm/brcmfmac4339-sdio.bin \ laird/lib/firmware/brcm/brcmfmac4339-sdio.txt:$(TARGET_COPY_OUT_VENDOR)/firmware/brcm/brcmfmac4339-sdio.txt \ laird/lib/firmware/brcm/brcmfmac43430-sdio.bin:$(TARGET_COPY_OUT_VENDOR)/firmware/brcm/brcmfmac43430-sdio.bin \ laird/lib/firmware/brcm/brcmfmac43430-sdio.clm_blob:$(TARGET_COPY_OUT_VENDOR)/firmware/brcm/brcmfmac43430-sdio.clm_blob \ laird/lib/firmware/brcm/brcmfmac43430-sdio.txt:$(TARGET_COPY_OUT_VENDOR)/firmware/brcm/brcmfmac43430-sdio.txt \ laird/lib/firmware/brcm/brcmfmac4373-sdio.txt:$(TARGET_COPY_OUT_VENDOR)/firmware/brcm/brcmfmac4373-sdio.txt \ laird/lib/firmware/brcm/brcmfmac4373-sdio.clm_blob:$(TARGET_COPY_OUT_VENDOR)/firmware/brcm/brcmfmac4373-sdio.clm_blob \ laird/lib/firmware/brcm/brcmfmac4373-sdio.bin:$(TARGET_COPY_OUT_VENDOR)/firmware/brcm/brcmfmac4373-sdio.bin \ laird/lib/firmware/brcm/BCM4373A0.hcd:$(TARGET_COPY_OUT_VENDOR)/firmware/brcm/BCM4373A0.hcd \ laird/lib/firmware/brcm/BCM4373A0-04b4-640c.hcd:$(TARGET_COPY_OUT_VENDOR)/firmware/brcm/BCM4373A0-04b4-640c.hcd \ laird/lib/firmware/brcm/BCM4373A0.hcd:$(TARGET_COPY_OUT_VENDOR)/firmware/brcm/BCM4373A0.hcd \ laird/lib/firmware/brcm/BCM4373A0-sdio-div.hcd:$(TARGET_COPY_OUT_VENDOR)/firmware/brcm/BCM4373A0-sdio-div.hcd \ laird/lib/firmware/brcm/BCM4373A0-sdio-sa.hcd:$(TARGET_COPY_OUT_VENDOR)/firmware/brcm/BCM4373A0-sdio-sa.hcd \ laird/lib/firmware/brcm/brcmfmac4373.bin:$(TARGET_COPY_OUT_VENDOR)/firmware/brcm/brcmfmac4373.bin \ laird/lib/firmware/brcm/brcmfmac4373.clm_blob:$(TARGET_COPY_OUT_VENDOR)/firmware/brcm/brcmfmac4373.clm_blob \ laird/lib/firmware/brcm/brcmfmac4373-clm-div.clm_blob:$(TARGET_COPY_OUT_VENDOR)/firmware/brcm/brcmfmac4373-clm-div.clm_blob \ laird/lib/firmware/brcm/brcmfmac4373-clm-sa.clm_blob:$(TARGET_COPY_OUT_VENDOR)/firmware/brcm/brcmfmac4373-clm-sa.clm_blob \ laird/lib/firmware/brcm/brcmfmac4373-div.txt:$(TARGET_COPY_OUT_VENDOR)/firmware/brcm/brcmfmac4373-div.txt \ laird/lib/firmware/brcm/brcmfmac4373-sa.txt:$(TARGET_COPY_OUT_VENDOR)/firmware/brcm/brcmfmac4373-sa.txt \ laird/lib/firmware/brcm/brcmfmac4373-sdio-prod.bin:$(TARGET_COPY_OUT_VENDOR)/firmware/brcm/brcmfmac4373-sdio-prod.bin \ SE policy file for WiFi HAL ensure the contents of the /device/$(vendor)/sepolicy file are set: $ cat hal_wifi_default.te allow hal_wifi_default sysfs:file { write }; vndbinder_use(hal_wifi_default) allow hal_wifi_default kernel:system module_request; binder_call(hal_wifi_default, system_server) allow hal_wifi_default system_server:binder {call transfer}; allow hal_wifi_default self:udp_socket {create ioctl create_socket_perms}; allow hal_wifi_default init:unix_stream_socket connect; allow hal_wifi_default property_socket: sock_file write; #mark as permissive domain #permissive hal_wifi_default; # allow hal_wifi_default access /data/misc/wifi allow hal_wifi_default wifi_data_file:dir create_dir_perms; allow hal_wifi_default wifi_data_file:dir create_file_perms; allow hal_wifi_default wifi_data_file:dir rw_dir_perms; allow hal_wifi_default wifi_data_file:file create_file_perms; allow hal_wifi_default wifi_data_file:file rw_file_perms; Bluetooth integration add the bt_config attribute for Bluetooth Java layer in the configuration file in the following path: <aosp_root>/device/${vendor}/${device}/overlay/framework/base/core/res/res/values/config.xml (your path may vary) --- a/overlay/frameworks/base/core/res/res/values/config.xml +++ b/overlay/frameworks/base/core/res/res/values/config.xml @@ -74,7 +74,7 @@ <!-- the 6th element indicates boot-time dependency-met value. --> <string-array translatable="false" name="networkAttributes"> <item>"wifi,1,1,1,-1,true"</item> + <item>"bluetooth,7,7,2,-1,true"</item> <item>"ethernet,9,9,2,-1,true"</item> </string-array> Add sepolicy for the Bluetooth modules: create or add the hal_bluetooth_default.te file under the sepolicy directory as: $ cat hal_bluetooth_default.te allow hal_bluetooth_default sysfs:file { write }; #allow hal_bluetooth_default bluetooth_data_file:file { write read append getattr }; allow hal_bluetooth_default hal_bluetooth_default:unix_stream_socket { ioctl }; allow hal_bluetooth_default sysfs_rfkill:file { write }; # connect to the UART allow hal_bluetooth_default wcnss_filter:unix_stream_socket {connectto}; # vendor.wc_transport.start_hci and friends set_prop(hal_bluetooth_default, wc_prop) set_prop(hal_bluetooth_default, vendor_bluetooth_prop) # talk to system_server to set priority allow hal_bluetooth_default fwk_scheduler_hwservice:hwservice_manager {find}; allow hal_bluetooth_default system_server:binder {call}; # Use bluetooth device allow hal_bluetooth_default hci_attach_dev:chr_file rw_file_perms; allow hal_bluetooth_default bluetooth_data_file:dir {rw_dir_perms add_name remove_name}; allow hal_bluetooth_default hci_attach_dev:chr_file {open read write ioctl}; In the same directory. update the sepolicy/system_server.te file: --- a/sepolicy/system_server.te +++ b/sepolicy/system_server.te @@ -28,3 +28,5 @@ allow system_server shell_data_file:file { map }; allow system_server graphics_device:dir { search }; allow system_server graphics_device:chr_file { open read ioctl }; allow system_server sysfs_extcon:file { getattr open read }; + +dontaudit system_server bluetooth:file write; Also in the same directory, modify file_contexts to include the UART you are using for BT. In this example, we use ttymxc3: + /dev/tty??? if using UART. Check your system to determine the port name --- a/sepolicy/file_contexts +++ b/sepolicy/file_contexts @@ -15,6 +15,7 @@ /dev/dri/controlD65 u:object_r:graphics_device:s0 /dev/dri/renderD128 u:object_r:gpu_device:s0 /dev/dri/renderD129 u:object_r:gpu_device:s0 +/dev/ttymxc3 u:object_r:hci_attach_dev:s0 update uevent permissions modify the uevent.rc file for for the appropriate port: (as with earlier entries, your port name will likely be different. See above section) --- a/ueventd.freescale.rc +++ b/ueventd.freescale.rc @@ -1,6 +1,6 @@ /dev/block/platform/30b50000\.usdhc/by-name/presistdata 0600 system system /dev/block/platform/30b40000\.usdhc/by-name/presistdata 0600 system system +/dev/ttymxc3 0660 bluetooth bluetooth /dev/snd/* 0660 system audio /dev/video* 0660 system camera /dev/mxc_hantro 0660 media drmrpc update the UART port in broadcom/libbt/conf/fsl/mek_8q/bt_vendor.conf $ cat broadcom/libbt/conf/fsl/mek_8q/bt_vendor.conf # UART device port where Bluetooth controller is attached UartPort = /dev/ttymxc3 # Firmware patch file location #FwPatchFilePath = /vendor/firmware/brcm #FwPatchFileName = CYW4354A2.1CX.hcd add bluetooth to manifest.xml --- a/manifest.xml +++ b/manifest.xml <instance>default</instance> </interface> </hal> + <hal format="hidl"> + <name>android.hardware.bluetooth</name> + <transport>hwbinder</transport> + <version>1.0</version> + <interface> + <name>IBluetoothHci</name> + <instance>default</instance> + </interface> + </hal> <hal format="hidl"> <name>android.hardware.boot</name> <transport>hwbinder</transport> revert bt initialization timeout from new 2.9 seconds back to 8 second system/bt/hci/src/hci_layer.cc // Using a define here, because it can be stringified for the property lookup // Default timeout should be less than BLE_START_TIMEOUT and // having less than 3 sec would hold the wakelock for init -#define DEFAULT_STARTUP_TIMEOUT_MS 2900 +//#define DEFAULT_STARTUP_TIMEOUT_MS 2900 +#define DEFAULT_STARTUP_TIMEOUT_MS 8000 #define STRING_VALUE_OF(x) #x // Abort if there is no response to an HCI command.