BlueZ


一、BlueZ在ubuntu PC上的基礎應用

1、bluez的安裝及基本功能

dong@ubuntu:~/bluez$ ls
bluez-5.47.tar.xz   SPP-loopback.py
dong@ubuntu:~/bluez$ tar xvf bluez-5.47.tar.xz
dong@ubuntu:~/bluez/bluez-5.47$ ./configure --prefix=/usr --mandir=/usr/share/man --sysconfdir=/etc --localstatedir=/var
make
make install

裝完bluez,然后插上藍牙適配器就可以測試了,如果不能啟動就注銷或者重啟一下電腦。

 

2、bluez配對
dong@ubuntu:~/bluez/bluez-5.47$ cd test/
dong@ubuntu:~/bluez/bluez-5.47/test$ python simple-agent
Agent registered

然后可以用手機藍牙助手(Bluetooth spp pro/藍牙串口助手 Pro)來掃描配對藍牙適配器,ubuntu上的simple-agent會彈出配對確認信息,輸入yes回車完成配對

simple-agent是通過主從機之間的交互來實現的,可以實現加密配對。

 

3、bluez spp藍牙透傳demo

bluez-spp-example.zip

SPP-loopback.py和bluez5-spp-example分別是用python和c語言實現的SPP Demo,SPP-loopback.py更簡單一些,運行即可透傳與手機交互。

如果是ubuntu版本太低,安裝bluez可能會缺一些庫文件,裝上庫文件即可,可以參考http://blog.csdn.net/twy76/article/details/23851587

 

過了幾年了,還有人看,剛好整理手機,補兩張圖上來。

 

 

PC上也可以用圖形工具來配置藍牙,blueman-applet比較方便。

 

4、BlueZ文件共享

示例:BlueZ設備(這里是ubuntu PC)與手機之間的文件收發

dong@dong-ubuntu:~$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 004: ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)
Bus 001 Device 002: ID 17ef:6019 Lenovo 
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
dong@dong-ubuntu:~$ hciconfig -a
hci0:    Type: BR/EDR  Bus: USB
    BD Address: 00:1A:7D:DA:71:13  ACL MTU: 310:10  SCO MTU: 64:8
    UP RUNNING PSCAN ISCAN 
    RX bytes:1932 acl:0 sco:0 events:125 errors:0
    TX bytes:4107 acl:0 sco:0 commands:125 errors:0
    Features: 0xff 0xff 0x8f 0xfe 0xdb 0xff 0x5b 0x87
    Packet type: DM1 DM3 DM5 DH1 DH3 DH5 HV1 HV2 HV3 
    Link policy: RSWITCH HOLD SNIFF PARK 
    Link mode: SLAVE ACCEPT 
    Name: 'BlueZ 5.47'
    Class: 0x0c0104
    Service Classes: Rendering, Capturing
    Device Class: Computer, Desktop workstation
    HCI Version: 4.0 (0x6)  Revision: 0x22bb
    LMP Version: 4.0 (0x6)  Subversion: 0x22bb
    Manufacturer: Cambridge Silicon Radio (10)

dong@dong-ubuntu:~$ hcitool scan
Scanning ...
    00:19:86:00:12:12    ZHDZXD
    00:90:A2:CC:57:D8    ZHDGIS
    50:68:0A:42:C5:67    wifitest
    E4:46:DA:6E:8D:85    小米手機
    44:C3:46:56:2E:50    Honor 8 Lite
dong@dong-ubuntu:~$ sdptool browse E4:46:DA:6E:8D:85
Browsing E4:46:DA:6E:8D:85 ...
Service RecHandle: 0x10000
Service Class ID List:
  "Generic Attribute" (0x1801)
Protocol Descriptor List:
  "L2CAP" (0x0100)
    PSM: 31
  "ATT" (0x0007)
    uint16: 0x0001
    uint16: 0x0005
...
...

