您的位置:首页 > 移动开发 > Android开发

Cubietruck---25.android蓝牙分析3_search分析 2

2016-06-28 18:34 609 查看
一. start_disconvery的上层一系列的调用
1. 界面上的"search for device"
在./device/softwinner/common/packages/TvdSettings/src/com/android/settings/bluetooth/BluetoothSettings.java中
当点击“searching devices"或者打开时就会去扫描蓝牙设备

public boolean onOptionsItemSelected(MenuItem item) {

        switch (item.getItemId()) {

            case MENU_ID_SCAN:

                if (mLocalAdapter.getBluetoothState() == BluetoothAdapter.STATE_ON) {

                    startScanning();

                }

                return true;

}

在device/softwinner/common/packages/TvdSettings/src/com/android/settings/bluetooth/BluetoothSettings.java中

private void startScanning() {

        if (!mAvailableDevicesCategoryIsPresent) {

            getPreferenceScreen().addPreference(mAvailableDevicesCategory);

        }

        mLocalAdapter.startScanning(true);

    }

在./device/softwinner/common/packages/TvdSettings/src/com/android/settings/bluetooth/LocalBluetoothAdapter.java中

void startScanning(boolean force) {

        if (!mAdapter.isDiscovering()) {

            if (!force) {

                if (mLastScan + SCAN_EXPIRATION_MS > System.currentTimeMillis()) {

                    return;

                }

                A2dpProfile a2dp = mProfileManager.getA2dpProfile();

                if (a2dp != null && a2dp.isA2dpPlaying()) {

                    return;

                }

            }

            if (mAdapter.startDiscovery()) {

                mLastScan = System.currentTimeMillis();

            }

        }

    }

2. frameworks中的调用
在frameworks/base/core/java/android/bluetooth/BluetoothAdapter.java中

public boolean startDiscovery() {

        if (getState() != STATE_ON) return false;

        try {

            synchronized(mManagerCallback) {

                if (mService != null) return
mService.startDiscovery();

            }

        } catch (RemoteException e) {Log.e(TAG, "", e);} 

        return false;

    }

mService用binder调用startDiscovery
3. packages中的调用
在./packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java中

private static class AdapterServiceBinder extends IBluetooth.Stub {

public boolean startDiscovery() {

            if (!Utils.checkCaller()) {

                Log.w(TAG,"startDiscovery():
not allowed for non-active user");

                return false;

            }

            AdapterService service = getService();

            if (service == null) return false;

            return service.startDiscovery();

        }

}

3.1 server的
在./packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java中

public class AdapterService extends Service {

boolean startDiscovery() {

        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, “Need BLUETOOTH
ADMIN permission");

        return startDiscoveryNative();

    }

}

会调用jni的startDiscoveryNative
4. jni中的调用
在./packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp中

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

    ALOGV("%s:",__FUNCTION__);

    jboolean result = JNI_FALSE;

    if (!sBluetoothInterface) return
result;

    int ret = sBluetoothInterface->start_discovery();

    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;

    return result;

}

sBluetoothInterface是bluetooth.default.so的接口,即协议栈的接口

二.协议栈中的start_discovery
到了协议栈了,协议栈是在./external/bluetooth/bluedroid/中
2.1在./btif/src/bluetooth.c中

static int start_discovery(void)

{

    /* sanity check */

    if (interface_ready() == FALSE)

        return BT_STATUS_NOT_READY;

    return btif_dm_start_discovery();

}

2.2在btif/src/btif_dm.c中

bt_status_t btif_dm_start_discovery(void)

{

    tBTA_DM_INQ inq_params;

    tBTA_SERVICE_MASK services = 0;

    inq_params.mode = BTA_DM_GENERAL_INQUIRY;

    inq_params.duration = BTIF_DM_DEFAULT_INQ_MAX_DURATION;

    inq_params.max_resps = BTIF_DM_DEFAULT_INQ_MAX_RESULTS;

    inq_params.report_dup = TRUE;

    inq_params.filter_type = BTA_DM_INQ_CLR;

    btif_dm_inquiry_in_progress = FALSE;

    BTA_DmSearch(&inq_params, services, bte_search_devices_evt);

    return BT_STATUS_SUCCESS;

}

2.3在bta/dm/bta_dm_api.c中

void BTA_DmSearch(tBTA_DM_INQ *p_dm_inq, tBTA_SERVICE_MASK
services, tBTA_DM_SEARCH_CBACK *p_cback)

{

    tBTA_DM_API_SEARCH *p_msg;

    if ((p_msg = (tBTA_DM_API_SEARCH *) GKI_getbuf(sizeof(tBTA_DM_API_SEARCH))) != NULL)

    {

        memset(p_msg, 0, sizeof(tBTA_DM_API_SEARCH));

        p_msg->hdr.event = BTA_DM_API_SEARCH_EVT;

        memcpy(&p_msg->inq_params, p_dm_inq, sizeof(tBTA_DM_INQ));  //将这个inq复制到了inq_params中

        p_msg->services = services;

        p_msg->p_cback = p_cback;

        p_msg->rs_res = BTA_DM_RS_NONE;

        bta_sys_sendmsg(p_msg);

    }

}

其作用是调用bta_sys_sendmsg是向btu_task发送一个命令:p_msg->hdr.event = BTA_DM_API_SEARCH_EVT,参数是:inq_params
2.4 在stack/btu/btu_task.c中

BTU_API UINT32 btu_task (UINT32 param)

{

    event = GKI_wait (0xFFFF, 0); 
//从GKI_wait返回的event是4,这个不重要不管它了

    if (event & TASK_MBOX_2_EVT_MASK)

        while ((p_msg = (BT_HDR *) GKI_read_mbox(TASK_MBOX_2)) != NULL) //从这里面读取的才是真正发送的msg

           bta_sys_event(p_msg);   //进行msg的处理,这里的msg才是BTA_DmSearch中发送的msg

}

2.5在bta/sys/bta_sys_main.c中

BTA_API void bta_sys_event(BT_HDR *p_msg)

{

    id = (UINT8) (p_msg->event >> 8);

    if ((id < BTA_ID_MAX) && (bta_sys_cb.reg[id] != NULL))

    {

        freebuf = (*bta_sys_cb.reg[id]->evt_hdlr)(p_msg);

    }

}

又一个函数指针数组,那么这个evt_hdlr是在哪个地方初始化的呢?
2.6.evt_hdlr的初始化
在bta/dm/bta_dm_api.c中

static const tBTA_SYS_REG bta_dm_search_reg =

{

    bta_dm_search_sm_execute,

    bta_dm_search_sm_disable

};

tBTA_STATUS BTA_EnableBluetooth(tBTA_DM_SEC_CBACK *p_cback)

{

    bta_sys_register (BTA_ID_DM_SEARCH, &bta_dm_search_reg );

}

下面就进入函数bta_dm_search_sm_execute
2.7 在bta/dm/bta_dm_main.c中,此时的msg还是BTA_DmSearch中发送的msg

BOOLEAN bta_dm_search_sm_execute(BT_HDR *p_msg)

{

    tBTA_DM_ST_TBL state_table;

    UINT8 action;

    int i;

    state_table = bta_dm_search_st_tbl[bta_dm_search_cb.state];

    bta_dm_search_cb.state = state_table[p_msg->event & 0x00ff][BTA_DM_SEARCH_NEXT_STATE];

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

    {

        if ((action = state_table[p_msg->event & 0x00ff][i]) != BTA_DM_SEARCH_IGNORE)

        {

            (*bta_dm_search_action[action])( (tBTA_DM_MSG*) p_msg); //为什么要搞得这么复杂?

        }

        else

        {

            break;

        }

    }

    return TRUE;

}

这个函数指针数组看起来很复杂,但实际执行起来就是调用了bta_dm_search_action[0],
即: bta_dm_search_start
2.8 在bta/dm/bta_dm_act.c中

void bta_dm_search_start (tBTA_DM_MSG *p_data)

{

    bta_dm_search_cb.p_search_cback = p_data->search.p_cback;

    bta_dm_search_cb.services = p_data->search.services;

    result.status = BTM_StartInquiry( (tBTM_INQ_PARMS*)&p_data->search.inq_params,

                        bta_dm_inq_results_cb,

                        (tBTM_CMPL_CB*) bta_dm_inq_cmpl_cb);

    if (result.status != BTM_CMD_STARTED)

    {

        result.num_resp = 0;

        bta_dm_inq_cmpl_cb ((void *)&result);

    }

}

a.发送的msg是一个tBTA_DM_API_SEARCH结构体,
而tBTA_DM_API_SEARCH结构体又属于tBTA_DM_MSG(enum)类型的search,
所以这儿就用了p_data->search来代替msg,但这个msg所指的内容,还是BTA_DmSearch所发送的msg
b. 同时BTM_StartInquiry中的第一个参数中inq_params,也就是btif_dm_start_discovery发送的参数
2.9 在stack/btm/btm_inq.c中

tBTM_STATUS BTM_StartInquiry (tBTM_INQ_PARMS *p_inqparms, tBTM_INQ_RESULTS_CB *p_results_cb,

                              tBTM_CMPL_CB *p_cmpl_cb)

{

    tBTM_STATUS status;

    tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;

 

    if (p_inq->inq_active || p_inq->inqfilt_active)

        return (BTM_BUSY);

    if (!BTM_IsDeviceUp())

        return (BTM_WRONG_MODE);

    if ((p_inqparms->mode & BTM_BR_INQUIRY_MASK)!= BTM_GENERAL_INQUIRY &&

        (p_inqparms->mode & BTM_BR_INQUIRY_MASK)!= BTM_LIMITED_INQUIRY)

        return (BTM_ILLEGAL_VALUE);

    p_inq->inqparms = *p_inqparms;

    p_inq->inqparms.mode = (UINT8)(1 << (p_inqparms->mode & BTM_BR_INQUIRY_MASK));

    p_inq->state = BTM_INQ_ACTIVE_STATE;

    p_inq->p_inq_cmpl_cb = p_cmpl_cb;

    p_inq->p_inq_results_cb = p_results_cb;

    p_inq->inq_cmpl_info.num_resp = 0; /* Clear
the results counter */

    p_inq->inq_active = (UINT8)(1 << (p_inqparms->mode & BTM_BR_INQUIRY_MASK));

    switch (p_inqparms->filter_cond_type)

    {

    case BTM_CLR_INQUIRY_FILTER:

        p_inq->state = BTM_INQ_SET_FILT_STATE;

        break;

    case BTM_FILTER_COND_DEVICE_CLASS:

    case BTM_FILTER_COND_BD_ADDR:

        p_inq->state = BTM_INQ_CLR_FILT_STATE;

        p_inqparms->filter_cond_type = BTM_CLR_INQUIRY_FILTER;

        break;

    default:

        return (BTM_ILLEGAL_VALUE);

    }

    if ((status = btm_set_inq_event_filter (p_inqparms->filter_cond_type, &p_inqparms->filter_cond)) != BTM_CMD_STARTED)

        p_inq->state = BTM_INQ_INACTIVE_STATE;

    return (status);

}

3.0 与/dev/ttyS0进行通信
btm_set_inq_event_filter
    -->btsnd_hcic_set_event_filter
        -->btu_hcif_send_cmd
            --> HCI_CMD_TO_LOWER  
            --> bte_main_hci_send    // 发送了一个msg
     --> bt_hc_worker_thread    //接收者
        --> hci_h4_send_msg     //向/dev/ttyS2写入

void hci_h4_send_msg(HC_BT_HDR *p_msg)



    bytes_to_send = p_msg->len + 1;

    //下面就是向/dev/ttyS2写入msg 

    bytes_sent = userial_write(event,(uint8_t *) p, bytes_to_send);

    return;

}

当/dev/ttyS2有数据返回时,其监听线程会从select_read中返回
在hci/src/userial.c中

static void *userial_read_thread(void *arg)

{

    while (userial_running)

    {

       rx_length = select_read(userial_cb.fd, p, READ_LIMIT);

        if (rx_length > 0)

        {

            p_buf->len = (uint16_t)rx_length;

            utils_enqueue(&(userial_cb.rx_q), p_buf);

            bthc_signal_event(HC_EVENT_RX);

        }        

    }   

    return NULL; // Compiler
friendly

}

 select_read不仅监听,当有数据时还会读取数据,当数据读取后会返回,
并用信号HC_EVENT_RX唤醒线程bt_hc_worker_thread
在hci/src/bt_hci_bdroid.c中

static void *bt_hc_worker_thread(void *arg)



    if (events & HC_EVENT_RX)

       p_hci_if->rcv();

}

又会调用hci/src/hci_h4.c中的hci_h4_receive_msg
当hci_h4_receive_msg中接收完所有的msg之后

uint16_t hci_h4_receive_msg(void)

{

    if (msg_received)

    {

        if ((bt_hc_cbacks) && (intercepted == FALSE))

         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中的data_ind
而main/bte_main.c中的data_ind就是发送了一个GKI_send_msg给BTU_TASK
在stack/./btu/btu_task.c中btu_task
btu_task收到了这个BT_EVT_TO_BTU_HCI_EVT,然后会调用
stack/./btu/btu_hcif.c:btu_hcif_process_event
    --> btu_hcif_command_status_evt   //当收到状态改变消息时会调用这个
    --> btu_hcif_inquiry_rssi_result_evt  //当查找到设备时会调用这个(buf中是以字符串形式存着:mac地址,类型等信息)
        --> btm_process_inq_results      //解析字符串,分析出bd_addr, dev_class等信息
            --> bta_dm_inq_results_cb     //bta/dm/bta_dm_act.c
                --> BTM_InqDbRead          //stack/btm/btm_inq.c 在记录的database中查看这个mac的记录是否存在
                --> 回调函数bte_search_devices_evt //这个就是在刚开始btif_dm_start_discovery时传来的回调函数           
在main/../btif/src/btif_dm.c中

static void bte_search_devices_evt(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data)

{

    btif_transfer_context (btif_dm_search_devices_evt , (UINT16) event, (void *)p_data, param_len,

        (param_len > sizeof(tBTA_DM_SEARCH)) ? search_devices_copy_cb : NULL);

}

在./btif/src/btif_dm.c中是回调函数

static void btif_dm_search_devices_evt (UINT16 event, char *p_param)

{

    btif_storage_add_remote_device(&bdaddr, num_properties, properties);

    HAL_CBACK(bt_hal_cbacks, device_found_cb, num_properties, properties);

}

把数据保存在cfg中,但这时候还不会写入/data/misc/bluedroid/bt_config.xml中,当与设备进行connect之后才会写入
最后调用HAL_CBACK,即调用./packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp中的函数,
./packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp又会调用java层的方法。
然后在CachedBluetoothDevice中添加了一个设备

附一: 与上层的交互
btif_dm_cb_create_bond时,会有状态变化:由原先的BT_BOND_STATE_NONE变为BT_BOND_STATE_BONDING
此时会调用bond_state_changed,上层就会收到bond_state_changed的消息,下面详细分析一下:
1.1 在btif/src/btif_dm.c中
    bond_state_changed(BT_STATUS_SUCCESS, bd_addr, BT_BOND_STATE_BONDING);

static void bond_state_changed(bt_status_t status, bt_bdaddr_t *bd_addr, bt_bond_state_t
state)

{

    HAL_CBACK(bt_hal_cbacks, bond_state_changed_cb, status, bd_addr, state);

}

1.2 其中HAL_CBACK是一个宏

#define HAL_CBACK(P_CB, P_CBACK, ...)\

    if (P_CB && P_CB->P_CBACK) { \

        P_CB->P_CBACK(__VA_ARGS__); \

    } \

    else { \

        ASSERTC(0, "Callback is NULL", 0); \

    }

这儿展开后: bt_hal_cbacks->bond_state_changed_cb(status,
bd_addr, state);
其中status=BT_STATUS_SUCCESS,说明通知上层状态改变成功
bd_addr: 要pair的设备mac地址
state: 改变后的状态BT_BOND_STATE_BONDING
1.3 bt_hal_cbacks是如何初始化的呢?
来到bt_hal_cbacks的初始化函数中
在btif/src/bluetooth.c中

static int init(bt_callbacks_t* callbacks )

{

    /* store reference to user callbacks */

    bt_hal_cbacks = callbacks;

}

1.4这个callbacks是如何来的呢?答案是在apk的jni层调用的
在./packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp中

static bool initNative(JNIEnv* env, jobject
obj) {

    sJniCallbacksObj = env->NewGlobalRef(env->GetObjectField(obj, sJniCallbacksField));

    if (sBluetoothInterface) {

        sBluetoothInterface->init(&sBluetoothCallbacks);  

    return JNI_FALSE;

}

上面这个init就是调用bluetooth.default.so中的init,其中sBluetoothCallbacks的定义

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,

};

1.5 
在./packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp中

static void bond_state_changed_callback(bt_status_t status, bt_bdaddr_t *bd_addr,

                                        bt_bond_state_t state) {

    jbyteArray addr;

    addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t));

    

    callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *)bd_addr);

    //这儿是c调用java的方法

    callbackEnv->CallVoidMethod(sJniCallbacksObj, method_bondStateChangeCallback, (jint) status, addr, (jint)state);

    checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);

    callbackEnv->DeleteLocalRef(addr);

}

其中在classInitNative中被初始化:
method_bondStateChangeCallback = env->GetMethodID(jniCallbackClass, "bondStateChangeCallback", "(I[BI)V");
原来这儿是调用了java的bondStateChangeCallback这个方法。

1.6 java
在./packages/apps/Bluetooth/src/com/android/bluetooth/btservice/JniCallbacks.java中

void bondStateChangeCallback(int status, byte[] address, int newState) {

        mBondStateMachine.bondStateChangeCallback(status, address, newState);

    }

1.7 
在 ./packages/apps/Bluetooth/src/com/android/bluetooth/btservice/BondStateMachine.java中

void bondStateChangeCallback(int status, byte[] address, int newState) {

        BluetoothDevice device = mRemoteDevices.getDevice(address);

        infoLog("bondStateChangeCallback: Status: " + status + "
Address: " + device + " newState: " + newState);

        Message msg = obtainMessage(BONDING_STATE_CHANGE);

        msg.obj = device;

        if (newState == BOND_STATE_BONDED)

            msg.arg1 = BluetoothDevice.BOND_BONDED;

        else if (newState == BOND_STATE_BONDING)

            msg.arg1 = BluetoothDevice.BOND_BONDING;

        else

            msg.arg1 = BluetoothDevice.BOND_NONE;

        msg.arg2 = status;

        sendMessage(msg);

    }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: