赞
踩
文章问题很多,纯属自己看看,请勿相信。。
我们先借用下网上的一张框架图,以便于一目了然的观察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 DLib
const 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);
}
}
到这里开启蓝牙的过程应该是差不多了,我们先到此为止,接下来涉及到蓝牙驱动,暂时不在讨论范围之内。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。