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芯片不同,做法不同。

posted @ 2016-04-21 13:41  蝴蝶泉  阅读(3609)  评论(0编辑  收藏  举报