Browsing E4:46:DA:6E:8D:85 ... Service Search failed: Invalid argument Service Name: OBEX Object Push Service RecHandle: 0x1000b Service Class ID List: "OBEX Object Push" (0x1105) Protocol Descriptor List: "L2CAP" (0x0100) "RFCOMM" (0x0003) Channel: 6 "OBEX" (0x0008) Profile Descriptor List: "OBEX Object Push" (0x1105) Version: 0x0102 Browsing E4:46:DA:6E:8D:85 ... Service Search failed: Invalid argument //send file to moble dong@dong-ubuntu:~$ obex_test -b E4:46:DA:6E:8D:85 6 Using Bluetooth RFCOMM transport OBEX Interactive test client/server. > c Made some progress... Connect OK! Version: 0x10. Flags: 0x00 > x PUSH file> test.txt name=test.txt, size=5 Going to send test.txt(test.txt), 5 bytes Filling stream! Filling stream! Made some progress... Made some progress... PUT successful! > q dong@dong-ubuntu:~$ sudo sdptool add OPUSH OBEX Object Push service registered dong@dong-ubuntu:~$ sudo sdptool browse local Browsing FF:FF:FF:00:00:00 ... Service RecHandle: 0x10000 Service Class ID List: "PnP Information" (0x1200) Profile Descriptor List: "PnP Information" (0x1200) Version: 0x0103 ... ... Service Name: OBEX Object Push Service RecHandle: 0x10008 Service Class ID List: "OBEX Object Push" (0x1105) Protocol Descriptor List: "L2CAP" (0x0100) "RFCOMM" (0x0003) Channel: 9 "OBEX" (0x0008) Profile Descriptor List: "OBEX Object Push" (0x1105) Version: 0x0100 //receive file from moble dong@dong-ubuntu:~$ obex_test -b local 9 Using Bluetooth RFCOMM transport OBEX Interactive test client/server. > s OBEX_HandleInput() returned 1 Unknown event 0b! connect_server() connect_server() Skipped header c0 Made some progress... Server request finished! server_done() Command (00) has now finished OBEX_HandleInput() returned 1 Made some progress... OBEX_HandleInput() returned 1 Made some progress... OBEX_HandleInput() returned 1 Made some progress... OBEX_HandleInput() returned 1 ... ... Made some progress... OBEX_HandleInput() returned 1 put_server() put_server() Found name put_server() Skipped header 42 put_server() Skipped header c3 put_server() Found body Filename = Screenshot_2017-12-19-15-44-49-059_com.baidu.searchbox.png Wrote Screenshot_2017-12-19-15-44-49-059_com.baidu.searchbox.png (257776 bytes) Made some progress... Server request finished! server_done() Command (02) has now finished OBEX_HandleInput() returned 1 Unknown event 0b! We got a disconnect-request Made some progress... Server request finished! Disconnect done! OBEX_HandleInput() returned 1 >

 

二、BlueZ在ARM上的基礎應用

1、BlueZ移植

BlueZ依賴的第三方庫比較多,編譯起來很繁瑣,給每個庫都創建一個config.sh文件,並設置777權限,

創建安裝目錄/usr/local/bluez,也設置777權限,

如下依次運行每個庫的配置文件./config.sh可完整的編譯出ARM的可執行文件。

編譯環境

ubuntu + linaro gcc

gcc編譯器https://www.linaro.org/downloads/

 

硬件環境

CPU: Cortex A5

Bluetooth: wg7813(bluetooth和wifi的復合模塊,芯片是TI的wl18xx)

移植主要參考這個wiki,依賴庫的版本最好也按wiki里的版本,一堆開源庫,不同版本會有沖突,wiki里的版本是一次編譯通過,配合如下腳本。

http://wiki.beyondlogic.org/index.php?title=Cross_Compiling_BlueZ_Bluetooth_tools_for_ARM

1) zlib-1.2.8

#!/bin/bash
cd /home/dong/bluez/zlib-1.2.8
CC=arm-linux-gnueabihf-gcc \
AR=arm-linux-gnueabihf-ar \
RANLIB=arm-linux-gnueabihf-ranlib \
./configure --prefix=/usr/local/bluez

make
if [ $? == 0 ]; then
    make install
else
    echo -e "\n\tmake fail\n"
fi

zlib第一次還不能運行腳本,一步一步來,其他庫都能通過腳本自動化編譯,安裝。

Download, cross compile and install the zlib compression libraries. Configure doesn't accept the --host parameter (reports unknown option), so you need to hack the makefile. 

wget http://zlib.net/zlib-1.2.8.tar.gz
tar -xzf zlib-1.2.8.tar.gz
cd zlib-1.2.8/
./configure --prefix=/usr/local/bluez

Edit the makefile and prefix the build tools with arm-linux-gnueabi-.

CC=arm-linux-gnueabihf-gcc
LDSHARED=arm-linux-gnueabihf-gcc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map
CPP=arm-linux-gnueabihf-gcc -E
AR=arm-linux-gnueabihf-ar
RANLIB=arm-linux-gnueabihf-ranlib

Make and install:

make
make install

2) libffi-3.0.13

#!/bin/bash
./configure --host=arm-linux-gnueabihf --prefix=/usr/local/bluez

make
if [ $? == 0 ]; then
    make install
else
    echo -e "\n\tmake fail\n"
fi

 

3) glib-2.40.0

