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参数初始化;

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

  1.         public boolean processMessage(Message msg) {  
  2.             boolean isTurningOn= isTurningOn();  
  3.             boolean isTurningOff = isTurningOff();  
  4. ………………  
  5.                 case STARTED:   {  
  6.                     if (DBG) Log.d(TAG,"CURRENT_STATE=PENDING, MESSAGE = STARTED, isTurningOn=" + isTurningOn + ", isTurningOff=" + isTurningOff);  
  7.                     //Remove start timeout  
  8.                     removeMessages(START_TIMEOUT);  
  9.   
  10.                     //Enable  
  11.                     boolean ret = adapterService.enableNative();//调用Native函数;  
  12.                     if (!ret) {  
  13.                         Log.e(TAG, "Error while turning Bluetooth On");  
  14.                         notifyAdapterStateChange(BluetoothAdapter.STATE_OFF);  
  15.                         transitionTo(mOffState);  
  16.                     } else {  
  17.                         sendMessageDelayed(ENABLE_TIMEOUT, ENABLE_TIMEOUT_DELAY);  
  18.                     }  
  19.                 }  
  20.                     break;  
  21. ………………  
  22. }  
  23. /*package*/ native boolean enableNative();  
        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

  1. static jboolean enableNative(JNIEnv* env, jobject obj) {  
  2.     ALOGV("%s:",__FUNCTION__);  
  3.   
  4.     jboolean result = JNI_FALSE;  
  5.     if (!sBluetoothInterface) return result;  
  6.   
  7.     int ret = sBluetoothInterface->enable();//JNI部分Native函数调用C语言中的函数实现;  
  8.     result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;//判断是打开还是关闭状态;  
  9.     return result;  
  10. }  
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 

  1. static int enable( void )  
  2. {  
  3.     ALOGI("enable");  
  4.   
  5.     /* sanity check */  
  6.     if (interface_ready() == FALSE)  
  7.         return BT_STATUS_NOT_READY;  
  8.   
  9.     return btif_enable_bluetooth();//enable汗的具体实现;  
  10. }<strong>  
  11. </strong>  
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|

  1. bt_status_t btif_enable_bluetooth(void)  
  2. {  
  3.     BTIF_TRACE_DEBUG0("BTIF ENABLE BLUETOOTH");  
  4.   
  5.     if (btif_core_state != BTIF_CORE_STATE_DISABLED)  
  6.     {  
  7.         ALOGD("not disabled\n");  
  8.         return BT_STATUS_DONE;  
  9.     }  
  10.   
  11.     btif_core_state = BTIF_CORE_STATE_ENABLING;//设定为正在打开状态;  
  12.   
  13.     /* Create the GKI tasks and run them */  
  14.     bte_main_enable();//BTE部分的enable  
  15.   
  16.     return BT_STATUS_SUCCESS;  
  17. }<strong>  
  18. </strong>  
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

  1. void bte_main_enable()  
  2. {  
  3.     int ret = -1;  
  4.   
  5.     APPL_TRACE_DEBUG1("%s", __FUNCTION__);  
  6.   
  7.     /* Initialize BTE control block */  
  8.     BTE_Init();//(1)、初始化BTE控制块;  
  9.   
  10.     lpm_enabled = FALSE;  
  11. //(2)、创建BTU_TASK 进程  
  12.     GKI_create_task((TASKPTR)btu_task, BTU_TASK, BTE_BTU_TASK_STR,  
  13.                     (UINT16 *) ((UINT8 *)bte_btu_stack + BTE_BTU_STACK_SIZE),  
  14.                     sizeof(bte_btu_stack));  
  15.     bte_hci_enable();//(3)、打开HCI和厂商模块控制;  
  16.     GKI_run(0);  
  17.     ret = bte_snoop_create_task();//BT  log 进程创建;  
  18.     if(ret != 0)  
  19.         APPL_TRACE_DEBUG1("bte_snoop_create_task fail %d",ret);  
  20. }  
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控制块

  1. BTE_Init();  
  2. 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.  
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 进程

  1. GKI_create_task((TASKPTR)btu_task, BTU_TASK, BTE_BTU_TASK_STR,  
  2.                 (UINT16 *) ((UINT8 *)bte_btu_stack + BTE_BTU_STACK_SIZE),  
  3.                 sizeof(bte_btu_stack));  
    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的处理都通过它来完成;

  1. BTU_API UINT32 btu_task (UINT32 param)  
  2. {  
  3. …………  
  4.     /* Initialize the mandatory core stack control blocks 
  5.        (BTU, BTM, L2CAP, and SDP) 
  6.      */  
  7.     btu_init_core();//1)、初始化核心control block,比如BTU, BTM, L2CAP, and SDP  
  8.   
  9.     /* Initialize any optional stack components */  
  10.     BTE_InitStack();//2)、初始化BTE控制块,比如RFCOMM, DUN, SPP, HSP2, HFP, OBX, BIP  
  11.   
  12. #if (defined(BTU_BTA_INCLUDED) && BTU_BTA_INCLUDED == TRUE)  
  13.     bta_sys_init();//3)、初始化BTA  
  14. #endif  
  15. …………  
  16.     /* Wait for, and process, events */  
  17.     for (;;)//进入循环状态  
  18.     {  
  19.         event = GKI_wait (0xFFFF, 0);//4)、获取相应EVENT;  
  20.   
  21.         if (event & TASK_MBOX_0_EVT_MASK)  
  22.         {…………}  
  23.         if (event & TIMER_0_EVT_MASK)  
  24.         {…………}  
  25.   
  26. #if defined(QUICK_TIMER_TICKS_PER_SEC) && (QUICK_TIMER_TICKS_PER_SEC > 0)  
  27.         if (event & TIMER_2_EVT_MASK)  
  28.         {  
  29.             btu_process_quick_timer_evt();  
  30.         }  
  31. #endif  
  32. #if (defined(BTU_BTA_INCLUDED) && BTU_BTA_INCLUDED == TRUE)  
  33.         if (event & TASK_MBOX_2_EVT_MASK)//这个状态比较重要  
  34.         {  
  35.             while ((p_msg = (BT_HDR *) GKI_read_mbox(TASK_MBOX_2)) != NULL)  
  36.             {  
  37.                 bta_sys_event(p_msg);//接收到的event在这里解析,然后执行BTU中的函数。  
  38.             }  
  39.         }  
  40.   
  41.         if (event & TIMER_1_EVT_MASK)  
  42.         {  
  43.             bta_sys_timer_update();  
  44.         }  
  45. #endif  
  46.   
  47.         if (event & EVENT_MASK(APPL_EVT_7))  
  48.             break;  
  49.     }  
  50.     return(0);  
  51. }  
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_enableEnable HCI & Vendor modules,打开HCI和厂商模块
bte_hci_enable的实现流程如下图所示

