您的位置:首页 > 其它

蓝牙开启流程(enable)分析

2015-10-12 15:58 716 查看
转自:http://blog.csdn.net/xubin341719/article/details/40402637

一、enableNative函数的的实现

(1)、初始化BTE;

(2)、创建BTIU_TASK;

(3)、初始化HCI、串口相关,启动HCI工作主线程:bt_hc_callback,芯片上电、RF参数初始化;



1、应用部分对enableNative函数的调用

packages\apps\Bluetooth\src\com\android\bluetooth\btservice\AdapterState.java


[cpp] view
plaincopy





public boolean processMessage(Message msg) {

boolean isTurningOn= isTurningOn();

boolean isTurningOff = isTurningOff();

………………

case STARTED: {

if (DBG) Log.d(TAG,"CURRENT_STATE=PENDING, MESSAGE = STARTED, isTurningOn=" + isTurningOn + ", isTurningOff=" + isTurningOff);

//Remove start timeout

removeMessages(START_TIMEOUT);

//Enable

boolean ret = adapterService.enableNative();//调用Native函数;

if (!ret) {

Log.e(TAG, "Error while turning Bluetooth On");

notifyAdapterStateChange(BluetoothAdapter.STATE_OFF);

transitionTo(mOffState);

} else {

sendMessageDelayed(ENABLE_TIMEOUT, ENABLE_TIMEOUT_DELAY);

}

}

break;

………………

}

/*package*/ native boolean enableNative();

2、JNI函数的实现

packages\apps\Bluetooth\jni\com_android_bluetooth_btservice_AdapterService.cpp

[cpp] view
plaincopy





static jboolean enableNative(JNIEnv* env, jobject obj) {

ALOGV("%s:",__FUNCTION__);

jboolean result = JNI_FALSE;

if (!sBluetoothInterface) return result;

int ret = sBluetoothInterface->enable();//JNI部分Native函数调用C语言中的函数实现;

result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;//判断是打开还是关闭状态;

return result;

}

3、C函数中对enable函数的实现,这部分和init的流程一样

external\bluetooth\bluedroid\btif\src\bluetooth.c


[cpp] view
plaincopy





static int enable( void )

{

ALOGI("enable");

/* sanity check */

if (interface_ready() == FALSE)

return BT_STATUS_NOT_READY;

return btif_enable_bluetooth();//enable汗的具体实现;

}<strong>

</strong>

4、btif_enable_bluetooth函数的实现,Performschip power on and kickstarts OS scheduler

external\bluetooth\bluedroid\btif\src\btif_core.c|


[cpp] view
plaincopy





bt_status_t btif_enable_bluetooth(void)

{

BTIF_TRACE_DEBUG0("BTIF ENABLE BLUETOOTH");

if (btif_core_state != BTIF_CORE_STATE_DISABLED)

{

ALOGD("not disabled\n");

return BT_STATUS_DONE;

}

btif_core_state = BTIF_CORE_STATE_ENABLING;//设定为正在打开状态;

/* Create the GKI tasks and run them */

bte_main_enable();//BTE部分的enable

return BT_STATUS_SUCCESS;

}<strong>

</strong>

5、bte_main_enable函数,这个函数是enable函数的具体实现

BTEMAIN API - Creates all the BTE tasks. Should be called part of the Bluetooth stack enable sequence

iexternal\bluetooth\bluedroid\main\bte_main.c

[cpp] view
plaincopy





void bte_main_enable()

{

int ret = -1;

APPL_TRACE_DEBUG1("%s", __FUNCTION__);

/* Initialize BTE control block */

BTE_Init();//(1)、初始化BTE控制块;

lpm_enabled = FALSE;

//(2)、创建BTU_TASK 进程

GKI_create_task((TASKPTR)btu_task, BTU_TASK, BTE_BTU_TASK_STR,

(UINT16 *) ((UINT8 *)bte_btu_stack + BTE_BTU_STACK_SIZE),

sizeof(bte_btu_stack));

bte_hci_enable();//(3)、打开HCI和厂商模块控制;

GKI_run(0);

ret = bte_snoop_create_task();//BT log 进程创建;

if(ret != 0)

APPL_TRACE_DEBUG1("bte_snoop_create_task fail %d",ret);

}

