代码位置:       frameworks/base/services/java/com/android/server/BluetoothManagerService.java       这部分代码,生成libandroid_runtime.so 完成功能,中转BluetoothAdapter和Bluetooth.apk,所有来自其他应用的请求,都通过IBluetooth接口,转发到Bluetooth.apk      启动方式:      Intent i = new Intent(IBluetooth.class.getName());                 if (!mContext.bindService(i, mConnection,Context.BIND_AUTO_CREATE,
                                          UserHandle.USER_CURRENT)) {      这里IBluetooth.class.getName实际返回android.bluetooth.IBluetooth      这个action正好是packages/app/Bluetooth/AdapterService要处理的action。            BluetoothManagerService保持一个BluetoothServiceConnection的回调,当AdapterService启动时,就可以拿到IBluetooth接口了。
代码位置:      packages/apps/Bluetooth      这部分代码,生成Bluetooth.apk 完成功能: 1、IBluetooh.aidl的服务端,由AdapterService的内部类AdapterServiceBinder实现 2、在BluetoothManagerService调用IBluetooth接口时,实际上是在AdapterServiceBinder端来处理。 3、IBluetooth.enable -> AdapterServiceBinder->enable -> BluetoothManagerService.enable      BluetoothManagerService初始化了一个蓝牙状态机AdapterState实例,mAdapterStateMachine,调用enable是给状态机发一个消息AdapterState.USER_TURN_ON 4、再往下层的调用是通过,AdapterService的JNI接口enableNative
代码位置:       packages/apps/Bluetooth/jni       这部分代码,是AdapterService的JNI实现  完成功能: 1、获取bluetooth.default接口,这个接口是android获取HAL的通用方式,       err = hw_get_module(id, (hw_module_t const**)&module); 2、因此调用JNI enableNative实际是调用bluetooth.default的实现enable
蓝牙关闭过程: 1、客户端调用AdapterService.java的disable接口 2、AdapterService给AdapterStateMachine发送一个USER_TURN_OFF的Message 3、AdapterStateMachine调用AdapterProperties的onBluetoothDisable接口 4、AdapterProperties把scan mode设置为AbstractionLayer.BT_SCAN_MODE_NONE 5、AdapterProperties调用AdapterService的setAdapterPropertyNative接口,往底层调用 6、在JNI层com_android_bluetooth_btservice_AdapterServices的setAdapterPropertyNative,调用蓝牙HAL接口sBluetoothInterface->set_adapter_property(&prop); 7、蓝牙HAL接口的实现,在external/bluetooth/bluedroid/btif/src/bluetooth.c中 8、bluetooth.c :: set_adapter_property -> btif_core.c :: btif_set_adapter_property 9、btif_set_adapter_property对属性BT_PROPERTY_ADAPTER_SCAN_MODE设置的处理,先保存discovery mode为BTA_DM_NON_DISC,表示不可发现,保存connecable mode为BTA_DM_NON_CONN,表示不可连接。然后,调用external/bluetooth/bluedroid/bta/dm/bta_dm_api.c :: BTA_DmSetVisibility方法 10、BTA_DmSetVisibility构造一个tBTA_DM_API_SET_VISIBILITY    *p_msg,填入discovery mode, connetiable mode等参数,然后调用external/bluetooth/bluedroid/bta/sys/bta_sys_main.c :: bta_sys_sendmsg 11、bta_sys_sendmsg调用external/bluetooth/bluedroid/gki/common/gki_buffer.c :: GKI_send_msg发送一条GKI信息到BTA,GKI_send_msg有三个参数,第一个参数是线程id,也作为task id, 通过bta_sys_init获得,第二个参数是mailbox id,第三个是上一步封装好的p_msg 12、GKI_send_msg首先对p_msg进一步封装成event,通过链表存到mailbox id对应的任务队列中,调用external/bluetooth/bluedroid/gki/ulinux/gki_ulinux.c :: GKI_send_event进行发送 13、GKI_send_event设置事件掩码gki_cb.com.OSWaitEvt[task_id] |= event;, 通过pthread_cond_signal(&gki_cb.os.thread_evt_cond[task_id]);通知另外线程。 14、这样,在另外一个等待线程函数中gki_ulinux.c :: GKI_wait可以返回了,现在来看这个等待线程是怎么起来的
在调用HAL接口bluetoothInterface集合中的init的时候, 1、btif/src/bluetooth.c :: init 会调用 btif/src/btif_core.c :: btif_init_bluetooth 启动一个BTIF任务 2、btif_init_bluetooth 调用gki/ulinux/gki_ulinux.c :: GKI_create_task(btif_task, BTIF_TASK, BTIF_TASK_STR,                 (UINT16 *) ((UINT8 *)btif_task_stack + BTIF_TASK_STACK_SIZE),
                sizeof(btif_task_stack)); 启动这个任务,第一个参数btif_task是任务处理函数,第二个参数是task id,第三个是对应string表示形式,第四个是任务列表的起始指针,第四个是任务栈最大深度。 3、GKI_create_task 启动一个线程,等待任务事件     ret = pthread_create( &gki_cb.os.thread_id[task_id], //保存了线程id               &attr1,
              (void *)gki_task_entry,
              &gki_pthread_info[task_id]);   //gki_pthread_info保存了任务信息:task_id,task_entry。
可向而知,刚刚创建的任务线程,就是那个等待线程,来看gki_task_entry,即是btif_task的实现: btif/src/btif_core.c 1、因为我们已经要开始等待事件了,因此要通知JAVA/JNI层,记得刚刚我们有注册了回调,那么就通过宏HAL_CBACK(bt_hal_cbacks, thread_evt_cb, ASSOCIATE_JVM);来通知JNI 2、进入for(;;) 3、调用GKI_wait,等待一个事件的返回 4、判断事件 event == BT_EVT_TRIGGER_STACK_INIT,如果是,就调用BTA_EnableBluetooth(bte_dm_evt)初始化蓝牙芯片组 5、判断事件event & EVENT_MASK(GKI_SHUTDOWN_EVT,如果是,就对出任务循环 6、判断事件event & TASK_MBOX_1_EVT_MASK 判断是否是1好mbox里面的事件。 7、如果第6步满足判断事件,那么判断事件 event  & BT_EVT_CONTEXT_SWITCH_EVT,如果是,调用btif_context_switched(p_msg)切换上下文 8、回第三步
到这里,很奇怪,为什么没有我们要处理的事件,难道在另外的任务线程里面处理? 在回过头来,看GKI对TASK_MBOX, TASK_MBOX_EVT_MASK的规划 TIMER事件,TASK事件,APPL事件(应用程序请求事件?)
gki/common/gki.h #define TASK_MBOX_0    0
#define TASK_MBOX_1    1
#define TASK_MBOX_2    2
#define TASK_MBOX_3    3
                   
#define NUM_TASK_MBOX  4
#define MAX_EVENTS              16
                   
#define TASK_MBOX_0_EVT_MASK   0x0001
#define TASK_MBOX_1_EVT_MASK   0x0002
#define TASK_MBOX_2_EVT_MASK   0x0004
#define TASK_MBOX_3_EVT_MASK   0x0008
/* Definitions of task IDs for inter-task messaging */
#ifndef BTU_TASK
#define BTU_TASK                0
#endif

#ifndef BTIF_TASK
#define BTIF_TASK               1
#endif

#ifndef A2DP_MEDIA_TASK
#define A2DP_MEDIA_TASK         2
#endif

/* The number of GKI tasks in the software system. */
#ifndef GKI_MAX_TASKS
#define GKI_MAX_TASKS               3
#endif
在第11步bta_sys_sendmsg调用GKI_send_msg(bta_sys_cb.task_id, p_bta_sys_cfg->mbox, p_msg); 他的TASK_ID就是bta_sys_cb.task_id,现在看下这个task_id的初始化过程,也就是BTA系统的初始化过程 BTA的初始化,要从在BTU的任务处理函数(btu_task)中开始的,那么btu_task又是怎么起来的, 这就要从bt开启的时候说起了。 1、在开启蓝牙之时,JNI调用HAL接口bluetoothInterface的enable函数,即btif/src/btif_core.c :: btif_enable_bluetooth 2、btif_enable_bluetooth调用main/bte_main.c的BTE API函数bte_main_enable(btif_local_bd_addr.address); 其从bte task,这个address怎么来的? 3、bte_main_enable,首先,初始化BTE控制块(HCI相关回调) 4、调用hci接口,(替代4.1的hciattach进程?),给bt设备上电。 5、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));   //启动BTU任务 6、pthread_create( &timer_thread_id,
              &timer_attr,
              timer_thread,
              NULL); //根据NO_GKI_RUN_RETURN是否执行timer_thread线程,NO_GKI_RUN_RETURN是什么意思?LINUX是否需要定义此宏?
再来看btu_task的实现: 1、btu_init_core(); 初始化核心control block,比如BTU, BTM, L2CAP, and SDP 2、BTE_InitStack();初始化BTE控制块,比如RFCOMM, DUN, SPP, HSP2, HFP, OBX, BIP 3、#if (defined(BTU_BTA_INCLUDED) && BTU_BTA_INCLUDED == TRUE)  //初始化BTA      bta_sys_init();
     #endif  4、#if ( BT_USE_TRACES==TRUE )   //此宏用于调试,是否设置?      BTE_InitTraceLevels();  
     #endif 5、进入for(;;) 6、处理事件的列表://为什么不是全部?      TASK_MBOX_0_EVT_MASK      TIMER_0_EVT_MASK      TIMER_1_EVT_MASK      TIMER_2_EVT_MASK      RPCGEN_MSG_EVT      TASK_MBOX_2_EVT_MASK      EVENT_MASK(APPL_EVT_7) //APPL_EVT_7事件      再来看bta_sys_init的实现 bta/sys/bta_sys_main.c bta_sys_init //注意到这里并没有建一个bta_task 1、bta_sys_cb.task_id = GKI_get_taskid();   //获取task id,是什么? 这里的GKI_get_taskid()仅是调用pthread_self()获取pthread_t,那么这段代码很明显是跟btu_task是同一个pthread,因此发给bta_sys_cb.task_id自然而然的由btu_task来处理了。
再回过头来看bta_sys_sendmsg的实现 void bta_sys_sendmsg(void *p_msg)
{
    GKI_send_msg(bta_sys_cb.task_id, p_bta_sys_cfg->mbox, p_msg);
}
这里GKI_send_msg的第一个参数已经确定,第二个参数见BTA相关参数的映射:       BTA相关映射关系如下: /* GKI task mailbox event for BTA. */
#ifndef BTA_MBOX_EVT
#define BTA_MBOX_EVT                TASK_MBOX_2_EVT_MASK
#endif

/* GKI task mailbox for BTA. */
#ifndef BTA_MBOX
#define BTA_MBOX                    TASK_MBOX_2
#endif

/* GKI timer id used for protocol timer for BTA. */
#ifndef BTA_TIMER
#define BTA_TIMER                   TIMER_1
#endif

const tBTA_SYS_CFG bta_sys_cfg =
{
    BTA_MBOX_EVT,               /* GKI mailbox event */
    BTA_MBOX,                   /* GKI mailbox id */
    BTA_TIMER,                  /* GKI timer id */
    APPL_INITIAL_TRACE_LEVEL    /* initial trace level */
}; 

tBTA_SYS_CFG *p_bta_sys_cfg = (tBTA_SYS_CFG *)&bta_sys_cfg;           
那么第二个参数也确定下来了,就是TASK_MBOX_2

再回过头来看btu_task处理的时间列表,里面正包含了TASK_MBOX_2_EVT_MASK
这样,我们终于找到处理设置BT_PROPERTY_ADAPTER_SCAN_MODE的债主了,就是btu_task 再来看btu_task对TASK_MBOX_2_EVT_MASK的实现         if (event & TASK_MBOX_2_EVT_MASK)
        {
            while ((p_msg = (BT_HDR *) GKI_read_mbox(TASK_MBOX_2)) != NULL)  //取出p_msg
            {
                bta_sys_event(p_msg); //处理p_msg
            }
        }
也就是说bta_sys_event会调用子系统回调函数去处理p_msg,看怎么实现的。bta/sys/bta_sys_main.c ::  bta_sys_event BTA_API void bta_sys_event(BT_HDR *p_msg)  //这里名字也正好与BTA对应上 1、UINT8 id = (UINT8) (p_msg->event >> 8); 获取id 右移8位 2、    if ((id < BTA_ID_MAX) && (bta_sys_cb.reg[id] != NULL))          {              freebuf = (*bta_sys_cb.reg[id]->evt_hdlr)(p_msg);          }  3、再看当初event的形成      void BTA_DmSetVisibility(tBTA_DM_DISC disc_mode, tBTA_DM_CONN conn_mode, UINT8 pairable_mode, UINT8 conn_filter )           p_msg->hdr.event = BTA_DM_API_SET_VISIBILITY_EVT; 4、BTA_DM_API_SET_VISIBILITY_EVT的取值定义在bta/dm/bta_dm_int.h enum
{  
    /* device manager local device API events */
    BTA_DM_API_ENABLE_EVT = BTA_SYS_EVT_START(BTA_ID_DM),  //注意这里BTA_SYS_EVT_START(BTA_ID_DM)实现#define BTA_SERVICE_ID_TO_SERVICE_MASK(id)       (1 << (id));因为BTA_ID_DM是1,     BTA_DM_API_DISABLE_EVT,
    BTA_DM_API_SET_NAME_EVT,
    BTA_DM_API_SET_VISIBILITY_EVT,
    BTA_DM_API_SET_AFH_CHANNELS_EVT,
    BTA_API_DM_SIG_STRENGTH_EVT,
    BTA_DM_API_VENDOR_SPECIFIC_COMMAND_EVT, 
    BTA_DM_API_TX_INQPWR_EVT,
    BTA_DM_ACL_CHANGE_EVT,
    BTA_DM_API_ADD_DEVICE_EVT,      ... }; 5、因此计算刚才的id,也是1
BTA_ID_DM的回调函数的注册的过程 1、还记得btif_task刚起来的时候,会等待一个BT_EVT_TRIGGER_STACK_INIT的事件,对那个事件的处理,就是调用BTA_EnableBluetooth进行初始化硬件。         if (event == BT_EVT_TRIGGER_STACK_INIT)
        {
            BTIF_TRACE_DEBUG0("btif_task: received trigger stack init event");
            BTA_EnableBluetooth(bte_dm_evt);
        } 2、bta/dm/bta_dm_api.c :: tBTA_STATUS BTA_EnableBluetooth(tBTA_DM_SEC_CBACK *p_cback)      在这里面,注册两个子系统处理回调      bta_sys_register (BTA_ID_DM, &bta_dm_reg );      bta_sys_register (BTA_ID_DM_SEARCH, &bta_dm_search_reg );      那么,我们来看他的定义      static const tBTA_SYS_REG bta_dm_reg =      {
         bta_dm_sm_execute,          bta_dm_sm_disable      };
     那么,bta_dm_sm_execute正是bta_sys_event要调用的实现
bta_dm_sm_execute的实现: 1、UINT16  event = p_msg->event & 0x00ff; //获得event事件,BTA_DM_API_SET_VISIBILITY_EVT 2、 (*bta_dm_action[event])( (tBTA_DM_MSG*) p_msg); 调用这个函数来处理 3、bta_dm_action列表:      const tBTA_DM_ACTION bta_dm_action[] =                                       
{                                                                            
   
    /* device manager local device API events */
    bta_dm_enable,            /* 0  BTA_DM_API_ENABLE_EVT */
    bta_dm_disable,           /* 1  BTA_DM_API_DISABLE_EVT */
    bta_dm_set_dev_name,      /* 2  BTA_DM_API_SET_NAME_EVT */
    bta_dm_set_visibility,    /* 3  BTA_DM_API_SET_VISIBILITY_EVT */
    bta_dm_set_afhchannels,   /* 4  BTA_DM_API_SET_AFH_CHANNELS_EVT */       
    bta_dm_signal_strength,   /* 5  BTA_API_DM_SIG_STRENGTH_EVT */
    bta_dm_vendor_spec_command,/* 6  BTA_DM_API_VENDOR_SPECIFIC_COMMAND_EVT */
    bta_dm_tx_inqpower,       /* 7  BTA_DM_API_SIG_STRENGTH_EVT */           
    bta_dm_acl_change,        /* 8  BTA_DM_ACL_CHANGE_EVT */
    bta_dm_add_device,        /* 9  BTA_DM_API_ADD_DEVICE_EVT */             
    ... } 4、也就是说调用bta_dm_set_visibility来实现。
bta_dm_set_visibility的实现bta/dm/bta_dm_act.c 1、BTM_SetDiscoverability((UINT8)p_data->set_visibility.disc_mode,                                 bta_dm_cb.inquiry_scan_window,
                                bta_dm_cb.inquiry_scan_interval);   //调用这个实现设置discovery mode           BTM_SetDeviceClass (cod);//DEV_CLASS cod封装好discory mode                btsnd_hcic_write_dev_class (dev_class); //stack/hcic/hcicmds.c 2、BTM_SetConnectability((UINT8)p_data->set_visibility.conn_mode,
                                bta_dm_cb.page_scan_window,
                                bta_dm_cb.page_scan_interval);   //调用这个实现设置can mode           btsnd_hcic_write_scan_enable (scan_mode);  //stack/hcic/hcicmds.c 3、btsnd_hcic_write_dev_class 和 btsnd_hcic_write_scan_enable 都会将参数封包,通过cmd方式,调用btu_hcif_send_cmd发送出去。
btu_hcif_send_cmd的实现: 1、首先取出命令控制块      tHCI_CMD_CB * p_hci_cmd_cb = &(btu_cb.hci_cmd_cb[controller_id]); 2、p_hci_cmd_cb->cmd_window = p_hci_cmd_cb->cmd_xmit_q.count + 1;   //打开发送窗口 3、while (p_hci_cmd_cb->cmd_window != 0) {           ...           p_buf = (BT_HDR *)GKI_dequeue (&(p_hci_cmd_cb->cmd_xmit_q));   //从链表中取出一个消息           btu_hcif_store_cmd(controller_id, p_buf);   //保存发出去的消息,用于超时机制                GKI_enqueue(&(p_hci_cmd_cb->cmd_cmpl_q), p_cmd); // 拷贝到链表中                btu_start_timer (&(p_hci_cmd_cb->cmd_cmpl_timer),                          (UINT16)(BTU_TTYPE_BTU_CMD_CMPL + controller_id),
                         BTU_CMD_CMPL_TIMEOUT);   //启动计时器,  cmd_cmpltimer与cmd_cmpl_q的关系?             p_hci_cmd_cb->cmd_window--; //计数器减一
            if (controller_id == LOCAL_BR_EDR_CONTROLLER_ID)
            {
                HCI_CMD_TO_LOWER(p_buf); //发送到底层,是一个宏
            }
          ...      } 4、HCI_CMD_TO_LOWER的宏定义       bluedroid/include/bt_target.h:#define HCI_CMD_TO_LOWER(p)         bte_main_hci_send((BT_HDR *)(p), BT_EVT_TO_LM_HCI_CMD);       来看bte_main_hci_send的实现: 1、UINT16 sub_event = event & BT_SUB_EVT_MASK;//利用子事件掩码,BT_EVT_TO_LM_HCI_CMD & BT_SUB_EVT_MASK = 0 2、    if((sub_event == LOCAL_BR_EDR_CONTROLLER_ID) || \        (sub_event == LOCAL_BLE_CONTROLLER_ID))
            bt_hc_if->transmit_buf((TRANSAC)p_msg, \
                                       (char *) (p_msg + 1), \
                                        p_msg->len);  //调用transmit_buf接口发送出去。
      bt_hc_if是在HCI初始化的过程中得到的。
HCI初始化过程 在调用HAL接口bluetoothInterface集合中的init的时候, 1、btif/src/bluetooth.c :: init 会调用 btif/src/btif_core.c :: btif_init_bluetooth 2、btif_init_bluetooth 会调用main/bte_main.c ::  bte_main_boot_entry   //初始化BT芯片的入口 3、bte_main_boot_entry 调用 bte_main_in_hw_init 或许HCI接口           static bt_hc_interface_t * bt_hc_if = (bt_hc_interface_t *) bt_hc_get_interface();           static const bt_hc_callbacks_t bt_hc_callbacks; //回调,跟bt_hc_if调用方向刚好相反 4、hci/src/bt_hci_bdroid.c中      const bt_hc_interface_t *bt_hc_get_interface(void)      {
         return &bluetoothHCLibInterface; //返回接口列表      } 4、在使能蓝牙调用bte_main_enable的时候,开始btu_stack之前,会按顺序初始化蓝牙设备。      bt_hc_if->init(&hc_callbacks, local_addr);  //hc_callbacks是hci回调      bt_hc_if->set_power(BT_HC_CHIP_PWR_ON);
     bt_hc_if->preload(NULL); 5、bt_hc_if->init也就是调用bluetoothHCLibInterface的init方法       来看bluetoothHCLibInterface的init方法 hci/src/bt_hci_bdroid.c 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)   //起工作线程
在回过头来看transmit_buf,其实就是调用bluetoothHCLibInterface的transmit_buf方法 看transmit_buf的实现:hci/src/bt_hci_bdroid.c static int transmit_buf(TRANSAC transac, char *p_buf, int len)
{
    utils_enqueue(&tx_q, (void *) transac);  //链接到发送队列

    bthc_signal_event(HC_EVENT_TX); //广播事件

    return BT_HC_STATUS_SUCCESS;
}
另外一边的工作线程bt_hc_worker_thread,接收到上面的广播事件之后会判断事件类型,如果是HC_EVENT_TX,首先将目前所有的时间加入到数组sending_msg_que里面       for(i = 0; i < sending_msg_count; i++)                 p_hci_if->send(sending_msg_que[i]);   //调用p_hci_if的send接口发送出去。
上面已经提到p_hci_if的send接口在hci_h4_func_table中实现,hci/src/hci_h4.c 来看其send回调的实现 void hci_h4_send_msg(HC_BT_HDR *p_msg) {      ...      if (event == MSG_STACK_TO_HC_HCI_CMD)         type = H4_TYPE_COMMAND;   //设定cmd类型      if (sub_event == LOCAL_BR_EDR_CONTROLLER_ID)      {
        acl_data_size = h4_cb.hc_acl_data_size;
        acl_pkt_size = h4_cb.hc_acl_data_size + HCI_ACL_PREAMBLE_SIZE;  //设置数据大小
     }      ...      bytes_sent = userial_write(event,(uint8_t *) p, bytes_to_send);//写串口, 是否会阻塞
     ...      bt_hc_cbacks->tx_result((TRANSAC) p_msg, (char *) (p_msg + 1), \                                         BT_HC_TX_SUCCESS);   //将发送结果通过回调发回去,注意这里只是成功发送到串口,有没有成功,应该是从内核往上发,由userial_read_thread来完成。
来看读线程userial_read_thread的实现 static void *userial_read_thread(void *arg) {     while (userial_running) {          //调用回调申请一段消息BUFFER               p_buf = (HC_BT_HDR *) bt_hc_cbacks->alloc( \
                                                BTHC_USERIAL_READ_MEM_SIZE);         //select读取串口消息         rx_length = select_read(userial_cb.fd, p, READ_LIMIT);         //将消息发到rx队列,并广播出去         utils_enqueue(&(userial_cb.rx_q), p_buf);
        bthc_signal_event(HC_EVENT_RX);         //调用回调释放内存
        bt_hc_cbacks->dealloc((TRANSAC) p_buf, (char *) (p_buf + 1));
   } }
工作线程bt_hc_worker_thread得到广播之后         if (events & HC_EVENT_RX)
        {
            p_hci_if->rcv(); //调用rcv,也就是hci_h4_func_table的hci_h4_receive_msg回调
        } hci_h4_receive_msg有一个rcv_state变量,表征当前数据帧的收取状态 typedef enum {
    H4_RX_MSGTYPE_ST,
    H4_RX_LEN_ST,
    H4_RX_DATA_ST,
    H4_RX_IGNORE_ST
} tHCI_H4_RCV_STATE;
通过条件p_cb->rcv_msg_type和acl_rx_frame_end_chk()两个条件,判断当前是否收完一帧数据,如果是,则调用bt_hc_cbacks的data_ind回调把数据上发:                 bt_hc_cbacks->data_ind((TRANSAC) p_cb->p_rcv_msg, \
                                       (char *) (p_cb->p_rcv_msg + 1), \
                                       p_cb->p_rcv_msg->len + BT_HC_HDR_SIZE);

bt_hc_cbacks的data_ind回调,就是main/bte_main.c hc_callbacks的data_ind函数,来看它的实现 static int data_ind(TRANSAC transac, char *p_buf, int len)                 
{                                                                          
    BT_HDR *p_msg = (BT_HDR *) transac;                                   
    GKI_send_msg (BTU_TASK, BTU_HCI_RCV_MBOX, transac);  //发到btu task中去了,而且mbox为TASK_MBOX_0     //因为如下宏     //#define BTU_HCI_RCV_MBOX        TASK_MBOX_0     /* Messages from HCI  */
    return BT_HC_STATUS_SUCCESS;                                           
}                                                                          

那么在btu task中: 比较事件验码为BT_EVT_TO_BTU_HCI_EVT后, 进而调用btu_hcif.c的btu_hcif_process_event处理来自底层的事件上报,在 会取出event code,不同的code,调用不同的函数来处理,以HCI_PAGE_SCAN_REP_MODE_CHNG_EVT为例子,它的处理函数为btu_hcif_page_scan_rep_mode_chng_evt,这样,再一层层, 这里应该报上两个事件btif_adapter_properties_evt,一个是discovery mode一个是connectiable mode,是否保证到JAVA的通路是畅通的?

在写属性的过程中,往串口写是一方面,在写完串口之后,还需要更新本地数据库。(要是BT模块写拒绝怎么办?) 在btif/src/btif_core.c :: btif_set_adapter_property 中,最后一步     if (storage_req_id != BTIF_CORE_STORAGE_NO_ACTION)  //判断是否需要更新数据库
    {
        int btif_status;
        /* pass on to storage for updating local database */

        memset(&(req.write_req.bd_addr), 0, sizeof(bt_bdaddr_t));
        memcpy(&(req.write_req.prop), property, sizeof(bt_property_t));
        // btif_transfer_context会将一个消息到BTU_BTIF_MBO,也就是TASK_MBOX_1信箱,并且这个消息         // 由btif_task来处理
        return btif_transfer_context(execute_storage_request, 
                                     storage_req_id,
                                     (char*)&req,
                                     sizeof(btif_storage_req_t)+property->len,
                                     btif_in_storage_request_copy_cb);                  btif_sendmsg(p_msg)                     GKI_send_msg(BTIF_TASK, BTU_BTIF_MBOX, p_msg);
    }

来看btif的处理: if(event & TASK_MBOX_1_EVT_MASK)  {  //计算掩码,符合      while((p_msg = GKI_read_mbox(BTU_BTIF_MBOX)) != NULL) {   //取出消息           switch (p_msg->event)                 {
                    case BT_EVT_CONTEXT_SWITCH_EVT:  //判断消息类型,符合
                        btif_context_switched(p_msg); //处理消息
                        break;
                    ...                }      } }
来看btif_context_switched的实现: static void btif_context_switched(void *p_msg)
{
    tBTIF_CONTEXT_SWITCH_CBACK *p = (tBTIF_CONTEXT_SWITCH_CBACK *) p_msg;
    /* each callback knows how to parse the data */
    if (p->p_cb)
        p->p_cb(p->event, p->p_param);  //取出事件处理回调函数,也就是execute_storage_request
}

来看execute_storage_request的实现 static void execute_storage_request(UINT16 event, char *p_param) {     switch(event){
        case BTIF_CORE_STORAGE_ADAPTER_WRITE: //判断事件类型,符合
        {
            btif_storage_req_t *p_req = (btif_storage_req_t*)p_param;             bt_property_t *p_prop = &(p_req->write_req.prop);
            status = btif_storage_set_adapter_property(p_prop);   //是否会阻塞?             HAL_CBACK(bt_hal_cbacks, adapter_properties_cb, status, 1, p_prop);  //调用JNI测的回调           }           ...       } }
而在JAVA一侧,通过AdapterProperties.java的回调adapterPropertyChangedCallback,可以得知刚才property设置的结果(是否从串口发上来的?): case: AbstractionLayer.BT_PROPERTY_ADAPTER_SCAN_MODE:       mService.startBluetoothDisable 1、调用AdapterService的startBluetoothDisable方法 2、AdapterService给AdapterStateMachine发送AdaterState.BEGIN_DISABLE的Message 3、AdapterStateMachine调用AdapterService的disableNative接口
adapterPropertyChangedCallback回调,通过com_android_bluetooth_btservice_AdapterService.cpp调用JAVA的方式,调用 在JNI一层,有一组回调接口,是通过Android HAL层组织的 bt_callbacks_t sBluetoothCallbacks = {                                       
    sizeof(sBluetoothCallbacks),                                             
    adapter_state_change_callback,                                           
    adapter_properties_callback,                                             
    remote_device_properties_callback,                                       
    device_found_callback,                                                   
    discovery_state_changed_callback,                                        
    pin_request_callback,                                                    
    ssp_request_callback,                                                    
    bond_state_changed_callback,                                             
    acl_state_changed_callback,                                              
    callback_thread_event,                                                   
};  这组回调,通过sBluetoothInterface->init(&sBluetoothCallbacks);注册。 而sBluetoothInterface的实现,在external/bluetooth/bluedroid/btif/src const bt_interface_t* bluetooth__get_bluetooth_interface ()
{
    return &bluetoothInterface;
} static const bt_interface_t bluetoothInterface = {
    sizeof(bt_interface_t),
    init,
    enable,
    disable,
    cleanup,
    get_adapter_properties,
    get_adapter_property,
    set_adapter_property,
    get_remote_device_properties,
    get_remote_device_property,
    set_remote_device_property,
    get_remote_service_record,
    get_remote_services,
    start_discovery,
    cancel_discovery,
    create_bond,
    remove_bond,
    cancel_bond,
    pin_reply,
    ssp_reply,
    get_profile_interface,
    dut_mode_configure,
    dut_mode_send
}; 在init里面,会将sBluetoothInterface保存在bluetoothInterface中,
因此,反响调用的顺序是这样的 1、bluetoothInterface->adapter_properties_cb也就是com_android_bluetooth_btservice_AdapterService的adapter_properties_cb 2、adapter_properties_callback调用AdapterProperties的adapterPropertyChangedCallback方法
现在看btif_storage_set_adapter_property的实现,研究一下事件是怎么写入NVRAM中去。 btif/src/btif_storage.c bt_status_t btif_storage_set_adapter_property(bt_property_t *property)
{                             
    return prop2cfg(NULL, property) ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
}           
btif/src/btif_storage.c static int prop2cfg(bt_bdaddr_t *remote_bd_addr, bt_property_t *prop) {      switch(prop->type)     {         case BT_PROPERTY_ADAPTER_SCAN_MODE:
            btif_config_set_int("Local", "Adapter",
                                BTIF_STORAGE_KEY_ADAPTER_SCANMODE, *(int*)prop->val);  
            break;           ...      }      ...
} btif/src/btif_config.c int btif_config_set_int(const char* section, const char* key, const char* name, int value)
{  
    return btif_config_set(section, key, name, (char*)&value, sizeof(value), BTIF_CFG_TYPE_INT); //加上config类型
}   btif/src/btif_config.c int btif_config_set(const char* section, const char* key, const char* name, const char*  value, int bytes, int type)
{     ...
    set_node(section, key, name, value, (short)bytes, (short)type); //找到一个cfg_node*(配置节点)     btsock_thread_post_cmd(pth, CFG_CMD_SAVE, NULL, 0, 0); // pth是线程槽(thread slots)的序号。     ...
}
config node数据结构,root节点是所有配置的起始节点。 typedef struct cfg_node_s
{
    const char* name;
    union
    {
        struct cfg_node_s* child;
        char* value;
    };
    short bytes;
    short type;
    short used;
    short flag;
} cfg_node;

我理解的线程槽,BT中有很多业务,每一类的业余需要一个(或多个)额外的线程来处理一些事情,可以通过写线程槽的socket一端,那么读端在获取消息后,可以处理这些事情。 btif_init_bluetooth在创建btif_task之前,先会调用btif_config_init,初始config相关数据结构
btif/src/btif_config.c 1、stat(CFG_PATH, &st)  //确认配置文件,路径:/data/misc/bluedroid/ 2、btsock_thread_init();   //初始化thread_slogt ts数组 3、init_slot_lock(&slot_lock);//初始化线程锁 4、   root.name = "Bluedroid";         alloc_node(&root, CFG_GROW_SIZE);
        dump_node("root", &root);
        pth = btsock_thread_create(NULL, cfg_cmd_callback);
     创建一个跟配置节点,并创捷一个取用一个线程槽,pth为ts数组里面对应的序号。 5、load_cfg();   //导入配置文件,读取xml文件到内存,以config_node形式组织起来。
先看btsock_thread_create的线程创建过程: int btsock_thread_create(btsock_signaled_cb callback, btsock_cmd_cb cmd_callback) 1、int h = alloc_thread_slot();   //获取一个空闲槽,卧槽,这是什么节奏 2、init_poll(h);   //初始化这个槽点,创建一个socketpair,读写端分别是ts[h].cmd_fdr和ts[h].cmd_fdw,并且将cmd_fdr放入监听槽... 3、ts[h].thread_id = create_thread(sock_poll_thread, (void*)h); //给这个槽点创建线程,线程函数为sock_poll_thread 4、ts[h].callback = callback;      ts[h].cmd_callback = cmd_callback; //sock_poll_thread将会调用它来处理写config
那么先来看写端的处理,也就是btsock_thread_post_cmd是怎么做的 btif/src/btif_sock_thread.c int btsock_thread_post_cmd(int h, int type, const unsigned char* data, int size, uint32_t user_id)      sock_cmd_t cmd = {CMD_USER_PRIVATE, 0, type, size, user_id};       //将cmd包装到sock_cmd_t* cmd_send中      send(ts[h].cmd_fdw, cmd_send, size_send, 0)   //直接往cmd_fdw写
再看来cmd_fdr,也就是sock_poll_thread的处理 btif/src/btif_sock_thread.c {     for(;;)
    {
        prepare_poll_fds(h, pfds);
        int ret = poll(pfds, ts[h].poll_count, -1); //开始监听
        if(ret != 0)
        {
            int need_process_data_fd = TRUE;
            if(pfds[0].revents) //cmd fd always is the first one
            {
                asrt(pfds[0].fd == ts[h].cmd_fdr);
                if(!process_cmd_sock(h))  //先尝试处理cmd命令,即上面提到的CMD_USER_PRIVATE
                {
                    APPL_TRACE_DEBUG1("h:%d, process_cmd_sock return false, exit...", h);
                    break;
                }
                if(ret == 1)
                    need_process_data_fd = FALSE;
                else ret--; //exclude the cmd fd
            }
            if(need_process_data_fd)
                process_data_sock(h, pfds, ret); //再处理数据。
        }
        else {APPL_TRACE_DEBUG1("no data, select ret: %d", ret)};
    }
    ts[h].thread_id = -1;
}
看process_cmd_sock的实现 btif/src/btif_sock_thread.c static int process_cmd_sock(int h)
{
    sock_cmd_t cmd = {-1, 0, 0, 0, 0};
    int fd = ts[h].cmd_fdr;
    if(recv(fd, &cmd, sizeof(cmd), MSG_WAITALL) != sizeof(cmd))
    {
        APPL_TRACE_ERROR1("recv cmd errno:%d", errno);
        return FALSE;
    }
    switch(cmd.id)
    {
        case CMD_USER_PRIVATE:
            asrt(ts[h].cmd_callback);
            if(ts[h].cmd_callback)
                ts[h].cmd_callback(fd, cmd.type, cmd.flags, cmd.user_id);  //调用回调处理,即上文的cfg_cmd_callback
            break;         ...     }
    return TRUE;
}

再来看cfg_cmd_callback的实现: static void cfg_cmd_callback(int cmd_fd, int type, int size, uint32_t user_id)
{
  //BTIF_TRACE_DEBUG2("cmd type:%d, size:%d", type, size);
    switch(type)
    {
        case CFG_CMD_SAVE:
            lock_slot(&slot_lock);
            save_cfg();     //保存所有的config到配置文件中,从根config node:root开始遍历
            unlock_slot(&slot_lock);
            break;
    }
}

到目前为止蓝牙的关闭过程,才进行一般不到。 来看AbstractionLayer.BT_PROPERTY_ADAPTER_SCAN_MODE被JNI调用到AdapterProperties.java的adapterPropertyChangedCallback之后怎么处理的 AdapterProperties.java adapterPropertyChangedCallback                     case AbstractionLayer.BT_PROPERTY_ADAPTER_SCAN_MODE:
                        int mode = Utils.byteArrayToInt(val, 0);
                        mScanMode = mService.convertScanModeFromHal(mode);
                        intent = new Intent(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
                        intent.putExtra(BluetoothAdapter.EXTRA_SCAN_MODE, mScanMode);
                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
                        mService.sendBroadcast(intent, mService.BLUETOOTH_PERM); 
                        debugLog("Scan Mode:" + mScanMode);
                        if (mBluetoothDisabling) {
                            mBluetoothDisabling=false;
                            mService.startBluetoothDisable();  //调用服务的startBluetoothDisable停掉蓝牙设备
                        }
                        break;
AdapterService——com_android_bluetooth_btservice_AdapterService.cpp——bluetooth.c——btif_core.c 最终调用到btif_core.c的btif_disable_bluetooth,看btif_disable_bluetooth的实现 bt_status_t btif_disable_bluetooth(void) {      btif_dm_on_disable();//终止配对      btif_core_state = BTIF_CORE_STATE_DISABLING; //将状态设置为BTIF_CORE_STATE_DISABLING      btif_sock_cleanup();  //清理rfcomm & l2cap       btif_pan_cleanup(); 
     BTA_DisableBluetooth()//关闭蓝牙      btif_config_flush();//保存配置 } 先看btif_dm_on_disable的实现 btif/src/btif_sock.c void btif_dm_on_disable()
{
    if (pairing_cb.state == BT_BOND_STATE_BONDING)
    {
        bt_bdaddr_t bd_addr;
        bdcpy(bd_addr.address, pairing_cb.bd_addr);
        btif_dm_cancel_bond(&bd_addr);  如果正在配对,则取消配对
    }
}
btif_sock_cleanup和btif_pan_cleanup略过, 来看BTA_DisableBluetooth的实现: tBTA_STATUS BTA_DisableBluetooth(void)
{
   
    BT_HDR    *p_msg;
   
    if ((p_msg = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)  //太暴力了,直接从BTA中拿出一条消息,
    {
        p_msg->event = BTA_DM_API_DISABLE_EVT; //然后改写事件。
        bta_sys_sendmsg(p_msg);
    }
    else
    {  
        return BTA_FAILURE;
    }  
   
    return BTA_SUCCESS;
}   

这个消息按照之前介绍过的,最终会被btu_task处理。来看处理过程         if (event & TASK_MBOX_2_EVT_MASK)
        {
            while ((p_msg = (BT_HDR *) GKI_read_mbox(TASK_MBOX_2)) != NULL)
            {
                bta_sys_event(p_msg);
            }
        }
上面依然讲过,bta_sys_event的消息处理回调是bta_dm_reg 的bta_dm_sm_execute, BOOLEAN bta_dm_sm_execute(BT_HDR *p_msg)
{
    UINT16  event = p_msg->event & 0x00ff;

    APPL_TRACE_EVENT1("bta_dm_sm_execute event:0x%x", event);

    /* execute action functions */
    if(event < BTA_DM_NUM_ACTIONS)
    {
        (*bta_dm_action[event])( (tBTA_DM_MSG*) p_msg); //BTA_DM_API_DISABLE_EVT对应的处理函数是bta_dm_disable
    }

    return TRUE;
}

来看bta_dm_disable的实现 void bta_dm_disable (tBTA_DM_MSG *p_data)
{  
    /* Set l2cap idle timeout to 0 (so BTE immediately disconnects ACL link after last channel is closed) */
    L2CA_SetIdleTimeoutByBdAddr((UINT8 *)BT_BD_ANY, 0);    //设置L2CAP通道超时时间
   
    /* disable all active subsystems */
    bta_sys_disable(BTA_SYS_HW_BLUETOOTH);   //停掉BTA DM 子系统
   
    BTM_SetDiscoverability(BTM_NON_DISCOVERABLE, 0, 0); 
    BTM_SetConnectability(BTM_NON_CONNECTABLE, 0, 0); //这两者上文解析过了

    bta_dm_disable_pm();  
   
    bta_dm_cb.disabling = TRUE;
   
    bta_dm_search_cancel(NULL);  //停止搜寻设备
   
    if(BTM_GetNumAclLinks()==0)
    {
#if (defined(BTA_DISABLE_DELAY) && BTA_DISABLE_DELAY > 0)
        /* If BTA_DISABLE_DELAY is defined and greater than zero, then delay the shutdown by
         * BTA_DISABLE_DELAY milliseconds
         */
        APPL_TRACE_WARNING2("%s BTA_DISABLE_DELAY set to %d ms",
                            __FUNCTION__, BTA_DISABLE_DELAY);
        bta_sys_stop_timer(&bta_dm_cb.disable_timer);
        bta_dm_cb.disable_timer.p_cback = (TIMER_CBACK*)&bta_dm_disable_conn_down_timer_cback;
        bta_sys_start_timer(&bta_dm_cb.disable_timer, 0, BTA_DISABLE_DELAY);
#else
        bta_dm_disable_conn_down_timer_cback(NULL);
#endif
    }
    else
    {
        bta_dm_cb.disable_timer.p_cback = (TIMER_CBACK*)&bta_dm_disable_timer_cback;
        bta_sys_start_timer(&bta_dm_cb.disable_timer, 0, 5000);   //终止所有定时器的操作。
    } }

先看 bta_sys_disable(BTA_SYS_HW_BLUETOOTH)的实现,它调用子系统回调的bta_sys_cb.reg[bta_id]->disable方法,也就是上文的bta_dm_reg的其中的bta_dm_sm_disable方法 static const tBTA_SYS_REG bta_dm_reg =
{
    bta_dm_sm_execute,
    bta_dm_sm_disable
};
来看它的实现: void bta_dm_sm_disable( )
{
    bta_sys_deregister( BTA_ID_DM );
}   
void bta_sys_deregister(UINT8 id)
{
    bta_sys_cb.is_reg[id] = FALSE;//只是简单的将is_reg赋值为FALSE
}   

再来看bta_dm_search_cancel的实现 void bta_dm_search_cancel (tBTA_DM_MSG *p_data)
{

    tBTA_DM_MSG * p_msg;

    if(BTM_IsInquiryActive())  
    {
        BTM_CancelInquiry();   //取消搜寻
        bta_dm_search_cancel_notify(NULL);

        if ((p_msg = (tBTA_DM_MSG *) GKI_getbuf(sizeof(tBTA_DM_MSG))) != NULL)
        {
            p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
            p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
            bta_sys_sendmsg(p_msg);  //给btu_task发消息

        }
    }
    /* If no Service Search going on then issue cancel remote name in case it is active */
    else if (!bta_dm_search_cb.name_discover_done)
    {
        BTM_CancelRemoteDeviceName();
    }
#if ((BLE_INCLUDED == TRUE) && (defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE))
    if (bta_dm_search_cb.gatt_disc_active)
    {
        bta_dm_cancel_gatt_discovery(bta_dm_search_cb.peer_bdaddr);
    }
#endif
}

上面几步掠过,因为都是一些写过的消息线程间转发,到此为止停止蓝牙设备的工作已经接近尾声了 最后一步,是收尾工作,也就是btif_config_flush,来看它的实现: void btif_config_flush()
{
    lock_slot(&slot_lock);
    if(cached_change > 0)
        save_cfg();  //保存配置到文件
    unlock_slot(&slot_lock);
}

static int save_cfg()
{
    const char* file_name = CFG_PATH CFG_FILE_NAME CFG_FILE_EXT;
    const char* file_name_new = CFG_PATH CFG_FILE_NAME CFG_FILE_EXT_NEW;
    const char* file_name_old = CFG_PATH CFG_FILE_NAME CFG_FILE_EXT_OLD;
    int ret = FALSE;
    if(access(file_name_old,  F_OK) == 0)
        unlink(file_name_old);  //删除缓存文件
    if(access(file_name_new, F_OK) == 0)
        unlink(file_name_new);
   if(btif_config_save_file(file_name_new))  //保存最新配置到file_name_new,上文讲过了,就是根节点遍历config node数据结构,然后写入xml文件中。
    {
        cached_change = 0;
        chown(file_name_new, -1, AID_NET_BT_STACK);
        chmod(file_name_new, 0660);
        rename(file_name, file_name_old);
        rename(file_name_new, file_name);   //更新配置到file_name
        ret = TRUE;
    }
    else BTIF_TRACE_ERROR0("btif_config_save_file failed");
    return ret;
}






更多相关文章

  1. android hover监控鼠标移动事件
  2. Android按钮事件响应顺序
  3. 【Android View】Android中View对触摸事件的处理和传递dispatchT
  4. Java(Android)线程池
  5. Android热插拔事件处理详解
  6. android 线程间通信
  7. Android 多线程注意事项

随机推荐

  1. Android(安卓)各国语言缩写-各国语言简称
  2. Android(安卓)Studio开发准备
  3. Android(安卓)HelloWorld 例子
  4. Android自定义对话框(Custom Dialog)
  5. Android(安卓)O 硬鼠导致黑屏
  6. 性能优化之Java(Android)代码优化
  7. Android:Resources资源文件
  8. android WebView
  9. Android开发实战-项目学习笔记(1)
  10. 〖Android〗简单隐藏Android虚拟键盘的方