external\bluetooth\bluedroid\main\bte_main.c

  1. static void bte_hci_enable(void)  
  2. {  
  3.     APPL_TRACE_DEBUG1("%s", __FUNCTION__);  
  4.   
  5.     preload_start_wait_timer();  
  6.   
  7.     if (bt_hc_if)  
  8.     {  
  9.         int result = bt_hc_if->init(&hc_callbacks, btif_local_bd_addr.address);//初始化串口,HCI_H4、HCI工作线等;  
  10. ………………  
  11.         bt_hc_if->set_power(BT_HC_CHIP_PWR_ON);//给相应模块上电;  
  12.         bt_hc_if->preload(NULL);//下载相关配置参数;  
  13.         if (hci_logging_enabled == TRUE || hci_logging_config == TRUE)  
  14.             bt_hc_if->logging(BT_HC_LOGGING_ON, hci_logfile);  
  15.     }  
  16. }  
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

  1. static const bt_hc_interface_t bluetoothHCLibInterface = {  
  2.     sizeof(bt_hc_interface_t),  
  3.     init,//HCLib中的init;  
  4.     set_power,// HCLib中的power设定;  
  5.     lpm,  
  6.     preload, HCLib中的preload;  
  7.     postload,  
  8.     transmit_buf,  
  9.     set_rxflow,  
  10.     logging,  
  11.     cleanup  
  12. };<strong>  
  13. </strong>  
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

  1. static int init(const bt_hc_callbacks_t* p_cb, unsigned char *local_bdaddr)  
  2. {  
  3. …………  
  4.     /* store reference to user callbacks */  
  5.     bt_hc_cbacks = (bt_hc_callbacks_t *) p_cb;  
  6.   
  7.     init_vnd_if(local_bdaddr);//完成厂商模块的接口函数;      
  8. userial_init();//串口初始化  
  9.     lpm_init();//LPM初始化  
  10. …………  
  11. extern tHCI_IF hci_h4_func_table;// 应用HCI H4接口回调  
  12.     p_hci_if = &hci_h4_func_table;  
  13.     p_hci_if->init();//调用hci_h4_func_table的init办法,初始化H4模块  
  14.     utils_queue_init(&tx_q); //初始化发送队列  
  15. …………  
  16.     if (pthread_create(&hc_cb.worker_thread, &thread_attr, \  
  17.                        bt_hc_worker_thread, NULL) != 0) //起工作线程  
  18.     {  
  19.         ALOGE("pthread_create failed!");  
  20.         lib_running = 0;  
  21.         return BT_HC_STATUS_FAIL;  
  22.     }  
  23. …………  
  24. }  
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


  1. void init_vnd_if(unsigned char *local_bdaddr)  
  2. {  
  3.     void *dlhandle;  
  4.   
  5. dlhandle = dlopen("libbt-vendor.so", RTLD_NOW);// 1)、dlopen()函数以指定模式打开指定的动态链接库文件,并返回一个句柄给dlsym()的调用进程。  
  6. ………………  
  7.     bt_vnd_if = (bt_vendor_interface_t *) dlsym(dlhandle, "BLUETOOTH_VENDOR_LIB_INTERFACE");//2)、返回符号BLUETOOTH_VENDOR_LIB_INTERFACE,所对应的地址。  
  8. …………  
  9.     bt_vnd_if->init(&vnd_callbacks, local_bdaddr);//3)、调用返回地址结构体中的init函数;  
  10. }  
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()的调用进程。

  1. dlhandle = dlopen("libbt-vendor.so", RTLD_NOW);  
  2. void * dlopen( const char * pathname, int mode);  
  3. mode是打开方式,其值有多个,不同操作系统上实现的功能有所不同,在linux下,按功能可分为三类:  
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,所对应的地址,也就是:

  1. const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = {  
  2.     sizeof(bt_vendor_interface_t),  
  3.     init,  
  4.     op,  
  5.     cleanup  
  6. };  
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

  1. const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = {  
  2.     sizeof(bt_vendor_interface_t),  
  3.     init,  
  4.     op,  
  5.     cleanup  
  6. };  
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

  1. static int init(const bt_vendor_callbacks_t* p_cb, unsigned char *local_bdaddr)  
  2. {  
  3. …………  
  4.     /* store reference to user callbacks */  
  5.     bt_vendor_cbacks = (bt_vendor_callbacks_t *) p_cb;//把vnd_callbacks回调函数,保存到用户回调bt_vendor_cback;  
  6. …………  
  7. }<strong>  
  8. </strong>  
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

  1. static const bt_vendor_callbacks_t vnd_callbacks = {  
  2.     sizeof(bt_vendor_callbacks_t),  
  3.     fwcfg_cb,  
  4.     scocfg_cb,  
  5.     lpm_vnd_cb,  
  6.     alloc,  
  7.     dealloc,  
  8.     xmit_cb,  
  9.     epilog_cb  
  10. };  
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函数的初始化

  1. extern tHCI_IF hci_h4_func_table;  
  2. p_hci_if = &hci_h4_func_table;   
  3. p_hci_if->init();  
extern tHCI_IF hci_h4_func_table;
p_hci_if = &hci_h4_func_table; 
p_hci_if->init();
1)、hci_h4_func_table结构体成员函数
  1. const tHCI_IF hci_h4_func_table =  
  2. {  
  3.     hci_h4_init,//HCI_H4初始化;  
  4.     hci_h4_cleanup,  
  5.     hci_h4_send_msg,//发送msg;  
  6.     hci_h4_send_int_cmd,//发送int命令;  
  7.     hci_h4_get_acl_data_length,  
  8.     hci_h4_receive_msg//接收信息;  
  9. };  
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

  1. void hci_h4_init(void)  
  2. {  
  3.     HCIDBG("hci_h4_init");  
  4.     memset(&h4_cb, 0, sizeof(tHCI_H4_CB));  
  5.     utils_queue_init(&(h4_cb.acl_rx_q));  
  6.   
  7.     /* Per HCI spec., always starts with 1 */  
  8.     num_hci_cmd_pkts = 1;  
  9.   
  10.     /* Give an initial values of Host Controller's ACL data packet length 
  11.      * Will update with an internal HCI(_LE)_Read_Buffer_Size request 
  12.      */  
  13.     h4_cb.hc_acl_data_size = 1021;//hci ACL 数据的最大长度;  
  14.     h4_cb.hc_ble_acl_data_size = 27;//BLE  ACL最大数据长度;  
  15.   
  16.     btsnoop_init();  
  17. }<span style="color: red;">  
  18. </span>  
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工作线程,监听各种状态,处理相对应。

  1. static void *bt_hc_worker_thread(void *arg)  
  2. {  
  3. …………  
  4.         if (events & HC_EVENT_PRELOAD)  
  5.         {  
  6.             userial_open(USERIAL_PORT_1);  
  7. …………  
  8.                 bt_vnd_if->op(BT_VND_OP_FW_CFG, NULL);  
  9.     …………  
  10.         }  
  11.   
  12.         if (events & HC_EVENT_POSTLOAD)  
  13.   
  14.     …………  
  15.   
  16.         if (events & HC_EVENT_TX)  
  17.        …………  
  18.         if (events & HC_EVENT_LPM_ENABLE)  
  19.    ………………  
  20. }  
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

  1. /** Chip power control */  
  2. static void set_power(bt_hc_chip_power_state_t state)  
  3. {  
  4.     int pwr_state;  
  5. …………  
  6.     pwr_state = (state == BT_HC_CHIP_PWR_ON) ? BT_VND_PWR_ON : BT_VND_PWR_OFF;  
  7.   
  8.     if (bt_vnd_if)  
  9.         bt_vnd_if->op(BT_VND_OP_POWER_CTRL, &pwr_state);//设置controller  POWER ON/OFF  
  10. …………  
  11. }  
/** 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结构体:

  1. typedef struct {  
  2.     size_t          size;  
  3.     int   (*init)(const bt_vendor_callbacks_t* p_cb, unsigned char *local_bdaddr);  
  4.     int (*op)(bt_vendor_opcode_t opcode, void *param);  
  5.     void  (*cleanup)(void);  
  6. } bt_vendor_interface_t;  
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().

  1. static int op(bt_vendor_opcode_t opcode, void *param)  
  2. {  
  3. …………  
  4.     switch(opcode)  
  5.     {  
  6.         case BT_VND_OP_POWER_CTRL://如果是power控制  
  7.             {  
  8.          ALOGI("bt-vendor : BT_VND_OP_POWER_CTRL");       
  9.           #if 0//这部分代码展讯平台没有控制;  
  10.           nState = *(int *) param;  
  11.                 retval = hw_config(nState);  
  12.                 if(nState == BT_VND_PWR_ON  
  13.                    && retval == 0  
  14.                    && is_hw_ready() == TRUE)  
  15.                 {  
  16.                     retval = 0;  
  17.                 }  
  18.           #endif              
  19.             }  
  20.             break;  
  21.    …………  
  22. }  
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

  1. /** Called post stack initialization */  
  2. static void postload(TRANSAC transac)  
  3. {  
  4.     BTHCDBG("postload");  
  5.     bthc_signal_event(HC_EVENT_POSTLOAD);//发送信号量给线程<strong>bt_hc_worker_thread</strong>  
  6. }  