(1)、初始化BTE控制块

[csharp] view
plaincopy





BTE_Init();

BTU:Bluetooth Upper Layer, The Broadcom implementations of L2CAP RFCOMM, SDP and the BTIf run as one GKI task. The btu_task switches between them.

(2)、创建BTU_TASK 进程

[cpp] view
plaincopy





GKI_create_task((TASKPTR)btu_task, BTU_TASK, BTE_BTU_TASK_STR,

(UINT16 *) ((UINT8 *)bte_btu_stack + BTE_BTU_STACK_SIZE),

sizeof(bte_btu_stack));

external\bluetooth\bluedroid\stack\btu\btu_task.c

This is the main task of the Bluetooth Upper Layers unit. It sits in aloop waiting for messages, and dispatches them to the appropiate handlers.

btu_task这个函数非常重要,大部分event的处理都通过它来完成;

[cpp] view
plaincopy





BTU_API UINT32 btu_task (UINT32 param)

{

…………

/* Initialize the mandatory core stack control blocks

(BTU, BTM, L2CAP, and SDP)

*/

btu_init_core();//1)、初始化核心control block,比如BTU, BTM, L2CAP, and SDP

/* Initialize any optional stack components */

BTE_InitStack();//2)、初始化BTE控制块,比如RFCOMM, DUN, SPP, HSP2, HFP, OBX, BIP

#if (defined(BTU_BTA_INCLUDED) && BTU_BTA_INCLUDED == TRUE)

bta_sys_init();//3)、初始化BTA

#endif

…………

/* Wait for, and process, events */

for (;;)//进入循环状态

{

event = GKI_wait (0xFFFF, 0);//4)、获取相应EVENT;

if (event & TASK_MBOX_0_EVT_MASK)

{…………}

if (event & TIMER_0_EVT_MASK)

{…………}

#if defined(QUICK_TIMER_TICKS_PER_SEC) && (QUICK_TIMER_TICKS_PER_SEC > 0)

if (event & TIMER_2_EVT_MASK)

{

btu_process_quick_timer_evt();

}

#endif

#if (defined(BTU_BTA_INCLUDED) && BTU_BTA_INCLUDED == TRUE)

if (event & TASK_MBOX_2_EVT_MASK)//这个状态比较重要

{

while ((p_msg = (BT_HDR *) GKI_read_mbox(TASK_MBOX_2)) != NULL)

{

bta_sys_event(p_msg);//接收到的event在这里解析,然后执行BTU中的函数。

}

}

if (event & TIMER_1_EVT_MASK)

{

bta_sys_timer_update();

}

#endif

if (event & EVENT_MASK(APPL_EVT_7))

break;

}

return(0);

}

(3)、bte_hci_enable,Enable HCI & Vendor modules,打开HCI和厂商模块

bte_hci_enable的实现流程如下图所示



external\bluetooth\bluedroid\main\bte_main.c

[cpp] view
plaincopy





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);//初始化串口,HCI_H4、HCI工作线等;

………………

bt_hc_if->set_power(BT_HC_CHIP_PWR_ON);//给相应模块上电;

bt_hc_if->preload(NULL);//下载相关配置参数;

if (hci_logging_enabled == TRUE || hci_logging_config == TRUE)

bt_hc_if->logging(BT_HC_LOGGING_ON, hci_logfile);

}

}

6、相对于HCI接口库接口函数,这部分跟蓝牙芯片相关

external\bluetooth\bluedroid\hci\src\bt_hci_bdroid.c


[cpp] view
plaincopy





static const bt_hc_interface_t bluetoothHCLibInterface = {

sizeof(bt_hc_interface_t),

init,//HCLib中的init;

set_power,// HCLib中的power设定;

lpm,

preload, HCLib中的preload;

postload,

transmit_buf,

set_rxflow,

logging,

cleanup

};<strong>

</strong>

7、bluetoothHCLibInterface 中INIT实现过程

完成H4初始化、串口驱动初始化、LMP初始化、启动bt_hc_worker_thread主线程。



