Android平台上的WiFi BT共存機制


大多數Android設備上的WiFi/BT用的都是單芯片,但卻共用天線。這就需要WiFi、BT通過一定的機制合理分配天線的使用,因此,本文簡單介紹一下Android上的WiFi、BT共存機制。

 

下圖為共存機制的原理,是一個比較簡單的機制:WiFi監聽BT的工作狀態,根據BT的工作狀態來切換自己使用射頻天線的時隙。

 

 1. WiFi Service

frameworks/base/services/java/com/android/server/wifi/WifiService.java

 

    public WifiService(Context context) {
        mContext.registerReceiver(
                new BroadcastReceiver() {
                    @Override
                    public void onReceive(Context context, Intent intent) {
                          boolean mWifiEnabled;
                          int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
                                    WifiManager.WIFI_STATE_DISABLED);

                          mWifiEnabled = (wifiState == WifiManager.WIFI_STATE_ENABLED);
                          //bt wifi coexist by rda
                          if(mWifiEnabled){
                              int mode = 0;
                              if(mBluetoothState == BluetoothAdapter.STATE_CONNECTED ||
                                  mBluetoothState == BluetoothAdapter.STATE_CONNECTING){
                                  mode |= BT_STATE_CONNECTION_ON;
                              }
                              if(mScoState ==  BluetoothHeadset.STATE_AUDIO_CONNECTED){
                                  mode |= BT_STATE_SCO_ON;
                              }
                              if(mA2dpState == BluetoothA2dp.STATE_PLAYING){
                                  mode |= BT_STATE_A2DP_PLAYING;
                              }
                              mWifiStateMachine.setBtStateCommand(mode);
                        }
                    }
                },
                new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION));

    }

    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equals(Intent.ACTION_SCREEN_ON)) {
                mWifiController.sendMessage(CMD_SCREEN_ON);
            }else if (action.equals(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)) {
                int mode = BT_STATE_CONNECTION_OFF;
                int state = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE,
                        BluetoothAdapter.STATE_DISCONNECTED);
                        mBluetoothState = state;
                        if((state == BluetoothAdapter.STATE_DISCONNECTED) ||
                    (state == BluetoothAdapter.STATE_DISCONNECTING))
                        mode = BT_STATE_CONNECTION_OFF;
                        else
                                mode = BT_STATE_CONNECTION_ON;
                mWifiStateMachine.setBtStateCommand(mode);
                mWifiStateMachine.sendBluetoothAdapterStateChange(state);
            } else if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)){
                        int mode = -1;
                        mScoState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1);
                        if(mScoState ==  BluetoothHeadset.STATE_AUDIO_CONNECTED){
                        mode = BT_STATE_SCO_ON;
                        }else if(mScoState == BluetoothHeadset.STATE_AUDIO_CONNECTING){
                        mode = BT_STATE_SCO_ONGOING;
                        }else if((mScoState == BluetoothHeadset.STATE_AUDIO_DISCONNECTED)){
                        mode = BT_STATE_SCO_OFF;
                        }
                       mWifiStateMachine.setBtStateCommand(mode);
            }

    }

 

2.WifiStateMachine

Frameworks/base/wifi/java/android/net/wifi/WifiStateMachine.java

 

public class WifiStateMachine extends StateMachine {
    public void setBtStateCommand(int mode){

                sendMessage(CMD_BT_COEXIST,mode);

    }
    class DefaultState extends State {
        @Override
        public boolean processMessage(Message message) {

            switch (message.what) {
                case CMD_BT_COEXIST:
                    mWifiNative.setBluetoothCoexistenceMode(message.arg1);
                    break;
                default:
                    loge("Error! unhandled message" + message);
                    break;
            }
            return HANDLED;
        }
    }

}

 

3.WifiNative

Frameworks/base/wifi/java/android/net/wifi/WifiNative.java

 

public class WifiNative {
    public boolean setBluetoothCoexistenceMode(int mode) {
        return doBooleanCommand("DRIVER BTCOEXMODE " + mode);
    }

}

 

4.Wpa lib

 wpa_supplicant_8_lib/driver_cmd_nl80211.c

int wpa_driver_nl80211_driver_cmd(void *priv, char *cmd, char *buf,
                                  size_t buf_len )
{
        struct i802_bss *bss = priv;
        struct wpa_driver_nl80211_data *drv = bss->drv;
        struct ifreq ifr;
        android_wifi_priv_cmd priv_cmd;
        int ret = 0;

        if (os_strcasecmp(cmd, "STOP") == 0) {
........
        } else if( os_strncasecmp(cmd, "BTCOEXMODE", 10) == 0 ) {
                int bt_state = -1;
                ret = 0;
                bt_state = atoi(cmd + 11);
                memset(&ifr, 0, sizeof(ifr));
                os_strncpy(ifr.ifr_name, bss->ifname, IFNAMSIZ);
                ifr.ifr_metric = bt_state;
                if ((ret = ioctl(drv->global->ioctl_sock, BT_COEXIST, &ifr)) < 0) {
                        wpa_printf(MSG_ERROR, "%s: error ioctl[BT_COEXIST] ret= %d\n", __func__, ret);
                        return -1;
                }
        } else {
.........
        }

        return ret;
}

 

5.WiFi Driver

 驅動收到BT_COEXIST命令會與芯片交互,每家WiFi芯片不同,做法不同。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM