分享

安卓蓝牙开启流程

 兰宝888 2018-04-18

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

我们先借用下网上的一张框架图,以便于一目了然的观察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 DLib
const 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

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

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多