Chinaunix首页 | 论坛 | 博客
  • 博客访问: 28827
  • 博文数量: 6
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 116
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-28 14:21
文章分类
文章存档

2015年(1)

2014年(2)

2013年(3)

我的朋友

分类: LINUX

2013-09-26 22:14:07

   linux蓝牙移植使用

                            蓝牙介绍

一、蓝牙简介

是一个短距离无线通信标准,适用于手机、计算机和其他电子设备之间的通信。蓝牙采用分散式网络结构以及快跳频和短包技术,支持点对点及点对多点通信,工作在全球通用的 2.4GHz ISM(即工业、科学、医学)频段。采用时分双工传输方案实现全双工传输。在Linux 中,通常使用的蓝牙协议栈实现是 BlueZ(其他协议还有很多,NOKIA,BCM 都有开发,这里就不一一列举了)。

蓝牙基本知识:

?  采用跳频技术,数据包短,抗信号衰减能力强;

?  采用快速跳频和前向纠错方案以保证链路稳定,减少同频干扰和远距离传输时的       随机噪声影响;

?  使用2.4GHzISM频段,无须申请许可证;

?  可同时支持数据、音频、视频信号;

 

蓝牙2.02004年推出,虽然传输距离短,传输速度慢,但是已经基本满足数据传输需求。

蓝牙3.02009年推出,传输速度达24Mbps,是蓝牙2.0 的八倍。能轻松用于录像机至高清电视,pc至打印机之间的资料传输。

蓝牙4.02010年推出,传输距离达100m,(3.0传输距离10m)。功耗低,成本低。

 

二、蓝牙协议简介

1HCI协议编程

HCI是沟通上层协议以及程序与底层硬件协议的通道。所以,通过HCI发送的Command都是上层协议或者应用程序发送给Bluetooth Dongle的。它命令Bluetooth Dongle(或其中的硬件协议)去做什么何种动作。

 

?  得到Host上插入Dongle数目以及Dongle信息:

分配一个空间给 hci_dev_list_req。这里面将放所有Dongle信息。

 

struct hci_dev_list_req *dl;

struct hci_dev_req *dr;

struct hci_dev_info di;

int i;

 if(!(dl = malloc(HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t)))) {

 perror("Can't allocate memory");

 exit(1);

 }

 dl->dev_num= HCI_MAX_DEV;

 dr =dl->dev_req;

// 打开一个HCI socket.

if ((ctl = socket(AF_BLUETOOTH, SOCK_RAW,BTPROTO_HCI)) < 0) {

 perror("Can't open HCI socket.");

 exit(1);

 }

// 使用HCIGETDEVLIST,得到所有dongleDevice ID。存放在dl中。 

 if(ioctl(ctl, HCIGETDEVLIST, (void *) dl) < 0) {

 perror("Can't get device list");

 exit(1);

 }

// 使用HCIGETDEVINFO,得到对应Device IDDongle信息。

di.dev_id = (dr+i)->dev_id;

ioctl(ctl, HCIGETDEVINFO, (void *) &di)

 

 

?  UPDownBluetooth Dongle

ioctl(ctl, HCIDEVUP, hdev)

ioctl(ctl, HCIDEVDOWN, hdev)

ctl:为使用socket(AF_BLUETOOTH,SOCK_RAW, BTPROTO_HCI)打开的Socket.

hdev: Dongle Device ID.(所以上面的Socket不需要bind,因为这边指定了)

 

?  打开一个HCISocket---int hci_open_dev(int dev_id):

 

这个function用来打开一个HCI Socket。它首先打开一个HCI protocolSocket,并将此SocketdeviceID=参数dev_idDongle绑定起来。只有bind后,它才将Socket句柄与Dongle对应起来。

注意,所有的HCI Command发送之前,都需要使用 hci_open_dev打开并绑定。

 

?  关闭一个HCISocket

int hci_close_dev(int dd) //简单的关闭使用hci_open_dev打开的Socket

 

?  HCI Socket(对应一个Dongle)发送 request:

 

int hci_send_req(int dd, struct hci_request*r, int to)

 

BlueZ提供这个function非常有用,它可以实现一切HostModules发送Command的功能。

参数1HCI Socket

参数2Command内容。

参数3:以milliseconds为单位的timeout.

下面详细解释此function和用法:

当应用程序需要向Dongle(对应为一个bind后的Socket)发送Command时,调用此function.

其中,参数一dd对应一个使用hci_open_dev()打开的SocketDongle)。

参数三to则为等待Dongle执行并回复命令结果的timeout.以毫秒为单位。

参数二hci_request * r 最为重要,首先看它的结构:

struct hci_request {

 uint16_t ogf;    //Opcode Group

 uint16_t ocf;    //Opcode Command

 int     event;  //Command产生的Event类型。

 void    *cparam; //Command 参数

 int     clen;    //Command参数长度

 void    *rparam;  //Response 参数

 int     rlen;    //Response 参数长度

};

 

至于event.如果设置,它会被setsockopt设置于Socket

 

1:得到某个连接的Policy Setting.

 

HCI Spec以及~/include/net/bluetooth/hci.h中均可看到,OGF=OGF_LINK_POLICY(0x02). OCF=OCF_READ_LINK_POLICY(0x0C).

 

因为这个Command用来读取某个ACL连接的Policy Setting。所以输入参数即为此连接Handle.

 

返回参数则包含3部分,statusCommand是否顺利执行), handle(连接Handle)policy(得到的policy值)

 

这就又引入了一个新问题,如何得到某个ACL连接的Handle

 

可以使用ioctl HCIGETCONNINFO得到ACL 连接Handle

 

ioctl(dd, HCIGETCONNINFO, (unsigned long)cr)

 

Connect_handle =htobs(cr->conn_info->handle);

 

所以完整的过程如下:

 

struct hci_request HCI_Request;

 read_link_policy_cp Command_Param;

 read_link_policy_rp Response_Param;

 

// 1.得到ACL Connect Handle

 

if (ioctl(dd, HCIGETCONNINFO, (unsignedlong) cr) < 0)

 { 

 return -1

 }

 Connect_handle =htobs(cr->conn_info->handle);

 

memset(&HCI_Request, 0,sizeof(HCI_Request));

 memset(&Command_Param, 0 ,sizeof(Command_Param));

 memset(&Response_Param, 0 , sizeof(Response_Param));

 

// 2.填写Command输入参数

 Command_e = Connect_handle;

 

HCI_ = OGF_LINK_POLICY;  //CommandID

 HCI_ = OCF_READ_LINK_POLICY;//Command ID

 HCI_m = &Command_Param;

 HCI_ = READ_LINK_POLICY_CP_SIZE;

 HCI_m = &Response_Param;

 HCI_ = READ_LINK_POLICY_RP_SIZE;

 

if (hci_send_req(dd, &HCI_Request, to)< 0)

 {

 perror("\nhci_send_req()");

 return -1;

 }

 

//如果返回值状态不对

 

 if(Response_s) {

 return -1;

 }

 

 

//得到当前policy

 *policy = Response_y;

 

?  几个更基础的function:

 

static inline void bacpy(bdaddr_t *dst,const bdaddr_t *src) //bdaddr copy

 

static inline int bacmp(const bdaddr_t*ba1, const bdaddr_t *ba2)//bdaddr 比较

 

?  得到指定DongleBDAddr

 

int hci_read_bd_addr(int dd, bdaddr_t*bdaddr, int to)

 

参数1HCI Socket,使用hci_open_dev()打开的SocketDongle)。

 

参数2:输出参数,其中会放置bdaddr.

 

参数3:以milliseconds为单位的timeout.

 

?  读写DongleName

 

int hci_read_local_name(int dd, int len,char *name, int to)

 

int hci_write_local_name(int dd, const char*name, int to)

 

参数1HCI Socket,使用hci_open_dev()打开的SocketDongle)。

 

参数2:读取或设置Name

 

参数3:以milliseconds为单位的timeout.

 

注意:这里的NameIOCTL HCIGETDEVINFO 得到hci_dev_info中的name不同。

 

?  得到HCIVersion:

 

int hci_read_local_version(int dd, structhci_version *ver, int to)

 

?  得到已经UPDongle BDaddr

 

int hci_devba(int dev_id, bdaddr_t *bdaddr)

 

dev_id: Dongle Device ID.

 

bdaddr:输出参数,指定Dongle如果UP, 则放置其BDAddr

 

?  得到DongleInfo

 

int hci_devinfo(int dev_id, structhci_dev_info *di)

 

dev_id: Dongle Device ID.

 

di: Dongle信息。

 

出错返回 -1

 

注意,这个Function的做法与3.0的方法完全一致。

 

?  hciX中得到X

 

int hci_devid(const char *str)

 

str: 类似 hci0这样的字串。

 

如果hciX对应的Device ID(X)是现实存在且UP。则返回此设备Device ID

 

?  得到BDADDR不等于参数bdaddrDongle Device ID

 

int hci_get_route(bdaddr_t *bdaddr)

 

查找Dongle,发现Dongle Bdaddr不等于参数bdaddr的第一个Dongle,则返回此Dongle Device ID

 

所以,如果: inthci_get_route(NULL),则得到第一个可用的Dongle Device ID

 

?  BDADDR转换为字符串:

 

int ba2str(const bdaddr_t *ba, char *str)

 

?  将自串转换为BDADDR

 

int str2ba(const char *str, bdaddr_t *ba)

 

?  inquiry 远程BluetoothDevice

 

int hci_inquiry(int dev_id, int len, intnrsp, const uint8_t *lap, inquiry_info **ii, long flags)

 

hci_inquiry()用来命令指定的Dongle去搜索周围所有bluetooth device.并将搜索到的Bluetooth Devicebdaddr 传递回来。

 

参数1dev_id:指定Dongle Device ID。如果此值小于0,则会使用第一个可用的Dongle

 

参数2len: 此次inquiry的时间长度(每增加1,则增加1.25秒时间)

 

参数3nrsp:此次搜索最大搜索数量,如果给0。则此值会取255

 

参数4lap:BDADDRLAP部分,Inquiry时这块值缺省为0X9E8B33.通常使用NULL。则自动设置。

 

参数5ii:存放搜索到Bluetooth Device的地方。给一个存放inquiry_info指针的地址,它会自动分配空间。并把那个空间头地址放到其中。

 

参数6flags:搜索flags.使用IREQ_CACHE_FLUSH,则会真正重新inquiry。否则可能会传回上次的结果。

 

返回值是这次Inquiry到的Bluetooth Device 数目。

 

