美文网首页蓝牙和WIFI
蓝牙笔记 | hfp profile

蓝牙笔记 | hfp profile

作者: 力卉编程 | 来源:发表于2019-12-31 16:47 被阅读0次

    一、首先确认配置文件是否开启hfp profile功能。根据设备的角色(hfp client / hfp server)来配置hfp profile.
    profile 配置文件路径:

    // packages/apps/Bluetooth/res/values/config.xml  
    // e.g.  设备的角色定义为hfp client,需做如下配置:
        <bool name="profile_supported_hs_hfp">false</bool>
        <bool name="profile_supported_hfpclient">true</bool
    

    二、步获取hfp client service

    BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();
    mAdapter.getProfileProxy(getApplicationContext(),new MServerListener(), BluetoothProfile.HEADSET_CLIENT);
    public class MServerListener implements ServiceListener {
    @Override
    public void onServiceConnected(int profile, BluetoothProfile proxy) {
    if (profile == BluetoothProfile.HEADSET_CLIENT) {
      mclient=(BluetoothHeadsetClient)proxy;
      .......   
    }
    }
    

    三、app获取hfp client service 的proxy之后,就可以直接调用相应的API进行连接控制与call 控制。e.g.

    mclient.connect( device) //Connects to remote device.
    mclient.connectAudio() //Initiates a connection of audio channel, set up SCO channel
    mclient.acceptCall(device,0);
    mclient.rejectCall(device);
    mclient.terminateCall(device,0);
    

    四、android hfp 对外API:

    //frameworks/base/core/java/android/bluetooth/
    BluetoothHeadsetClientCall.aidl
    BluetoothHeadsetClientCall.java
    BluetoothHeadsetClient.java
    BluetoothHeadset.java
    IBluetoothHeadset.aidl
    IBluetoothHeadsetClient.aidl
    IBluetoothHeadsetPhone.aidl
    

    BluetoothHeadsetClient.acceptCall()

    五、android hfp client services

    //packages\apps\bluetooth\src\com\android\bluetooth\hfpclient
    //HeadsetClientHalConstants.java
    //HeadsetClientService.java
    //HeadsetClientStateMachine.java
    //e.g.  send msg to state machine  and handle these msg
      boolean acceptCall(BluetoothDevice device, int flag) {
            enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
            int connectionState = mStateMachine.getConnectionState(device);
            if (connectionState != BluetoothProfile.STATE_CONNECTED &&
                    connectionState != BluetoothProfile.STATE_CONNECTING) {
                return false;
            }
            Message msg = mStateMachine.obtainMessage(HeadsetClientStateMachine.ACCEPT_CALL);
            msg.arg1 = flag;
            mStateMachine.sendMessage(msg);
            return true;
        }
    private void acceptCall(int flag, boolean retry) {
            if (handleCallActionNative(action, 0)) {
                addQueuedAction(ACCEPT_CALL, action);
            } else {
                Log.e(TAG, "ERROR: Couldn't accept a call, action:" + action);
            }
    }
    

    六、enter native layter

    //packages/apps/Bluetooth/jni
    //com_android_bluetooth_hfpclient.cpp
    //com_android_bluetooth_hfp.cpp
    //e.g.
    static jboolean handleCallActionNative(JNIEnv *env, jobject object, jint action, jint index) {
        bt_status_t status;
        if (!sBluetoothHfpClientInterface) return JNI_FALSE;
        if ( (status = sBluetoothHfpClientInterface->handle_call_action((bthf_client_call_action_t)action, (int)index)) != BT_STATUS_SUCCESS) {
            ALOGE("Failed to enter private mode, status: %d", status);
        }
        return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
    }
    
    //get bt stack profile interface
    static void initializeNative(JNIEnv *env, jobject object) {
    ......
        if ( (btInf = getBluetoothInterface()) == NULL) {
            ALOGE("Bluetooth module is not loaded");
            return;
        }
        sBluetoothHfpClientInterface = (bthf_client_interface_t *)
                btInf->get_profile_interface(BT_PROFILE_HANDSFREE_CLIENT_ID);
        if (sBluetoothHfpClientInterface  == NULL) {
            ALOGE("Failed to get Bluetooth HFP Client Interface");
            return;
        }
    }
    

    七、enter bt stack

    //external/bluetooth/bluedroid/bta/hf_client
    //bta_hf_client_act.c
    //bta_hf_client_api.c
    //bta_hf_client_at.c
    //bta_hf_client_at.h
    //bta_hf_client_cmd.c
    //bta_hf_client_int.h
    //bta_hf_client_main.c
    //bta_hf_client_rfc.c
    //bta_hf_client_sco.c
    //bta_hf_client_sdp.c
    
    //e.g. send AT cmd ATA to accept this call
    
    handle_call_action(bthf_client_call_action_t action, int idx){
    ......
        case BTHF_CLIENT_CALL_ACTION_ATA:
            BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_ATA, 0, 0, NULL);
            break;
    }
    

    完~~~

    文 | 力卉编程

    相关文章

      网友评论

        本文标题:蓝牙笔记 | hfp profile

        本文链接:https://www.haomeiwen.com/subject/jmxioctx.html