文章问题很多,纯属自己看看,请勿相信。。
我们先借用下网上的一张框架图,以便于一目了然的观察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 }
有个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;}
这里主要要注意的是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"); }
这里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};
然后来看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};
这个结构体中定义了bt协议栈中调用的回调函数,在下面的介绍中我们会用到。
OK. 接下来我们先来看下在这个init()函数中做了什么?
static int init(bt_callbacks_t* callbacks ){ ALOGI("init"); ......//省略 /* init btif */ btif_init_bluetooth(); return BT_STATUS_SUCCESS;}
其中的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. 我们先看下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));}
上面代码中的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};
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;}
具体就是调用我们上面说的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);}
然后通过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; }}
在这里我们又看到了熟悉的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);}
具体的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;}
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 }}
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);}
在上述操作中,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};
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); } }
到这里开启蓝牙的过程应该是差不多了,我们先到此为止,接下来涉及到蓝牙驱动,暂时不在讨论范围之内。
联系客服