#!/bin/bash
./configure --host=arm-linux-gnueabihf \
LIBFFI_CFLAGS="-I/usr/local/bluez/lib/libffi-3.0.13/include" \
LIBFFI_LIBS="-lffi -L/usr/local/bluez/lib" \
ZLIB_CFLAGS="-I/usr/local/bluez/include" \
ZLIB_LIBS="-lz -L/usr/local/bluez/lib" \
--prefix=/usr/local/bluez PKG_CONFIG_PATH=/usr/local/bluez/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

make
if [ $? == 0 ]; then
    make install
else
    echo -e "\n\tmake fail\n"
fi

報錯configure: error: Could not find a glib-genmarshal in your PATH,缺了libglib2.0-dev

sudo apt-get install libglib2.0-dev

 

4) expat-2.1.0

#!/bin/bash
./configure --host=arm-linux-gnueabihf --prefix=/usr/local/bluez

make
if [ $? == 0 ]; then
    make install
else
    echo -e "\n\tmake fail\n"
fi

 

5) dbus-1.8.0

#!/bin/bash
./configure --host=arm-linux-gnueabihf --prefix=/usr/local/bluez PKG_CONFIG_PATH=/usr/local/bluez/lib/pkgconfig \
--disable-tests \
--sysconfdir=/usr/local/bluez/etc                    \
--localstatedir=/usr/local/bluez/var                 \
--enable-user-session                \
--disable-doxygen-docs               \
--disable-xml-docs                   \
--disable-static                     \
--docdir=/usr/local/bluez/share/doc/dbus-1.8.0   \
--with-console-auth-dir=/usr/local/bluez/var/run/console \
--with-system-pid-file=/usr/local/bluez/var/run/dbus/pid \
--with-system-socket=/usr/local/bluez/var/run/dbus/system_bus_socket \
CPPFLAGS='-I/usr/local/bluez/include/' \
CFLAGS='-I/usr/local/bluez/include/' \
LDFLAGS='-L/usr/local/bluez/lib'

make
if [ $? == 0 ]; then
    make install
else
    echo -e "\n\tmake fail\n"
fi

 

6) libical-1.0

#!/bin/bash
export CC=arm-linux-gnueabihf-gcc
export CXX=arm-linux-gnueabihf-g++
cmake -DCMAKE_INSTALL_PREFIX=/usr/local/bluez

make
if [ $? == 0 ]; then
    make install
else
    echo -e "\n\tmake fail\n"
fi

 

7) ncurses-5.9

#!/bin/bash
cd /home/dong/bluez/ncurses-5.9
./configure --prefix=/usr/local/bluez --with-shared \
CC=arm-linux-gnueabihf-gcc \
CXX=arm-linux-gnueabihf-g++ \
--host=arm-linux-gnueabihf

make
if [ $? == 0 ]; then
    make install
else
    echo -e "\n\tmake fail\n"
fi

 

8) readline-6.3

#!/bin/bash
./configure --host=arm-linux-gnueabihf --prefix=/usr/local/bluez bash_cv_wcwidth_broken=yes \
PKG_CONFIG_PATH=/usr/local/bluez/lib/pkgconfig \
CPPFLAGS='-I/usr/local/bluez/include/' \
CFLAGS='-I/usr/local/bluez/include/' \
LDFLAGS='-lncurses -L/usr/local/bluez/lib'

#make SHLIB_LIBS=-lncurses
make
if [ $? == 0 ]; then
    make install
else
    echo -e "\n\tmake fail\n"
fi

 

9) bluez-5.18

#!/bin/bash
./configure --host=arm-linux-gnueabihf \
--prefix=/usr/local/bluez \
CC="arm-linux-gnueabihf-gcc \
-L/usr/local/bluez/lib \
-I/usr/local/bluez/include \
-I/usr/local/bluez/include/glib-2.0 \
-I/usr/local/bluez/include/dbus-1.0 \
-I/usr/local/bluez/lib/glib-2.0/include \
-I/usr/local/bluez/lib/dbus-1.0/include \
-I/usr/local/bluez/lib/libffi-3.0.13/include " \
PKG_CONFIG_PATH=/usr/local/bluez/lib/pkgconfig \
CPPFLAGS='-I/usr/local/bluez/include/' \
CFLAGS='-I/usr/local/bluez/include/' \
LDFLAGS='-lrt -lreadline -lncurses -L/usr/local/bluez/lib' \
--disable-systemd --disable-udev --disable-cups --enable-library 

make
if [ $? == 0 ]; then
    make install
else
    echo -e "\n\tmake fail\n"
fi

再次說明版本務必要匹配,否則會沖突,怎么檢查版本匹配,暫時不清楚,新版本庫匹配在下面這網站去找,下面兩個版本都有匹配好的BlueZ Dependencies

BlueZ-5.46

http://www.linuxfromscratch.org/blfs/view/stable/general/bluez.html

BlueZ-5.48

http://www.linuxfromscratch.org/blfs/view/svn/general/bluez.html

 

2、板載bluez調試

1)linux內核配置bluetooth驅動參考 http://blog.csdn.net/new_abc/article/details/7639326 (bluetooth和wifi)
 [*]Networking support  --->               

                   <*>   Bluetooth subsystem support  ---> //藍牙子系統必須選擇

                   <*>   L2CAP protocol suppor                  //邏輯鏈路控制和適配協議。

                   <*>   SCO links support                          //藍牙語音和耳機支持

                   <*>   RFCOMM protocol suppor             //面向流的傳輸協議,支持撥號網絡等

                   [*]   RFCOMM TTY support                

                   <*>   BNEP protocol support                   //藍牙網絡封裝協議,自組網支持

                   [*]   Multicast filter support                      //藍牙多播,支持支持BNEP

                   [*]   Protocol filter support                       //藍牙多播,支持支持支持BNEP

                   <*>   HIDP protocol support                   //基本支持協議

         Bluetoothdevice drivers  --->

                   <*>HCI USB driver                                 //USB藍牙模塊支持

                   <*>HCIUART driver                               //基於串口,CF卡或PCMCIA的藍牙

                   <*>HCI BlueFRITZ! USB driver

                   <*>HCI VHCI (Virtual HCI device) driver

其余的選項,根據自己的藍牙設備進行調整。

2)移植完的bluez,把安裝文件拷貝到板子上,只需要dbus和bluez的安裝文件,總共應該不超過5M,我的在/usr/local/bluez,然后添加環境變量。

拷貝幾個庫文件,添加messagebus用戶,還是參考剛才的wiki

addgroup -S messagebus
adduser -S messagebus -G messagebus

http://wiki.beyondlogic.org/index.php?title=Cross_Compiling_BlueZ_Bluetooth_tools_for_ARM

可以試試hciconfig, hcitool, dbus-deamon等工具是否正常,正常了就移植成功了。

板子內存緊張可以用nfs掛載的方式來調試,掛載好了,環境變量設置到掛載的路徑就可以了。

先安裝好nfs服務器

https://jingyan.baidu.com/article/e5c39bf5abc8f739d76033be.html

開發板掛載ubuntu,在ubuntu用戶目錄下的nfs目錄中准備好文件

在開發板上掛載ubuntu
mkdir /mnt/bluez
#在開發板端掛載板子網卡,這里用的USB模擬的網卡,掛載到usb0,真實的網卡就不需要模擬這一步了。

modprobe g_multi.ko file=/dev/mmcblk0p5,/dev/mmcblk0p6 ro=0,0 luns=2 stall=0 removable=1,1 iSerialNumber=3000111
ifconfig usb0 192.168.10.2

在ubuntu端打開網卡
ifconfig enp0s20f0u2 192.168.10.6 netmask 255.255.255.0
ifconfig enp0s20f0u2 up 192.168.10.6
#在開發板端掛載ubuntu上的nfs服務器
mount -t nfs -o nolock 192.168.10.6:/home/dong/nfs /mnt
#umount -t nfs -a nolock 192.168.10.6:/home/dong/nfs /mnt

開發板添加環境變量
#add path
export PATH=/mnt/bluez/bin:$PATH
export LD_LIBRARY_PATH=/mnt/bluez/lib:$LD_LIBRARY_PATH


或者在/etc/profile里添加環境變量永久生效

export PATH=\
/bin:\
/sbin:\
/usr/bin:\
/usr/sbin:\
/usr/bin/X11:\
/usr/local/bin:\
/mnt/bluez/bin:\

export LD_LIBRARY_PATH=/mnt/bluez/lib:$LD_LIBRARY_PATH


source /etc/profile

創建並運行腳本文件bluez.init.sh,運行成功就可以用手機搜到BlueZ-5.18的藍牙設備

#power on
echo 49 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio49/direction
echo 0 > /sys/class/gpio/gpio49/value
sleep 0.2
echo 1 > /sys/class/gpio/gpio49/value
sleep 0.2

#load firmware
hciattach -s 115200 /dev/ttyS2 texas 115200 flow

hciconfig hci0 up                                                                             
sleep 0.1                                                                                     
hciconfig hci0 iscan                                                                          
sleep 0.1

rm -rf /usr/local/bluez/var/run/dbus/pid                                                                         

dbus-daemon --system                                                              
sleep 0.2                                                                                    
bluetoothd &                                                                     
sleep 1                                                                                                                                                            
hciconfig hci0 iscan  

有時候環境變量寫到配置文件會失效,程序運行會從系統庫目錄/lib  /usr/lib查找庫文件,不從我們配置的/mnt/bluez/lib目錄里找

運行臨時環境變量配置指令即可生效

export PATH=/mnt/bluez/bin:$PATH
export LD_LIBRARY_PATH=/mnt/bluez/lib:$LD_LIBRARY_PATH

3、python移植

新版本bluez的demo都是python寫的,所以還需要把python也移植到板子上。
1)下載好Python-2.7.2.tgz和補丁文件Python-2.7.2-xcompile.patch
2)編譯PC上運行的pgen
./configure

make python Parser/pgen

mv python hostpython

mv Parser/pgen Parser/hostpgen

make distclean

3)給Python-2.7.2打補丁
patch -p1 < Python-2.7.2-xcompile.patch

4)交叉編譯,編譯器arm-linux-gnueabihf-
CC=arm-linux-gnueabihf-gcc CXX=arm-linux-gnueabihf-g++ AR=arm-linux-gnueabihf-ar RANLIB=arm-linux-gnueabihf-ranlib ./configure --host=arm-linux-gnueabihf --build=x86_64-linux-gnu --prefix=/home/dong/_install

chmod 777 ./setup.py

如果空間緊張,可以更改Makefile,不需要debug,去掉-g,優化等級調成-o2
#OPT=        -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes
OPT=        -DNDEBUG -fwrapv -O2 -Wall -Wstrict-prototypes

make HOSTPYTHON=./hostpython HOSTPGEN=./Parser/hostpgen BLDSHARED="arm-linux-gnueabihf-gcc -shared" CROSS_COMPILE=arm-linux-gnueabihf- CROSS_COMPILE_TARGET=yes HOSTARCH=arm-linux-gnueabihf BUILDARCH=x86_64-linux-gnu

make install HOSTPYTHON=./hostpython BLDSHARED="arm-linux-gnueabihf-gcc -shared" CROSS_COMPILE=arm-linux-gnueabihf- CROSS_COMPILE_TARGET=yes prefix=/home/dong/_install

如果安裝報錯
python: Syntax error: word unexpected (expecting ")")
將install-sh文件第一行#!/bin/sh改成#!/bin/bash

5)把安裝目錄下的文件復制到arm設備上,並吧Python路徑添加到PATH中,然后執行測試
python /usr/local/python/lib/python2.7/test/test___all__.py

我的板內存空間緊張,先用nfs掛載來調試

轉自
http://blog.csdn.net/xiwenfuor/article/details/38384687
http://blog.sina.com.cn/s/blog_609b4c0d01012j5q.html

 

我移植完了,發現這個blog寫得很簡潔。

https://blog.csdn.net/qq_28351465/article/details/54406180



4、板載python調試

python的庫文件很大,還是跟上面調試bluez一樣,采用nfs來調試

開發板添加環境變量
#add path
export PATH=/mnt/python/bin:$PATH
export LD_LIBRARY_PATH=/mnt/python/lib:$LD_LIBRARY_PATH


或者在/etc/profile里添加環境變量永久生效

export PATH=\
/bin:\
/sbin:\
/usr/bin:\
/usr/sbin:\
/usr/bin/X11:\
/usr/local/bin:\
/mnt/bluez/bin:\
/mnt/python/bin:\

 

export LD_LIBRARY_PATH=/mnt/bluez/lib:$LD_LIBRARY_PATH

export LD_LIBRARY_PATH=/mnt/python/lib:$LD_LIBRARY_PATH


source /etc/profile

掛載后運行python –V就可以看到python的版本信息了。

python /mnt/python/lib/python2.7/test/test___all__.py
運行結果
Following modules have no __all__ and have been ignored: ['DocXMLRPCServer', 'HTMLParser', 'SimpleXMLRPCServer', 'UserDict', 'UserList', '_LWPCookieJar', '_MozillaCookieJar', '__phello__.foo', 'abc', 'an]
Following modules failed to be imported: ['ctypes.wintypes', 'dbhash', 'gzip', 'idlelib.AutoComplete']
ok

----------------------------------------------------------------------
Ran 1 test in 48.532s

OK

 

5、運行simple-agent 或者 BlueZ SPP Demo
[root@sama5d3x /mnt]# python simple-agent
Traceback (most recent call last):
  File "simple-agent", line 7, in <module>
    import dbus
ImportError: No module named dbus

缺了dbus模塊
交叉編譯dbus-python-1.2.4

折騰一天看見這個心碎了

https://www.zhihu.com/question/34573048

找了一圈,只能用buildroot來制作支持python的文件系統

http://www.at91.com/linux4sam/bin/view/Linux4SAM/BuildRootBuild

https://www.cnblogs.com/chencanjian/p/6060448.html

 

6、buildroot編譯dbus-python庫

進入buildroot根目錄
make menuconfig
找到

dbus-python

gobject

其實不用像上面那樣單獨移植python也可以,就在buildroot里把python和需要的庫都選上更方便,

buildroot還可以壓縮庫文件,還更省空間。

用yocto或者 OpenEmbedded來構建文件系統貌似也行,沒有驗證

 
make編譯完就有了dbus-python庫,運行python simple-agent,缺哪個庫就拷貝哪個庫,一共需要10幾個吧。
庫都不缺了,發現連接不上 dbus.SystemBus()
[root@sama5d3x /mnt]# python
Python 2.7.2 (default, Jan 20 2018, 15:29:23) 
[GCC 4.7.3 20121205 (prerelease)] on linux4
Type "help", "copyright", "credits" or "license" for more information.
>>> from __future__ import absolute_import, print_function, unicode_literals
>>> import gobject as GObject
>>> import sys
>>> import dbus
>>> import dbus.service
>>> import dbus.mainloop.glib
>>> from optparse import OptionParser
>>> dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
<dbus.mainloop.NativeMainLoop object at 0x2ecc08>
>>> bus = dbus.SystemBus()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/site-packages/dbus/_dbus.py", line 194, in __new__
  File "/usr/lib/python2.7/site-packages/dbus/_dbus.py", line 100, in __new__
  File "/usr/lib/python2.7/site-packages/dbus/bus.py", line 122, in __new__
dbus.exceptions.DBusException: org.freedesktop.DBus.Error.FileNotFound: Failed to connect to socket /var/run/dbus/system_bus_socket: No such file or directory

連不上dbus的socket,就差一口氣了......

突然發現dbus-1.8.0庫編譯的時候沒打開--with-system-socket

參考http://www.linuxfromscratch.org/blfs/view/svn/general/dbus.html

./configure --prefix=/usr                        \
            --sysconfdir=/etc                    \
            --localstatedir=/var                 \
            --disable-doxygen-docs               \
            --disable-xml-docs                   \
            --disable-static                     \
            --docdir=/usr/share/doc/dbus-1.8.0 \
            --with-console-auth-dir=/run/console \
            --with-system-pid-file=/run/dbus/pid \
            --with-system-socket=/run/dbus/system_bus_socket &&
make

更改上面dbus-1.8.0的編譯配置,上面已經改過來了,重新編譯,再運行配對例子

[root@sama5d3x test]# hciconfig hci0 pscan
[root@sama5d3x test]# hciconfig hci0 noauth
[root@sama5d3x test]# python simple-agent
Agent registered
RequestConfirmation (/org/bluez/hci0/dev_E4_46_DA_6E_8D_85, 565038)
Confirm passkey (yes/no): yes
[root@sama5d3x test]# cd ..
[root@sama5d3x /mnt]# python SPP-loopback.py 
NewConnection(/org/bluez/hci0/dev_E4_46_DA_6E_8D_85, 9)
received: aaa
received: step by step
received: BlueZ SPP OK !

配對simple-agent和藍牙透傳SPP-loopback.py都正常,再把bluez和python庫裁剪,整理好就可以植入產品里了。

SPP-loopback.py藍牙串口透傳例子是intel的Edison模塊的,也可以用在這里。

intel edison bluetooth guide 這個文檔比較完整。

http://download.intel.com/support/edison/sb/edisonbluetooth_331704004.pdf

 

我整理的啟動腳本 bluez_init.sh

#power on
echo 49 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio49/direction
echo 0 > /sys/class/gpio/gpio49/value
sleep 0.2
echo 1 > /sys/class/gpio/gpio49/value
sleep 0.2

#load firmware
hciattach -s 115200 /dev/ttyS2 texas 115200 flow
sleep 1 
hciconfig hci0 up                                                                             
sleep 0.1                                                                                     
hciconfig hci0 iscan                                                                          
sleep 0.1

#add dbus dir
rm -r /usr/local/bluez/var/run/dbus
ln -s /run/dbus/ /usr/local/bluez/var/run/
rm -rf /usr/local/bluez/var/run/dbus/pid 
mkdir /run/dbus 

#boot bluez process                                                                       
dbus-daemon --system                                                              
sleep 1                                                                                    
bluetoothd &                                                                    
sleep 1 

#run user app                                                                        
python simple-agent &
sleep 0.1
python SPP-loopback.py &
sleep 0.1
hciconfig hci0 name "bluez_test"
hciconfig hci0 piscan

 

將bluez-5.18的simple-agent文件中配對認證注釋掉,設備就不認證了

    def AuthorizeService(self, device, uuid):
        print("AuthorizeService (%s, %s)" % (device, uuid))
        #authorize = ask("Authorize connection (yes/no): ")
        #if (authorize == "yes"):
        #    return
        #raise Rejected("Connection rejected by user")
...
...

    def RequestConfirmation(self, device, passkey):
        print("RequestConfirmation (%s, %06d)" % (device, passkey))
        #confirm = ask("Confirm passkey (yes/no): ")
        #if (confirm == "yes"):
        set_trusted(device)
        #    return
        #raise Rejected("Passkey doesn't match")

    @dbus.service.method(AGENT_INTERFACE,
                    in_signature="o", out_signature="")
    def RequestAuthorization(self, device):
        print("RequestAuthorization (%s)" % (device))
        #auth = ask("Authorize? (yes/no): ")
        #if (auth == "yes"):
        #    return
        #raise Rejected("Pairing rejected")

給板子上電,掛載好bluez和python的庫文件,然后運行上面的啟動腳本 ./bluez.init.sh

[root@sama5d3x /root]# mount -t nfs -o nolock 192.168.10.6:/home/dong/nfs /mnt  
[root@sama5d3x /root]# cd /mnt/                                                 
[root@sama5d3x /mnt]# ./bluez.init.sh                                           
Found a Texas Instruments' chip!                                                
Firmware file : /lib/firmware/ti-connectivity/TIInit_11.8.32.bts                
Loaded BTS script version 1                                                     
Device setup complete                                                           
[root@sama5d3x /mnt]# Agent registered                                          
RequestConfirmation (/org/bluez/hci0/dev_E4_46_DA_6E_8D_85, 345760)             
NewConnection(/org/bluez/hci0/dev_E4_46_DA_6E_8D_85, 9)                         
received: step by step                                                          
received: step by step                                                          
received: step by step

 

 7、python與c之間的交互

可以用的方式很多,共享內存,消息隊列,管道,進程池或者直接封裝接口互相調用函數。

搜一下就有了.下面是我找的共享內存機制

1) Python讀取c語言進程的內存塊

