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