手把手教你移植bluez 5.47蓝牙协议栈

更新于2020.12.24

自从发布这篇文章后,不少同学有各种各样的问题私聊我,奈何博主能力有限,很多问题无法回答。不过我是一个热爱分享个人技术心得的人,如果你也是这样的人的话,可以加入下面的Q群和大家一起讨论有关bluez移植或者蓝牙技术相关的问题!

群名称:bluez/蓝牙技术讨论

群   号:237659197

********************************************************

目录

背景

编译bluez

1、glib的编译

1.1、编译zlib

1.2、编译libffi

1.3、编译glib

2、DBUS编译

2.1、编译expat

2.2、编译DBUS

3、readline的编译

3.1、编译ncurses

3.2、编译readline

4、libical编译

5、bluez的编译

5.1、copy所有依赖库的pkg文件到一个公共的路径并设置为全局变量

5.2、配置

5.3、编译

测试

1、创建DBUS服务

2、查看system bus上面挂载的service

3、启动bluetoothd

4、加载固件

5、连接蓝牙设备

5.1、用bluetoothctl工具使能板子上的蓝牙

5.2、上电

5.3、连接蓝牙音箱

编译bluez-alsa

1、编译libsndfile-1.0.28

2、编译fdk-aac

3、编译sbc

4、编译alsa-lib

5、编译bluez-alsa

6、编译alsa-utils-1.1.9

7、拉起ALSA服务

8、播放音频

结语


背景

最近在移植一款RTL8761ATV的蓝牙芯片到我的ARM板子上,用的是Linux 4.9的系统,需要自己编译一个蓝牙协议栈。bluez是Linux的官方蓝牙协议栈,所以我也用这个来调试我的蓝牙功能。虽然网上很多资料讲述bluez的移植,但是每个人在移植过程中都可能遇到不同的问题,所以在这里做个记录,方便自己也方便他人。

编译bluez

在正式编译bluez之前,我们还需要编译很多其依赖的东西,下面我们按顺序来一个一个的编译。

1、glib的编译

1.1、编译zlib

因为在编译前需要设置一下环境变量什么的,比如交叉编译工具链的路径。包括后面编译的库文件也是这样,所以我将这些环境变量都写到一个sh脚本里面了:

#!/bin/sh
export PKG_CONFIG_PATH=/home/jimmy/bluez-compile/pkgconfig:$PKG_CONFIG_PATH
export PATH=/home/jimmy/bluez-compile/arm-2014.05/bin:/home/jimmy/bluez-compile/gettext-0.20/install_us/bin:$PATH

设置完交叉编译命令的环境,然后分别执行下面的编译命令:

生成Makefile文件:
host=arm-none-linux-gnueabi  prefix=/home/jimmy/bluez-compile/zlib-1.2.8/install_us CC=arm-none-linux-gnueabi-gcc  ./configure --shared

编译:
make

安装:
make install

注意:编译完后需要设置下路径,否则glib编译时可能找不到依赖包。在install_us/lib/pkg-config/目录中有zlib.pc
执行:pkg-config --cflags zlib.pc
完成后把libz.so* 拷贝到编译工具链libc.so所在目录:
e.g.  install_us/lib/$cp -a libz.so* /home/jimmy/bluez-compile/arm-2014.05/arm-none-linux-gnueabi/libc/lib

1.2、编译libffi

和zlib的编译类似
./configure --host=arm-none-linux-gnueabi  --prefix=/home/jimmy/bluez-compile/libffi-3.2.1/install_us CC=arm-none-linux-gnueabi-gcc

make

make install

1.3、编译glib

1.3.1、创建cache文件

jimmy@ubuntu:~/bluez-compile/glib-2.45.3$ vim arm-linux.cache
加入如下设置:
    glib_cv_long_long_format=ll
    glib_cv_stack_grows=no
    glib_cv_uscore=no
    ac_cv_func_posix_getpwuid_r=yes
    ac_cv_func_posix_getgrgid_r=yes
    glib_cv_working_bcopy=no
    ac_cv_type_long_long=yes
    glib_cv_has__inline=yes
参数的意义可浏览:
https://www.gtk.org/api/2.6/glib/glib-cross-compiling.html

1.3.2、执行configure

./configure    --host=arm-none-linux-gnueabi  CC=arm-none-linux-gnueabi-gcc --prefix=/home/jimmy/bluez-compile/glib-2.45.3/install_us LIBFFI_CFLAGS="-I/home/jimmy/bluez-compile/libffi-3.2.1/install_us/lib/libffi-3.2.1/include" LIBFFI_LIBS="-lffi -L/home/jimmy/bluez-compile/libffi-3.2.1/install_us/lib" ZLIB_CFLAGS="-I/home/jimmy/bluez-compile/zlib-1.2.8/install_us/include" ZLIB_LIBS="-lz -L/home/jimmy/bluez-compile/zlib-1.2.8/install_us/lib" --cache-file=arm-linux.cache --disable-selinux --disable-xattr --disable-libelf --disable-fam

执行过程中遇到的问题及解答:

Q1:
*** You must have either have gettext support in your C library, or use the
*** GNU gettext library. (http://www.gnu.org/software/gettext/gettext.html

A1:
1)下载和编译gettext,并把编译出来的bin目录加入到环境变量中,比如我上面提到的sh脚本
./configure  --prefix=/home/jimmy/bluez-compile/gettext-0.20/install_us --host=arm-none-linux-gnueabi CC=arm-none-linux-gnueabi-gcc
make
make install

2)修改后的configure命令为
./configure    --host=arm-none-linux-gnueabi  CC=arm-none-linux-gnueabi-gcc --prefix=/home/jimmy/bluez-compile/glib-2.45.3/install_us LIBFFI_CFLAGS="-I/home/jimmy/bluez-compile/libffi-3.2.1/install_us/lib/libffi-3.2.1/include" LIBFFI_LIBS="-lffi -L/home/jimmy/bluez-compile/libffi-3.2.1/install_us/lib" ZLIB_CFLAGS="-I/home/jimmy/bluez-compile/zlib-1.2.8/install_us/include" ZLIB_LIBS="-lz -L/home/jimmy/bluez-compile/zlib-1.2.8/install_us/lib" LD_LIBRARY_PATH="/home/jimmy/bluez-compile/gettext-0.20/install_us/lib" LDFLAGS="-L/home/jimmy/bluez-compile/gettext-0.20/install_us/lib" --cache-file=arm-linux.cache --disable-selinux --disable-xattr --disable-libelf --disable-fam
Q2:error: Could not find a glib-genmarshal in your PATH
A2:apt-get install libglib2.0-dev

2、DBUS编译

因为DBUS的编译依赖expat,所以我们先编译expat。

2.1、编译expat

./configure  --prefix=/home/jimmy/bluez-compile/expat-2.2.7/install_us --host=arm-none-linux-gnueabi CC=arm-none-linux-gnueabi-gcc --enable-shared

make

make install

2.2、编译DBUS

./configure --prefix= --host=arm-none-linux-gnueabi CC=arm-none-linux-gnueabi-gcc CXX=arm-none-linux-gnueabi-g++  --with-xml=expat --without-x LDFLAGS="-L/home/jimmy/bluez-compile/expat-2.2.7/install_us/lib"  CFLAGS="-fPIE -I/home/jimmy/bluez-compile/expat-2.2.7/install_us/include/" CPPFLAGS="-I/home/jimmy/bluez-compile/expat-2.2.7/install_us/include/" enable_selinux="no" --disable-tests

make

make install DESTDIR=/home/jimmy/bluez-compile/dbus-1.12.12/install_us

注:
我们可以看到这里的编译命令会有所不同,比如执行configure的时候,设置prefix为空,在make install的时候增加了DESTDIR。这是因为DBUS编译出来的bin文件,我需要在ARM板子上执行,如果设置prefix前缀的话,会执行不了,比如二进制想去/lib/路径找个依赖的so,它会去${prefix}/lib这个路径去找,而不是/lib/路径。所以我们应该设置prefix为空,在make install的时候加上DESTDIR设置临时目录,就能解决这个问题了。

3、readline的编译

3.1、编译ncurses

export CPPFLAGS="-P"

./configure  --prefix=/home/jimmy/bluez-compile/ncurses-5.9/install_us  --host=arm-none-linux-gnueabi CC=arm-none-linux-gnueabi-gcc CXX=arm-none-linux-gnueabi-g++ 

make

make install

3.2、编译readline

./configure  --host=arm-none-linux-gnueabi  CC=arm-none-linux-gnueabi-gcc --prefix=/home/jimmy/bluez-compile/readline-8.0/install_us bash_cv_wcwidth_broken=yes

make SHLIB_LIBS=-lncurses

make install
Q1:make SHLIB_LIBS=-lncurses 的时候报错
/home/jimmy/bluez-compile/arm-2014.05/bin/../lib/gcc/arm-none-linux-gnueabi/4.8.3/../../../../arm-none-linux-gnueabi/bin/ld: cannot find -lncurses
collect2: error: ld returned 1 exit status
make[1]: *** [libreadline.so.8.0] Error 1
make[1]: Leaving directory `/home/jimmy/bluez-compile/readline-8.0/shlib'
make: *** [shared] Error 2

A1:
将编译出来的libncurses.a放到工具链的/home/jimmy/bluez-compile/arm-2014.05/arm-none-linux-gnueabi/libc/usr/lib目录

4、libical编译

注意:libical编译与上述依赖库的编译体系不同,它采用的是cmake编译方式,首先服务器要安装3.14以上的版本才能编译。
服务器更新到:

jimmy@ubuntu$ cmake --version
cmake version 3.14.3
编译过程:
libical-2.0.0$mkdir build && cd build

libical-2.0.0$export CC=arm-none-linux-gnueabi-gcc;export CXX=arm-none-linux-gnueabi-g++

#将工具链libstdc++库文件拷贝到build,否则下面编译可能会报错
libical-2.0.0$cmake -DCMAKE_INSTALL_PREFIX=/home/jimmy/bluez-compile/libical-3.0.4/build -DCMAKE_BUILD_TYPE=Release -DSHARED_ONLY=yes

libical-2.0.0$make && make install

5、bluez的编译

5.1、copy所有依赖库的pkg文件到一个公共的路径并设置为全局变量

export PKG_CONFIG_PATH=/home/jimmy/bluez-compile/pkgconfig:$PKG_CONFIG_PATH

这样做的好处是不用在configure中填写一堆-L -I

5.2、配置

./configure --prefix= --sysconfdir=/home/jimmy/bluez-compile/bluez-5.47/install_us/etc --localstatedir=/home/jimmy/bluez-compile/bluez-5.47/install_us/var --enable-experimental --with-systemdsystemunitdir=/home/jimmy/bluez-compile/bluez-5.47/install_us/ll_lib/systemd/system --with-systemduserunitdir=/home/jimmy/bluez-compile/bluez-5.47/install_us/ll_usr/lib/systemd -enable-tools  --enable-debug --enable-test --disable-udev --host=arm-none-linux-gnueabi CC=arm-none-linux-gnueabi-gcc --enable-library  --enable-shared=yes --enable-network --enable-health  --enable-cups  --enable-threads --enable-pie --enable-deprecated

其中,--enable-deprecated  这个选项可以编译出hciconfig和hciattach等工具。参考连接:https://blog.csdn.net/luotong86/article/details/38094425
Q1:error: readline header files are required
A1:
1)sudo apt-get install libreadline-dev
2)如果第一步还不行,就将宿主机的/usr/include/readline整个目录拷贝到自己的arm-linux的编译器的usr/include目录:cp /usr/include/readline/* bluez-compile/arm-2014.05/arm-none-linux-gnueabi/libc/usr/include/readline

5.3、编译

make

Q1:ld: cannot find -lreadline
A1:把编译好的readline库拷贝到编译工具链的usr/lib目录下

make install DESTDIR=/home/jimmy/bluez-compile/bluez-5.47/install_us

测试

在测试前,先了解一下概念:

dbus-daemon是一个后台进程,负责消息的转发。它就像个路由器。最常见的基于dbus的程序也是符合C/S结构的。比如我们自己写了两个程序,A和B,其中A是客户,B是服务。假设A要调用B的一个函数C,那么实际的消息流动方向是:A告诉dbus-daemon我要调用B的C函数,然后dbus-daemon则去调用B的C函数,如果C有返回值的话,B会把返回值告诉dbus-daemon,然后dbus-daemon再把返回值告诉A。由此可以看出,dbus-daemon是很关键的一个后台进程。

1、创建DBUS服务

#dbus-daemon --system --print-pid --print-address

执行后可能会报的错:

Q1:
# dbus-daemon --system --print-pid --print-address
dbus-daemon: /mnt/app/lib/libdbus-1.so.3: version `LIBDBUS_PRIVATE_1.12.12' not found (required by dbus-daemon)

A1:
导入DBUS编译出来的libdbus-1.so.3.19.9,并重新创建软链接:
ln -svf libdbus-1.so.3.19.9 libdbus-1.so.3
还不行的话,重新拷贝文件和重启几次。。。(我就是这么成功运行的)
Q2:
# dbus-daemon --system --print-pid --print-address
dbus[3066]: Failed to start message bus: Failed to open "/share/dbus-1/system.conf": No such file or directory

A2:
手动创建/share/dbus-1/,并导入system.conf
Q3:
# dbus-daemon --system --print-pid --print-address
dbus-daemon[3076]: Failed to start message bus: Failed to bind socket "/var/run/dbus/system_bus_socket": No such file or directory

A3:
手动创建/var/run/dbus目录,然后再执行会报下面的错:
# dbus-daemon --system --print-pid --print-address
unix:path=/var/run/dbus/system_bus_socket,guid=56ffdd41a4365304d3346656586868bc
dbus-daemon[2824]: Failed to start message bus: Could not get UID and GID for username "messagebus"

按照网上的说法(http://www.makaidong.com/%E5%8D%9A%E5%AE%A2%E5%9B%AD%E7%83%AD/26458.shtml):
通过添加用户解决 adduser messagebus 密码设为dbus。

注:其实这一步出错,主要是我的系统在启动过程中,没有在启动脚本rcS里面执行dbus-daemon命令,如果正确执行,是不会出现这个问题的。

2、查看system bus上面挂载的service

注:这步不是必须的,不过可以看到我们成功挂载我们的服务没有

dbus-send --system --type=method_call --print-reply --dest=org.freedesktop.DBus / org.freedesktop.DBus.Introspectable.Introspect

3、启动bluetoothd

# bluetoothd -n -d &
Q1:有以下报错
# bluetoothd[2856]: Bluetooth daemon 5.47
D-Bus setup failed: Connection ":1.3" is not allowed to own the service "org.bluez" due to security policies in the configuration file
bluetoothd[2856]: Unable to get on D-Bus

A1:
参考链接:http://blog.sina.com.cn/s/blog_7cedb56d0102v0r3.html
将dbus编译出来的dbus-1.12.12/install_us/etc/dbus-1/system.d/bluetooth.conf拷贝到板子的/etc/dbus-1/system.d目录

4、加载固件

1)将rtl8761a_config和rtl8761a_fw导入到/lib/firmware/rtlbt
2)先手动将蓝牙的Reset引脚复位一下,这个是调试时候用的,正式版本会在kernel里面做复位动作
# echo 0 > /sys/class/rfkill/rfkill0/state
# echo 1 > /sys/class/rfkill/rfkill0/state
3)rtk_hciattach  -n  -s 115200 ttyS1 rtk_h5

5、连接蓝牙设备

5.1、用bluetoothctl工具使能板子上的蓝牙

# bluetoothctl
[bluetooth]# power on
[bluetooth]#agent on
[bluetooth]#default-agent

或者使用hciconfig 工具,命令为 hciconfig hci0 up。建议使用 bluetoothctl 使能蓝牙
Q1:
# bluetoothctl
bluetoothctl: error while loading shared libraries: libreadline.so.8: cannot open shared object file: No such file or directory

A1:
将readline-8.0编译出来的libreadline.so.8.0导入/mnt/app/lib,并创建软链接:ln -svf libreadline.so.8.0 libreadline.so.8

5.2、上电

查看控制器的 Power 是否为 yes,如果 Power 为 no,则运行 power on

[bluetooth]# show
Controller 00:E0:4C:23:99:87
        Name: BlueZ 5.47
        Alias: BlueZ 5.47
        Class: 0x00000000
        Powered: yes
        Discoverable: no
        Pairable: yes
        UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb)
        UUID: A/V Remote Control        (0000110e-0000-1000-8000-00805f9b34fb)
        UUID: PnP Information           (00001200-0000-1000-8000-00805f9b34fb)
        UUID: Generic Access Profile    (00001800-0000-1000-8000-00805f9b34fb)
        UUID: A/V Remote Control Target (0000110c-0000-1000-8000-00805f9b34fb)
        Modalias: usb:v1D6Bp0246d052F
        Discovering: no
[bluetooth]#

5.3、连接蓝牙音箱

5.3.1、启动扫描

[bluetooth]# scan on
Discovery started
[CHG] Controller 00:E0:4C:23:99:87 Discovering: yes
[NEW] Device E0:B6:55:4E:F2:5F MI BT18
...
[bluetooth]# scan off

5.3.2、信任

[bluetooth]# trust E0:B6:55:4E:F2:5F
[CHG] Device E0:B6:55:4E:F2:5F Trusted: yes
Changing E0:B6:55:4E:F2:5F trust succeeded

5.3.3、配对

[bluetooth]# pair E0:B6:55:4E:F2:5F
Attempting to pair with E0:B6:55:4E:F2:5F
[CHG] Device E0:B6:55:4E:F2:5F Connected: yes]#
[CHG] Device E0:B6:55:4E:F2:5F Modalias: bluetooth:v05D6p000Ad0240
[CHG] Device E0:B6:55:4E:F2:5F UUIDs: 00001101-0000-1000-8000-00805f9b34fb
[CHG] Device E0:B6:55:4E:F2:5F UUIDs: 0000110b-0000-1000-8000-00805f9b34fb
[CHG] Device E0:B6:55:4E:F2:5F UUIDs: 0000110c-0000-1000-8000-00805f9b34fb
[CHG] Device E0:B6:55:4E:F2:5F UUIDs: 0000110e-0000-1000-8000-00805f9b34fb
[CHG] Device E0:B6:55:4E:F2:5F UUIDs: 0000111e-0000-1000-8000-00805f9b34fb
[CHG] Device E0:B6:55:4E:F2:5F UUIDs: 00001200-0000-1000-8000-00805f9b34fb
[CHG] Device E0:B6:55:4E:F2:5F ServicesResolved: yes
[CHG] Device E0:B6:55:4E:F2:5F Paired: yes
Pairing successful

5.3.4、连接

[bluetooth]# connect E0:B6:55:4E:F2:5F
Attempting to connect to E0:B6:55:4E:F2:5F
Failed to connect: org.bluez.Error.Failed
a2dp-sink profile connect failed for E0:B6:55:4E:F2:5F: Protocol not available

但是连接失败了,从打印来看,没有支持的profile。搜了资料我们还需要移植bluez-alsa,下面我们就来交叉编译我们的bluez-alsa。

编译bluez-alsa

bluez-alsa的执行需要依赖一些库文件,我们先编译这些依赖的文件先。

1、编译libsndfile-1.0.28

./configure --prefix=/home/jimmy/bluez-compile/bluez-alsa/libsndfile-1.0.28/install_us --host=arm-none-linux-gnueabi CC=arm-none-linux-gnueabi-gcc 
 
make

make install

2、编译fdk-aac

./configure --prefix=/home/jimmy/bluez-compile/bluez-alsa/fdk-aac-2.0.0/install_us --host=arm-none-linux-gnueabi CC=arm-none-linux-gnueabi-gcc 

make

make install

3、编译sbc

./configure --prefix=/home/jimmy/bluez-compile/bluez-alsa/sbc-1.3/install_us --host=arm-none-linux-gnueabi  CC=arm-none-linux-gnueabi-gcc

make

make install

4、编译alsa-lib

./configure --prefix= --host=arm-none-linux-gnueabi  CC=arm-none-linux-gnueabi-gcc

make

make install DESTDIR=/home/jimmy/bluez-compile/bluez-alsa/alsa-lib-1.1.9/install_us

5、编译bluez-alsa

autoreconf --install

./configure --prefix=/home/jimmy/bluez-compile/bluez-alsa/bluez-alsa/install_us --enable-aac --enable-debug --host=arm-none-linux-gnueabi CC=arm-none-linux-gnueabi-gcc

make

make install

编译中遇到的问题: 

Q1:
../../src/shared/dbus-client.h:15:33: fatal error: bluetooth/bluetooth.h: No such file or directory

A1:
如果PKG_CONFIG_PATH已经设置了,很有可能是工具链没有找到依赖的文件,需要把bluez编译出来的include/bluetooth整个目录拷贝到你的工具链对应的include目录下。
Q2:
cannot find -lbluetooth
collect2: error: ld returned 1 exit status

A2:
把bluez编译出来的lib库都拷贝到工具链的libc/usr/lib目录下

6、编译alsa-utils-1.1.9

后续在调试音频时,会用到aplay工具,所以这里编译一下alsa-utils工具。因为交叉编译alsa-utils默认会生成alsamixer,此时会用到ncurses,但即使交叉编译了ncurses库并加入alsa-utils调用路径,问题仍然存在,所以暂时不编译alsamixer。
 

./configure --prefix= --host=arm-none-linux-gnueabi CC=arm-none-linux-gnueabi-gcc CFLAGS="-I/home/jimmy/bluez-compile/bluez-alsa/alsa-lib-1.1.9/install_us/include" LDFLAGS="-L/home/jimmy/bluez-compile/bluez-alsa/alsa-lib-1.1.9/install_us/lib -lasound" --disable-alsamixer --disable-xmlto

make

make install DESTDIR=/home/jimmy/bluez-compile/bluez-alsa/alsa-utils-1.1.9/install_us

编译中遇到的问题:

Q1:
make[2]: Entering directory `/home/jimmy/bluez-compile/bluez-alsa/alsa-utils-1.1.9/alsaconf/po'
mv: cannot stat ‘t-ja.gmo’: No such file or directory
make[2]: *** [ja.gmo] Error 1

A1:
touch alsaconf/po/t-ja.gmo
注意:根据自己的错误提示来输入命令
如果提示是t-ru.gmo的话,就用命令:touch alsaconf/po/t-ru.gmo
如果提示是t-ja.gmo的话,就用命令:touch alsaconf/po/t-ja.gmo
值得注意的地方是:如果还是报错,那就make clean一下
避免之后make报错

参考链接:https://www.cnblogs.com/lifan3a/articles/5563049.html

7、拉起ALSA服务

二进制由bluez-alsa编译出来

# ./bluealsa

执行中可能遇到的问题:

Q1:
./bluealsa: error while loading shared libraries: libbluetooth.so.3: cannot open shared object file: No such file or directory

A1:将bluez-5.47编译出来的libbluetooth.so.3.18.16导入板子
# wget http://192.168.1.13/libbluetooth.so.3.18.16
# ln -svf libbluetooth.so.3.18.16 libbluetooth.so.3
'libbluetooth.so.3' -> 'libbluetooth.so.3.18.16'
Q2:
./bluealsa: error while loading shared libraries: libgio-2.0.so.0: cannot open shared object file: No such file or directory

A2:将glib-2.45.3编译出来的libgio-2.0.so.0.4503.0导入板子
# ln -svf libgio-2.0.so.0.4503.0 libgio-2.0.so.0
Q3:
./bluealsa: error while loading shared libraries: libgobject-2.0.so.0: cannot open shared object file: No such file or directory

A3:将glib-2.45.3编译出来的libgobject-2.0.so.0.4503.0导入板子
# ln -svf libgobject-2.0.so.0.4503.0 libgobject-2.0.so.0
Q4:
./bluealsa: error while loading shared libraries: libfdk-aac.so.2: cannot open shared object file: No such file or directory

A4:将fdk-aac-2.0.0编译出来的libfdk-aac.so.2.0.0导入板子
# ln -svf libfdk-aac.so.2.0.0 libfdk-aac.so.2
Q5:
./bluealsa: error while loading shared libraries: libsbc.so.1: cannot open shared object file: No such file or directory

A5:
将sbc-1.3编译出来的libsbc.so.1.2.1导入板子
# ln -svf libsbc.so.1.2.1 libsbc.so.1
Q6:
./bluealsa: error while loading shared libraries: libgmodule-2.0.so.0: cannot open shared object file: No such file or directory

A6:将glib-2.45.3编译出来的libgmodule-2.0.so.0.4503.0导入板子
# ln -svf libgmodule-2.0.so.0.4503.0 libgmodule-2.0.so.0
Q7:
./bluealsa: bluez.c:803: Registering endpoint: /org/bluez/hci0/A2DP/MPEG24/Source/1
./bluealsa: bluez.c:803: Registering endpoint: /org/bluez/hci0/A2DP/SBC/Source/1
./bluealsa: ba-adapter.c:134: Freeing adapter: hci0
./bluealsa: bluez.c:1066: Registering profile: /org/bluez/HSP/AudioGateway
./bluealsa: bluez.c:1066: Registering profile: /org/bluez/HFP/AudioGateway
./bluealsa: main.c:328: Acquiring D-Bus service name: org.bluealsa
./bluealsa: main.c:333: Starting main dispatching loop
./bluealsa: Couldn't acquire D-Bus name: org.bluealsa
./bluealsa: main.c:337: Exiting main loop

A7:
参考官方链接:https://github.com/Arkq/bluez-alsa/blob/master/README.md

It is not possible to run more than one instance of the BlueALSA server per D-Bus interface. If one tries to run second instance, it will fail with the "Couldn't acquire D-Bus name: org.bluealsa" error message. This message might also appear when D-Bus policy does not allow acquiring "org.bluealsa" name for a particular user - by default only root is allowed to start BlueALSA server.

所以,在/etc/dbus-1/system.d/bluetooth.conf添加org.bluealsa的服务:
  <policy user="root">
    ...
    <allow own="org.bluealsa"/>
    <allow send_destination="org.bluealsa"/>
  </policy>

8、播放音频

aplay -D bluealsa:HCI=hci0,DEV=E0:B6:55:4E:F2:5F,PROFILE=a2dp becauseoflove.wav

执行过程中可能遇到的问题:

Q1:
ALSA lib conf.c:3956:(snd_config_update_r) Cannot access file /share/alsa/alsa.conf

A1:
将alsa-lib-1.1.9编译出来的share/alsa/alsa.conf导入板子
Q2:
ALSA lib pcm.c:2564:(snd_pcm_open_noupdate) Unknown PCM bluealsa:HCI=hci0,DEV=E0:B6:55:4E:F2:5F,PROFILE=A2DP
aplay: main:828: audio open error: No such file or directory

A2:
这个问题搜索了很多资料和参考了其他同事的文档,有的做法如下:

需要加个配置,默认为F0:13:C3:A7:60:D1地址的音箱播放
alsa配置:
主入口:/usr/share/alsa/alsa.conf

# vi /etc/asound.conf
pcm.!default {
        type plug
        slave.pcm {
                type bluealsa
                device "E0:B6:55:4E:F2:5F"
                profile "a2dp"
        }
        hint {
                show on
                description "BT Speaker"
        }
}

但是在我的平台却还是不行,所以我直接执行下面的命令:

aplay becauseoflove.wav

有以下的报错:

ALSA lib dlmisc.c:287:(snd1_dlobj_cache_get) Cannot open shared library /lib/alsa-lib/libasound_module_pcm_bluealsa.so ((null): /lib/alsa-lib/libasound_module_pcm_bluealsa.so: cannot open shared object file: No such file or directory)
aplay: main:828: audio open error: No such device or address

所以我按照提示,导入/lib/alsa-lib/libasound_module_pcm_bluealsa.so。再执行命令就能正常播放了。
不过上面的asound.conf配置还是要改的,不同的音箱需要修改MAC地址,调试阶段暂时这么做。

结语

移植的过程中,真的会遇到很多很多的问题,几乎很多是靠搜索的,有的连搜索都找不到,所以我也想将我的经验分享出来,希望也能帮忙大家,也当作给自己做过笔记吧。

  • 27
    点赞
  • 96
    收藏
    觉得还不错? 一键收藏
  • 31
    评论
蓝牙协议栈bluez是用于在Linux系统上支持蓝牙功能的开源软件项目。对于蓝牙协议栈移植和开发,以下是一些关键点: 1. 移植蓝牙协议栈移植通常需要适配特定的硬件平台或操作系统。移植的关键在于理解目标平台的硬件特性和操作系统的API,并根据这些特性进行相应的修改。从硬件层面,可能需要针对不同的蓝牙芯片进行驱动程序的开发或移植。从操作系统层面,需要根据操作系统的内核和接口规范进行适配,确保蓝牙协议栈能够正确地与操作系统进行通信。 2. 开发:蓝牙协议栈bluez的开发需要理解蓝牙协议的基本原理和相关规范。开发人员需要掌握Linux系统编程和网络编程的相关知识,并深入了解蓝牙协议栈的各个层级和模块。在蓝牙协议栈的开发过程中,可能需要进行协议栈的扩展、功能的优化或新特性的添加。开发人员需要进行代码的编写、调试和测试,并确保新开发的功能与蓝牙协议栈的其他部分相互兼容。 3. 调试和问题解决:在蓝牙协议栈移植和开发过程中,可能会遇到各种问题和挑战。调试是解决这些问题的关键步骤之一,开发人员需要使用适当的工具和技术,如调试器、日志和追踪功能来定位和排除问题。在解决问题时,需要仔细查看相关文档、设计规范和代码实现,并通过分析日志和跟踪信息来理解问题的来源并提供解决方案。 总之,蓝牙协议栈bluez移植和开发需要掌握蓝牙协议的基础知识,具备Linux系统编程经验,了解硬件和操作系统的特性,并运用合适的调试和问题解决技术来确保蓝牙协议栈能够在目标平台上正确运行和提供所需的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 31
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值