Loading jni/com_android_bluetooth_btservice_AdapterService.cpp +51 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,8 @@ namespace android { #define OOB_TK_SIZE 16 #define ADDITIONAL_NREFS 50 static jmethodID method_stateChangeCallback; static jmethodID method_adapterPropertyChangedCallback; Loading Loading @@ -772,6 +774,54 @@ static jboolean createBondNative(JNIEnv* env, jobject obj, jbyteArray address, j return result; } static jbyteArray callByteArrayGetter(JNIEnv* env, jobject object, char* className, char* methodName) { jclass myClass = env->FindClass(className); jmethodID myMethod = env->GetMethodID(myClass, methodName, "()[B"); return (jbyteArray) env->CallObjectMethod(object, myMethod); } static jboolean createBondOutOfBandNative(JNIEnv* env, jobject obj, jbyteArray address, jint transport, jobject oobData) { jbyte *addr; jboolean result = JNI_FALSE; bt_out_of_band_data_t oob_data; memset(&oob_data, 0, sizeof(oob_data)); if (!sBluetoothInterface) return result; addr = env->GetByteArrayElements(address, NULL); if (addr == NULL) { jniThrowIOException(env, EINVAL); return result; } jbyte* smTKBytes = NULL; jbyteArray smTK = callByteArrayGetter(env, oobData, "android/bluetooth/OobData", "getSecurityManagerTk"); if (smTK != NULL) { smTKBytes = env->GetByteArrayElements(smTK, NULL); int len = env->GetArrayLength(smTK); if (len != OOB_TK_SIZE) { ALOGI("%s: wrong length of smTK, should be empty or %d bytes.", __FUNCTION__, OOB_TK_SIZE); jniThrowIOException(env, EINVAL); goto done; } memcpy(oob_data.sm_tk, smTKBytes, len); } if (sBluetoothInterface->create_bond_out_of_band((bt_bdaddr_t *)addr, transport, &oob_data) == BT_STATUS_SUCCESS) result = JNI_TRUE; done: env->ReleaseByteArrayElements(address, addr, 0); if (smTK != NULL) env->ReleaseByteArrayElements(smTK, smTKBytes, 0); return result; } static jboolean removeBondNative(JNIEnv* env, jobject obj, jbyteArray address) { ALOGV("%s:",__FUNCTION__); Loading Loading @@ -1166,6 +1216,7 @@ static JNINativeMethod sMethods[] = { {"startDiscoveryNative", "()Z", (void*) startDiscoveryNative}, {"cancelDiscoveryNative", "()Z", (void*) cancelDiscoveryNative}, {"createBondNative", "([BI)Z", (void*) createBondNative}, {"createBondOutOfBandNative", "([BILandroid/bluetooth/OobData;)Z", (void*) createBondOutOfBandNative}, {"removeBondNative", "([B)Z", (void*) removeBondNative}, {"cancelBondNative", "([B)Z", (void*) cancelBondNative}, {"getConnectionStateNative", "([B)I", (void*) getConnectionStateNative}, Loading src/com/android/bluetooth/btservice/AdapterService.java +21 −3 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import android.bluetooth.IBluetoothCallback; import android.bluetooth.IBluetoothManager; import android.bluetooth.IBluetoothManagerCallback; import android.bluetooth.BluetoothActivityEnergyInfo; import android.bluetooth.OobData; import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.Context; Loading Loading @@ -965,7 +966,18 @@ public class AdapterService extends Service { AdapterService service = getService(); if (service == null) return false; return service.createBond(device, transport); return service.createBond(device, transport, null); } public boolean createBondOutOfBand(BluetoothDevice device, int transport, OobData oobData) { if (!Utils.checkCaller()) { Log.w(TAG, "createBondOutOfBand() - Not allowed for non-active user"); return false; } AdapterService service = getService(); if (service == null) return false; return service.createBond(device, transport, oobData); } public boolean cancelBondProcess(BluetoothDevice device) { Loading Loading @@ -1462,8 +1474,7 @@ public class AdapterService extends Service { } } boolean createBond(BluetoothDevice device, int transport) { boolean createBond(BluetoothDevice device, int transport, OobData oobData) { enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission"); DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); Loading @@ -1478,6 +1489,12 @@ public class AdapterService extends Service { Message msg = mBondStateMachine.obtainMessage(BondStateMachine.CREATE_BOND); msg.obj = device; msg.arg1 = transport; if (oobData != null) { Bundle oobDataBundle = new Bundle(); oobDataBundle.putParcelable(BondStateMachine.OOBDATA, oobData); msg.setData(oobDataBundle); } mBondStateMachine.sendMessage(msg); return true; } Loading Loading @@ -2138,6 +2155,7 @@ public class AdapterService extends Service { /*package*/ native boolean getDevicePropertyNative(byte[] address, int type); /*package*/ native boolean createBondNative(byte[] address, int transport); /*package*/ native boolean createBondOutOfBandNative(byte[] address, int transport, OobData oobData); /*package*/ native boolean removeBondNative(byte[] address); /*package*/ native boolean cancelBondNative(byte[] address); /*package*/ native boolean sdpSearchNative(byte[] address, byte[] uuid); Loading src/com/android/bluetooth/btservice/BondStateMachine.java +24 −4 Original line number Diff line number Diff line Loading @@ -23,6 +23,8 @@ import android.bluetooth.BluetoothDevice; import com.android.bluetooth.a2dp.A2dpService; import com.android.bluetooth.hid.HidService; import com.android.bluetooth.hfp.HeadsetService; import android.bluetooth.OobData; import android.content.Context; import android.content.Intent; import android.os.Message; Loading Loading @@ -66,6 +68,8 @@ final class BondStateMachine extends StateMachine { private PendingCommandState mPendingCommandState = new PendingCommandState(); private StableState mStableState = new StableState(); public static final String OOBDATA = "oobdata"; private BondStateMachine(AdapterService service, AdapterProperties prop, RemoteDevices remoteDevices) { super("BondStateMachine:"); Loading Loading @@ -110,7 +114,11 @@ final class BondStateMachine extends StateMachine { switch(msg.what) { case CREATE_BOND: createBond(dev, msg.arg1, true); OobData oobData = null; if (msg.getData() != null) oobData = msg.getData().getParcelable(OOBDATA); createBond(dev, msg.arg1, oobData, true); break; case REMOVE_BOND: removeBond(dev, true); Loading Loading @@ -171,7 +179,11 @@ final class BondStateMachine extends StateMachine { switch (msg.what) { case CREATE_BOND: result = createBond(dev, msg.arg1, false); OobData oobData = null; if (msg.getData() != null) oobData = msg.getData().getParcelable(OOBDATA); result = createBond(dev, msg.arg1, oobData, false); break; case REMOVE_BOND: result = removeBond(dev, false); Loading Loading @@ -288,11 +300,19 @@ final class BondStateMachine extends StateMachine { return false; } private boolean createBond(BluetoothDevice dev, int transport, boolean transition) { private boolean createBond(BluetoothDevice dev, int transport, OobData oobData, boolean transition) { if (dev.getBondState() == BluetoothDevice.BOND_NONE) { infoLog("Bond address is:" + dev); byte[] addr = Utils.getBytesFromAddress(dev.getAddress()); if (!mAdapterService.createBondNative(addr, transport)) { boolean result; if (oobData != null) { result = mAdapterService.createBondOutOfBandNative(addr, transport, oobData); } else { result = mAdapterService.createBondNative(addr, transport); } if (!result) { sendIntent(dev, BluetoothDevice.BOND_NONE, BluetoothDevice.UNBOND_REASON_REMOVED); return false; Loading Loading
jni/com_android_bluetooth_btservice_AdapterService.cpp +51 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,8 @@ namespace android { #define OOB_TK_SIZE 16 #define ADDITIONAL_NREFS 50 static jmethodID method_stateChangeCallback; static jmethodID method_adapterPropertyChangedCallback; Loading Loading @@ -772,6 +774,54 @@ static jboolean createBondNative(JNIEnv* env, jobject obj, jbyteArray address, j return result; } static jbyteArray callByteArrayGetter(JNIEnv* env, jobject object, char* className, char* methodName) { jclass myClass = env->FindClass(className); jmethodID myMethod = env->GetMethodID(myClass, methodName, "()[B"); return (jbyteArray) env->CallObjectMethod(object, myMethod); } static jboolean createBondOutOfBandNative(JNIEnv* env, jobject obj, jbyteArray address, jint transport, jobject oobData) { jbyte *addr; jboolean result = JNI_FALSE; bt_out_of_band_data_t oob_data; memset(&oob_data, 0, sizeof(oob_data)); if (!sBluetoothInterface) return result; addr = env->GetByteArrayElements(address, NULL); if (addr == NULL) { jniThrowIOException(env, EINVAL); return result; } jbyte* smTKBytes = NULL; jbyteArray smTK = callByteArrayGetter(env, oobData, "android/bluetooth/OobData", "getSecurityManagerTk"); if (smTK != NULL) { smTKBytes = env->GetByteArrayElements(smTK, NULL); int len = env->GetArrayLength(smTK); if (len != OOB_TK_SIZE) { ALOGI("%s: wrong length of smTK, should be empty or %d bytes.", __FUNCTION__, OOB_TK_SIZE); jniThrowIOException(env, EINVAL); goto done; } memcpy(oob_data.sm_tk, smTKBytes, len); } if (sBluetoothInterface->create_bond_out_of_band((bt_bdaddr_t *)addr, transport, &oob_data) == BT_STATUS_SUCCESS) result = JNI_TRUE; done: env->ReleaseByteArrayElements(address, addr, 0); if (smTK != NULL) env->ReleaseByteArrayElements(smTK, smTKBytes, 0); return result; } static jboolean removeBondNative(JNIEnv* env, jobject obj, jbyteArray address) { ALOGV("%s:",__FUNCTION__); Loading Loading @@ -1166,6 +1216,7 @@ static JNINativeMethod sMethods[] = { {"startDiscoveryNative", "()Z", (void*) startDiscoveryNative}, {"cancelDiscoveryNative", "()Z", (void*) cancelDiscoveryNative}, {"createBondNative", "([BI)Z", (void*) createBondNative}, {"createBondOutOfBandNative", "([BILandroid/bluetooth/OobData;)Z", (void*) createBondOutOfBandNative}, {"removeBondNative", "([B)Z", (void*) removeBondNative}, {"cancelBondNative", "([B)Z", (void*) cancelBondNative}, {"getConnectionStateNative", "([B)I", (void*) getConnectionStateNative}, Loading
src/com/android/bluetooth/btservice/AdapterService.java +21 −3 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import android.bluetooth.IBluetoothCallback; import android.bluetooth.IBluetoothManager; import android.bluetooth.IBluetoothManagerCallback; import android.bluetooth.BluetoothActivityEnergyInfo; import android.bluetooth.OobData; import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.Context; Loading Loading @@ -965,7 +966,18 @@ public class AdapterService extends Service { AdapterService service = getService(); if (service == null) return false; return service.createBond(device, transport); return service.createBond(device, transport, null); } public boolean createBondOutOfBand(BluetoothDevice device, int transport, OobData oobData) { if (!Utils.checkCaller()) { Log.w(TAG, "createBondOutOfBand() - Not allowed for non-active user"); return false; } AdapterService service = getService(); if (service == null) return false; return service.createBond(device, transport, oobData); } public boolean cancelBondProcess(BluetoothDevice device) { Loading Loading @@ -1462,8 +1474,7 @@ public class AdapterService extends Service { } } boolean createBond(BluetoothDevice device, int transport) { boolean createBond(BluetoothDevice device, int transport, OobData oobData) { enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission"); DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); Loading @@ -1478,6 +1489,12 @@ public class AdapterService extends Service { Message msg = mBondStateMachine.obtainMessage(BondStateMachine.CREATE_BOND); msg.obj = device; msg.arg1 = transport; if (oobData != null) { Bundle oobDataBundle = new Bundle(); oobDataBundle.putParcelable(BondStateMachine.OOBDATA, oobData); msg.setData(oobDataBundle); } mBondStateMachine.sendMessage(msg); return true; } Loading Loading @@ -2138,6 +2155,7 @@ public class AdapterService extends Service { /*package*/ native boolean getDevicePropertyNative(byte[] address, int type); /*package*/ native boolean createBondNative(byte[] address, int transport); /*package*/ native boolean createBondOutOfBandNative(byte[] address, int transport, OobData oobData); /*package*/ native boolean removeBondNative(byte[] address); /*package*/ native boolean cancelBondNative(byte[] address); /*package*/ native boolean sdpSearchNative(byte[] address, byte[] uuid); Loading
src/com/android/bluetooth/btservice/BondStateMachine.java +24 −4 Original line number Diff line number Diff line Loading @@ -23,6 +23,8 @@ import android.bluetooth.BluetoothDevice; import com.android.bluetooth.a2dp.A2dpService; import com.android.bluetooth.hid.HidService; import com.android.bluetooth.hfp.HeadsetService; import android.bluetooth.OobData; import android.content.Context; import android.content.Intent; import android.os.Message; Loading Loading @@ -66,6 +68,8 @@ final class BondStateMachine extends StateMachine { private PendingCommandState mPendingCommandState = new PendingCommandState(); private StableState mStableState = new StableState(); public static final String OOBDATA = "oobdata"; private BondStateMachine(AdapterService service, AdapterProperties prop, RemoteDevices remoteDevices) { super("BondStateMachine:"); Loading Loading @@ -110,7 +114,11 @@ final class BondStateMachine extends StateMachine { switch(msg.what) { case CREATE_BOND: createBond(dev, msg.arg1, true); OobData oobData = null; if (msg.getData() != null) oobData = msg.getData().getParcelable(OOBDATA); createBond(dev, msg.arg1, oobData, true); break; case REMOVE_BOND: removeBond(dev, true); Loading Loading @@ -171,7 +179,11 @@ final class BondStateMachine extends StateMachine { switch (msg.what) { case CREATE_BOND: result = createBond(dev, msg.arg1, false); OobData oobData = null; if (msg.getData() != null) oobData = msg.getData().getParcelable(OOBDATA); result = createBond(dev, msg.arg1, oobData, false); break; case REMOVE_BOND: result = removeBond(dev, false); Loading Loading @@ -288,11 +300,19 @@ final class BondStateMachine extends StateMachine { return false; } private boolean createBond(BluetoothDevice dev, int transport, boolean transition) { private boolean createBond(BluetoothDevice dev, int transport, OobData oobData, boolean transition) { if (dev.getBondState() == BluetoothDevice.BOND_NONE) { infoLog("Bond address is:" + dev); byte[] addr = Utils.getBytesFromAddress(dev.getAddress()); if (!mAdapterService.createBondNative(addr, transport)) { boolean result; if (oobData != null) { result = mAdapterService.createBondOutOfBandNative(addr, transport, oobData); } else { result = mAdapterService.createBondNative(addr, transport); } if (!result) { sendIntent(dev, BluetoothDevice.BOND_NONE, BluetoothDevice.UNBOND_REASON_REMOVED); return false; Loading