android系统学习笔记九

 蓝牙部分

蓝牙协议栈 1.1    1.2   2.0   2.1   3.0

 异步数据和语音传输  采用的协议:

  逻辑链路控制和适配协议(L2CAP) 、服务发现协议(SDP) 、串口模拟协议(RFCOMM) 

  主要控制接口由主机控制接口层体现,他是蓝牙协议里软硬件之间的接口

   在HCI之上的是蓝牙的上层应用框架,每个应用模式为一个profile ,如无线立体声耳机A2DP

    (Advanced   Audio  Distribution   Profile)

蓝牙的基本架构

 自上而下包括以下内容:

  Linux 内核的蓝牙驱动程序

  Linux 内核的蓝牙协议层

  Bluez 蓝牙在用户空间的库

  Bluez 适配层

  Android.bluetooth包中的各个类(蓝牙在框架层的内容)

  蓝牙相关的应用程序

 

蓝牙部分的结构图:

  

蓝牙的用户空间库 bluez 

 空间库bluez  linux平台上的一套完整的蓝牙协议栈,通过D-BUS IPC机制来提供应用层接口

 它的底层协议实现在kernel 代码中

 D-BUS是一套应用广泛的进程间通信(IPC)机制,是相对比较底层的(类似socket) 它更加复杂

 

代码位于kernl目录下的net/bluetooth

底层协议方面;

 HCI:  主机控制协议完成与蓝牙硬件的交互

 SDP:  服务发现协议访问其他服务的基础协议

 RFCOMM: 类似于串口的通信协议 为上层服务的实现提供传输接口

 L2CAP: 逻辑链路和控制协议,RFCOMM.SDP等协议的基础

 SCO:  同步数据交换协议

上图中左侧部分为HCI具体功能实现;

 Adapter  一个adapter对应一个蓝牙设备,管理设备相关信息

Manager  管理主机上的蓝牙设备

 Service  服务

 Security  安全相关功能模块 

 Database 管理组织服务列表

 右侧是各种服务

 Audio  语音  A2DP  普通语音同步

 Input   输入服务

 Transfer  文件交换服务

 Network  网络服务

 各种协议之间的关系 

android系统中,bluez的源码在以下的目录中:  \external\bluetooth\bluez

 会生成若干个动态库和可执行程序

  动态库

  Libbluetooth: 公共库被各部分应用使用,

  Libhcid:  主机接口的实现

  Audio:  音频服务

  Input :   输入服务

  Liba2dp:  蓝牙立体声服务

可执行程序

 Hcid:   直接封装libhcid 主机接口的实现  守护进程,提供对外的D-BUS接口

 Hciconfig  hcitool  hciattach 主机接口辅助工具

 Dund   提供dun服务

 Pand   提供pan服务

 Sdptool 提供sdp服务相关接口

 Rfcomm   rfcomm配置工具

Bluez的适配层

 代码路径为:\system\bluetoot

 封装了蓝牙的开关功能和射频开关

蓝牙的JNI部分和java部分

JNI部分的代码路径为: \frameworks\base\core\jni

最终生成libandroid_runtime.so

Jvav部分代码路径

蓝牙的服务部分代码路径 \frameworks\base\core\java\android\server 

支持耳机(headset)  免提(handsfree) 立体声(a2dp) 

核心组成  android.bluetooth包中以IBluetoothDevice.aidl为接口的IBinder服务端BluetoothDeviceService

 客户端 BluetoothDevice以及android.service包中的BluetothEventLoop

 bluetoothdeviceService 主要是用于蓝牙的开启和关闭,设备的发现和配对,服务的发现和邦定

  开关功能是直接调用底层的bluezr接口来实现

  Java部分和底层的关系

客户端bluetoothDevice.getRemoteServiceChannel调用服务端的bluetoothDeviceService.getRemoteServiceChannel然后调用JNIgetRemoteServiceChannelNative

Android_bluetooth_common.h的部分代码如下;

dbus_bool_t dbus_func_args_async(JNIEnv *env,

                                 DBusConnection *conn,

                                 int timeout_ms,

                                 void (*reply)(DBusMessage *, void *, void *),

                                 void *user,

                                 void *nat,

                                 const char *path,

                                 const char *ifc,

                                 const char *func,

                                 int first_arg_type,

                                 ...);

最后调用;dbus_func_args_async_valist

static dbus_bool_t dbus_func_args_async_valist(JNIEnv *env,

                                        DBusConnection *conn,

                                        int timeout_ms,

                                        void (*user_cb)(DBusMessage *,

                                                        void *,

                                                        void*),

                                        void *user,

                                        void *nat,

                                        const char *path,

                                        const char *ifc,

                                        const char *func,

                                        int first_arg_type,

                                        va_list args) {

    DBusMessage *msg = NULL;

    const char *name;

    dbus_async_call_t *pending;

    dbus_bool_t reply = FALSE;

/* Compose the command */

//组成命令   (创建一个消息结构)

    msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC, path, ifc, func);

    if (msg == NULL) {

        LOGE("Could not allocate D-Bus message object!");

        goto done;

    }

/* append arguments */

//附加参数

    if (!dbus_message_append_args_valist(msg, first_arg_type, args)) {

        LOGE("Could not append argument to method call!");

        goto done;

    }

/* Make the call. */

//通过D-BUS调用接口

    pending = (dbus_async_call_t *)malloc(sizeof(dbus_async_call_t));

    if (pending) {

        DBusPendingCall *call;

        pending->env = env;  //设置参数中的内容

        pending->user_cb = user_cb;

        pending->user = user;

        pending->nat = nat;

        //pending->method = msg;

       // 发送命令返回信息

        reply = dbus_connection_send_with_reply(conn, msg,

                                                &call,

                                                timeout_ms);

        if (reply == TRUE) {

            dbus_pending_call_set_notify(call,

                                         dbus_func_args_async_callback,

                                         pending,

                                         NULL);

        }

    }

done:

    if (msg) dbus_message_unref(msg);

    return reply;

}

//本机的首个蓝牙设备

#define BLUEZ_ADAPTER_OBJECT_NAME BLUEZ_DBUS_BASE_PATH "/hci0"

Ifc DBUS_CLASS_NAME 指向org.bluez.adapter  直接访问HCI部分的adapter

 在android 2.3之后有采用level11 ,支持了测试蓝牙链接状态的函数

//链接spp类的设备

BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
BluetoothDevice bd = adapter.getRemoteDevice(addr);
Method m = bd.getClass().getMethod("createRfcommSocket", new Class[]{int.class});
BluetoothSocket bs = (BluetoothSocket) m.invoke(bd, Integer.valueOf(1));

posted @ 2012-09-03 15:21  retacn_yue  阅读(405)  评论(0编辑  收藏  举报