/** 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

  1. static void *bt_hc_worker_thread(void *arg)  
  2. {  
  3.     uint16_t events;  
  4. HC_BT_HDR *p_msg, *p_next_msg;  
  5. …………  
  6.         if (events & HC_EVENT_PRELOAD)  
  7.         {  
  8.             userial_open(USERIAL_PORT_1);//打开串口;  
  9.             /* Calling vendor-specific part */  
  10.             if (bt_vnd_if)  
  11.             {  
  12.                 bt_vnd_if->op(BT_VND_OP_FW_CFG, NULL);//(1)、mac、ini、pskey初始化  
  13.             }  
  14.             else  
  15.             {  
  16.                 if (bt_hc_cbacks)  
  17.                     bt_hc_cbacks->preload_cb(NULL, BT_HC_PRELOAD_FAIL);(2)、失败preload 回调函数              
  18. …………  
  19. }<strong>  
  20. </strong>  
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函数:

  1. static int op(bt_vendor_opcode_t opcode, void *param)  
  2. {  
  3. …………  
  4.                case BT_VND_OP_FW_CFG:  
  5.             {  
  6.                     ALOGI("bt-vendor : BT_VND_OP_FW_CFG");  
  7.                     retval = sprd_config_init(s_bt_fd,NULL,NULL);//初始化展讯平台  
  8.                     ALOGI("bt-vendor : sprd_config_init retval = %d.",retval);  
  9.                     if(bt_vendor_cbacks)  
  10.                     {  
  11.                         if(retval == 0)  
  12.                         {  
  13.                             ALOGI("Bluetooth Firmware and smd is initialized");  
  14.                        bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS);//初始化成功后回调函数  
  15.                         }  
  16.                         else  
  17.                         {  
  18.                             ALOGE("Error : hci, smd initialization Error");  
  19.                             bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_FAIL);  
  20.                         }  
  21.                     }  
  22.             }  
  23.             break;    
  24. }  
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

  1. //******************create bt addr end***********************  
  2. int sprd_config_init(int fd, char *bdaddr, struct termios *ti)  
  3. {  
  4. ………………  
  5.     if(access(BT_MAC_FILE, F_OK) == 0)// MAC地址创建如果btmac不存在,随机生成;  
  6.     {  
  7.         ALOGI("%s: %s exists",__FUNCTION__, BT_MAC_FILE);  
  8.         read_btmac=read_mac_from_file(BT_MAC_FILE,bt_mac);  
  9.     }  
  10.     if(read_btmac == 1)  
  11.     {  
  12.         for(i=0; i<6; i++)  
  13.         {  
  14.             bt_mac_tmp[i*2] = bt_mac[3*(5-i)];  
  15.             bt_mac_tmp[i*2+1] = bt_mac[3*(5-i)+1];  
  16.         }  
  17.         ALOGI("====bt_mac_tmp=%s", bt_mac_tmp);  
  18.         ConvertHexToBin((uint8*)bt_mac_tmp, strlen(bt_mac_tmp), bt_mac_bin);  
  19.     }  
  20.     /* Reset the BT Chip */  
  21.     memset(resp, 0, sizeof(resp));  
  22.     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: rgb(255, 0, 0);">文件的初始化</span></strong>  
  23.  …………  
  24.     {  
  25.         ALOGI("get_pskey_from_file ok \n");  
  26.         /* Send command from pskey_bt.txt*/  
  27.         if(read_btmac == 1)  
  28.         {  
  29.             memcpy(bt_para_tmp.device_addr, bt_mac_bin, sizeof(bt_para_tmp.device_addr));  
  30.         }  
  31.         if (write(s_bt_fd, (char *)&bt_para_tmp, sizeof(BT_PSKEY_CONFIG_T)) != sizeof(BT_PSKEY_CONFIG_T))   
  32.         {  
  33.             ALOGI("Failed to write pskey command from pskey file\n");  
  34.             return -1;  
  35.         }  
  36.     }  
  37.     ALOGI("sprd_config_init write pskey command ok \n");  
  38.     while (1)   
  39.     {  
  40.         r = read(s_bt_fd, resp, 1);  
  41.         if (r <= 0)  
  42.         return -1;  
  43.         if (resp[0] == 0x05)  
  44.         {  
  45.             ALOGI("read pskey response ok \n");  
  46.             break;  
  47.         }  
  48.     }  
  49.     ALOGI("sprd_config_init ok \n");  
  50.     return 0;  
  51. }  
//******************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: rgb(255, 0, 0);">文件的初始化</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 FOROM FILE ,这里完成 INI 文件的初始化:这部分内容和芯片相关, 不同厂商的芯片有不同的处理方法;

++++++sprd start 其他平台可以不看+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vendor\sprd\open-source\libs\libbt\src\bt_vendor_sprd.c

  1. int bt_getPskeyFromFile(void *pData)  
  2. {  
  3. …………  
  4. #ifdef HW_ADC_ADAPT_SUPPORT//不同INI文件  
  5.     char *CFG_2351_PATH[] = {  
  6.         "/system/etc/connectivity_configure_hw100.ini",  
  7.         "/system/etc/connectivity_configure_hw102.ini",  
  8.         "/system/etc/connectivity_configure_hw104.ini"  
  9.     };  
  10. #else  
  11.     char *CFG_2351_PATH[] = {  
  12.         "/system/etc/connectivity_configure.ini"  
  13.     };  
  14. #endif  
  15. #ifdef HW_ADC_ADAPT_SUPPORT  
  16. //如果是不同的硬件,获取板子信息,给board_type赋值,后面选择用那个ini文件。这个是展讯平台相关,不同平台有不同的做法;  
  17.     char *BOARD_TYPE_PATH = "/dev/board_type";  
  18.     int fd_board_type;  
  19.     char board_type_str[MAX_BOARD_TYPE_LEN] = {0};  
  20.     fd_board_type = open(BOARD_TYPE_PATH, O_RDONLY);//(1)、获取硬件版本信息  
  21.     if (fd_board_type<0)  
  22.     {  
  23.         ALOGI("#### %s file open %s err ####\n", __FUNCTION__, BOARD_TYPE_PATH);  
  24.         board_type = 2; // default is 1.0.4  
  25.     }  
  26.     else  
  27.     {  
  28.         len = read(fd_board_type, board_type_str, MAX_BOARD_TYPE_LEN);  
  29.         if (strstr(board_type_str, "1.0.0"))  
  30.         {  
  31.             board_type = 0;  
  32.         }  
  33.  …………  
  34. #endif  
  35.     ALOGI("begin to bt_getPskeyFromFile");    
  36.     fd = open(CFG_2351_PATH[board_type], O_RDONLY, 0644);  
  37.     if(-1 != fd)  
  38.     {  
  39.         len = bt_getFileSize(CFG_2351_PATH[board_type]);//(2)、获得相应的版本的PSKEY;  
  40.         pBuf = (unsigned char *)malloc(len);  
  41.         ret = read(fd, pBuf, len);  
  42.      …………  
  43.     ret = bt_getDataFromBuf(pData, pBuf, len);  
  44.     if(-1 == ret)  
  45.     {  
  46.         free(pBuf);  
  47.         return -1;  
  48.     }  
  49.     ALOGI("begin to dumpPskey");  
  50.     bt_dumpPskey((BT_PSKEY_CONFIG_T *)pData);//(3)、解析相应数据  
  51.     free(pBuf);  
  52.     return 0;  
  53. }  
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;

  1. char *CFG_2351_PATH[] = {  
  2.         "/system/etc/connectivity_configure_hw100.ini",  
  3.         "/system/etc/connectivity_configure_hw102.ini",  
  4.         "/system/etc/connectivity_configure_hw104.ini"  
  5.     };  
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

  1. static void fwcfg_cb(bt_vendor_op_result_tresult)  
  2. {  
  3.     bt_hc_postload_result_tstatus = (result == BT_VND_OP_RESULT_SUCCESS) ? \  
  4.                                     BT_HC_PRELOAD_SUCCESS : BT_HC_PRELOAD_FAIL;//判定prelaod是否成功;  
  5.     fwcfg_acked = TRUE;  
  6.     if (bt_hc_cbacks)  
  7.         bt_hc_cbacks->preload_cb(NULL, status);//对应preload_cb  
  8. }  
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
  1. static void preload_cb(TRANSACtransac, bt_hc_preload_result_t result)  
  2. {  
  3.     APPL_TRACE_EVENT1("HC preload_cb %d[0:SUCCESS 1:FAIL]", result);  
  4.     if (result == BT_HC_PRELOAD_SUCCESS)  
  5.     {  
  6.         preload_stop_wait_timer();  
  7.         /* notify BTU task that libbt-hci isready */  
  8.         GKI_send_event(BTU_TASK, BT_EVT_PRELOAD_CMPL);//发送BT_EVT_PRELOAD_CMPL到BTU_TASK  
  9.     }  
  10. }  
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实现流程;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值