Android BlueDroid(BlueDroid蓝牙开启过程enable)

厌伴老儒烹瓠叶,强随举子踏槐花。这篇文章主要讲述Android BlueDroid:BlueDroid蓝牙开启过程enable相关的知识,希望能为你提供帮助。
关键词:bluedroid  enableNative BTIF_TASK  BTU_TASK bt_hc_work_thread set_power  preload  GKI
作者:xubin341719(欢迎转载。请注明作者,请尊重版权,谢谢!)
画图工具:Edraw Maindmap
欢迎指正错误。共同学习、共同进步。。

一、enableNative函数的的实现
(1)、初始化BTE;
(2)、创建BTIU_TASK。
(3)、初始化HCI、串口相关。启动HCI工作主线程:bt_hc_callback,芯片上电、RF參数初始化;

Android BlueDroid(BlueDroid蓝牙开启过程enable)

文章图片


1、应用部分对enableNative函数的调用
packages\apps\Bluetooth\src\com\android\bluetooth\btservice\AdapterState.java

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

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 

static int enable( void ) { ALOGI("enable"); /* sanity check */ if (interface_ready() == FALSE) return BT_STATUS_NOT_READY; return btif_enable_bluetooth(); //enable汗的详细实现; }


4、btif_enable_bluetooth函数的实现,Performschip power on and kickstarts OS scheduler
external\bluetooth\bluedroid\btif\src\btif_core.c|

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部分的enablereturn BT_STATUS_SUCCESS; }


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

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(); //BTlog 进程创建。 if(ret != 0) APPL_TRACE_DEBUG1("bte_snoop_create_task fail %d",ret); }


(1)、初始化BTE控制块

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 进程

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的处理都通过它来完毕;

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(); } #endifif (event & EVENT_MASK(APPL_EVT_7)) break; } return(0); }


(3)、bte_hci_enable,Enable HCI & Vendor modules,打开HCI和厂商模块
bte_hci_enable的实现流程例如以下图所看到的
Android BlueDroid(BlueDroid蓝牙开启过程enable)

文章图片



external\bluetooth\bluedroid\main\bte_main.c

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

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


7、bluetoothHCLibInterface 中INIT实现过程
完毕H4初始化、串口驱动初始化、LMP初始化、启动bt_hc_worker_thread主线程。
Android BlueDroid(BlueDroid蓝牙开启过程enable)

文章图片



(1)、init函数实现
external\bluetooth\bluedroid\hci\src\bt_hci_bdroid.c

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
Android BlueDroid(BlueDroid蓝牙开启过程enable)

文章图片


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()的调用进程。


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,所相应的地址,也就是:

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

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

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; ………… }


vnd_callbacks,这些函数在
//The libbt-vendor Callback Functions Table

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_table中init函数的初始化

extern tHCI_IF hci_h4_func_table; p_hci_if = & hci_h4_func_table; p_hci_if-> init();

1)、hci_h4_func_table结构体成员函数
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

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; //BLEACL最大数据长度。btsnoop_init(); }



(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工作线程。监听各种状态,处理相相应。


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脚操作。
Android BlueDroid(BlueDroid蓝牙开启过程enable)

文章图片



idh.code\external\bluetooth\bluedroid\hci\src\bt_hci_bdroid.c
/** 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); //设置controllerPOWER 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结构体:

typedef struct { size_tsize; 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 theBT Controller. This is called before stack initialization
BT_VND_OP_SCO_CFG
【Android BlueDroid(BlueDroid蓝牙开启过程enable)】Perform any vendor specific SCO/PCM configuration on the BTController.This is called after stack initialization.
BT_VND_OP_USERIAL_OPEN
Open UART port on where the BT Controller is attached. This iscalled 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 thisinformation to launch a timer delay before it attempts to de-assert LPM WAKEsignal 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-specificprocesses (e.g. send a HCI_RESET to BT Controller)before the caller calls forcleanup().
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射频相关设定,流程例如以下所看到的。
Android BlueDroid(BlueDroid蓝牙开启过程enable)

文章图片




(1)、发送HC_EVENT_POSTLOAD 信令,线程bt_hc_worker_thread接收并处理
external\bluetooth\bluedroid\hci\src\bt_hci_bdroid.c

/** Called post stack initialization */ static void postload(TRANSAC transac) { BTHCDBG("postload"); bthc_signal_event(HC_EVENT_POSTLOAD); //发送信号量给线程bt_hc_worker_thread }


10、bt_hc_worker_thread处理HC_EVENT_PRELOAD

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 回调函数 ………… }


11、bt_vnd_if-> op(BT_VND_OP_FW_CFG, NULL); 调用
vendor\sprd\open-source\libs\libbt\src\bt_vendor_sprd.c中的OP函数:

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

//******************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)、GETPSKEY FOROMFILE。这里完毕INI文件的初始化 ………… { 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

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例如以下图:
Android BlueDroid(BlueDroid蓝牙开启过程enable)

文章图片

获得相应的版本号的PSKEY;
char *CFG_2351_PATH[] = { "/system/etc/connectivity_configure_hw100.ini", "/system/etc/connectivity_configure_hw102.ini", "/system/etc/connectivity_configure_hw104.ini" };

Android BlueDroid(BlueDroid蓝牙开启过程enable)

文章图片

解析相应数据
bt_dumpPskey((BT_PSKEY_CONFIG_T*)pData);
++++++++++++++sprd end 其它平台能够不看+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
12、    配置成功后回调函数fwcfg_cb
Android BlueDroid(BlueDroid蓝牙开启过程enable)

文章图片


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

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

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
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其它协议层的初始化。
下节我们分析:
1、GKI_send_msg进程间通信怎样完毕。
2、bta_sys_sendmsg event怎样解析;
3、GKI_Wait实现流程;












































































































    推荐阅读