Bluetoothオープン-bluedroidのプロセス(android Oコードベース)

6208 ワード

Bluetoothはapp層からプロトコルスタックまで開くスパンが大きすぎて、コードだけを見ると方向を見失いやすく、まずlogから見ます.
01-18 18 18 18 18:25:311.570 D/BluetoothAdapterService(21885):onCreate()/adapterservice起動01-18 18 18 18:25:311.570 I/BluetoothVeendorJni(21885):classInitNative:succeds 01-18 18 18:25:311.570 D/BluetoothAdapterState(21885):make(-)-Creating AdapterState 01-18 18 18 18 18:25:311.580 I/BluetoothAdapterState(21885):Entering OffState 01-18 18 18 18 18 18:25:25:31588 I/1.5 80 I/BluetoothAdapterState(21885):Entering OffState 01-18 18 18 18 18 18 18 bt_btif(21885):initは次にinitメソッド01-18 18 18:25:31.580 D/bt_に呼び出されるosi_allocation_tracker(21885): canary initialized 01-18 18:25:31.590 I/bt_osi_thread(21885): run_thread: thread id 21915, thread name stack_manager started
AdapterServiceファイルではclassInitNativeメソッドが呼び出されます.このメソッドの定義はJNIファイルで、次のように定義されています.
static void classInitNative(JNIEnv* env, jclass clazz) {
    int err;
    hw_module_t* module;

    jclass jniCallbackClass =
        env->FindClass("com/android/bluetooth/btservice/JniCallbacks");
    sJniCallbacksField = env->GetFieldID(clazz, "mJniCallbacks",
        "Lcom/android/bluetooth/btservice/JniCallbacks;");

    method_stateChangeCallback = env->GetMethodID(jniCallbackClass, "stateChangeCallback", "(I)V");

    method_adapterPropertyChangedCallback = env->GetMethodID(jniCallbackClass,
                                                             "adapterPropertyChangedCallback",
                                                             "([I[[B)V");
    method_discoveryStateChangeCallback = env->GetMethodID(jniCallbackClass,
                                                           "discoveryStateChangeCallback", "(I)V");

    method_devicePropertyChangedCallback = env->GetMethodID(jniCallbackClass,
                                                            "devicePropertyChangedCallback",
                                                            "([B[I[[B)V");
    method_deviceFoundCallback = env->GetMethodID(jniCallbackClass, "deviceFoundCallback", "([B)V");
    method_pinRequestCallback = env->GetMethodID(jniCallbackClass, "pinRequestCallback",
                                                 "([B[BIZ)V");
    method_sspRequestCallback = env->GetMethodID(jniCallbackClass, "sspRequestCallback",
                                                 "([B[BIII)V");

    method_bondStateChangeCallback = env->GetMethodID(jniCallbackClass,
                                                     "bondStateChangeCallback", "(I[BI)V");

    method_aclStateChangeCallback = env->GetMethodID(jniCallbackClass,
                                                    "aclStateChangeCallback", "(I[BI)V");

    method_setWakeAlarm = env->GetMethodID(clazz, "setWakeAlarm", "(JZ)Z");
    method_acquireWakeLock = env->GetMethodID(clazz, "acquireWakeLock", "(Ljava/lang/String;)Z");
    method_releaseWakeLock = env->GetMethodID(clazz, "releaseWakeLock", "(Ljava/lang/String;)Z");
    method_energyInfo = env->GetMethodID(clazz, "energyInfoCallback", "(IIJJJJ)V");

    char value[PROPERTY_VALUE_MAX];
    property_get("bluetooth.mock_stack", value, "");

    const char *id = (strcmp(value, "1")? BT_STACK_MODULE_ID : BT_STACK_TEST_MODULE_ID);

    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");
    }

このメソッドではコールバック関数が定義され、sBluetoothInterfaceインタフェースが初期化されます.get_bluetooth_interfaceメソッドは、プロトコルスタックで定義されたメソッドのインタフェースを返します.プロトコルスタックのメソッドは次のようになります.
static const bt_interface_t bluetoothInterface = {
    sizeof(bluetoothInterface),
    init,
    enable,
    disable,
    cleanup,
    get_adapter_properties,
    get_adapter_property,
    set_adapter_property,
    get_remote_device_properties,
    get_remote_device_property,
    set_remote_device_property,
    get_remote_service_record,
    get_remote_services,
    start_discovery,
    cancel_discovery,
    create_bond,
    remove_bond,
    cancel_bond,
    get_connection_state,
    pin_reply,
    ssp_reply,
    get_profile_interface,
    dut_mode_configure,
    dut_mode_send,
#if BLE_INCLUDED == TRUE
    le_test_mode,
#else
    NULL,
#endif
    config_hci_snoop_log,
    set_os_callouts,
    read_energy_info,
    dump,
    config_clear
};

プロトコル内のinitメソッドが呼び出されます.
static int init(bt_callbacks_t *callbacks) {
  LOG_INFO("%s", __func__);

  if (interface_ready())
    return BT_STATUS_DONE;

#ifdef BLUEDROID_DEBUG
  allocation_tracker_init();
#endif

  bt_hal_cbacks = callbacks;
  stack_manager_get_interface()->init_stack();
  btif_debug_init();
  return BT_STATUS_SUCCESS;
}

initでstack_が作成されますmanagerスレッドを使用し、thread_を使用します.postメソッドstack_managerスレッド転送処理関数event_init_stack、この関数は主にプロトコルスタックを初期化するために使用され、関数の中でbtif_が呼び出されます.init_bluetooth, btif_init_bluetooth関数ではJNIスレッドが作成され、このスレッドに渡される処理関数はrun_message_loop.
これで、Bluetoothプロトコルスタックの初期化が完了し、enableプロセスに進みます.
01-18 18:25:31.760 I/bt_btif (21885): enable: start restricted = 0 01-18 18:25:31.760 I/bt_stack_manager(21885): event_start_up_stack is bringing up the stack
enableメソッドではstack_が与えられますmanagerスレッド転送処理関数event_start_up_stack、event_start_up_stack関数でbt_が作成されますworkqueueスレッド、このスレッドの処理方法は:btu_task_start_up
01-18 18:25:31.870 I/bt_osi_thread(21885): run_thread: thread id 21934, thread name bt_workqueue started
btu_task_start_upメソッドでは、BTU,BTM,L 2 CAP,SDPが初期化する.btu message_の作成loopスレッド、このスレッドに入力される処理関数は
btu_message_loop_初期化完了メッセージをJNIスレッドに送信するrun関数.