打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
安卓蓝牙开启流程

文章问题很多,纯属自己看看,请勿相信。。

我们先借用下网上的一张框架图,以便于一目了然的观察android蓝牙的大致结构。

首先,我们来看在起蓝牙service的初始化过程中,所做的一些事情,这些事情跟我们下面要讲的开启蓝牙过程有关联。

我们可以看到在AdapterService(位于packages/apps/bluetooth/btservice)的onCreate函数中,

public void onCreate() {        super.onCreate();        if (DBG) debugLog("onCreate");        mBinder = new AdapterServiceBinder(this);        mAdapterProperties = new AdapterProperties(this);        mAdapterStateMachine =  AdapterState.make(this, mAdapterProperties);        mJniCallbacks =  new JniCallbacks(mAdapterStateMachine, mAdapterProperties);        initNative();//初始化        mNativeAvailable=true;        mCallbacks = new RemoteCallbackList<IBluetoothCallback>();        //Load the name and address        getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_BDADDR);//获取address        getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_BDNAME);//获取name    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

有个initNative()函数,该函数对应JNI(com_android_bluetooth_btservice_AdapterService.cpp)中,

static bool initNative(JNIEnv* env, jobject obj) {    ALOGV("%s:",__FUNCTION__);    sJniCallbacksObj = env->NewGlobalRef(env->GetObjectField(obj, sJniCallbacksField));    if (sBluetoothInterface) {        int ret = sBluetoothInterface->init(&sBluetoothCallbacks);        if (ret != BT_STATUS_SUCCESS) {            ALOGE("Error while setting the callbacks \n");            sBluetoothInterface = NULL;            return JNI_FALSE;        }        if ( (sBluetoothSocketInterface = (btsock_interface_t *)                  sBluetoothInterface->get_profile_interface(BT_PROFILE_SOCKETS_ID)) == NULL) {                ALOGE("Error getting socket interface");        }        return JNI_TRUE;    }    return JNI_FALSE;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

这里主要要注意的是sBluetoothInterface和sBluetoothCallbacks两个变量。

先来看sBluetoothInterface,我们可以看到在classinitNative中,

    err = hw_get_module(id, (hw_module_t const**)&module);    if (err == 0) {        hw_device_t* abstraction;        err = module->methods->open(module, id, &abstraction);        if (err == 0) {            bluetooth_module_t* btStack = (bluetooth_module_t *)abstraction;            sBluetoothInterface = btStack->get_bluetooth_interface();        } else {           ALOGE("Error while opening Bluetooth library");        }    } else {        ALOGE("No Bluetooth Library found");    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

这里hw_get_module是jni层获取HAL层module的接口函数,原型为:int hw_get_module(const char *id, const struct hw_module_t **module)。

那么它的HAL层代码在哪里呢?extern/bluetooth/bluedroid/btif/src/bluetooth.c中注册了这个模块。

**Attention:在海思的平台上如果用的是rtl的8723,则相关代码在
./device/hisilicon/bigfish/bluetooth/下,其他各芯片也类似**/

struct hw_module_t HAL_MODULE_INFO_SYM = {    .tag = HARDWARE_MODULE_TAG,    .version_major = 1,    .version_minor = 0,    .id = BT_HARDWARE_MODULE_ID,//值为bluetooth    .name = "Bluetooth Stack",    .author = "The Android Open Source Project",    .methods = &bt_stack_module_methods};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

然后来看sBluetoothCallbacks,

bt_callbacks_t sBluetoothCallbacks = {    sizeof(sBluetoothCallbacks),    adapter_state_change_callback,    adapter_properties_callback,    remote_device_properties_callback,    device_found_callback,    discovery_state_changed_callback,    pin_request_callback,    ssp_request_callback,    bond_state_changed_callback,    acl_state_changed_callback,    callback_thread_event,    dut_mode_recv_callback,    le_test_mode_recv_callback};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

这个结构体中定义了bt协议栈中调用的回调函数,在下面的介绍中我们会用到。

OK. 接下来我们先来看下在这个init()函数中做了什么?

static int init(bt_callbacks_t* callbacks ){    ALOGI("init");     ......//省略    /* init btif */    btif_init_bluetooth();    return BT_STATUS_SUCCESS;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

其中的btif_init_Bluetooth()中

bt_status_t btif_init_bluetooth(){    UINT8 status;    btif_config_init();    bte_main_boot_entry();//初始化hw    /* As part of the init, fetch the local BD ADDR */    memset(&btif_local_bd_addr, 0, sizeof(bt_bdaddr_t));    btif_fetch_local_bdaddr(&btif_local_bd_addr);//获取本机的蓝牙地址    /* start btif task */    status = GKI_create_task(btif_task, BTIF_TASK, BTIF_TASK_STR,                (UINT16 *) ((UINT8 *)btif_task_stack + BTIF_TASK_STACK_SIZE),                sizeof(btif_task_stack));//建立一个任务线程btif_task来循环处理bt的指令    if (status != GKI_SUCCESS)        return BT_STATUS_FAIL;    return BT_STATUS_SUCCESS;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

在上面的代码中,主要做了三件事情,
1. 我们先看下bte_main_boot_entry(),该函数会调用到bte_main.c中的bte_main_in_hw_init()

static void bte_main_in_hw_init(void){    if ( (bt_hc_if = (bt_hc_interface_t *) bt_hc_get_interface())          == NULL)    {        APPL_TRACE_ERROR0("!!! Failed to get BtHostControllerInterface !!!");    }    memset(&preload_retry_cb, 0, sizeof(bt_preload_retry_cb_t));}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

上面代码中的bt_hc_if就是我们这次的目标,这是个bt_hc_interface_t*的变量,具体定义了跟硬件相关的一些函数指针(定义在bt_hci_bdroid.c中)

static const bt_hc_interface_t bluetoothHCLibInterface = {    sizeof(bt_hc_interface_t),    init,    set_power,    lpm,    preload,    postload,    transmit_buf,    set_rxflow,    logging,    cleanup};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  1. btif_fetch_local_bdaddr,主要是为了获取到当前设备的蓝牙地址,并且上报给jvm
  2. GKI_create_task(btif_task。。。。),在btif_task中,我们可以看到先调用了btif_associate_evt();
static bt_status_t btif_associate_evt(void){    BTIF_TRACE_DEBUG1("%s: notify ASSOCIATE_JVM", __FUNCTION__);    HAL_CBACK(bt_hal_cbacks, thread_evt_cb, ASSOCIATE_JVM);    return BT_STATUS_SUCCESS;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

具体就是调用我们上面说的sBluetoothCallbacks中的callback_thread_event回调,告诉jvm我们起了一个新的线程。后面应该还有类似的调用被使用。

至此,initNative工作算是做完了,接下来就是获取蓝牙名称和地址给上层了。

getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_BDADDR);//获取address
getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_BDNAME);//获取name

同样,调用bluetooth.c中的

static int get_adapter_property(bt_property_type_t type){    /* sanity check */    if (interface_ready() == FALSE)        return BT_STATUS_NOT_READY;    return btif_get_adapter_property(type);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

然后通过btif_sendmsg去调用

static void execute_storage_request(UINT16 event, char *p_param){    uint8_t is_local;    int num_entries = 0;    bt_status_t status = BT_STATUS_SUCCESS;    BTIF_TRACE_EVENT1("execute storage request event : %d", event);    switch(event)    {        case BTIF_CORE_STORAGE_ADAPTER_WRITE:        {            btif_storage_req_t *p_req = (btif_storage_req_t*)p_param;            bt_property_t *p_prop = &(p_req->write_req.prop);            BTIF_TRACE_EVENT3("type: %d, len %d, 0x%x", p_prop->type,                               p_prop->len, p_prop->val);            status = btif_storage_set_adapter_property(p_prop);            HAL_CBACK(bt_hal_cbacks, adapter_properties_cb, status, 1, p_prop);        } break;        case BTIF_CORE_STORAGE_ADAPTER_READ:        {            btif_storage_req_t *p_req = (btif_storage_req_t*)p_param;            char buf[512];            bt_property_t prop;            prop.type = p_req->read_req.type;            prop.val = (void*)buf;            prop.len = sizeof(buf);            status = btif_storage_get_adapter_property(&prop);            HAL_CBACK(bt_hal_cbacks, adapter_properties_cb, status, 1, &prop);        } break;        case BTIF_CORE_STORAGE_ADAPTER_READ_ALL:        {            status = btif_in_get_adapter_properties();        } break;        case BTIF_CORE_STORAGE_NOTIFY_STATUS:        {            HAL_CBACK(bt_hal_cbacks, adapter_properties_cb, status, 0, NULL);        } break;        default:            BTIF_TRACE_ERROR2("%s invalid event id (%d)", __FUNCTION__, event);            break;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

在这里我们又看到了熟悉的HAL_CBACK(bt_hal_cbacks, adapter_properties_cb, status, 1, &prop);

也就是回调com_android_bluetooth_btservice_AdapterService.cpp中的static void adapter_properties_callback(bt_status_t status, int num_properties,
bt_property_t *properties)来上报给java层。

好了。这就是我们的准备工作,有了这些函数,我们下面在打开蓝牙的过程中就可以调用到他们了。

下面我们来看下蓝牙打开的流程:
首先在Framework层,应用app会调用BluetoothAdapter的enable(),然后在packages下面有个bluetooth apk,其中包含了各种profile的service实现,比如在enable这个动作执行时,会通过ipc调用AdapterService.java中的enable()函数。

同时,为了管理不同蓝牙状态的切换,该类中还保存了一个StateMachine,执行enableNative(),由此进入到JNI层。

boolean ret = adapterService.enableNative();if (!ret) {    Log.e(TAG, "Error while turning Bluetooth On");                            notifyAdapterStateChange(BluetoothAdapter.STATE_OFF);                        transitionTo(mOffState);} else {                        sendMessageDelayed(ENABLE_TIMEOUT, ENABLE_TIMEOUT_DELAY);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

具体的JNI层实现在com_android_bluetooth_btservice_AdapterService.app中可以找到。

static jboolean enableNative(JNIEnv* env, jobject obj) {    ALOGV("%s:",__FUNCTION__);    jboolean result = JNI_FALSE;    if (!sBluetoothInterface) return result;    int ret = sBluetoothInterface->enable();    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;    return result;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

ok,由此我们进入了bluedroid的范围。在这个文件中,调用了btif_enable_bluetooth(), BTIF(BLuetooth Interface)的简称,个人初步就当它是bluedroid提供给应用的一些接口吧。

btif_core.c中继续调用bte_main_enable(),在调用的bte_hci_enable()中

static void bte_hci_enable(void){    APPL_TRACE_DEBUG1("%s", __FUNCTION__);    preload_start_wait_timer();    if (bt_hc_if)    {        int result = bt_hc_if->init(&hc_callbacks, btif_local_bd_addr.address);//步骤1:        APPL_TRACE_EVENT1("libbt-hci init returns %d", result);        assert(result == BT_HC_STATUS_SUCCESS);        if (hci_logging_enabled == TRUE || hci_logging_config == TRUE)            bt_hc_if->logging(BT_HC_LOGGING_ON, hci_logfile);#if (defined (BT_CLEAN_TURN_ON_DISABLED) && BT_CLEAN_TURN_ON_DISABLED == TRUE)        APPL_TRACE_DEBUG1("%s  Not Turninig Off the BT before Turninig ON", __FUNCTION__);#else        /* toggle chip power to ensure we will reset chip in case           a previous stack shutdown wasn't completed gracefully */        bt_hc_if->set_power(BT_HC_CHIP_PWR_OFF);//步骤2#endif        bt_hc_if->set_power(BT_HC_CHIP_PWR_ON);//步骤3        bt_hc_if->preload(NULL);//步骤4    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

OK,我们来看下这3个步骤,主要就3个函数
bt_hc_if->init()和bt_hc_if->set_power、bt_hc_if->preload:

static int init(const bt_hc_callbacks_t* p_cb, unsigned char *local_bdaddr){    .......//省略    init_vnd_if(local_bdaddr);    p_hci_if->init();    userial_init();    lpm_init();    /*起一个线程来处理对硬件的操作命令*/    if (pthread_create(&hc_cb.worker_thread, &thread_attr,                        bt_hc_worker_thread, NULL) != 0)    {        ALOGE("pthread_create failed!");        lib_running = 0;        return BT_HC_STATUS_FAIL;    }    ........//省略    return BT_HC_STATUS_SUCCESS;}/** Chip power control */static void set_power(bt_hc_chip_power_state_t state){    int pwr_state;    BTHCDBG("set_power %d", state);    /* Calling vendor-specific part */    pwr_state = (state == BT_HC_CHIP_PWR_ON) ? BT_VND_PWR_ON : BT_VND_PWR_OFF;    if (bt_vnd_if)        bt_vnd_if->op(BT_VND_OP_POWER_CTRL, &pwr_state);//bt_vnd_if是个关键    else        ALOGE("vendor lib is missing!");}/** Called prio to stack initialization */static void preload(TRANSAC transac){    BTHCDBG("preload");    bthc_signal_event(HC_EVENT_PRELOAD);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

在上述操作中,bt_vnd_if这个结构体是个关键,我们针对蓝牙硬件的操作很多都是通过这个函数指针进行调用。

在bt_hw.c中,我们可以看到
bt_vnd_if =(bt_vendor_interface_t *) &BLUETOOTH_VENDOR_LIB_INTERFACE;

BLUETOOTH_VENDOR_LIB_INTERFACE就是不同的平台厂商,使用不同蓝牙芯片时提供的接口。
比如8723芯片在bt_vendor_rtk.c中定义了

// Entry point of DLibconst bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = {    sizeof(bt_vendor_interface_t),    init,    op,    cleanup};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

preload()中执行了id为HC_EVENT_PRELOAD的消息,在bt_hc_worker_thread线程中执行

if (events & HC_EVENT_PRELOAD)        {            userial_open(USERIAL_PORT_1);            /* Calling vendor-specific part */            if (bt_vnd_if)            {                bt_vnd_if->op(BT_VND_OP_FW_CFG, NULL);            }            else            {                if (bt_hc_cbacks)                    bt_hc_cbacks->preload_cb(NULL, BT_HC_PRELOAD_FAIL);            }        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

到这里开启蓝牙的过程应该是差不多了,我们先到此为止,接下来涉及到蓝牙驱动,暂时不在讨论范围之内。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
android
Android Bluetooth 移植(上)
(ios7)解决xib布局方式支持ios6,ios7
HC05蓝牙模块Arduino即插即用开发板
HC05蓝牙模块的使用
Android蓝牙的启动
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服