找了之前写的关于Raspberry Pi上的蓝牙设备的相关配置,发现还在存在一些问题。
下面这篇是通过上层命令去初始化蓝牙设备:
下面再看看另外一种方式,由linux kernel去初始化蓝牙设备的方法
- Linux Kernel
代码http://mirrors.ustc.edu.cn/aosp/kernel/common.git/
这里使用的是 android kernel中的android-4.19-q的代码,commit id:
commit ba835f8db4a3005e34542a3af7f19fce30ade6fd Author: Jeff Vander Stoep <jeffv@google.com> Date: Wed Jan 22 11:19:58 2020 +0100 ANDROID: selinux: modify RTM_GETLINK permission
- device tree的配置
从arch/arm/boot/dts/bcm2835-rpi-zero-w.dts中可以看到,在uart0上已经加了蓝牙相关的描述:
&uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_gpio32 &uart0_ctsrts_gpio30>; status = "okay"; bluetooth { compatible = "brcm,bcm43438-bt"; max-speed = <2000000>; shutdown-gpios = <&gpio 45 GPIO_ACTIVE_HIGH>; }; };
- linux driver 层
由于上面device tree上描述,使用如果kernel编译时配置了CONFIG_BT_HCIUART_BCM=y时,就可以让drivers/bluetooth/hci_bcm.c去初始化蓝牙设备。
当然,在初始化蓝牙设备时,还需要相关的固件文件:BCM43430A1.hcd。
初始化时,我们可以从kernel log中看到如下信息:
[ 4.289228] Bluetooth: hci0: command 0xfc18 tx timeout [ 4.383397] sdhost-bcm2835 20202000.mmc: loaded - DMA enabled (>1) [ 4.427188] mmc1: SDHCI controller on 20300000.mmcnr [20300000.mmcnr] using PIO [ 4.441914] hctosys: unable to open rtc device (rtc0) [ 4.452859] Bluetooth: hci0: BCM: chip id 94 [ 4.462173] Bluetooth: hci0: BCM: features 0x2e [ 4.473474] Bluetooth: hci0: BCM43430A1 [ 4.481723] Bluetooth: hci0: BCM43430A1 (001.002.009) build 0000 [ 4.494815] cfg80211: Loading compiled-in X.509 certificates for regulatory database ... [ 5.798836] ueventd: ueventd started! [ 5.978242] Bluetooth: hci0: BCM43430A1 (001.002.009) build 0360 [ 6.703432] ueventd: Coldboot took 0.89s. [ 6.712687] init: Waiting for /dev/.coldboot_done took 0.93s.
之后,我们就可以在系统中看到 /sys/class/rfkill/rfkill0 及/sys/devices/platform/soc/20201000.serial/serial0/serial0-0/bluetooth/hci0 这两个关于蓝牙设备的信息。
- 上层应用
对于Brillo m10系统来说,与蓝牙设备进行交互的app为bluetoothtbd。这里,我们还需要一个libbt-vendor.so的动态库,实现与kernel driver层的交互。
由于driver已经初始化好蓝牙设备并且创建好了hci0的设备。我们的上层应用就可以通过hci0这个设备去与蓝牙设备进行交互。
这里会用到system/bt/vendor_libs/linux下的代码,commit id:
commit 10dd30d45a1f03bd7668df9e2cad4498d110ce0b Author: Ajay Panicker <apanicke@google.com> Date: Thu Feb 18 16:33:07 2016 -0800 Clean up dump printout Change-Id: I0b7e5a9dda30875c9fc877baffa0daac9184cd42
初始化代码:
static int bt_vendor_init(const bt_vendor_callbacks_t *p_cb, unsigned char *local_bdaddr) { char prop_value[PROPERTY_VALUE_MAX]; LOG_INFO(LOG_TAG, "%s", __func__); if (p_cb == NULL) { LOG_ERROR(LOG_TAG, "init failed with no user callbacks!"); return -1; } bt_vendor_callbacks = p_cb; memcpy(bt_vendor_local_bdaddr, local_bdaddr, sizeof(bt_vendor_local_bdaddr)); property_get("bluetooth.interface", prop_value, "0"); errno = 0; if (memcmp(prop_value, "hci", 3)) hci_interface = strtol(prop_value, NULL, 10); else hci_interface = strtol(prop_value + 3, NULL, 10); if (errno) hci_interface = 0; LOG_INFO(LOG_TAG, "Using interface hci%d", hci_interface); property_get("bluetooth.rfkill", prop_value, "0"); rfkill_en = atoi(prop_value); if (rfkill_en) LOG_INFO(LOG_TAG, "RFKILL enabled"); bt_hwcfg_en = property_get("bluetooth.hwcfg", prop_value, NULL) > 0 ? 1 : 0; if (bt_hwcfg_en) LOG_INFO(LOG_TAG, "HWCFG enabled"); return 0; }
配置三个系统属性:
– bluetooth.interface=hci0
– bluetooth.rfkill=0
– bluetooth.hwcfg=0
同时,从bluetoothtbd.rc文件中可以看到,该进程是以bluetooth的用户运行的,还需要具备CAP_NET_ADMIN 权限。
service bluetoothtbd /system/bin/bluetoothtbd class main user bluetooth group wakelock net_bt_admin net_bt_stack net_admin
这个权限可以在bluetoothtbd.rc中文件配置,也可以在fs_config/android_filesystem_config.h中配置:
/* Rules for files. ** These rules are applied based on "first match", so they ** should start with the most specific path and work their ** way up to the root. Prefixes ending in * denote wildcards ** and will allow partial matches. */ static const struct fs_path_config android_device_files[] = { { 00755, AID_SYSTEM, AID_SHELL, CAP_MASK_LONG(CAP_NET_BIND_SERVICE) | CAP_MASK_LONG(CAP_NET_ADMIN) | CAP_MASK_LONG(CAP_NET_RAW), "system/bin/dnsmasq" }, { 00700, AID_SYSTEM, AID_SHELL, CAP_MASK_LONG(CAP_BLOCK_SUSPEND), "system/bin/nativepowerman" }, { 00700, AID_SYSTEM, AID_SHELL, CAP_MASK_LONG(CAP_SYS_TIME), "system/bin/tlsdated" }, { 00700, AID_WEBSERV, AID_SHELL, CAP_MASK_LONG(CAP_NET_BIND_SERVICE), "system/bin/webservd" }, { 00700, AID_DHCP, AID_DBUS, CAP_MASK_LONG(CAP_NET_ADMIN) | CAP_MASK_LONG(CAP_NET_BIND_SERVICE) | CAP_MASK_LONG(CAP_NET_RAW), "system/bin/dhcpcd-6.8.2" }, { 00700, AID_WIFI, AID_SHELL, CAP_MASK_LONG(CAP_NET_ADMIN) | CAP_MASK_LONG(CAP_NET_RAW), "system/bin/wpa_supplicant" }, { 00755, AID_WIFI, AID_SHELL, CAP_MASK_LONG(CAP_NET_ADMIN) | CAP_MASK_LONG(CAP_NET_RAW), "system/bin/apmanager" }, { 00755, AID_WIFI, AID_SHELL, CAP_MASK_LONG(CAP_NET_ADMIN) | CAP_MASK_LONG(CAP_NET_RAW), "system/bin/hostapd" }, { 00700, AID_BLUETOOTH, AID_SHELL, CAP_MASK_LONG(CAP_BLOCK_SUSPEND) | CAP_MASK_LONG(CAP_WAKE_ALARM) | CAP_MASK_LONG(CAP_NET_ADMIN), "system/bin/bluetoothtbd" }, { 00550, AID_ROOT, AID_SHELL, 0, "system/etc/init.firewall-adbd-setup.sh" }, { 00550, AID_ROOT, AID_SHELL, 0, "system/etc/init.firewall-setup.sh" }, { 00550, AID_ROOT, AID_SHELL, 0, "system/etc/init.wifi-setup.sh" }, { 00755, AID_SYSTEM, AID_SHELL, CAP_MASK_LONG(CAP_NET_ADMIN) | CAP_MASK_LONG(CAP_NET_RAW), "system/bin/iptables" }, { 00755, AID_SYSTEM, AID_SHELL, CAP_MASK_LONG(CAP_NET_ADMIN) | CAP_MASK_LONG(CAP_NET_RAW), "system/bin/ip6tables" }, { 00755, AID_SYSTEM, AID_SHELL, CAP_MASK_LONG(CAP_NET_ADMIN) | CAP_MASK_LONG(CAP_NET_RAW), "system/bin/crda" },
如果不去设置文件的capability, 在使用蓝牙设备时,会报如下错误:
01-24 11:00:11.887 123 220 I bt_vendor: bt_vendor_op op 3 retval 1 01-24 11:00:11.903 123 220 I bt_vendor: bt_vendor_op op 1 01-24 11:00:11.903 123 220 I bt_vendor: bt_vendor_fw_cfg 01-24 11:00:11.903 123 220 I bt_vendor: bt_vendor_wait_hcidev 01-24 11:00:11.904 123 220 E bt_vendor: socket bind error Operation not permitted 01-24 11:00:11.904 123 220 E bt_vendor: Hardware Config Error 01-24 11:00:11.904 123 220 I bt_vendor: firmware callback
初始化时,还需要蓝牙协议栈配置信息(配置log)文件:/etc/bluetooth/bt_stack.conf
01-24 11:00:19.963 123 178 E bt_hci : command_timed_out restarting the bluetooth process. 01-24 11:00:20.003 113 113 I ServiceManager: service 'bluetooth-service' died 01-24 11:00:20.572 227 227 I bt_btif : init 01-24 11:00:20.581 227 228 I bt_stack_config: init attempt to load stack conf from /etc/bluetooth/bt_stack.conf 01-24 11:00:20.586 227 227 I bt_osi_wakelock: wakelock_set_os_callouts set to non-native
selinux权限
allow bluetoothtbd self:socket create_socket_perms;