(1)、init函数实现

external\bluetooth\bluedroid\hci\src\bt_hci_bdroid.c


[cpp] view
plaincopy





static int init(const bt_hc_callbacks_t* p_cb, unsigned char *local_bdaddr)

{

…………

/* store reference to user callbacks */

bt_hc_cbacks = (bt_hc_callbacks_t *) p_cb;

init_vnd_if(local_bdaddr);//完成厂商模块的接口函数;

userial_init();//串口初始化

lpm_init();//LPM初始化

…………

extern tHCI_IF hci_h4_func_table;// 应用HCI H4接口回调

p_hci_if = &hci_h4_func_table;

p_hci_if->init();//调用hci_h4_func_table的init办法,初始化H4模块

utils_queue_init(&tx_q); //初始化发送队列

…………

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;

}

…………

}

1)、bt_hc_callbacks_t*bt_hc_cbacks = (bt_hc_callbacks_t *) p_cb; //保存回调;

2)、init_vnd_if(local_bdaddr);//调用厂商库里面的bt_vendor_interface_t*接口,初始化蓝牙设备;

3)、p_hci_if =&hci_h4_func_table; //应用HCI H4接口回调;

4)、p_hci_if->init(); //调用hci_h4_func_table的init办法,初始化H4模块;

5)、userial_init();//初始化uart数据布局;

6)、lpm_init();//初始化低功耗模块,调用bt_vendor_interface_t的op接口;

7)、utils_queue_init(&tx_q); //初始化发送队列;

8)、pthread_create(&hc_cb.worker_thread,&thread_attr, bt_hc_worker_thread, NULL) != 0) //起工作线程;

(2)、init_vnd_if 的实现过程

idh.code\external\bluetooth\bluedroid\hci\src\bt_hw.c



[cpp] view
plaincopy





void init_vnd_if(unsigned char *local_bdaddr)

{

void *dlhandle;

dlhandle = dlopen("libbt-vendor.so", RTLD_NOW);// 1)、dlopen()函数以指定模式打开指定的动态链接库文件,并返回一个句柄给dlsym()的调用进程。

………………

bt_vnd_if = (bt_vendor_interface_t *) dlsym(dlhandle, "BLUETOOTH_VENDOR_LIB_INTERFACE");//2)、返回符号BLUETOOTH_VENDOR_LIB_INTERFACE,所对应的地址。

…………

bt_vnd_if->init(&vnd_callbacks, local_bdaddr);//3)、调用返回地址结构体中的init函数;

}

1)、dlopen()

函数以指定模式打开指定的动态链接库文件,并返回一个句柄给dlsym()的调用进程。

[html] view
plaincopy





dlhandle = dlopen("libbt-vendor.so", RTLD_NOW);

void * dlopen( const char * pathname, int mode);

mode是打开方式,其值有多个,不同操作系统上实现的功能有所不同,在linux下,按功能可分为三类:

解析方式

RTLD_LAZY:

在dlopen返回前,对于动态库中的未定义的符号不执行解析(只对函数引用有效,对于变量引用总是立即解析)。

RTLD_NOW:

需要在dlopen返回前,解析出所有未定义符号,如果解析不出来,在dlopen会返回NULL,错误为:: undefined symbol: xxxx.......

作用范围,可与解析方式通过“|”组合使用。

RTLD_GLOBAL:

动态库中定义的符号可被其后打开的其它库重定位。

RTLD_LOCAL:

与RTLD_GLOBAL作用相反,动态库中定义的符号不能被其后打开的其它库重定位。如果没有指明是RTLD_GLOBAL还是RTLD_LOCAL,则缺省为RTLD_LOCAL。

作用方式

RTLD_NODELETE:

在dlclose()期间不卸载库,并且在以后使用dlopen()重新加载库时不初始化库中的静态变量。这个flag不是POSIX-2001标准。

RTLD_NOLOAD:

不加载库。可用于测试库是否已加载(dlopen()返回NULL说明未加载,否则说明已加载),也可用于改变已加载库的flag,如:先前加载库的flag为RTLD_LOCAL,用dlopen(RTLD_NOLOAD|RTLD_GLOBAL)后flag将变成RTLD_GLOBAL。这个flag不是POSIX-2001标准。

RTLD_DEEPBIND:

在搜索全局符号前先搜索库内的符号,避免同名符号的冲突。这个flag不是POSIX-2001标准。

2)、dlsym根据动态链接库操作句柄与符号,返回符号对应的地址

返回符号BLUETOOTH_VENDOR_LIB_INTERFACE,所对应的地址,也就是:

[cpp] view
plaincopy





const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = {

sizeof(bt_vendor_interface_t),

init,

op,

cleanup

};

3)、调用返回地址结构体中的init函数

bt_vnd_if->init(&vnd_callbacks,local_bdaddr);

有两个参数:厂商提供的回调函数vnd_callbacks;蓝牙地址:local_badaddr。

函数init的实现:

vendor\sprd\open-source\libs\libbt\src\bt_vendor_sprd.c

[cpp] view
plaincopy





const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = {

sizeof(bt_vendor_interface_t),

init,

op,

cleanup

};

BLUETOOTH_VENDOR_LIB_INTERFACE中INIT函数实现

vendor\sprd\open-source\libs\libbt\src\bt_vendor_sprd.c


[cpp] view
plaincopy





static int init(const bt_vendor_callbacks_t* p_cb, unsigned char *local_bdaddr)

{

…………

/* store reference to user callbacks */

bt_vendor_cbacks = (bt_vendor_callbacks_t *) p_cb;//把vnd_callbacks回调函数,保存到用户回调bt_vendor_cback;

…………

}<strong>

</strong>

vnd_callbacks,这些函数在

//The libbt-vendor Callback Functions Table

[cpp] view
plaincopy





static const bt_vendor_callbacks_t vnd_callbacks = {

sizeof(bt_vendor_callbacks_t),

fwcfg_cb,

scocfg_cb,

lpm_vnd_cb,

alloc,

dealloc,

xmit_cb,

epilog_cb

};

(3)、hci_h4_func_tableinit函数的初始化

[html] view
plaincopy





extern tHCI_IF hci_h4_func_table;

p_hci_if = &hci_h4_func_table;

p_hci_if->init();

1)、hci_h4_func_table结构体成员函数

[cpp] view
plaincopy





const tHCI_IF hci_h4_func_table =

{

hci_h4_init,//HCI_H4初始化;

hci_h4_cleanup,

hci_h4_send_msg,//发送msg;

hci_h4_send_int_cmd,//发送int命令;

hci_h4_get_acl_data_length,

hci_h4_receive_msg//接收信息;

};

2)、 p_hci_if->init();调用hci_h4_func_table的init办法,初始化H4模块,对应实现函数对应:hci_h4_init

[cpp] view
plaincopy





void hci_h4_init(void)

{

HCIDBG("hci_h4_init");

memset(&h4_cb, 0, sizeof(tHCI_H4_CB));

utils_queue_init(&(h4_cb.acl_rx_q));

/* Per HCI spec., always starts with 1 */

num_hci_cmd_pkts = 1;

/* Give an initial values of Host Controller's ACL data packet length

* Will update with an internal HCI(_LE)_Read_Buffer_Size request

*/

h4_cb.hc_acl_data_size = 1021;//hci ACL 数据的最大长度;

h4_cb.hc_ble_acl_data_size = 27;//BLE ACL最大数据长度;

btsnoop_init();

}<span style="color: red;">

</span>

(4)、初始化串口、LPM

userial_init();

lpm_init();

(5)、创建工作线程

if(pthread_create(&hc_cb.worker_thread, &thread_attr, \

bt_hc_worker_thread, NULL) != 0)

idh.code\external\bluetooth\bluedroid\hci\src\bt_hci_bdroid.c

bt_hc_worker_thread工作线程,监听各种状态,处理相对应。


[cpp] view
plaincopy





static void *bt_hc_worker_thread(void *arg)

{

…………

if (events & HC_EVENT_PRELOAD)

{

userial_open(USERIAL_PORT_1);

…………

bt_vnd_if->op(BT_VND_OP_FW_CFG, NULL);

…………

}

if (events & HC_EVENT_POSTLOAD)

…………

if (events & HC_EVENT_TX)

…………

if (events & HC_EVENT_LPM_ENABLE)

………………

}

8、bluetoothHCLibInterface中set_power流程

这部分主要完成上电操作,SPRD的蓝牙芯片集成到AP端,由芯片内部控制。如果用其他蓝牙WIFI芯片,这部分应该对应相关power PIN脚操作。



idh.code\external\bluetooth\bluedroid\hci\src\bt_hci_bdroid.c

[cpp] view
plaincopy





/** Chip power control */

static void set_power(bt_hc_chip_power_state_t state)

{

int pwr_state;

…………

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);//设置controller POWER ON/OFF

…………

}

bt_vnd_if这个结构体在idh.code\external\bluetooth\bluedroid\hci\include\bt_vendor_lib.h中定义,相对应的op函数在bt_vendor_sprd.c中实现。

(1)、bt_vnd_if结构体:

[cpp] view
plaincopy





typedef struct {

size_t size;

int (*init)(const bt_vendor_callbacks_t* p_cb, unsigned char *local_bdaddr);

int (*op)(bt_vendor_opcode_t opcode, void *param);

void (*cleanup)(void);

} bt_vendor_interface_t;

(2)、bt_vnd_if->op的函数实现

vendor\sprd\open-source\libs\libbt\src\bt_vendor_sprd.c

相对应不同op操作
BT_VND_OP_POWER_CTRL
Power on or off the BT Controller
BT_VND_OP_FW_CFG
Perform any vendor specific initialization or configuration on the BT Controller. This is called before stack initialization
BT_VND_OP_SCO_CFG
Perform any vendor specific SCO/PCM configuration on the BT Controller.This is called after stack initialization.
BT_VND_OP_USERIAL_OPEN
Open UART port on where the BT Controller is attached. This is called before stack initialization.
BT_VND_OP_USERIAL_CLOSE
Close the previously opened UART port.
BT_VND_OP_GET_LPM_IDLE_TIMEOUT
Get the LPM idle timeout in milliseconds.The stack uses this information to launch a timer delay before it attempts to de-assert LPM WAKE signal once downstream HCI packet has been delivered.
BT_VND_OP_LPM_SET_MODE
Enable or disable LPM mode on BT Controller.
BT_VND_OP_LPM_WAKE_SET_STATE
Assert or Deassert LPM WAKE on BT Controller.
BT_VND_OP_EPILOG
The epilog call to the vendor module so that it can perform any vendor-specific processes (e.g. send a HCI_RESET to BT Controller)before the caller calls for cleanup().
[cpp] view
plaincopy





static int op(bt_vendor_opcode_t opcode, void *param)

{

…………

switch(opcode)

{

case BT_VND_OP_POWER_CTRL://如果是power控制

{

ALOGI("bt-vendor : BT_VND_OP_POWER_CTRL");

#if 0//这部分代码展讯平台没有控制;

nState = *(int *) param;

retval = hw_config(nState);

if(nState == BT_VND_PWR_ON

&& retval == 0

&& is_hw_ready() == TRUE)

{

retval = 0;

}

#endif

}

break;

…………

}

9、bluetoothHCLibInterface中Preload流程

这部分主要完成蓝牙MAC地址、RF射频相关设定,流程如下所示。



(1)、发送HC_EVENT_POSTLOAD 信令,线程bt_hc_worker_thread接收并处理

external\bluetooth\bluedroid\hci\src\bt_hci_bdroid.c


[html] view
plaincopy





/** Called post stack initialization */

static void postload(TRANSAC transac)

{

BTHCDBG("postload");

bthc_signal_event(HC_EVENT_POSTLOAD);//发送信号量给线程<strong>bt_hc_worker_thread</strong>

}

10、bt_hc_worker_thread处理HC_EVENT_PRELOAD

[cpp] view
plaincopy





static void *bt_hc_worker_thread(void *arg)

{

uint16_t events;

HC_BT_HDR *p_msg, *p_next_msg;

…………

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);//(1)、mac、ini、pskey初始化

}

else

{

if (bt_hc_cbacks)

bt_hc_cbacks->preload_cb(NULL, BT_HC_PRELOAD_FAIL);(2)、失败preload 回调函数

…………

}<strong>

</strong>

11、bt_vnd_if->op(BT_VND_OP_FW_CFG, NULL);调用

vendor\sprd\open-source\libs\libbt\src\bt_vendor_sprd.c中的OP函数:


[cpp] view
plaincopy





static int op(bt_vendor_opcode_t opcode, void *param)

{

…………

case BT_VND_OP_FW_CFG:

{

ALOGI("bt-vendor : BT_VND_OP_FW_CFG");

retval = sprd_config_init(s_bt_fd,NULL,NULL);//初始化展讯平台

ALOGI("bt-vendor : sprd_config_init retval = %d.",retval);

if(bt_vendor_cbacks)

{

if(retval == 0)

{

ALOGI("Bluetooth Firmware and smd is initialized");

bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS);//初始化成功后回调函数

}

else

{

ALOGE("Error : hci, smd initialization Error");

bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_FAIL);

}

}

}

break;

}

(1)、sprd_config_init的实现

这部分针对芯片部分,展讯的蓝牙芯片处理流程,在这里完成:蓝牙MAC地址、RF ini文件相关;

vendor\sprd\open-source\libs\libbt\src\ bt_vendor_sprd.c中sprd_config_init

[cpp] view
plaincopy





//******************create bt addr end***********************

int sprd_config_init(int fd, char *bdaddr, struct termios *ti)

{

………………

if(access(BT_MAC_FILE, F_OK) == 0)// MAC地址创建如果btmac不存在,随机生成;

{

ALOGI("%s: %s exists",__FUNCTION__, BT_MAC_FILE);

read_btmac=read_mac_from_file(BT_MAC_FILE,bt_mac);

}

if(read_btmac == 1)

{

for(i=0; i<6; i++)

{

bt_mac_tmp[i*2] = bt_mac[3*(5-i)];

bt_mac_tmp[i*2+1] = bt_mac[3*(5-i)+1];

}

ALOGI("====bt_mac_tmp=%s", bt_mac_tmp);

ConvertHexToBin((uint8*)bt_mac_tmp, strlen(bt_mac_tmp), bt_mac_bin);

}

/* Reset the BT Chip */

memset(resp, 0, sizeof(resp));

ret = bt_getPskeyFromFile(&bt_para_tmp);//1)、<span style=" color: red;"><strong>GETPSKEY FOROM</strong></span><span style=" color: red;"><strong>FILE</strong></span><span style=" color: red;"><strong>,这里完成</strong></span><span style=" color: red;"><strong>INI</strong></span><strong><span style="color:#ff0000;">文件的初始化</span></strong>

…………

{

ALOGI("get_pskey_from_file ok \n");

/* Send command from pskey_bt.txt*/

if(read_btmac == 1)

{

memcpy(bt_para_tmp.device_addr, bt_mac_bin, sizeof(bt_para_tmp.device_addr));

}

if (write(s_bt_fd, (char *)&bt_para_tmp, sizeof(BT_PSKEY_CONFIG_T)) != sizeof(BT_PSKEY_CONFIG_T))

{

ALOGI("Failed to write pskey command from pskey file\n");

return -1;

}

}

ALOGI("sprd_config_init write pskey command ok \n");

while (1)

{

r = read(s_bt_fd, resp, 1);

if (r <= 0)

return -1;

if (resp[0] == 0x05)

{

ALOGI("read pskey response ok \n");

break;

}

}

ALOGI("sprd_config_init ok \n");

return 0;

}

1)、GETPSKEY FOROMFILE,这里完成INI文件的初始化:这部分内容和芯片相关,
不同厂商的芯片有不同的处理方法;

++++++sprd start 其他平台可以不看+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

vendor\sprd\open-source\libs\libbt\src\bt_vendor_sprd.c


[cpp] view
plaincopy





int bt_getPskeyFromFile(void *pData)

{

…………

#ifdef HW_ADC_ADAPT_SUPPORT//不同INI文件

char *CFG_2351_PATH[] = {

"/system/etc/connectivity_configure_hw100.ini",

"/system/etc/connectivity_configure_hw102.ini",

"/system/etc/connectivity_configure_hw104.ini"

};

#else

char *CFG_2351_PATH[] = {

"/system/etc/connectivity_configure.ini"

};

#endif

#ifdef HW_ADC_ADAPT_SUPPORT

//如果是不同的硬件,获取板子信息,给board_type赋值,后面选择用那个ini文件。这个是展讯平台相关,不同平台有不同的做法;

char *BOARD_TYPE_PATH = "/dev/board_type";

int fd_board_type;

char board_type_str[MAX_BOARD_TYPE_LEN] = {0};

fd_board_type = open(BOARD_TYPE_PATH, O_RDONLY);//(1)、获取硬件版本信息

if (fd_board_type<0)

{

ALOGI("#### %s file open %s err ####\n", __FUNCTION__, BOARD_TYPE_PATH);

board_type = 2; // default is 1.0.4

}

else

{

len = read(fd_board_type, board_type_str, MAX_BOARD_TYPE_LEN);

if (strstr(board_type_str, "1.0.0"))

{

board_type = 0;

}

…………

#endif

ALOGI("begin to bt_getPskeyFromFile");

fd = open(CFG_2351_PATH[board_type], O_RDONLY, 0644);

if(-1 != fd)

{

len = bt_getFileSize(CFG_2351_PATH[board_type]);//(2)、获得相应的版本的PSKEY;

pBuf = (unsigned char *)malloc(len);

ret = read(fd, pBuf, len);

…………

ret = bt_getDataFromBuf(pData, pBuf, len);

if(-1 == ret)

{

free(pBuf);

return -1;

}

ALOGI("begin to dumpPskey");

bt_dumpPskey((BT_PSKEY_CONFIG_T *)pData);//(3)、解析相应数据

free(pBuf);

return 0;

}

获取硬件版本信息

fd_board_type = open(BOARD_TYPE_PATH,O_RDONLY);

Board_type如下图:



获得相应的版本的PSKEY;

[cpp] view
plaincopy





char *CFG_2351_PATH[] = {

"/system/etc/connectivity_configure_hw100.ini",

"/system/etc/connectivity_configure_hw102.ini",

"/system/etc/connectivity_configure_hw104.ini"

};



解析相应数据

bt_dumpPskey((BT_PSKEY_CONFIG_T*)pData);
++++++++++++++sprd end [b]其他平台可以不看+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++[/b]

12、 配置成功后回调函数fwcfg_cb



bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS);//初始化成功后回调函数,这部分在case BT_VND_OP_FW_CFG中完成



external\bluetooth\bluedroid\hci\src\bt_hw.c

[cpp] view
plaincopy





static void fwcfg_cb(bt_vendor_op_result_tresult)

{

bt_hc_postload_result_tstatus = (result == BT_VND_OP_RESULT_SUCCESS) ? \

BT_HC_PRELOAD_SUCCESS : BT_HC_PRELOAD_FAIL;//判定prelaod是否成功;

fwcfg_acked = TRUE;

if (bt_hc_cbacks)

bt_hc_cbacks->preload_cb(NULL, status);//对应preload_cb

}

preload_cb的实现,把BT_EVT_PRELOAD_CMPL成功消息通过GKI返回BTU_TASK;



external\bluetooth\bluedroid\main\bte_main.c

[cpp] view
plaincopy





static void preload_cb(TRANSACtransac, bt_hc_preload_result_t result)

{

APPL_TRACE_EVENT1("HC preload_cb %d[0:SUCCESS 1:FAIL]", result);

if (result == BT_HC_PRELOAD_SUCCESS)

{

preload_stop_wait_timer();

/* notify BTU task that libbt-hci isready */

GKI_send_event(BTU_TASK, BT_EVT_PRELOAD_CMPL);//发送BT_EVT_PRELOAD_CMPL到BTU_TASK

}

}

preload完成后,回调函数返回到BTU_TASK,启动BT其他协议层的初始化。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: