Linux之蓝牙协议栈 bluez移植

一、前言

使用情景:将嵌入式Linux系统作为slaver,并定义相关服务与手机进行发送接受及通知等相关操作。

二、编译依赖和BlueZ

1、zlib

LIB_TAR = zlib-1.2.11
LIB_PATH = $(PWD)/../libtar/zlib-1.2.11.tar.gz

all:
	cd $(LIB_TAR) &&  CC=$(LIB_CC)  ./configure --prefix=$(OUT_DIR)
	cd $(LIB_TAR) && make && make install

prepare:
	rm -rf $(LIB_TAR)
	tar -xvzf $(LIB_PATH)  -C ./

clean:
	cd $(LIB_TAR) && make clean

distclean:
	rm -rf $(LIB_TAR)

2、libffi

LIB_TAR = libffi-3.0.13
LIB_PATH = $(PWD)/../libtar/libffi-3.0.13.tar.gz

all:
	cd $(LIB_TAR) && ./configure --prefix=$(OUT_DIR) --host=arm-linux CC=$(LIB_CC)
	cd $(LIB_TAR) && make && make install

prepare:
	rm -rf $(LIB_TAR)
	tar -xvzf $(LIB_PATH)  -C ./

clean:
	cd $(LIB_TAR) && make clean

distclean:
	rm -rf $(LIB_TAR)

3、glib

LIB_TAR = glib-2.40.0
LIB_PATH = $(PWD)/../libtar/glib-2.40.0.tar.xz

all:
	cd $(LIB_TAR) && ./configure --prefix=$(OUT_DIR)  --host=arm-linux CC=$(LIB_CC) PKG_CONFIG_PATH=$(OUT_DIR)/lib/pkgconfig  glib_cv_stack_grows=no glib_cv_uscore=yes ac_cv_func_posix_getpwuid_r=yes ac_cv_func_posix_getgrgid_r=yes CPPFLAGS="-I$(OUT_DIR)/include/" LDFLAGS="-L$(OUT_DIR)/lib/"
	cd $(LIB_TAR) && make && make install

prepare:
	rm -rf $(LIB_TAR)
	tar -xvJf $(LIB_PATH)  -C ./
	cd $(LIB_TAR) && git apply $(PWD)/patch/glib/001-glib-gdate-suppress-string-format-literal-warning.patch

clean:
	cd $(LIB_TAR) && make clean

distclean:
	rm -rf $(LIB_TAR)

PS:编译该库的时候出现异常报错,解决方法如下

diff --git a/code/glib-2.40.0/glib/gdate.c b/code/glib-2.40.0/glib/gdate.c
index 670f7aa..5f03e61 100644
--- a/code/glib-2.40.0/glib/gdate.c
+++ b/code/glib-2.40.0/glib/gdate.c
@@ -2439,6 +2439,9 @@ win32_strftime_helper (const GDate     *d,
  *
  * Returns: number of characters written to the buffer, or 0 the buffer was too small
  */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
+
 gsize     
 g_date_strftime (gchar       *s, 
                  gsize        slen, 
@@ -2549,3 +2552,5 @@ g_date_strftime (gchar       *s,
   return retval;
 #endif
 }
+
+#pragma GCC diagnostic pop

4、expat

LIB_TAR = expat-2.1.0
LIB_PATH = $(PWD)/../libtar/expat-2.1.0.tar.gz

all:
	cd $(LIB_TAR) && ./configure --prefix=$(OUT_DIR) --host=arm-linux CC=$(LIB_CC)
	cd $(LIB_TAR) && make && make install

prepare:
	rm -rf $(LIB_TAR)
	tar -xvzf $(LIB_PATH)  -C ./

clean:
	cd $(LIB_TAR) && make clean

distclean:
	rm -rf $(LIB_TAR)

5、dbus

LIB_TAR = dbus-1.9.4
LIB_PATH = $(PWD)/../libtar/dbus-1.9.4.tar.gz

all:
	cd $(LIB_TAR) && ./configure --prefix=$(OUT_DIR) --host=arm-linux --with-x=no --disable-tests --enable-abstract-sockets CC=$(LIB_CC) CPPFLAGS="-I$(OUT_DIR)/include/" LDFLAGS="-L$(OUT_DIR)/lib/"
	cd $(LIB_TAR) && make && make install

prepare:
	rm -rf $(LIB_TAR)
	tar -xvzf $(LIB_PATH)  -C ./

clean:
	cd $(LIB_TAR) && make clean

distclean:
	rm -rf $(LIB_TAR)

6、libical

LIB_TAR = libical-1.0
LIB_PATH = $(PWD)/../libtar/libical-1.0.tar.gz

all:
	cd $(LIB_TAR) && ./bootstrap
	cd $(LIB_TAR) && ./configure --prefix=$(OUT_DIR) --host=arm-linux CC=$(LIB_CC)
	cd $(LIB_TAR) && make && make install

prepare:
	rm -rf $(LIB_TAR)
	tar -xvzf $(LIB_PATH)  -C ./

clean:
	cd $(LIB_TAR) && make clean

distclean:
	rm -rf $(LIB_TAR)

7、ncurses

LIB_TAR = ncurses-5.9
LIB_PATH = $(PWD)/../libtar/ncurses-5.9.tar.gz

all:
	cd $(LIB_TAR) && ./configure --prefix=$(OUT_DIR) --host=arm-linux CC=$(LIB_CC) --with-shared
	cd $(LIB_TAR) && make && make install

prepare:
	rm -rf $(LIB_TAR)
	tar -xvzf $(LIB_PATH)  -C ./
	cd .. && git apply $(PWD)/patch/ncurses/001-ncurses-curses-note-error.patch

clean:
	cd $(LIB_TAR) && make clean

distclean:
	rm -rf $(LIB_TAR)

PS:编译该库时发生异常报错,解决方案如下

diff --git a/code/ncurses-5.9/include/curses.tail b/code/ncurses-5.9/include/curses.tail
index 098c898..e81cc5a 100644
--- a/code/ncurses-5.9/include/curses.tail
+++ b/code/ncurses-5.9/include/curses.tail
@@ -101,7 +101,7 @@ extern NCURSES_EXPORT(mmask_t) mousemask (mmask_t, mmask_t *);
 extern NCURSES_EXPORT(bool)    wenclose (const WINDOW *, int, int);
 extern NCURSES_EXPORT(int)     mouseinterval (int);
 extern NCURSES_EXPORT(bool)    wmouse_trafo (const WINDOW*, int*, int*, bool);
-extern NCURSES_EXPORT(bool)    mouse_trafo (int*, int*, bool);              /* generated */
+extern NCURSES_EXPORT(bool)    mouse_trafo (int*, int*, bool);
 
 #if NCURSES_SP_FUNCS
 extern NCURSES_EXPORT(bool)    NCURSES_SP_NAME(has_mouse) (SCREEN*);

8、readline

LIB_TAR = readline-6.3
LIB_PATH = $(PWD)/../libtar/readline-6.3.tar.gz

all:
	cd $(LIB_TAR) && ./configure --prefix=$(OUT_DIR) --host=arm-linux CC=$(LIB_CC) bash_cv_wcwidth_broken=yes
	cd $(LIB_TAR) && make && make install

prepare:
	rm -rf $(LIB_TAR)
	tar -xvzf $(LIB_PATH)  -C ./

clean:
	cd $(LIB_TAR) && make clean

distclean:
	rm -rf $(LIB_TAR)

9、bluez

LIB_TAR = bluez-5.44
LIB_PATH = $(PWD)/../libtar/bluez-5.44.tar.xz

all:
	cd $(LIB_TAR) && ./configure --prefix=$(OUT_DIR) --host=arm-linux CC=$(LIB_CC) CFLAGS="-I$(OUT_DIR)/include/ -I$(OUT_DIR)/include/glib-2.0 -I$(OUT_DIR)/include/dbus-1.0" LDFLAGS="-lncurses  -lreadline -ldbus-1 -lglib-2.0 -lical -L/$(OUT_DIR)/lib -L$(OUT_DIR)/lib" DBUS_CFLAGS="-I$(OUT_DIR)/lib/dbus-1.0/include" DBUS_LIBS="-L$(OUT_DIR)/lib" GLIB_CFLAGS="-I$(OUT_DIR)/lib/glib-2.0/include" GLIB_LIBS="-L$(OUT_DIR)/lib" ICAL_CFLAGS="-I$(OUT_DIR)/include" ICAL_LIBS="-L$(OUT_DIR)/lib" --enable-library --sysconfdir=/etc --localstatedir=/var --enable-experimental --with-systemdsystemunitdir=/lib/systemd/system --with-systemduserunitdir=/usr/lib/system --with-dbusconfdir=$(OUT_DIR)/dbus-1/system.d --enable-testing --enable-experimental  --enable-deprecated --disable-systemd --disable-udev --disable-cups --disable-obex
	cd $(LIB_TAR) && make && make install

prepare:
	rm -rf $(LIB_TAR)
	tar -xvJf $(LIB_PATH)  -C ./

clean:
	cd $(LIB_TAR) && make clean

distclean:
	rm -rf $(LIB_TAR)

10、Makefile

export LIB_CC=arm-himix200-linux-gcc
export OUT_DIR=/usr/etc/bluez/

all:
	$(MAKE) -f ./zlib.mk
	$(MAKE) -f ./libffi.mk
	$(MAKE) -f ./glib.mk
	$(MAKE) -f ./expat.mk
	$(MAKE) -f ./dbus.mk
	$(MAKE) -f ./libical.mk
	$(MAKE) -f ./ncurses.mk
	$(MAKE) -f ./readline.mk
	$(MAKE) -f ./bluez.mk

prepare:
	$(MAKE) prepare -f ./zlib.mk
	$(MAKE) prepare -f ./libffi.mk
	$(MAKE) prepare -f ./glib.mk
	$(MAKE) prepare -f ./expat.mk
	$(MAKE) prepare -f ./dbus.mk
	$(MAKE) prepare -f ./libical.mk
	$(MAKE) prepare -f ./ncurses.mk
	$(MAKE) prepare -f ./readline.mk
	$(MAKE) prepare -f ./bluez.mk

clean:
	$(MAKE) clean -f ./zlib.mk
	$(MAKE) clean -f ./libffi.mk
	$(MAKE) clean -f ./glib.mk
	$(MAKE) clean -f ./expat.mk
	$(MAKE) clean -f ./dbus.mk
	$(MAKE) clean -f ./libical.mk
	$(MAKE) clean -f ./ncurses.mk
	$(MAKE) clean -f ./readline.mk
	$(MAKE) clean -f ./bluez.mk

distclean:
	$(MAKE) distclean -f ./zlib.mk
	$(MAKE) distclean -f ./libffi.mk
	$(MAKE) distclean -f ./glib.mk
	$(MAKE) distclean -f ./expat.mk
	$(MAKE) distclean -f ./dbus.mk
	$(MAKE) distclean -f ./libical.mk
	$(MAKE) distclean -f ./ncurses.mk
	$(MAKE) distclean -f ./readline.mk
	$(MAKE) distclean -f ./bluez.mk

PS:在运行bluez的时候,指定的bluez配置文件路径为编译时–prefix参数所指定的路径。为了方便交叉编译后文件的移植,该参数最好为绝对根路径。

三、移植库

编译好后的文件输出目录:

bin/     dbus-1/  etc/     include/ lib/     libexec/ man/     share/   var/

挂载该目录后将下列文件依次拷贝到对应目录下

cp /mnt/bin/*   /usr/bin/  -rf
cp /mnt/lib/*    /usr/lib/  -rf
cp /mnt/libexec/*  /usr/libexec/  -rf
cp /mnt/libexec/bluetooth/bluetoothd /usr/lib/ -rf
cp /mnt/share/* /share/ -rf

上面我说过注意–prefix=$(PATH) 参数所指定的路径,如果不是交叉编译的话,var和etc会考到跟目录下的var和etc下并为本机配置该参数。但由于我们是交叉编译的,该配置文件要集中输出到输出目录$(PATH) 去,然而有个问题是该路径为dbus和bluez运行时寻找的配置路径,因此本应该在根目录下etc和var目录下寻找的配置文件就变成了$(PATH)/etc和$(PATH)/var。(有兴趣的小伙伴可以研究下代码改下这个路径)
因此需要将该目录创建出来,然后将etc和var拷贝到这里。

mkdir -p $(PATH)
cp /mnt/etc  $(PATH) -rf
cp /mnt/var  $(PATH) -rf
cp  /mnt/dbus-1/system.d/dbus-1/system.d/bluetooth.conf  $(PATH)/etc/dbus-1/system.d/bluetooth.conf

dbus需要有个messagebus用户,创建一个

adduser messagebus

开启蓝牙模块

hciconfig hci0 up

启动dbus和bluez

dbus-daemon --system --print-pid --print-address
bluetoothd -d -n --compat &

然后就可以用下列命令控制蓝牙了

扫描周围传统/低功耗蓝牙:hcitool scan/lescan
发送广播:hciconfig hci0 leadv

四、效果演示

在这里插入图片描述
这里我定义了一个具有读、写、通知功能的服务
在这里插入图片描述
开启通知按钮,收到notify字符串。
在这里插入图片描述
写个个字符串进去。
在这里插入图片描述
读到的就是写进去的字符串。
emmmmmmmmmmmmmm,完美

五、异常问题

1、

Unknown group "lp" in message bus configuration file
Failed to start message bus: The pid file "/usr/etc/bluez/var/run/dbus/pid" exists, if the message bus is not running, remove this file

将/usr/etc/bluez/var/run/dbus/pid删除掉再运行就好了。

2、

src/adapter.c:read_index_list_complete() Number of controllers: 0

当Number of controllers为0时说明蓝牙模块驱动异常。

吐槽下hcitool是真的难用,连bluez的官方都是不推荐使用了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值