16654f5c903de510a70f9e72cd5ad7837b615d93ffredc/*
2ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Copyright (C) 2012 The Android Open Source Project
3ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu *
4ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Licensed under the Apache License, Version 2.0 (the "License");
5ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * you may not use this file except in compliance with the License.
6ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * You may obtain a copy of the License at
7ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu *
8ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu *      http://www.apache.org/licenses/LICENSE-2.0
9ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu *
10ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Unless required by applicable law or agreed to in writing, software
11ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * distributed under the License is distributed on an "AS IS" BASIS,
12ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * See the License for the specific language governing permissions and
14ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * limitations under the License.
156654f5c903de510a70f9e72cd5ad7837b615d93ffredc */
166654f5c903de510a70f9e72cd5ad7837b615d93ffredc
176654f5c903de510a70f9e72cd5ad7837b615d93ffredcpackage com.android.bluetooth.pan;
186654f5c903de510a70f9e72cd5ad7837b615d93ffredc
196654f5c903de510a70f9e72cd5ad7837b615d93ffredcimport android.app.Service;
206654f5c903de510a70f9e72cd5ad7837b615d93ffredcimport android.bluetooth.BluetoothDevice;
216654f5c903de510a70f9e72cd5ad7837b615d93ffredcimport android.bluetooth.BluetoothPan;
226654f5c903de510a70f9e72cd5ad7837b615d93ffredcimport android.bluetooth.BluetoothProfile;
236654f5c903de510a70f9e72cd5ad7837b615d93ffredcimport android.bluetooth.BluetoothTetheringDataTracker;
246654f5c903de510a70f9e72cd5ad7837b615d93ffredcimport android.bluetooth.IBluetooth;
256654f5c903de510a70f9e72cd5ad7837b615d93ffredcimport android.bluetooth.IBluetoothPan;
266654f5c903de510a70f9e72cd5ad7837b615d93ffredcimport android.content.Context;
276654f5c903de510a70f9e72cd5ad7837b615d93ffredcimport android.content.Intent;
286654f5c903de510a70f9e72cd5ad7837b615d93ffredcimport android.content.pm.PackageManager;
296654f5c903de510a70f9e72cd5ad7837b615d93ffredcimport android.content.res.Resources.NotFoundException;
306654f5c903de510a70f9e72cd5ad7837b615d93ffredcimport android.net.ConnectivityManager;
316654f5c903de510a70f9e72cd5ad7837b615d93ffredcimport android.net.InterfaceConfiguration;
326654f5c903de510a70f9e72cd5ad7837b615d93ffredcimport android.net.LinkAddress;
336654f5c903de510a70f9e72cd5ad7837b615d93ffredcimport android.net.NetworkUtils;
3437510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xuimport android.os.Handler;
356654f5c903de510a70f9e72cd5ad7837b615d93ffredcimport android.os.IBinder;
366654f5c903de510a70f9e72cd5ad7837b615d93ffredcimport android.os.INetworkManagementService;
376654f5c903de510a70f9e72cd5ad7837b615d93ffredcimport android.os.Message;
386654f5c903de510a70f9e72cd5ad7837b615d93ffredcimport android.os.RemoteException;
396654f5c903de510a70f9e72cd5ad7837b615d93ffredcimport android.os.ServiceManager;
406654f5c903de510a70f9e72cd5ad7837b615d93ffredcimport android.provider.Settings;
416654f5c903de510a70f9e72cd5ad7837b615d93ffredcimport android.util.Log;
4237510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xuimport com.android.bluetooth.btservice.ProfileService;
4337510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xuimport com.android.bluetooth.Utils;
446654f5c903de510a70f9e72cd5ad7837b615d93ffredcimport java.net.InetAddress;
456654f5c903de510a70f9e72cd5ad7837b615d93ffredcimport java.util.ArrayList;
466654f5c903de510a70f9e72cd5ad7837b615d93ffredcimport java.util.Collections;
476654f5c903de510a70f9e72cd5ad7837b615d93ffredcimport java.util.HashMap;
486654f5c903de510a70f9e72cd5ad7837b615d93ffredcimport java.util.List;
496654f5c903de510a70f9e72cd5ad7837b615d93ffredcimport java.util.Map;
5037510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
516654f5c903de510a70f9e72cd5ad7837b615d93ffredc
526654f5c903de510a70f9e72cd5ad7837b615d93ffredc/**
536654f5c903de510a70f9e72cd5ad7837b615d93ffredc * Provides Bluetooth Pan Device profile, as a service in
546654f5c903de510a70f9e72cd5ad7837b615d93ffredc * the Bluetooth application.
556654f5c903de510a70f9e72cd5ad7837b615d93ffredc * @hide
566654f5c903de510a70f9e72cd5ad7837b615d93ffredc */
57b5cc776c9353a203cdde97e62b25f05d9633d14cfredcpublic class PanService extends ProfileService {
58b5cc776c9353a203cdde97e62b25f05d9633d14cfredc    private static final String TAG = "PanService";
59fd1da115cbf09b7dd9bca3c7d3a4fb816a835dc5Matthew Xie    private static final boolean DBG = false;
606654f5c903de510a70f9e72cd5ad7837b615d93ffredc
616654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private static final String BLUETOOTH_IFACE_ADDR_START= "192.168.44.1";
626654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private static final int BLUETOOTH_MAX_PAN_CONNECTIONS = 5;
636654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private static final int BLUETOOTH_PREFIX_LENGTH        = 24;
646654f5c903de510a70f9e72cd5ad7837b615d93ffredc
656654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private HashMap<BluetoothDevice, BluetoothPanDevice> mPanDevices;
666654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private ArrayList<String> mBluetoothIfaceAddresses;
676654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private int mMaxPanDevices;
686654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private String mPanIfName;
6974ae04c73312403e89db0f8e9bd9601d403b4783fredc    private boolean mNativeAvailable;
706654f5c903de510a70f9e72cd5ad7837b615d93ffredc
716654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private static final int MESSAGE_CONNECT = 1;
726654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private static final int MESSAGE_DISCONNECT = 2;
736654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private static final int MESSAGE_CONNECT_STATE_CHANGED = 11;
74ac7e62c64b4cd8d864f125d3225474a04b867606zzy    private boolean mTetherOn = false;
756654f5c903de510a70f9e72cd5ad7837b615d93ffredc
766654f5c903de510a70f9e72cd5ad7837b615d93ffredc
776654f5c903de510a70f9e72cd5ad7837b615d93ffredc    static {
786654f5c903de510a70f9e72cd5ad7837b615d93ffredc        classInitNative();
796654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
806654f5c903de510a70f9e72cd5ad7837b615d93ffredc
81b5cc776c9353a203cdde97e62b25f05d9633d14cfredc    protected String getName() {
82b5cc776c9353a203cdde97e62b25f05d9633d14cfredc        return TAG;
836654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
846654f5c903de510a70f9e72cd5ad7837b615d93ffredc
8574ae04c73312403e89db0f8e9bd9601d403b4783fredc    public IProfileServiceBinder initBinder() {
8674ae04c73312403e89db0f8e9bd9601d403b4783fredc        return new BluetoothPanBinder(this);
876654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
886654f5c903de510a70f9e72cd5ad7837b615d93ffredc
89b5cc776c9353a203cdde97e62b25f05d9633d14cfredc    protected boolean start() {
906654f5c903de510a70f9e72cd5ad7837b615d93ffredc        mPanDevices = new HashMap<BluetoothDevice, BluetoothPanDevice>();
916654f5c903de510a70f9e72cd5ad7837b615d93ffredc        mBluetoothIfaceAddresses = new ArrayList<String>();
926654f5c903de510a70f9e72cd5ad7837b615d93ffredc        try {
936654f5c903de510a70f9e72cd5ad7837b615d93ffredc            mMaxPanDevices = getResources().getInteger(
946654f5c903de510a70f9e72cd5ad7837b615d93ffredc                                 com.android.internal.R.integer.config_max_pan_devices);
956654f5c903de510a70f9e72cd5ad7837b615d93ffredc        } catch (NotFoundException e) {
966654f5c903de510a70f9e72cd5ad7837b615d93ffredc            mMaxPanDevices = BLUETOOTH_MAX_PAN_CONNECTIONS;
976654f5c903de510a70f9e72cd5ad7837b615d93ffredc        }
986654f5c903de510a70f9e72cd5ad7837b615d93ffredc        initializeNative();
9974ae04c73312403e89db0f8e9bd9601d403b4783fredc        mNativeAvailable=true;
100b5cc776c9353a203cdde97e62b25f05d9633d14cfredc        return true;
1016654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
1026654f5c903de510a70f9e72cd5ad7837b615d93ffredc
103b5cc776c9353a203cdde97e62b25f05d9633d14cfredc    protected boolean stop() {
10474ae04c73312403e89db0f8e9bd9601d403b4783fredc        mHandler.removeCallbacksAndMessages(null);
10574ae04c73312403e89db0f8e9bd9601d403b4783fredc        return true;
10674ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
1076654f5c903de510a70f9e72cd5ad7837b615d93ffredc
10874ae04c73312403e89db0f8e9bd9601d403b4783fredc    protected boolean cleanup() {
10974ae04c73312403e89db0f8e9bd9601d403b4783fredc        if (mNativeAvailable) {
11074ae04c73312403e89db0f8e9bd9601d403b4783fredc            cleanupNative();
11174ae04c73312403e89db0f8e9bd9601d403b4783fredc            mNativeAvailable=false;
11274ae04c73312403e89db0f8e9bd9601d403b4783fredc        }
113b5cc776c9353a203cdde97e62b25f05d9633d14cfredc        if(mPanDevices != null) {
1148120c75b7a8b5a9c0e00df500c1ed072a952bda1zzy            List<BluetoothDevice> DevList = getConnectedDevices();
1158120c75b7a8b5a9c0e00df500c1ed072a952bda1zzy            for(BluetoothDevice dev : DevList) {
1168120c75b7a8b5a9c0e00df500c1ed072a952bda1zzy               handlePanDeviceStateChange(dev, mPanIfName, BluetoothProfile.STATE_DISCONNECTED,
1178120c75b7a8b5a9c0e00df500c1ed072a952bda1zzy                                                   BluetoothPan.LOCAL_PANU_ROLE, BluetoothPan.REMOTE_NAP_ROLE);
1188120c75b7a8b5a9c0e00df500c1ed072a952bda1zzy            }
119b5cc776c9353a203cdde97e62b25f05d9633d14cfredc            mPanDevices.clear();
120b5cc776c9353a203cdde97e62b25f05d9633d14cfredc        }
121b5cc776c9353a203cdde97e62b25f05d9633d14cfredc        if(mBluetoothIfaceAddresses != null) {
122b5cc776c9353a203cdde97e62b25f05d9633d14cfredc            mBluetoothIfaceAddresses.clear();
1236654f5c903de510a70f9e72cd5ad7837b615d93ffredc        }
124b5cc776c9353a203cdde97e62b25f05d9633d14cfredc        return true;
1256654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
1266654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1276654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private final Handler mHandler = new Handler() {
1286654f5c903de510a70f9e72cd5ad7837b615d93ffredc        @Override
1296654f5c903de510a70f9e72cd5ad7837b615d93ffredc        public void handleMessage(Message msg) {
1306654f5c903de510a70f9e72cd5ad7837b615d93ffredc            switch (msg.what) {
1316654f5c903de510a70f9e72cd5ad7837b615d93ffredc                case MESSAGE_CONNECT:
1326654f5c903de510a70f9e72cd5ad7837b615d93ffredc                {
1336654f5c903de510a70f9e72cd5ad7837b615d93ffredc                    BluetoothDevice device = (BluetoothDevice) msg.obj;
13474ae04c73312403e89db0f8e9bd9601d403b4783fredc                    if (!connectPanNative(Utils.getByteAddress(device), BluetoothPan.LOCAL_PANU_ROLE, BluetoothPan.REMOTE_NAP_ROLE)) {
1356654f5c903de510a70f9e72cd5ad7837b615d93ffredc                        handlePanDeviceStateChange(device, null, BluetoothProfile.STATE_CONNECTING,
1366654f5c903de510a70f9e72cd5ad7837b615d93ffredc                                                   BluetoothPan.LOCAL_PANU_ROLE, BluetoothPan.REMOTE_NAP_ROLE);
1376654f5c903de510a70f9e72cd5ad7837b615d93ffredc                        handlePanDeviceStateChange(device, null, BluetoothProfile.STATE_DISCONNECTED,
1386654f5c903de510a70f9e72cd5ad7837b615d93ffredc                                                   BluetoothPan.LOCAL_PANU_ROLE, BluetoothPan.REMOTE_NAP_ROLE);
1396654f5c903de510a70f9e72cd5ad7837b615d93ffredc                        break;
1406654f5c903de510a70f9e72cd5ad7837b615d93ffredc                    }
1416654f5c903de510a70f9e72cd5ad7837b615d93ffredc                }
1426654f5c903de510a70f9e72cd5ad7837b615d93ffredc                    break;
1436654f5c903de510a70f9e72cd5ad7837b615d93ffredc                case MESSAGE_DISCONNECT:
1446654f5c903de510a70f9e72cd5ad7837b615d93ffredc                {
1456654f5c903de510a70f9e72cd5ad7837b615d93ffredc                    BluetoothDevice device = (BluetoothDevice) msg.obj;
14674ae04c73312403e89db0f8e9bd9601d403b4783fredc                    if (!disconnectPanNative(Utils.getByteAddress(device)) ) {
1476654f5c903de510a70f9e72cd5ad7837b615d93ffredc                        handlePanDeviceStateChange(device, mPanIfName, BluetoothProfile.STATE_DISCONNECTING,
1486654f5c903de510a70f9e72cd5ad7837b615d93ffredc                                                   BluetoothPan.LOCAL_PANU_ROLE, BluetoothPan.REMOTE_NAP_ROLE);
1496654f5c903de510a70f9e72cd5ad7837b615d93ffredc                        handlePanDeviceStateChange(device, mPanIfName, BluetoothProfile.STATE_DISCONNECTED,
1506654f5c903de510a70f9e72cd5ad7837b615d93ffredc                                                   BluetoothPan.LOCAL_PANU_ROLE, BluetoothPan.REMOTE_NAP_ROLE);
1516654f5c903de510a70f9e72cd5ad7837b615d93ffredc                        break;
1526654f5c903de510a70f9e72cd5ad7837b615d93ffredc                    }
1536654f5c903de510a70f9e72cd5ad7837b615d93ffredc                }
1546654f5c903de510a70f9e72cd5ad7837b615d93ffredc                    break;
1556654f5c903de510a70f9e72cd5ad7837b615d93ffredc                case MESSAGE_CONNECT_STATE_CHANGED:
1566654f5c903de510a70f9e72cd5ad7837b615d93ffredc                {
1576654f5c903de510a70f9e72cd5ad7837b615d93ffredc                    ConnectState cs = (ConnectState)msg.obj;
1586654f5c903de510a70f9e72cd5ad7837b615d93ffredc                    BluetoothDevice device = getDevice(cs.addr);
1596654f5c903de510a70f9e72cd5ad7837b615d93ffredc                    // TBD get iface from the msg
1606654f5c903de510a70f9e72cd5ad7837b615d93ffredc                    if (DBG) log("MESSAGE_CONNECT_STATE_CHANGED: " + device + " state: " + cs.state);
1616654f5c903de510a70f9e72cd5ad7837b615d93ffredc                    handlePanDeviceStateChange(device, mPanIfName /* iface */, convertHalState(cs.state),
1626654f5c903de510a70f9e72cd5ad7837b615d93ffredc                                               cs.local_role,  cs.remote_role);
1636654f5c903de510a70f9e72cd5ad7837b615d93ffredc                }
1646654f5c903de510a70f9e72cd5ad7837b615d93ffredc                break;
1656654f5c903de510a70f9e72cd5ad7837b615d93ffredc            }
1666654f5c903de510a70f9e72cd5ad7837b615d93ffredc        }
1676654f5c903de510a70f9e72cd5ad7837b615d93ffredc    };
1686654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1696654f5c903de510a70f9e72cd5ad7837b615d93ffredc    /**
1706654f5c903de510a70f9e72cd5ad7837b615d93ffredc     * Handlers for incoming service calls
1716654f5c903de510a70f9e72cd5ad7837b615d93ffredc     */
17274ae04c73312403e89db0f8e9bd9601d403b4783fredc    private static class BluetoothPanBinder extends IBluetoothPan.Stub implements IProfileServiceBinder {
17374ae04c73312403e89db0f8e9bd9601d403b4783fredc        private PanService mService;
17474ae04c73312403e89db0f8e9bd9601d403b4783fredc        public BluetoothPanBinder(PanService svc) {
17574ae04c73312403e89db0f8e9bd9601d403b4783fredc            mService = svc;
17674ae04c73312403e89db0f8e9bd9601d403b4783fredc        }
17774ae04c73312403e89db0f8e9bd9601d403b4783fredc        public boolean cleanup() {
17874ae04c73312403e89db0f8e9bd9601d403b4783fredc            mService = null;
1796654f5c903de510a70f9e72cd5ad7837b615d93ffredc            return true;
1806654f5c903de510a70f9e72cd5ad7837b615d93ffredc        }
18174ae04c73312403e89db0f8e9bd9601d403b4783fredc        private PanService getService() {
18237510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            if (!Utils.checkCaller()) {
18337510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                Log.w(TAG,"Pan call not allowed for non-active user");
18437510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu                return null;
18537510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu            }
18637510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu
18774ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (mService  != null && mService.isAvailable()) {
18874ae04c73312403e89db0f8e9bd9601d403b4783fredc                return mService;
18974ae04c73312403e89db0f8e9bd9601d403b4783fredc            }
19074ae04c73312403e89db0f8e9bd9601d403b4783fredc            return null;
19174ae04c73312403e89db0f8e9bd9601d403b4783fredc        }
19274ae04c73312403e89db0f8e9bd9601d403b4783fredc        public boolean connect(BluetoothDevice device) {
19374ae04c73312403e89db0f8e9bd9601d403b4783fredc            PanService service = getService();
19474ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return false;
19574ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.connect(device);
19674ae04c73312403e89db0f8e9bd9601d403b4783fredc        }
1976654f5c903de510a70f9e72cd5ad7837b615d93ffredc        public boolean disconnect(BluetoothDevice device) {
19874ae04c73312403e89db0f8e9bd9601d403b4783fredc            PanService service = getService();
19974ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return false;
20074ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.disconnect(device);
2016654f5c903de510a70f9e72cd5ad7837b615d93ffredc        }
2026654f5c903de510a70f9e72cd5ad7837b615d93ffredc        public int getConnectionState(BluetoothDevice device) {
20374ae04c73312403e89db0f8e9bd9601d403b4783fredc            PanService service = getService();
20474ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return BluetoothPan.STATE_DISCONNECTED;
20574ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.getConnectionState(device);
2066654f5c903de510a70f9e72cd5ad7837b615d93ffredc        }
2076654f5c903de510a70f9e72cd5ad7837b615d93ffredc        private boolean isPanNapOn() {
20874ae04c73312403e89db0f8e9bd9601d403b4783fredc            PanService service = getService();
20974ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return false;
21074ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.isPanNapOn();
2116654f5c903de510a70f9e72cd5ad7837b615d93ffredc        }
2126654f5c903de510a70f9e72cd5ad7837b615d93ffredc        private boolean isPanUOn() {
2136654f5c903de510a70f9e72cd5ad7837b615d93ffredc            if(DBG) Log.d(TAG, "isTetheringOn call getPanLocalRoleNative");
21474ae04c73312403e89db0f8e9bd9601d403b4783fredc            PanService service = getService();
21574ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.isPanUOn();
2166654f5c903de510a70f9e72cd5ad7837b615d93ffredc        }
2176654f5c903de510a70f9e72cd5ad7837b615d93ffredc        public boolean isTetheringOn() {
2186654f5c903de510a70f9e72cd5ad7837b615d93ffredc            // TODO(BT) have a variable marking the on/off state
21974ae04c73312403e89db0f8e9bd9601d403b4783fredc            PanService service = getService();
22074ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return false;
22174ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.isTetheringOn();
2226654f5c903de510a70f9e72cd5ad7837b615d93ffredc        }
2236654f5c903de510a70f9e72cd5ad7837b615d93ffredc        public void setBluetoothTethering(boolean value) {
22474ae04c73312403e89db0f8e9bd9601d403b4783fredc            PanService service = getService();
22574ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return;
226fd1da115cbf09b7dd9bca3c7d3a4fb816a835dc5Matthew Xie            Log.d(TAG, "setBluetoothTethering: " + value +", mTetherOn: " + service.mTetherOn);
22774ae04c73312403e89db0f8e9bd9601d403b4783fredc            service.setBluetoothTethering(value);
2286654f5c903de510a70f9e72cd5ad7837b615d93ffredc        }
2296654f5c903de510a70f9e72cd5ad7837b615d93ffredc
2306654f5c903de510a70f9e72cd5ad7837b615d93ffredc        public List<BluetoothDevice> getConnectedDevices() {
23174ae04c73312403e89db0f8e9bd9601d403b4783fredc            PanService service = getService();
23274ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return new ArrayList<BluetoothDevice>(0);
23374ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.getConnectedDevices();
2346654f5c903de510a70f9e72cd5ad7837b615d93ffredc        }
2356654f5c903de510a70f9e72cd5ad7837b615d93ffredc
2366654f5c903de510a70f9e72cd5ad7837b615d93ffredc        public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
23774ae04c73312403e89db0f8e9bd9601d403b4783fredc            PanService service = getService();
23874ae04c73312403e89db0f8e9bd9601d403b4783fredc            if (service == null) return new ArrayList<BluetoothDevice>(0);
23974ae04c73312403e89db0f8e9bd9601d403b4783fredc            return service.getDevicesMatchingConnectionStates(states);
24074ae04c73312403e89db0f8e9bd9601d403b4783fredc        }
24174ae04c73312403e89db0f8e9bd9601d403b4783fredc    };
24274ae04c73312403e89db0f8e9bd9601d403b4783fredc
24374ae04c73312403e89db0f8e9bd9601d403b4783fredc    boolean connect(BluetoothDevice device) {
24474ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
24574ae04c73312403e89db0f8e9bd9601d403b4783fredc        if (getConnectionState(device) != BluetoothProfile.STATE_DISCONNECTED) {
24674ae04c73312403e89db0f8e9bd9601d403b4783fredc            Log.e(TAG, "Pan Device not disconnected: " + device);
24774ae04c73312403e89db0f8e9bd9601d403b4783fredc            return false;
24874ae04c73312403e89db0f8e9bd9601d403b4783fredc        }
24974ae04c73312403e89db0f8e9bd9601d403b4783fredc        Message msg = mHandler.obtainMessage(MESSAGE_CONNECT,device);
25074ae04c73312403e89db0f8e9bd9601d403b4783fredc        mHandler.sendMessage(msg);
25174ae04c73312403e89db0f8e9bd9601d403b4783fredc        return true;
25274ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
25374ae04c73312403e89db0f8e9bd9601d403b4783fredc
25474ae04c73312403e89db0f8e9bd9601d403b4783fredc    boolean disconnect(BluetoothDevice device) {
25574ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
25674ae04c73312403e89db0f8e9bd9601d403b4783fredc        Message msg = mHandler.obtainMessage(MESSAGE_DISCONNECT,device);
25774ae04c73312403e89db0f8e9bd9601d403b4783fredc        mHandler.sendMessage(msg);
25874ae04c73312403e89db0f8e9bd9601d403b4783fredc        return true;
25974ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
26074ae04c73312403e89db0f8e9bd9601d403b4783fredc
26174ae04c73312403e89db0f8e9bd9601d403b4783fredc    int getConnectionState(BluetoothDevice device) {
26274ae04c73312403e89db0f8e9bd9601d403b4783fredc        BluetoothPanDevice panDevice = mPanDevices.get(device);
26374ae04c73312403e89db0f8e9bd9601d403b4783fredc        if (panDevice == null) {
26474ae04c73312403e89db0f8e9bd9601d403b4783fredc            return BluetoothPan.STATE_DISCONNECTED;
26574ae04c73312403e89db0f8e9bd9601d403b4783fredc        }
26674ae04c73312403e89db0f8e9bd9601d403b4783fredc        return panDevice.mState;
26774ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
26874ae04c73312403e89db0f8e9bd9601d403b4783fredc
26974ae04c73312403e89db0f8e9bd9601d403b4783fredc    boolean isPanNapOn() {
27074ae04c73312403e89db0f8e9bd9601d403b4783fredc        if(DBG) Log.d(TAG, "isTetheringOn call getPanLocalRoleNative");
27174ae04c73312403e89db0f8e9bd9601d403b4783fredc        return (getPanLocalRoleNative() & BluetoothPan.LOCAL_NAP_ROLE) != 0;
27274ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
27374ae04c73312403e89db0f8e9bd9601d403b4783fredc     boolean isPanUOn() {
27474ae04c73312403e89db0f8e9bd9601d403b4783fredc        if(DBG) Log.d(TAG, "isTetheringOn call getPanLocalRoleNative");
27574ae04c73312403e89db0f8e9bd9601d403b4783fredc        return (getPanLocalRoleNative() & BluetoothPan.LOCAL_PANU_ROLE) != 0;
27674ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
27774ae04c73312403e89db0f8e9bd9601d403b4783fredc     boolean isTetheringOn() {
27874ae04c73312403e89db0f8e9bd9601d403b4783fredc        // TODO(BT) have a variable marking the on/off state
27974ae04c73312403e89db0f8e9bd9601d403b4783fredc        return mTetherOn;
28074ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
28174ae04c73312403e89db0f8e9bd9601d403b4783fredc
28274ae04c73312403e89db0f8e9bd9601d403b4783fredc    void setBluetoothTethering(boolean value) {
28374ae04c73312403e89db0f8e9bd9601d403b4783fredc        if(DBG) Log.d(TAG, "setBluetoothTethering: " + value +", mTetherOn: " + mTetherOn);
28474ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission");
28574ae04c73312403e89db0f8e9bd9601d403b4783fredc        if(mTetherOn != value) {
28674ae04c73312403e89db0f8e9bd9601d403b4783fredc            //drop any existing panu or pan-nap connection when changing the tethering state
28774ae04c73312403e89db0f8e9bd9601d403b4783fredc            mTetherOn = value;
28874ae04c73312403e89db0f8e9bd9601d403b4783fredc            List<BluetoothDevice> DevList = getConnectedDevices();
28974ae04c73312403e89db0f8e9bd9601d403b4783fredc            for(BluetoothDevice dev : DevList)
29074ae04c73312403e89db0f8e9bd9601d403b4783fredc                disconnect(dev);
29174ae04c73312403e89db0f8e9bd9601d403b4783fredc        }
29274ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
29374ae04c73312403e89db0f8e9bd9601d403b4783fredc
29474ae04c73312403e89db0f8e9bd9601d403b4783fredc    List<BluetoothDevice> getConnectedDevices() {
29574ae04c73312403e89db0f8e9bd9601d403b4783fredc        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
29674ae04c73312403e89db0f8e9bd9601d403b4783fredc        List<BluetoothDevice> devices = getDevicesMatchingConnectionStates(
29774ae04c73312403e89db0f8e9bd9601d403b4783fredc                new int[] {BluetoothProfile.STATE_CONNECTED});
29874ae04c73312403e89db0f8e9bd9601d403b4783fredc        return devices;
29974ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
30074ae04c73312403e89db0f8e9bd9601d403b4783fredc
30174ae04c73312403e89db0f8e9bd9601d403b4783fredc    List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
30274ae04c73312403e89db0f8e9bd9601d403b4783fredc         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
30374ae04c73312403e89db0f8e9bd9601d403b4783fredc        List<BluetoothDevice> panDevices = new ArrayList<BluetoothDevice>();
30474ae04c73312403e89db0f8e9bd9601d403b4783fredc
30574ae04c73312403e89db0f8e9bd9601d403b4783fredc        for (BluetoothDevice device: mPanDevices.keySet()) {
30674ae04c73312403e89db0f8e9bd9601d403b4783fredc            int panDeviceState = getConnectionState(device);
30774ae04c73312403e89db0f8e9bd9601d403b4783fredc            for (int state : states) {
30874ae04c73312403e89db0f8e9bd9601d403b4783fredc                if (state == panDeviceState) {
30974ae04c73312403e89db0f8e9bd9601d403b4783fredc                    panDevices.add(device);
31074ae04c73312403e89db0f8e9bd9601d403b4783fredc                    break;
3116654f5c903de510a70f9e72cd5ad7837b615d93ffredc                }
3126654f5c903de510a70f9e72cd5ad7837b615d93ffredc            }
3136654f5c903de510a70f9e72cd5ad7837b615d93ffredc        }
31474ae04c73312403e89db0f8e9bd9601d403b4783fredc        return panDevices;
31574ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
31674ae04c73312403e89db0f8e9bd9601d403b4783fredc
3176654f5c903de510a70f9e72cd5ad7837b615d93ffredc    static protected class ConnectState {
3186654f5c903de510a70f9e72cd5ad7837b615d93ffredc        public ConnectState(byte[] address, int state, int error, int local_role, int remote_role) {
3196654f5c903de510a70f9e72cd5ad7837b615d93ffredc            this.addr = address;
3206654f5c903de510a70f9e72cd5ad7837b615d93ffredc            this.state = state;
3216654f5c903de510a70f9e72cd5ad7837b615d93ffredc            this.error = error;
3226654f5c903de510a70f9e72cd5ad7837b615d93ffredc            this.local_role = local_role;
3236654f5c903de510a70f9e72cd5ad7837b615d93ffredc            this.remote_role = remote_role;
3246654f5c903de510a70f9e72cd5ad7837b615d93ffredc        }
3256654f5c903de510a70f9e72cd5ad7837b615d93ffredc        byte[] addr;
3266654f5c903de510a70f9e72cd5ad7837b615d93ffredc        int state;
3276654f5c903de510a70f9e72cd5ad7837b615d93ffredc        int error;
3286654f5c903de510a70f9e72cd5ad7837b615d93ffredc        int local_role;
3296654f5c903de510a70f9e72cd5ad7837b615d93ffredc        int remote_role;
3306654f5c903de510a70f9e72cd5ad7837b615d93ffredc    };
3316654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private void onConnectStateChanged(byte[] address, int state, int error, int local_role, int remote_role) {
3326654f5c903de510a70f9e72cd5ad7837b615d93ffredc        if (DBG) log("onConnectStateChanged: " + state + ", local role:" + local_role + ", remote_role: " + remote_role);
3336654f5c903de510a70f9e72cd5ad7837b615d93ffredc        Message msg = mHandler.obtainMessage(MESSAGE_CONNECT_STATE_CHANGED);
3346654f5c903de510a70f9e72cd5ad7837b615d93ffredc        msg.obj = new ConnectState(address, state, error, local_role, remote_role);
3356654f5c903de510a70f9e72cd5ad7837b615d93ffredc        mHandler.sendMessage(msg);
3366654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
3376654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private void onControlStateChanged(int local_role, int state, int error, String ifname) {
3386654f5c903de510a70f9e72cd5ad7837b615d93ffredc        if (DBG)
3396654f5c903de510a70f9e72cd5ad7837b615d93ffredc            log("onControlStateChanged: " + state + ", error: " + error + ", ifname: " + ifname);
3406654f5c903de510a70f9e72cd5ad7837b615d93ffredc        if(error == 0)
3416654f5c903de510a70f9e72cd5ad7837b615d93ffredc            mPanIfName = ifname;
3426654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
3436654f5c903de510a70f9e72cd5ad7837b615d93ffredc
34474ae04c73312403e89db0f8e9bd9601d403b4783fredc    private static int convertHalState(int halState) {
3456654f5c903de510a70f9e72cd5ad7837b615d93ffredc        switch (halState) {
3466654f5c903de510a70f9e72cd5ad7837b615d93ffredc            case CONN_STATE_CONNECTED:
3476654f5c903de510a70f9e72cd5ad7837b615d93ffredc                return BluetoothProfile.STATE_CONNECTED;
3486654f5c903de510a70f9e72cd5ad7837b615d93ffredc            case CONN_STATE_CONNECTING:
3496654f5c903de510a70f9e72cd5ad7837b615d93ffredc                return BluetoothProfile.STATE_CONNECTING;
3506654f5c903de510a70f9e72cd5ad7837b615d93ffredc            case CONN_STATE_DISCONNECTED:
3516654f5c903de510a70f9e72cd5ad7837b615d93ffredc                return BluetoothProfile.STATE_DISCONNECTED;
3526654f5c903de510a70f9e72cd5ad7837b615d93ffredc            case CONN_STATE_DISCONNECTING:
3536654f5c903de510a70f9e72cd5ad7837b615d93ffredc                return BluetoothProfile.STATE_DISCONNECTING;
3546654f5c903de510a70f9e72cd5ad7837b615d93ffredc            default:
3556654f5c903de510a70f9e72cd5ad7837b615d93ffredc                Log.e(TAG, "bad pan connection state: " + halState);
3566654f5c903de510a70f9e72cd5ad7837b615d93ffredc                return BluetoothProfile.STATE_DISCONNECTED;
3576654f5c903de510a70f9e72cd5ad7837b615d93ffredc        }
3586654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
3596654f5c903de510a70f9e72cd5ad7837b615d93ffredc
3606654f5c903de510a70f9e72cd5ad7837b615d93ffredc    void handlePanDeviceStateChange(BluetoothDevice device,
3616654f5c903de510a70f9e72cd5ad7837b615d93ffredc                                    String iface, int state, int local_role, int remote_role) {
3626654f5c903de510a70f9e72cd5ad7837b615d93ffredc        if(DBG) Log.d(TAG, "handlePanDeviceStateChange: device: " + device + ", iface: " + iface +
3636654f5c903de510a70f9e72cd5ad7837b615d93ffredc                    ", state: " + state + ", local_role:" + local_role + ", remote_role:" + remote_role);
3646654f5c903de510a70f9e72cd5ad7837b615d93ffredc        int prevState;
3656654f5c903de510a70f9e72cd5ad7837b615d93ffredc        String ifaceAddr = null;
3666654f5c903de510a70f9e72cd5ad7837b615d93ffredc        BluetoothPanDevice panDevice = mPanDevices.get(device);
3676654f5c903de510a70f9e72cd5ad7837b615d93ffredc        if (panDevice == null) {
3686654f5c903de510a70f9e72cd5ad7837b615d93ffredc            prevState = BluetoothProfile.STATE_DISCONNECTED;
3696654f5c903de510a70f9e72cd5ad7837b615d93ffredc        } else {
3706654f5c903de510a70f9e72cd5ad7837b615d93ffredc            prevState = panDevice.mState;
3716654f5c903de510a70f9e72cd5ad7837b615d93ffredc            ifaceAddr = panDevice.mIfaceAddr;
3726654f5c903de510a70f9e72cd5ad7837b615d93ffredc        }
3736654f5c903de510a70f9e72cd5ad7837b615d93ffredc        Log.d(TAG, "handlePanDeviceStateChange preState: " + prevState + " state: " + state);
3746654f5c903de510a70f9e72cd5ad7837b615d93ffredc        if (prevState == state) return;
3756654f5c903de510a70f9e72cd5ad7837b615d93ffredc        if (remote_role == BluetoothPan.LOCAL_PANU_ROLE) {
3766654f5c903de510a70f9e72cd5ad7837b615d93ffredc            if (state == BluetoothProfile.STATE_CONNECTED) {
3777ac24de2819e5e4140ab7ab264e7cfffed4d7398Ganesh Ganapathi Batta                if((!mTetherOn)||(local_role == BluetoothPan.LOCAL_PANU_ROLE)){
3787ac24de2819e5e4140ab7ab264e7cfffed4d7398Ganesh Ganapathi Batta                    Log.d(TAG,"handlePanDeviceStateChange BT tethering is off/Local role is PANU "+
3797ac24de2819e5e4140ab7ab264e7cfffed4d7398Ganesh Ganapathi Batta                              "drop the connection");
38074ae04c73312403e89db0f8e9bd9601d403b4783fredc                    disconnectPanNative(Utils.getByteAddress(device));
381ac7e62c64b4cd8d864f125d3225474a04b867606zzy                    return;
382ac7e62c64b4cd8d864f125d3225474a04b867606zzy                }
3837ac24de2819e5e4140ab7ab264e7cfffed4d7398Ganesh Ganapathi Batta                Log.d(TAG, "handlePanDeviceStateChange LOCAL_NAP_ROLE:REMOTE_PANU_ROLE");
3846654f5c903de510a70f9e72cd5ad7837b615d93ffredc                ifaceAddr = enableTethering(iface);
3856654f5c903de510a70f9e72cd5ad7837b615d93ffredc                if (ifaceAddr == null) Log.e(TAG, "Error seting up tether interface");
386ac7e62c64b4cd8d864f125d3225474a04b867606zzy
3876654f5c903de510a70f9e72cd5ad7837b615d93ffredc            } else if (state == BluetoothProfile.STATE_DISCONNECTED) {
3886654f5c903de510a70f9e72cd5ad7837b615d93ffredc                if (ifaceAddr != null) {
3896654f5c903de510a70f9e72cd5ad7837b615d93ffredc                    mBluetoothIfaceAddresses.remove(ifaceAddr);
3906654f5c903de510a70f9e72cd5ad7837b615d93ffredc                    ifaceAddr = null;
3916654f5c903de510a70f9e72cd5ad7837b615d93ffredc                }
3926654f5c903de510a70f9e72cd5ad7837b615d93ffredc            }
3936654f5c903de510a70f9e72cd5ad7837b615d93ffredc        } else {
3946654f5c903de510a70f9e72cd5ad7837b615d93ffredc            // PANU Role = reverse Tether
3956654f5c903de510a70f9e72cd5ad7837b615d93ffredc            Log.d(TAG, "handlePanDeviceStateChange LOCAL_PANU_ROLE:REMOTE_NAP_ROLE");
3966654f5c903de510a70f9e72cd5ad7837b615d93ffredc            if (state == BluetoothProfile.STATE_CONNECTED) {
3976654f5c903de510a70f9e72cd5ad7837b615d93ffredc                if(DBG) Log.d(TAG, "handlePanDeviceStateChange: panu STATE_CONNECTED, startReverseTether");
3986654f5c903de510a70f9e72cd5ad7837b615d93ffredc                IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
3996654f5c903de510a70f9e72cd5ad7837b615d93ffredc                INetworkManagementService service = INetworkManagementService.Stub.asInterface(b);
4006654f5c903de510a70f9e72cd5ad7837b615d93ffredc                Log.d(TAG, "call INetworkManagementService.startReverseTethering()");
4016654f5c903de510a70f9e72cd5ad7837b615d93ffredc                try {
4026654f5c903de510a70f9e72cd5ad7837b615d93ffredc                    service.startReverseTethering(iface);
4036654f5c903de510a70f9e72cd5ad7837b615d93ffredc                } catch (Exception e) {
4046654f5c903de510a70f9e72cd5ad7837b615d93ffredc                    Log.e(TAG, "Cannot start reverse tethering: " + e);
4056654f5c903de510a70f9e72cd5ad7837b615d93ffredc                    return;
4066654f5c903de510a70f9e72cd5ad7837b615d93ffredc                }
4076654f5c903de510a70f9e72cd5ad7837b615d93ffredc            } else if (state == BluetoothProfile.STATE_DISCONNECTED &&
4086654f5c903de510a70f9e72cd5ad7837b615d93ffredc                  (prevState == BluetoothProfile.STATE_CONNECTED ||
4096654f5c903de510a70f9e72cd5ad7837b615d93ffredc                  prevState == BluetoothProfile.STATE_DISCONNECTING)) {
4106654f5c903de510a70f9e72cd5ad7837b615d93ffredc                if(DBG) Log.d(TAG, "handlePanDeviceStateChange: stopReverseTether, panDevice.mIface: "
4116654f5c903de510a70f9e72cd5ad7837b615d93ffredc                                    + panDevice.mIface);
4126654f5c903de510a70f9e72cd5ad7837b615d93ffredc                IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
4136654f5c903de510a70f9e72cd5ad7837b615d93ffredc                INetworkManagementService service = INetworkManagementService.Stub.asInterface(b);
4146654f5c903de510a70f9e72cd5ad7837b615d93ffredc                try {
4156654f5c903de510a70f9e72cd5ad7837b615d93ffredc                    service.stopReverseTethering();
4166654f5c903de510a70f9e72cd5ad7837b615d93ffredc                } catch(Exception e) {
4176654f5c903de510a70f9e72cd5ad7837b615d93ffredc                    Log.e(TAG, "Cannot stop reverse tethering: " + e);
4186654f5c903de510a70f9e72cd5ad7837b615d93ffredc                    return;
4196654f5c903de510a70f9e72cd5ad7837b615d93ffredc                }
4206654f5c903de510a70f9e72cd5ad7837b615d93ffredc            }
4216654f5c903de510a70f9e72cd5ad7837b615d93ffredc        }
4226654f5c903de510a70f9e72cd5ad7837b615d93ffredc
4236654f5c903de510a70f9e72cd5ad7837b615d93ffredc        if (panDevice == null) {
4246654f5c903de510a70f9e72cd5ad7837b615d93ffredc            panDevice = new BluetoothPanDevice(state, ifaceAddr, iface, local_role);
4256654f5c903de510a70f9e72cd5ad7837b615d93ffredc            mPanDevices.put(device, panDevice);
4266654f5c903de510a70f9e72cd5ad7837b615d93ffredc        } else {
4276654f5c903de510a70f9e72cd5ad7837b615d93ffredc            panDevice.mState = state;
4286654f5c903de510a70f9e72cd5ad7837b615d93ffredc            panDevice.mIfaceAddr = ifaceAddr;
4296654f5c903de510a70f9e72cd5ad7837b615d93ffredc            panDevice.mLocalRole = local_role;
4306654f5c903de510a70f9e72cd5ad7837b615d93ffredc            panDevice.mIface = iface;
4316654f5c903de510a70f9e72cd5ad7837b615d93ffredc        }
4326654f5c903de510a70f9e72cd5ad7837b615d93ffredc
433a25e9c65c2a0192b7b3d819e2b87704f1942aa2fSreenidhi T        /* Notifying the connection state change of the profile before sending the intent for
434a25e9c65c2a0192b7b3d819e2b87704f1942aa2fSreenidhi T           connection state change, as it was causing a race condition, with the UI not being
435a25e9c65c2a0192b7b3d819e2b87704f1942aa2fSreenidhi T           updated with the correct connection state. */
436fd1da115cbf09b7dd9bca3c7d3a4fb816a835dc5Matthew Xie        Log.d(TAG, "Pan Device state : device: " + device + " State:" +
437a25e9c65c2a0192b7b3d819e2b87704f1942aa2fSreenidhi T                       prevState + "->" + state);
438a25e9c65c2a0192b7b3d819e2b87704f1942aa2fSreenidhi T        notifyProfileConnectionStateChanged(device, BluetoothProfile.PAN, state, prevState);
4396654f5c903de510a70f9e72cd5ad7837b615d93ffredc        Intent intent = new Intent(BluetoothPan.ACTION_CONNECTION_STATE_CHANGED);
4406654f5c903de510a70f9e72cd5ad7837b615d93ffredc        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
4416654f5c903de510a70f9e72cd5ad7837b615d93ffredc        intent.putExtra(BluetoothPan.EXTRA_PREVIOUS_STATE, prevState);
4426654f5c903de510a70f9e72cd5ad7837b615d93ffredc        intent.putExtra(BluetoothPan.EXTRA_STATE, state);
4436654f5c903de510a70f9e72cd5ad7837b615d93ffredc        intent.putExtra(BluetoothPan.EXTRA_LOCAL_ROLE, local_role);
4446654f5c903de510a70f9e72cd5ad7837b615d93ffredc        sendBroadcast(intent, BLUETOOTH_PERM);
4456654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
4466654f5c903de510a70f9e72cd5ad7837b615d93ffredc
4476654f5c903de510a70f9e72cd5ad7837b615d93ffredc    // configured when we start tethering
4486654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private String enableTethering(String iface) {
4496654f5c903de510a70f9e72cd5ad7837b615d93ffredc        if (DBG) Log.d(TAG, "updateTetherState:" + iface);
4506654f5c903de510a70f9e72cd5ad7837b615d93ffredc
4516654f5c903de510a70f9e72cd5ad7837b615d93ffredc        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
4526654f5c903de510a70f9e72cd5ad7837b615d93ffredc        INetworkManagementService service = INetworkManagementService.Stub.asInterface(b);
4536654f5c903de510a70f9e72cd5ad7837b615d93ffredc        ConnectivityManager cm =
4546654f5c903de510a70f9e72cd5ad7837b615d93ffredc            (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
4556654f5c903de510a70f9e72cd5ad7837b615d93ffredc        String[] bluetoothRegexs = cm.getTetherableBluetoothRegexs();
4566654f5c903de510a70f9e72cd5ad7837b615d93ffredc
4576654f5c903de510a70f9e72cd5ad7837b615d93ffredc        // bring toggle the interfaces
4586654f5c903de510a70f9e72cd5ad7837b615d93ffredc        String[] currentIfaces = new String[0];
4596654f5c903de510a70f9e72cd5ad7837b615d93ffredc        try {
4606654f5c903de510a70f9e72cd5ad7837b615d93ffredc            currentIfaces = service.listInterfaces();
4616654f5c903de510a70f9e72cd5ad7837b615d93ffredc        } catch (Exception e) {
4626654f5c903de510a70f9e72cd5ad7837b615d93ffredc            Log.e(TAG, "Error listing Interfaces :" + e);
4636654f5c903de510a70f9e72cd5ad7837b615d93ffredc            return null;
4646654f5c903de510a70f9e72cd5ad7837b615d93ffredc        }
4656654f5c903de510a70f9e72cd5ad7837b615d93ffredc
4666654f5c903de510a70f9e72cd5ad7837b615d93ffredc        boolean found = false;
4676654f5c903de510a70f9e72cd5ad7837b615d93ffredc        for (String currIface: currentIfaces) {
4686654f5c903de510a70f9e72cd5ad7837b615d93ffredc            if (currIface.equals(iface)) {
4696654f5c903de510a70f9e72cd5ad7837b615d93ffredc                found = true;
4706654f5c903de510a70f9e72cd5ad7837b615d93ffredc                break;
4716654f5c903de510a70f9e72cd5ad7837b615d93ffredc            }
4726654f5c903de510a70f9e72cd5ad7837b615d93ffredc        }
4736654f5c903de510a70f9e72cd5ad7837b615d93ffredc
4746654f5c903de510a70f9e72cd5ad7837b615d93ffredc        if (!found) return null;
4756654f5c903de510a70f9e72cd5ad7837b615d93ffredc
4766654f5c903de510a70f9e72cd5ad7837b615d93ffredc        String address = createNewTetheringAddressLocked();
4776654f5c903de510a70f9e72cd5ad7837b615d93ffredc        if (address == null) return null;
4786654f5c903de510a70f9e72cd5ad7837b615d93ffredc
4796654f5c903de510a70f9e72cd5ad7837b615d93ffredc        InterfaceConfiguration ifcg = null;
4806654f5c903de510a70f9e72cd5ad7837b615d93ffredc        try {
4816654f5c903de510a70f9e72cd5ad7837b615d93ffredc            ifcg = service.getInterfaceConfig(iface);
4826654f5c903de510a70f9e72cd5ad7837b615d93ffredc            if (ifcg != null) {
4836654f5c903de510a70f9e72cd5ad7837b615d93ffredc                InetAddress addr = null;
484e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie                LinkAddress linkAddr = ifcg.getLinkAddress();
485e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie                if (linkAddr == null || (addr = linkAddr.getAddress()) == null ||
4866654f5c903de510a70f9e72cd5ad7837b615d93ffredc                        addr.equals(NetworkUtils.numericToInetAddress("0.0.0.0")) ||
4876654f5c903de510a70f9e72cd5ad7837b615d93ffredc                        addr.equals(NetworkUtils.numericToInetAddress("::0"))) {
4886654f5c903de510a70f9e72cd5ad7837b615d93ffredc                    addr = NetworkUtils.numericToInetAddress(address);
4896654f5c903de510a70f9e72cd5ad7837b615d93ffredc                }
490e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie                ifcg.setInterfaceUp();
491e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie                ifcg.setLinkAddress(new LinkAddress(addr, BLUETOOTH_PREFIX_LENGTH));
492e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie                ifcg.clearFlag("running");
493e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie                // TODO(BT) ifcg.interfaceFlags = ifcg.interfaceFlags.replace("  "," ");
4946654f5c903de510a70f9e72cd5ad7837b615d93ffredc                service.setInterfaceConfig(iface, ifcg);
4956654f5c903de510a70f9e72cd5ad7837b615d93ffredc                if (cm.tether(iface) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
4966654f5c903de510a70f9e72cd5ad7837b615d93ffredc                    Log.e(TAG, "Error tethering "+iface);
4976654f5c903de510a70f9e72cd5ad7837b615d93ffredc                }
4986654f5c903de510a70f9e72cd5ad7837b615d93ffredc            }
4996654f5c903de510a70f9e72cd5ad7837b615d93ffredc        } catch (Exception e) {
5006654f5c903de510a70f9e72cd5ad7837b615d93ffredc            Log.e(TAG, "Error configuring interface " + iface + ", :" + e);
5016654f5c903de510a70f9e72cd5ad7837b615d93ffredc            return null;
5026654f5c903de510a70f9e72cd5ad7837b615d93ffredc        }
5036654f5c903de510a70f9e72cd5ad7837b615d93ffredc        return address;
5046654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
5056654f5c903de510a70f9e72cd5ad7837b615d93ffredc
5066654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private String createNewTetheringAddressLocked() {
5076654f5c903de510a70f9e72cd5ad7837b615d93ffredc        if (getConnectedPanDevices().size() == mMaxPanDevices) {
5086654f5c903de510a70f9e72cd5ad7837b615d93ffredc            if (DBG) Log.d(TAG, "Max PAN device connections reached");
5096654f5c903de510a70f9e72cd5ad7837b615d93ffredc            return null;
5106654f5c903de510a70f9e72cd5ad7837b615d93ffredc        }
5116654f5c903de510a70f9e72cd5ad7837b615d93ffredc        String address = BLUETOOTH_IFACE_ADDR_START;
5126654f5c903de510a70f9e72cd5ad7837b615d93ffredc        while (true) {
5136654f5c903de510a70f9e72cd5ad7837b615d93ffredc            if (mBluetoothIfaceAddresses.contains(address)) {
5146654f5c903de510a70f9e72cd5ad7837b615d93ffredc                String[] addr = address.split("\\.");
5156654f5c903de510a70f9e72cd5ad7837b615d93ffredc                Integer newIp = Integer.parseInt(addr[2]) + 1;
5166654f5c903de510a70f9e72cd5ad7837b615d93ffredc                address = address.replace(addr[2], newIp.toString());
5176654f5c903de510a70f9e72cd5ad7837b615d93ffredc            } else {
5186654f5c903de510a70f9e72cd5ad7837b615d93ffredc                break;
5196654f5c903de510a70f9e72cd5ad7837b615d93ffredc            }
5206654f5c903de510a70f9e72cd5ad7837b615d93ffredc        }
5216654f5c903de510a70f9e72cd5ad7837b615d93ffredc        mBluetoothIfaceAddresses.add(address);
5226654f5c903de510a70f9e72cd5ad7837b615d93ffredc        return address;
5236654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
5246654f5c903de510a70f9e72cd5ad7837b615d93ffredc
5256654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private List<BluetoothDevice> getConnectedPanDevices() {
5266654f5c903de510a70f9e72cd5ad7837b615d93ffredc        List<BluetoothDevice> devices = new ArrayList<BluetoothDevice>();
5276654f5c903de510a70f9e72cd5ad7837b615d93ffredc
5286654f5c903de510a70f9e72cd5ad7837b615d93ffredc        for (BluetoothDevice device: mPanDevices.keySet()) {
5296654f5c903de510a70f9e72cd5ad7837b615d93ffredc            if (getPanDeviceConnectionState(device) == BluetoothProfile.STATE_CONNECTED) {
5306654f5c903de510a70f9e72cd5ad7837b615d93ffredc                devices.add(device);
5316654f5c903de510a70f9e72cd5ad7837b615d93ffredc            }
5326654f5c903de510a70f9e72cd5ad7837b615d93ffredc        }
5336654f5c903de510a70f9e72cd5ad7837b615d93ffredc        return devices;
5346654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
5356654f5c903de510a70f9e72cd5ad7837b615d93ffredc
5366654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private int getPanDeviceConnectionState(BluetoothDevice device) {
5376654f5c903de510a70f9e72cd5ad7837b615d93ffredc        BluetoothPanDevice panDevice = mPanDevices.get(device);
5386654f5c903de510a70f9e72cd5ad7837b615d93ffredc        if (panDevice == null) {
5396654f5c903de510a70f9e72cd5ad7837b615d93ffredc            return BluetoothProfile.STATE_DISCONNECTED;
5406654f5c903de510a70f9e72cd5ad7837b615d93ffredc        }
5416654f5c903de510a70f9e72cd5ad7837b615d93ffredc        return panDevice.mState;
5426654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
5436654f5c903de510a70f9e72cd5ad7837b615d93ffredc
5446654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private class BluetoothPanDevice {
5456654f5c903de510a70f9e72cd5ad7837b615d93ffredc        private int mState;
5466654f5c903de510a70f9e72cd5ad7837b615d93ffredc        private String mIfaceAddr;
5476654f5c903de510a70f9e72cd5ad7837b615d93ffredc        private String mIface;
5486654f5c903de510a70f9e72cd5ad7837b615d93ffredc        private int mLocalRole; // Which local role is this PAN device bound to
5496654f5c903de510a70f9e72cd5ad7837b615d93ffredc
5506654f5c903de510a70f9e72cd5ad7837b615d93ffredc        BluetoothPanDevice(int state, String ifaceAddr, String iface, int localRole) {
5516654f5c903de510a70f9e72cd5ad7837b615d93ffredc            mState = state;
5526654f5c903de510a70f9e72cd5ad7837b615d93ffredc            mIfaceAddr = ifaceAddr;
5536654f5c903de510a70f9e72cd5ad7837b615d93ffredc            mIface = iface;
5546654f5c903de510a70f9e72cd5ad7837b615d93ffredc            mLocalRole = localRole;
5556654f5c903de510a70f9e72cd5ad7837b615d93ffredc        }
5566654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
5576654f5c903de510a70f9e72cd5ad7837b615d93ffredc
5586654f5c903de510a70f9e72cd5ad7837b615d93ffredc    // Constants matching Hal header file bt_hh.h
5596654f5c903de510a70f9e72cd5ad7837b615d93ffredc    // bthh_connection_state_t
5606654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private final static int CONN_STATE_CONNECTED = 0;
5616654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private final static int CONN_STATE_CONNECTING = 1;
5626654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private final static int CONN_STATE_DISCONNECTED = 2;
5636654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private final static int CONN_STATE_DISCONNECTING = 3;
5646654f5c903de510a70f9e72cd5ad7837b615d93ffredc
5656654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private native static void classInitNative();
5666654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private native void initializeNative();
5676654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private native void cleanupNative();
5686654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private native boolean connectPanNative(byte[] btAddress, int local_role, int remote_role);
5696654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private native boolean disconnectPanNative(byte[] btAddress);
5706654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private native boolean enablePanNative(int local_role);
5716654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private native int getPanLocalRoleNative();
57274ae04c73312403e89db0f8e9bd9601d403b4783fredc
5736654f5c903de510a70f9e72cd5ad7837b615d93ffredc}
574