http://chl0000.iteye.com/blog/1915303

http://www.linuxidc.com/Linux/2012-03/57430.htm

2) python和c語言參數傳遞

c--->python
http://blog.csdn.net/JoeBlackzqq/article/details/10441017
http://blog.csdn.net/chenyulancn/article/details/8158168
python--->c
http://blog.csdn.net/mrcheny/article/details/79022973

3) 實例:導出python進程的數據

我這個項目需要導出python進程的數據給c進程處理

給c語言進程提供一個數據結構

bluetooth_data.c

#include <stdio.h>

struct bluetooth_t{    
    int status;
    char *buf;
};

int bluetooth_cb(struct bluetooth_t bluetooth)
{
        printf("bluetooth status:%d, bluetooth buf:%s \n", bluetooth.status,bluetooth.buf);
        return 0;
}

編譯成so庫文件

gcc/arm-linux-gnueabihf-gcc -o bluetooth_data.so -shared -fPIC bluetooth_data.c

然后python進程把需要的數據寫到上面的數據結構

data_test.py

#!/usr/bin/python
import ctypes
from ctypes import *

class bluetooth(Structure):
        _fields_=[('status',c_int),('buf',c_char_p)]

if __name__ == "__main__":

    func = ctypes.cdll.LoadLibrary("./bluetooth_data.so")

    s = bluetooth()
    s.status = 1
    s.buf = bytes('hello,world')
    func.bluetooth_cb(s)

運行python data_test.py就可以打印出導出的數據

bluetooth status:1, bluetooth buf:hello,world.

 

8、bluez的BLE工作模式

只有bluez-5.xx以上版本才支持低功耗模式,配置跟普通模式有細微差別

我配置的BLE模式啟動腳本 bluez_le_init.sh

#power on
echo 49 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio49/direction
echo 0 > /sys/class/gpio/gpio49/value
sleep 0.2
echo 1 > /sys/class/gpio/gpio49/value
sleep 0.2

#load firmware
hciattach -s 115200 /dev/ttyS2 texas 115200 flow
sleep 1 
hciconfig hci0 up                                                                             
sleep 0.1                                                                                     
hciconfig hci0 iscan                                                                          
sleep 0.1

#add dbus dir
rm -r /usr/local/bluez/var/run/dbus
ln -s /run/dbus/ /usr/local/bluez/var/run/
rm -rf /usr/local/bluez/var/run/dbus/pid 
mkdir /run/dbus 


#boot bluez process                                                                       
dbus-daemon --system                                                              
sleep 1                                                                                    
bluetoothd &                                                                    
sleep 1 

#run user app                                                                        
python simple-agent &
sleep 0.1

if false ; then
#Bluetooth SPP
python SPP-loopback.py &
else
#Bluetooth profile
hciconfig hci0 up
sleep 0.1
hciconfig hci0 leadv
fi

sleep 0.1
hciconfig hci0 name "bluez_test"
hciconfig hci0 piscan

用了個

if false ; then

...

else

...

fi

把普通模式和BLE模式分開

給板子上電后運行./bluez.le.init.sh

找個藍牙4.0的工具( 我用的BLE Tool )就能掃到BlueZ-5.18的設備, 讀幾個自帶的特征值profile都正常。

 

9、藍牙NFS掛載模式應用(nfs_debug)

首次運行需要配置相關系統參數

1)#配置內核藍牙選項

2)#添加進程消息通道
addgroup -S messagebus
adduser -S messagebus -G messagebus

3#添加lp
vi /etc/group
lp:x:7:

4)#配置網卡
modprobe g_multi.ko file=/dev/mmcblk0p5,/dev/mmcblk0p6 ro=0,0 luns=2 stall=0 removable=1,1 iSerialNumber=3000111
ifconfig usb0 192.168.10.2

5)在ubuntu端打開網卡
不同主機生成的網卡名稱可能不一樣,ifconfig查看,這個是我的台式機,下面那個是我的筆記本
sudo ifconfig enp0s20f0u2 192.168.10.6 netmask 255.255.255.0
sudo ifconfig enp0s20f0u2 up 192.168.10.6


sudo ifconfig enp0s20f0u4 192.168.10.6 netmask 255.255.255.0
sudo ifconfig enp0s20f0u4 up 192.168.10.6

6)#在開發板端掛載ubuntu上的nfs服務器
mount -t nfs -o nolock 192.168.10.6:/home/dong/nfs /mnt/nfs
#umount -t nfs -a nolock 192.168.10.6:/home/dong/nfs /mnt/nfs

7)#添加環境變量

export PATH=\
/bin:\
/sbin:\
/usr/bin:\
/usr/sbin:\
/usr/bin/X11:\
/usr/local/bin:\
/mnt/nfs/bluez/bin:\
/mnt/nfs/python/bin:\

...

export LD_LIBRARY_PATH=/mnt/nfs/bluez/lib:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH=/mnt/nfs/python/lib:$LD_LIBRARY_PATH

source /etc/profile

8)添加bluez配置文件
#cp -r /mnt/bluez /usr/local/
#cp -r /mnt/python /usr/local/
cp -r config/bluez /usr/local/

9) 啟動藍牙應用
./bluez.init.sh                                  

10、藍牙正式應用(readme)

藍牙文件系統構建:

1) 配置內核藍牙選項

2) 添加進程消息通道
addgroup -S messagebus
adduser -S messagebus -G messagebus

3) 添加lp
vi /etc/group
lp:x:7:

4) 拷貝庫文件
cp -r bluez /usr/local/                                    
cp -r python /usr/local/

5)拷貝應用程序
cp bluez.init.sh SPP-loopback.py /usr/local/project/
cp -r test /usr/local/project/

6)添加dbus軟鏈接
rm -r /usr/local/bluez/var/run/dbus
ln -s /run/dbus/ /usr/local/bluez/var/run/

7)啟動藍牙進程bluez_init.sh

三、Bluetooth Audio ALSA Backend

https://github.com/Arkq/bluez-alsa

 

四、BLE4.0 Gatt-server

除了bluez的test目錄python腳本 example-gatt-server(依賴的組件比較多,可能運行起來有點困難)

還有兩種方案添加gatt自定義服務,都是開源的

一種是用bleno庫,一種是go-server

我用的芯片不支持完整的BLE4.0,不能自定義用戶profile 和 gatt service

一般完整支持BLE4.0或以上的芯片都是帶flash的,需要更改藍牙協議棧固件,能夠作為IoT場景應用的藍牙IC除了少部分通用芯片,大部分都是定制的專用芯片,像csr1000系列,TI的cc25xx cc26xx系列,nordic的rf51xx rf52xx系列等,都需要用廠商的專用工具來配置profile和gatt service.

下面參考文獻是我收集的藍牙自定義gatt-server方案和應用實例。

參考文獻

1)RPi Bluetooth LE

2)用樹莓派玩轉藍牙

3)A Node.js module for implementing BLE (Bluetooth Low Energy) peripherals

4)Package gatt provides a Bluetooth Low Energy GATT implementation

5)玩轉BLE(3)_使用微信藍牙精簡協議偽造記步數據

6)Implementation of BLE peripheral using bleno

7)Python BLE GATT Server (peripheral)

8)Standalone D-Bus-based BlueZ BLE GATT server for C/C++

9)A custom Prosthetic GATT profile BLE Server / Peripheral implementation for prototyping and GA integration testing.

越折騰越深入,工作上做的產品最多也就用到這些內容,你願意將業余時間花在藍牙協議棧上面,深挖到底嗎?對不起,我不舍得,就此打住!

 

最后總結:從0到調試完成,整個過程需要點耐心,我前面因為太急躁導致多做了不少無用功,欲速則不達。

 

end

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM