关键词: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參数初始化;

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部分的enable return 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();//BT log 进程创建。
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();
}
#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

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主线程。

(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

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_tableinit函数的初始化

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;//BLE ACL最大数据长度。 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脚操作。

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveHViaW4zNDE3MTk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />

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);//设置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结构体:

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().

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

/** 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例如以下图:

获得相应的版本号的PSKEY;

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 其它平台能够不看+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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

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实现流程;

Android BlueDroid(三):BlueDroid蓝牙开启过程enable的更多相关文章

  1. Android BlueDroid(二):BlueDroid蓝牙开启过程init

    关键词:bluedroid  initNative enableNative BTIF_TASK  BTU_TASKbt_hc_work_thread set_power  preload  GKI作 ...

  2. ZT Android 4.2 BT系统之蓝牙关闭过程全跟踪

    Android 4.2 BT系统之蓝牙关闭过程全跟踪 分类: android 2013-08-03 00:34 2252人阅读 评论(10) 收藏 举报 代码位置:       frameworks/ ...

  3. Android 8 蓝牙打开过程

    packages\apps\Settings\src\com\android\settings\bluetooth\BluetoothEnabler.java @Override public boo ...

  4. 【转】Android LCD(三):Samsung LCD接口篇

    关键词:android LCD控制器 Framebuffer PWM  平台信息:内核:linux2.6/linux3.0系统:android/android4.0 平台:samsung exynos ...

  5. Android LCD(三):Samsung LCD接口篇

    关键词:android LCD控制器 Framebuffer PWM  平台信息: 内核:linux2.6/linux3.0 系统:android/android4.0  平台:samsung exy ...

  6. Android应用程序内部启动Activity过程(startActivity)的源代码分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6703247 上文介绍了Android应用程序的 ...

  7. 【转】android camera(三):camera V4L2 FIMC

    关键词:android  camera CMM 模组 camera参数  CAMIF   V4L2  平台信息:内核:linux系统:android 平台:S5PV310(samsung exynos ...

  8. [Android学习笔记]View的measure过程学习

    View从创建到显示到屏幕需要经历几个过程: measure -> layout -> draw measure过程:计算view所占屏幕大小layout过程:设置view在屏幕的位置dr ...

  9. Android网络开发之蓝牙

    蓝牙采用分散式网络结构以及快调频和短包技术,支持点对点及点对多点通信,工作在全球通用的2.4GHz ISM(I-工业.S-科学.M-医学)频段,其数据速率为1Mbps,采用时分双工传输方案.   蓝牙 ...

随机推荐

  1. Codeforces Round #406 (Div. 2) D. Legacy (线段树建图dij)

    D. Legacy time limit per test 2 seconds memory limit per test 256 megabytes input standard input out ...

  2. hadoop遇到的问题(汇总)

    1. 如果Map和reduce的输出不一致,需要显示的设置Map的输出,没有根据参数进行推导的原因是类型擦除 combiner是在copy数据到机器之前可以进行的一些数据的合并,这和数据有关,不是所有 ...

  3. matlab的table数据类型初步接触

    由于数据分析,接触到cell的使用,字符串的使用以及ASCII的使用,但是发现在matlab中进行这样的操作相对繁琐,然后知道了table数据类型,是matlab新的数据类型,于2013版开始引入.据 ...

  4. [BZOJ 4720] 换教室

    Link: BZOJ 4720 传送门 Solution: 2016年$NOIP$考的一道语文题 题面虽长,但思路并不难想 对于这类期望问题,大多数时候都用期望$dp$来解决 根据询问:在$n$个时间 ...

  5. [CF935F]Fafa and Array

    法法round(雾 题意:给一个序列$a_{1\cdots n}$,定义$\begin{align*}f=\sum\limits_{i=1}^{n-1}\left|a_i-a_{i+1}\right| ...

  6. 十. 图形界面(GUI)设计5.布局设计

    在界面设计中,一个容器要放置许多组件,为了美观,为组件安排在容器中的位置,这就是布局设计.java.awt中定义了多种布局类,每种布局类对应一种布局的策略.常用的有以下布局类: FlowLayout, ...

  7. 爬取维基百科人物介绍,并使用pymysql存储到数据库

    代码如下: from urllib.request import urlopen from bs4 import BeautifulSoup import re import datetime imp ...

  8. iOS中的场景转换机制的浅显分析

    目前Apple推荐的场景转换的方法有以下几个: 一般的跳转方法: presentViewController Discussion In a horizontally compact environm ...

  9. Linux查看系统开机时间(转)

    1.who命令查看 who -b查看最后一次系统启动的时间. who -r查看当前系统运行时间 2.last  reboot last reboot可以看到Linux系统历史启动的时间. 重启一下操作 ...

  10. MediaInfo用来分析视频和音频文件的编码和内容信息的超好用工具

    转载:http://blog.csdn.net/ameyume/article/details/6718705 MediaInfo简介 MediaInfo 用来分析视频和音频文件的编码和内容信息. M ...