注意:如果*ii不是自己分配的,而是让hci_inquiry()自己分配的,则需要调用bt_free()来帮它释放空间。

 

?  得到指定BDAddrreomte device Name:

 

int hci_read_remote_name(int dd, constbdaddr_t *bdaddr, int len, char *name, int to)

 

参数1:使用hci_open_dev()打开的Socket

 

参数2:对方BDAddr.

 

参数3name 长度。

 

参数4(out)放置name的位置。

 

参数5:等待时间。

 

?  读取连接的信号强度:

 

int hci_read_rssi(int dd, uint16_t handle,int8_t *rssi, int to)

 

注意,所有对连接的操作,都会有一个参数,handle.这个参数是连接的Handle。前面讲过如何得到连接Handle的。

 

 

2,DBUS协议

D-Bus用于进程间的通信或进程与内核的通信。最基本的D-Bus协议是一对一的通信协议。但在很多情况下,通信的一方是消息总线。消息总线是一个特殊的应用,它同时与多个应用通信,并在应用之间传递消息。其实可以理解为上下文的概念。

Bluezdbus应用:文件系统启一个线程 bluetoothd,比如说配对操作,

应用程序会使用dbus 接口向bluetoothd 发送一个配对的操作,bluetoothd收到此消息之后调用内核相关的配对函数进行配对,内核配对完成之后会发送相应消息到bluetoothdbluetoothd收到消息之后将此消息反馈给应用。

1Bus Name

可以把Bus Name理解为连接的名称,一个Bus Name总是代表一个应用和消息总线的连接。有两种作用不同的Bus Name,一个叫公共名(well-knownnames),还有一个叫唯一名(UniqueConnectionName)。

公共名提供众所周知的服务。其他应用通过这个名称来使用名称对应的服务。可能有多个连接要求提供同个公共名的服务,即多个应用连接到消息总线,要求提供同个公共名的服务。消息总线会把这些连接排在链表中,并选择一个连接提供公共名代表的服务。可以说这个提供服务的连接拥有了这个公共名。如果这个连接退出了,消息总线会从链表中选择下一个连接提供服务。公共名是由一些圆点分隔的多个小写标志符组成的,例如“”、“”。

每个连接都有一个唯一名,当应用连接到消息总线时,消息总线会给每个应用分配一个唯一名。唯一名以“:”开头,“:”后面通常是圆点分隔的两个数字,例如“:1.0”。每个连接都有一个唯一名。在一个消息总线的生命期内,不会有两个连接有相同的唯一名。拥有公众名的连接同样有唯一名,例如在前面的图中,“”的唯一名是“:1.0”。有的连接只有唯一名,没有公众名。可以把这些名称称为私有连接,因为它们没有提供可以通过公共名访问的服务。(开发蓝牙的时候只需要了解,蓝牙使用的是公共名。)

通过公共名获取为一名例子

dbus-send--type=method_call --print-reply --system --dest=

 meOwner string:

2Object Paths

BusName确定了一个应用到消息总线的连接。在一个应用中可以有多个提供服务的对象。这些对象按照树状结构组织起来。每个对象都有一个唯一的路径(Object Paths)。或者说,在一个应用中,一个对象路径标志着一个唯一的对象。

”有一个叫作“/org/bluez/925/hci0”的对象“”有多个对象路径。

3InterfacesMethodsSignals

通过对象路径,我们找到应用中的一个对象。每个对象可以实现多个接口。例如:“/org/bluez/925/hci0”的

/TestObj”实现了以下接口:





2dbus-send--type=method_call --print-reply --system --dest=

 /ames  //使用ListNames服务查看system dbus 总线名

3dbus-send--type=method_call --print-reply --system --dest=

 /spect //列出总线名下面的基本服务

4dbus-send--type=method_call --print-reply --system --dest=

 /dapters        //使用system dbus 总线名为 里面的服务dapters  查看当前adapter

5,可知当前adapter object path,从而可获取当前adapter  提供的服务

dbus-send --type=method_call --print-reply--system --dest=

 /org/bluez/915/spect

6,从而可以使用dbus 总线对adapter 操作,比如说获取设备参数,创建配对设备,取消配对等操作,例如获取设备参数

dbus-send --type=method_call --print-reply--system --dest=

 /org/bluez/915/operties

 

有兴趣了解dbus 的可以看一下文档DBUS实例讲解.pdfDbus基础知识.docx

三、obex知识详解

OBEXObject Exchang的简称,本来是为红外传输制定的协议,但它并不限于特定的底层传输方式,可以运行于blueteethusbtcp/ip其它多种协议之上。OBEX主要是会话层协议,同时也包括应用层部分功能。它可以传输任何对象,在手机中,通常用来传输文件、图片、名片和日程等。OpenOBEX是一套开放源代码的OBEX协议实现,提供clientserver两端的功能。

OBEX协议说明

1 Connect(连接)

此操作初始化会话然后设置参数。其Request格式为

Byte 0

Byte 1,2

Byte 3

Byte 4

Byte 5,6

Byte 7 to n

0x80

包长度

OBEX版本

标志

最大OBEX包长度

可选Header

注:OBEX版本现在为1.0

Response格式为:

Byte 0

Byte 1,2

Byte 3

Byte 4

Byte 5,6

Byte 7 to n

ResponseCode

包长度

OBEX版本

标志

最大OBEX包长度

可选Header

对于更多关于Connect的说明请参考IrOBEX

2 Disconnect(断开当前会话)

此操作断开OBEX会话。例如断开当前FolderListing Service,然后使用Connect连接到IrMC Sync Service实现同步通讯薄等功能。

Disconnect格式为:

Byte 0

Bytes 1,2

Bytes 3 to n

0x81

包长度

可选Header

成功的断开会返回0Xa0,拒绝会返回0xD3

3 Put操作

 

Put操作从客户端发送一个对象到服务端。一般至少含有NameLength两个Header对于文件而言有可能还有Date/Time Header

Put操作的格式如下:

Byte 0

Bytes 1,2

Bytes 3 to n

0x02(FinalBit设置时为0x82)

PacketLength包长度

一组Header

回应格式如下:

Byte 0

Bytes 1,2

Bytes 3 to n

ResponseCode(要求继续为0x90;成功为0xA0

包长度

可选Header

关于Put操作的更详细的用法将在文件传输部分作解释。

4 Get操作

Get操作从服务端返回一个对象。

Get操作的格式如下:

Byte 0

Bytes 1,2

Bytes 3 to n

0x03

包长度

一组Header

回应格式如下:

Byte 0

Bytes 1,2

Bytes 3 to n

Response Code

包长度

可选Header

关于Get操作更详细的用法将在文件传输部分作解释。

5 Abort操作

Abort操作中断一个多包操作(例如发送一个大文件)。Abort操作可以包含描述中断原因的Description Header

Abort操作的格式如下:

Byte 0

Bytes 1,2

Bytes 3 to n

0xFF

包长度

可选Header

Abort对应的应该是一个成功的操作(0xA0),指明这个操作已被接收并且服务端已经重新与客户端同步。如果返回的另外的值,客户端应该Disconnect

6 SetPath

SetPath操作用于切换对方的路径。通常使用一个Name Header用于指定对方路径名称。如果为空,则返回默认目录,通常为根目录

SetPath操作格式如下:

Byte 0

Bytes 1,2

Byte 3

Byte 4

Bytes 5 to n

0x85

包长度

Flags

Constants(常数)

可选Header

注:Flags可以设置Bit0Bit1Bit0表示退回到上一层目录;Bit1表示如果目录不存在就创建一个目录,否则返回一个错误

回应格式如下:

Byte 0

Bytes 1,2

Bytes 3 to n

ResponseCode

包长度

可选Response Header

 

Header 定义

HI

Header名称

描述

0xC0

Count

连接中用于指名对象的数量。

0x01

Name

对象的名字。一般为文件名。

0x42

Type

对象的类型。例如text,html,binary,manufacture specific

0x44

0xC4

Time

时间戳。ISO 8601版本
时间戳。4Byte版本(用于兼容)

0x05

Description

对对象的文本描述

0x46

Target

操作的目的服务名

0x47

HTTP

一个HTTP1.x

0x48

Body

对象的一部分

0x49

End of body

对象的最后一部分

0x4A

Who

OBEX Application标识,用于表明是否是同一个应用。

0xCB

Connection ID

用于OBEX多路连接的标识

0x4C

eters

扩展的应用层请求和回复信息

0x4D

enge

Authentication digest-challenge

0x4E

nse

Authentication digest-response

0x4F

Object Class

对象的OBEX对象类

0x10 to 0x2F

Reserved

保留

0x30 to 0x3F

User defined

用户自定义的。

 

opcode

 

Opcode(w/high bit set)

定义

意义

0x80 *

Connect

连接

0x81 *

Disconnect

断开连接

0x02(0x82)

Put

发送一个对象

0x03(0x83)

Get

取得一个对象

0x04(0x84)

Reserved

保留的

0x85 *

SetPath

设置路径

0xFF *

Abort

取消当前的操作

0x060x0F

Reserved

作为扩展保留

0x100x1F

User definable

用户自定义的

 

ResponseCode

ResponseCode

定义

0x10(0x90)

Continue(继续)

  0x200xA0

OKSuccess

0x40(0xC0)

Bad Request(服务端不明白Request

0x41(0xC1)

Unauthorized(未授权的)

0x43(0xC3)

Fobidden(禁止——服务器明白Request,但拒绝)

 

 

有小米给机顶盒发送文件的打印

 

四、蓝牙交叉编译

1ST交叉编译

#! /bin/bash

 

#指定临时安装位置到/usr/share/bluetooth,最后会被复制到install目录

TMP_PATH=/usr/share/bluetooth

INSTALL_PATH=`pwd`/install

清除之间编译的文件,创建安装文件夹

rm -rf install

mkdir install

rm -rf $TMP_PATH/*

rm -rf $INSTALL_PATH/*

mkdir -p $INSTALL_PATH/root

mkdir -p $INSTALL_PATH/etc

mkdir -p $INSTALL_PATH/include

mkdir -p $INSTALL_PATH/usr/bin

mkdir -p $INSTALL_PATH/usr/sbin

mkdir -p $INSTALL_PATH/$TMP_PATH

mkdir -p $INSTALL_PATH/$TMP_PATH/lib

mkdir -p $INSTALL_PATH/$TMP_PATH/share/alsa

mkdir -p $INSTALL_PATH/$TMP_PATH/var

mkdir -p $INSTALL_PATH/$TMP_PATH/etc

 

指定编译器路径

PATH=$PATH:/opt/STM/STLinux-2.3/devkit/sh4/bin:/opt/STM/ST40R4.4.0:/opt/STM/ST40R4.4.0/bin:/opt/STM/STMCR1.4.0/bin:/opt/STM/STWORKBENCHR4.0.1:/opt/STM/STWORKBENCHR4.0.1/bin

export PATH

 

#编译alsabluez及依赖库

rm -rf expat-2.0.1 && tar 

cd expat-2.0.1

./configure --host=sh4-linux--prefix=/usr/share/Bluetooth

make -j 20 && make install&& cd -

 

rm -rf zlib-1.2.5 && tar 

cd zlib-1.2.5

CC=sh4-linux-gcc ./configure --prefix=/usr/share/Bluetooth

make -j 20 && make install&& cd -

 

rm -rf alsa-lib-1.0.23 && tar 2

cd alsa-lib-1.0.23

./configure --host=sh4-linux--prefix=/usr/share/bluetooth --enable-shared --disable-python--with-versioned=no

make -j 20 && make install&& cd -

 

rm -rf alsa-utils-1.0.23 && tarxjvf 2

cd alsa-utils-1.0.23

./configure --host=sh4-linux--prefix=/usr/share/bluetooth CPPFLAGS=-I/usr/share/bluetooth/includeLDFLAGS=-L/usr/share/bluetooth/lib --disable-alsamixer --disable-xmlto--disable-nls

make -j 20 && make install&& cd -

 

rm -rf dbus-1.2.26 && tar 

cd dbus-1.2.26

./configure --host=sh4-linux--prefix=/usr/share/bluetooth CPPFLAGS=-I/usr/share/bluetooth/includeLDFLAGS=-L/usr/share/bluetooth/lib --with-xml=expat --without-x--enable-selinux=no

make -j 20 && make install&& cd -

 

rm -rf glib-2.24.0 && tar 2

cd glib-2.24.0

./configure --host=sh4-linux--prefix=/usr/share/bluetooth CFLAGS=-I/usr/share/bluetooth/includeLDFLAGS=-L/usr/share/bluetooth/lib glib_cv_stack_grows=yes glib_cv_uscore=yesac_cv_func_posix_getpwuid_r=yes ac_cv_func_posix_getgrgid_r=yes

make -j 20 && make install&& cd -

 

rm -rf bluez-4.95 && tar 

cd bluez-4.95

./configure --host=sh4-linux--prefix=/usr/share/bluetoothPKG_CONFIG_PATH=/usr/share/bluetooth/lib/pkgconfigALSA_CFLAGS=-I/usr/share/bluetooth/include ALSA_LIBS=-L/usr/share/bluetooth/lib--disable-gstreamer --enable-hid2hci --enable-hidd --enable-alsa --enable-audio--enable-service --enable-tools --enable-serial --enable-input --enable-static--enable-shared --enable-test

make -j 20 && make install&& cd -

# bluez安装后的头文件hic_lib.h需要修改,用已修改好的替换

cp modify/hci_all/include/bluetooth/

 

rm -rf openobex-1.3 && tar 

cd openobex-1.3

./configure --prefix=$TMP_PATH--host=sh4-linux CC=sh4-linux-gcc CFLAGS=-I$TMP_PATH/includeLDFLAGS=-L$TMP_PATH/lib --enable-apps BLUEZ_LIBS=-lbluetooth

打开obex的蓝牙选项

cp ../modify/obex_config.h config.h

make -j 20 && make install&& cd -

 

cp -fr cfg/* $INSTALL_PATH/

 

#创建两个用户 messagebus和 lp

使用dbus 需要创建messagebus 用户,lp 用户

sed '$amessagebus:$1$84bC0OFA$m9ubAM6KGAmarFZOlbvCz.:1000:1000:LinuxUser,,,:/home/messagebus:/bin/sh' $INSTALL_PATH/etc/passwd >./tmp

sed '$alp:$1$pytSBKNZ$95Roy6wGH3V444ZOyZwjK0:1001:1001:Linux User,,,:/home/lp:/bin/sh'./tmp >$INSTALL_PATH/etc/passwd

sed '$a messagebus:x:1000:'$INSTALL_PATH/etc/group >./tmp

sed '$a lp:x:1001:' ./tmp>$INSTALL_PATH/etc/group

 

#拷贝相关文件到install 目录下

cd $TMP_PATH/bin

cp -lrf dbus-daemon hidd l2ping hcitoolsdptool rfcomm dbus-cleanup-sockets dbus-launch dbus-monitor dbus-senddbus-uuidgen aplay arecord $INSTALL_PATH/usr/bin/

cd -

cd $TMP_PATH

cp -rf $TMP_PATH/include/*$INSTALL_PATH/include

cp -rf $TMP_PATH/sbin/*$INSTALL_PATH/usr/sbin

cp -rf $TMP_PATH/lib/*$INSTALL_PATH/$TMP_PATH/lib

cp -rf $TMP_PATH/share/alsa/*$INSTALL_PATH/$TMP_PATH/share/alsa

cp -rf $TMP_PATH/var/*$INSTALL_PATH/$TMP_PATH/var

cp -rf $TMP_PATH/etc/*$INSTALL_PATH/$TMP_PATH/etc

cd -

 

 

#创建bluez启动自动化脚本

cd $INSTALL_PATH/etc

echo "rm -rf$TMP_PATH/var/run/dbus/pid" >bluez_init

echo"LD_LIBRARY_PATH=\$LD_LIBRARY_PATH:$TMP_PATH/lib

export LD_LIBRARY_PATH">>bluez_init

echo "touch$TMP_PATH/var/lib/dbus/machine-id

dbus-uuidgen >$TMP_PATH/var/lib/dbus/machine-id">>bluez_init

echo "dbus-daemon--config-file=$TMP_PATH/etc/dbus-1/" >>bluez_init

echo "bluetoothd --udev">>bluez_init

cd -

 

 

rm tmp

 

编译完成之后还需要将install目录下文件挪到rootfs里面,以下是在stapp makefile里面添加的部分逻辑,基本功能是编译九州添加的逻辑代码,将以上编译的文件挪到rootfs里面。

ALSA_DIR   = ../bluetooth

INCLUDE_DIR = ../include

LIB_DIR = ../share/target7162_A27/lib

ROOTFS_DIR = ../share/target7162_A27

BLUEZ_API_DIR_HI    = $(ALSA_DIR)/hi_api

BLUEZ_API_DIR    = $(ALSA_DIR)/bluetooth_utils

bluetooth:

#   cd$(ALSA_DIR)/src;tar -zxf bluez_;chmod 755 -R install;cd -

#   @echo"tar -zxf bluez_ done"

    @-cp-rf $(ALSA_DIR)/src/install/include/* $(ALSA_DIR)/include

    @-cp-rf $(ALSA_DIR)/src/install/usr/share/bluetooth/lib/* $(ALSA_DIR)/lib

    make-C $(BLUEZ_API_DIR)                //九州内部代码

    make-C $(BLUEZ_API_DIR_HI)         //九州内部代码

bluez_install: bluetooth

    @-cp-rvf $(BLUEZ_API_DIR)/*.h $(INCLUDE_DIR)  

    @-cp-rvf $(BLUEZ_API_DIR)/lib* $(LIB_DIR)

    @-cp-rvf $(BLUEZ_API_DIR)/*.so $(ROOTFS_DIR)/usr/lib

    @-cp-rvf $(BLUEZ_API_DIR)/*.a $(ROOTFS_DIR)/usr/lib

 

 

    @-cp-rvf $(BLUEZ_API_DIR_HI)/bluetooth*.h $(INCLUDE_DIR)  

    @-cp-rvf $(BLUEZ_API_DIR_HI)/lib* $(LIB_DIR)

    @-cp-rvf $(BLUEZ_API_DIR_HI)/*.so $(ROOTFS_DIR)/usr/lib

    @-cp-rvf $(BLUEZ_API_DIR_HI)/*.a $(ROOTFS_DIR)/usr/lib

 

 

 

    mkdir-p $(INCLUDE_DIR)/alsa_bluez

    mkdir-p $(LIB_DIR)/alsa_bluez

    @-cp-rf $(ALSA_DIR)/src/install/include/* $(INCLUDE_DIR)/alsa_bluez

    @-cp-rf $(ALSA_DIR)/src/install/usr/share/bluetooth/lib/* $(LIB_DIR)/alsa_bluez

 

    @-cp-rf $(ALSA_DIR)/bluetooth_utils/bt_test $(ROOTFS_DIR)/bin

 

    @-cp-rf $(ALSA_DIR)/src/install/etc/* $(ROOTFS_DIR)/etc

#   @-cp-rf $(ALSA_DIR)/src/install/kmod/* $(ROOTFS_DIR)/kmod 

    foraaa in $$(find $(ALSA_DIR)/src/install/usr/share/bluetooth/lib -name"*.a");do rm -rf $$aaa;done

    @-cp-rf $(ALSA_DIR)/src/install/usr/* $(ROOTFS_DIR)/usr       

    cp../bluetooth/src/expat-2.0.1/.libs/.1.5.2../share/target7162_A27/lib

 

 

 

,在启用bluez_init之前还需要对蓝牙残留文件做删除。

 

以下代码是在profile 添加的

if [ -f /usr/share/bluetooth/var/run/]; then

    rm/usr/share/bluetooth/var/run/

fi

rm -rf/usr/share/bluetooth/var/lib/bluetooth/*

rm -rf /usr/share/bluetooth/var/run/dbus/*

cd /etc

source bluez_init

 

如果启动的时候出现找不到.2,需要做一下操作,其他错误类似

/usr/share/bluetooth/lib # ln .3.11.3 .2

 

如果有些dongle 插入之后一直打印 unkown handle。。。错误,是因为kernel版本过低

需要修改kernel/driver/bluetooth/hci_usb.c

//  {USB_DEVICE(0x0a12, 0x0001), .driver_info = HCI_CSR },

    {USB_DEVICE(0x0a12, 0x0001), .driver_info = HCI_BROKEN_ISOC },

2HISI编译

 在这里就不重复说了。

. ./655V300DDR256M

如果是下载最新的标准版,需要先make build(生成rootfs_full

cd/home/work/HISI/3716SDK0A1/source/msp/component/alsa/src

. ./(生成alsa/src/install

cd /home/work/HISI/3716SDK0A1

gmake bluez_install (这个只是把alsa/src/install里面的东西拷贝到rootfs_full里面)

其中需要修改/home/work/HISI/3716SDK0A1makefile

 

1, 拷贝头文件

2, 拷贝lib

3, 修改etc 下面的passwd  group 

Passwd修改如下

Group修改如下

4, kmod 里面添加bluez_init bluetoothd_server

Bluez_init

Bluetooth_server

5, 删除.a文件

6, 拷贝usr 下面的命令动态库 配置文件到文件系统下面

7, 拷贝obex_test  agent 命令到文件系统下面

8gmake rootfs

 

8, 修改bin 目录下rcS_MV300  makefile

Rcs修改如下

这里的makefile ysstb 目录下面的makefile,在gmake all 的时候添加BT_CFLAGSBT_LDFLAGS

 

10,修改/home/work/HISI/3716SDK0A1/pub/hi3716mv300/rootbox,将.asoundrc 放在根目录下

11,编译驱动(将驱动部分代码蓝牙编译)

Driver makefile 修改

link_path 添加 driver$(LOCALIZATION_STRING)/ysbluetooth

同时   也需要修改,把蓝牙的相关目录添加进去

12,在ysstb gmake

五、蓝牙在HISI盒子上使用

 

在机顶盒启动之后 ps 能看到dbus-daemon bluetoothd –udev进程

?  蓝牙扫描

?  蓝牙配对

?  文件传输

如果发送文件,需要获取远端OBEX Object Push 服务channel

# sdptool browse 49:F2:1C:4E:66:12

Browsing 49:F2:1C:4E:66:12 ...

Service Name: Voiceg ateway

Service RecHandle: 0x10001

Service Class ID List:

 "Handsfree Audio Gateway" (0x111f)

 "Generic Audio" (0x1203)

Protocol Descriptor List:

 "L2CAP" (0x0100)

 "RFCOMM" (0x0003)

   Channel: 2

Language Base Attr List:

 code_ISO639: 0x656e

 encoding:    0x6a

 base_offset: 0x100

Profile Descriptor List:

 "Handsfree" (0x111e)

   Version: 0x0105

 

Service Name: AUDIO Gateway

Service RecHandle: 0x10002

Service Class ID List:

 "Headset Audio Gateway" (0x1112)

 "Generic Audio" (0x1203)

Protocol Descriptor List:

 "L2CAP" (0x0100)

  "RFCOMM"(0x0003)

   Channel: 1

Language Base Attr List:

 code_ISO639: 0x656e

 encoding:    0x6a

 base_offset: 0x100

Profile Descriptor List:

 "Headset" (0x1108)

   Version: 0x0100

 

Service Name: Serial Port0

Service RecHandle: 0x10003

Service Class ID List:

 "Serial Port" (0x1101)

Protocol Descriptor List:

 "L2CAP" (0x0100)

 "RFCOMM" (0x0003)

   Channel: 11

Language Base Attr List:

 code_ISO639: 0x656e

 encoding:    0x6a

 base_offset: 0x100

 

Service Name: Dial-up Networking

Service RecHandle: 0x10004

Service Class ID List:

 "Dialup Networking" (0x1103)

 "Generic Networking" (0x1201)

Protocol Descriptor List:

 "L2CAP" (0x0100)

 "RFCOMM" (0x0003)

   Channel: 9

Language Base Attr List:

 code_ISO639: 0x656e

 encoding:    0x6a

 base_offset: 0x100

Profile Descriptor List:

 "Dialup Networking" (0x1103)

   Version: 0x0100

 

Service Name: Advanced Audio

Service RecHandle: 0x10005

Service Class ID List:

 "Audio Source" (0x110a)

Protocol Descriptor List:

 "L2CAP" (0x0100)

   PSM: 25

 "AVDTP" (0x0019)

   uint16: 0x100

Profile Descriptor List:

 "Advanced Audio" (0x110d)

   Version: 0x0100

 

Service RecHandle: 0x10006

Service Class ID List:

 "AV Remote Target" (0x110c)

Protocol Descriptor List:

 "L2CAP" (0x0100)

   PSM: 23

 "AVCTP" (0x0017)

   uint16: 0x100

Profile Descriptor List:

 "AV Remote" (0x110e)

   Version: 0x0100

 

Service Name: Human interface device

Service Description: Human interface device

Service Provider: Mediatek Inc

Service RecHandle: 0x10007

Service Class ID List:

 "Human Interface Device" (0x1124)

Protocol Descriptor List:

 "L2CAP" (0x0100)

   PSM: 17

 "HIDP" (0x0011)

Language Base Attr List:

 code_ISO639: 0x656e

 encoding:    0x6a

 base_offset: 0x100

Profile Descriptor List:

 "Human Interface Device" (0x1124)

   Version: 0x0100

 

Service Name: OBEX Object Push

Service RecHandle: 0x10008

Service Class ID List:

 "OBEX Object Push" (0x1105)

Protocol Descriptor List:

 "L2CAP" (0x0100)

 "RFCOMM" (0x0003)

   Channel: 4

 "OBEX" (0x0008)

Language Base Attr List:

 code_ISO639: 0x656e

 encoding:    0x6a

 base_offset: 0x100

 

Service Name: OBEX File Transfer

Service RecHandle: 0x10009

Service Class ID List:

 "OBEX File Transfer" (0x1106)

Protocol Descriptor List:

 "L2CAP" (0x0100)

 "RFCOMM" (0x0003)

   Channel: 3

 "OBEX" (0x0008)

Language Base Attr List:

 code_ISO639: 0x656e

 encoding:    0x6a

 base_offset: 0x100

 

Service Name: Imaging

Service RecHandle: 0x1000a

Service Class ID List:

 "Imaging Responder" (0x111b)

Protocol Descriptor List:

 "L2CAP" (0x0100)

 "RFCOMM" (0x0003)

   Channel: 6

 "OBEX" (0x0008)

Language Base Attr List:

 code_ISO639: 0x656e

 encoding:    0x6a

 base_offset: 0x100

Profile Descriptor List:

 "Imaging" (0x111a)

   Version: 0x0100

 

Service Name: Imaging referenced Object

Service RecHandle: 0x1000b

Service Class ID List:

 "Imaging Referenced Objects" (0x111d)

Protocol Descriptor List:

 "L2CAP" (0x0100)

 "RFCOMM" (0x0003)

   Channel: 7

 "OBEX" (0x0008)

Language Base Attr List:

 code_ISO639: 0x656e

 encoding:    0x6a

 base_offset: 0x100

Profile Descriptor List:

 "Imaging" (0x111a)

   Version: 0x0100

发送文件

# obex_test -b 49:F2:1C:4E:66:12 4

Using Bluetooth RFCOMM transport

OBEX Interactive test client/server.

> c                             //连接

Connect OK!

Version: 0x10. Flags: 0x00

> x                             //发送文件

PUSH filename>               //需要发送的文件名字

 

接收文件

sdptool browse local 查看是否有 OBEXObject Push

如果没有 需要添加

sdptool add OPUSH

 

obex_test –b   //接收文件

 

?  蓝牙耳机使用

 蓝牙耳机使用需要在~/  目录下面建立.asoundrc文件

内容如下:

_record{

    type plug

    slave {

    pcm "bt_record_hw"

    }

    }

 

    _record_hw{

    type bluetooth

    device 70:F1:A1:EE:C5:70

    profile voice

 

    }

 

    _play{

    type plug

    slave {

    pcm "bt_play_hw"

    }

    }

 

    _play_hw{

    type bluetooth

    device 70:F1:A1:EE:C5:70

    }

其中文件中mac 地址为蓝牙耳机mac 地址

配对之后

Apply –D bt_play                    //播放

Arecord –D bt_record –f S16_LE    // 录制文件

 

 

备注:

蓝牙kernel 底层调试

?  修改$(kerneldir)/driver/bluetooth/Kconfig

在文件结尾添加

configCONFIG_BT_HCI_CORE_DEBUG

bool "CONFIG_BT_HCI_CORE_DEBUG"

default y

help

  CONFIG_BT_HCI_CORE_DEBUG.

 

config CONFIG_BT_RFCOMM_DEBUG

bool "CONFIG_BT_RFCOMM_DEBUG"

default y

help

  CONFIG_BT_RFCOMM_DEBUG.

 

 

config CONFIG_BT_SOCK_DEBUG

bool "CONFIG_BT_SOCK_DEBUG"

default y

help

  CONFIG_BT_SOCK_DEBUG.  

 

config CONFIG_BT_HCI_SOCK_DEBUG

bool "CONFIG_BT_SOCK_DEBUG"

default y

help

  CONFIG_BT_HCI_SOCK_DEBUG.

 

config CONFIG_BT_HCIUSB_DEBUG

bool "CONFIG_BT_HCIUSB_DEBUG"

default y

help

  CONFIG_BT_HCIUSB_DEBUG.  

 

config CONFIG_BT_L2CAP_DEBUG

bool "CONFIG_BT_L2CAP_DEBUG"

default y

help

 CONFIG_BT_L2CAP_DEBUG.

?  同时在hci_core.c或者 hci_usb.c 或者其他蓝牙相关文件里面加上以下代码

#undef  BT_DBG

#undef  BT_ERR

#define BT_DBG(fmt, arg...)printk("%s: " fmt "\n" , __FUNCTION__ , ## arg)

#defineBT_ERR(fmt, arg...) printk("%s: " fmt "\n" , __FUNCTION__ ,## arg)

 

HISI NFS 调试

?  打开NFS 挂载文件系统功能

注释3716SDK0A1\Makefile中的603行,因为每次编译HISI都会通过603使用默认的.config 

进入Y:\work\HISI\bluetooth\3716SDK0A1\source\osdrv\kernel\linux-2.6.35

Make menuconfig 修改kernel配置

Networking options 下面

 

Network file systems下面

然后开机启动盒子进入fastboot,输入以下命令,然后就可以方面的使用NFS文件系统了

set bootargs mem=128Mconsole=ttyAMA0,115200 root=/dev/nfs nfsroot= mmz=ddr,0,0x88000000,128M DmxPoolBufSize=0x200000LogBufSize=0x80000mtdparts=hinand:768K(fastboot),256K(bootargs),1M(stbinfo),8M(loader),8M(loaderbak),5M(kernel),50M(rootfs),35M(elf),8M(ui),8M(flashdata),256K(baseparam),1M(logo),2M(fastplay),-(others)

阅读(1684) | 评论(0) | 转发(1) |
1

上一篇:没有了

下一篇:profile 详解

给主人留下些什么吧!~~