am 32d8571f: Changes for BT 2.1

Merge commit '32d8571f509c392dca732c243e9b2138c15daecf' into eclair-plus-aosp

* commit '32d8571f509c392dca732c243e9b2138c15daecf':
  Changes for BT 2.1
This commit is contained in:
Jaikumar Ganesh
2009-09-11 14:27:33 -07:00
committed by Android Git Automerger
5 changed files with 118 additions and 16 deletions

View File

@@ -250,7 +250,7 @@ public final class BluetoothDevice implements Parcelable {
* @hide */
public static final int BOND_SUCCESS = 0;
/** A bond attempt failed because pins did not match, or remote device did
* not respond to pin request in time
* not respond to pin request in time
* @hide */
public static final int UNBOND_REASON_AUTH_FAILED = 1;
/** A bond attempt failed because the other side explicilty rejected
@@ -266,9 +266,15 @@ public final class BluetoothDevice implements Parcelable {
/** A bond attempt failed because a discovery is in progress
* @hide */
public static final int UNBOND_REASON_DISCOVERY_IN_PROGRESS = 5;
/** A bond attempt failed because of authentication timeout
* @hide */
public static final int UNBOND_REASON_AUTH_TIMEOUT = 6;
/** A bond attempt failed because of repeated attempts
* @hide */
public static final int UNBOND_REASON_REPEATED_ATTEMPTS = 7;
/** An existing bond was explicitly revoked
* @hide */
public static final int UNBOND_REASON_REMOVED = 6;
public static final int UNBOND_REASON_REMOVED = 8;
/** The user will be prompted to enter a pin
* @hide */
@@ -278,7 +284,13 @@ public final class BluetoothDevice implements Parcelable {
public static final int PAIRING_VARIANT_PASSKEY = 1;
/** The user will be prompted to confirm the passkey displayed on the screen
* @hide */
public static final int PAIRING_VARIANT_CONFIRMATION = 2;
public static final int PAIRING_VARIANT_PASSKEY_CONFIRMATION = 2;
/** The user will be prompted to accept or deny the incoming pairing request
* @hide */
public static final int PAIRING_VARIANT_CONSENT = 3;
/** The user will be prompted to enter the passkey displayed on remote device
* @hide */
public static final int PAIRING_VARIANT_DISPLAY_PASSKEY = 4;
private static IBluetooth sService; /* Guarenteed constant after first object constructed */

View File

@@ -17,8 +17,8 @@
package android.server;
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothUuid;
import android.content.Context;
@@ -53,6 +53,7 @@ class BluetoothEventLoop {
private static final int EVENT_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY = 1;
private static final int EVENT_RESTART_BLUETOOTH = 2;
private static final int EVENT_PAIRING_CONSENT_DELAYED_ACCEPT = 3;
// The time (in millisecs) to delay the pairing attempt after the first
// auto pairing attempt fails. We use an exponential delay with
@@ -67,9 +68,10 @@ class BluetoothEventLoop {
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
String address = null;
switch (msg.what) {
case EVENT_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY:
String address = (String)msg.obj;
address = (String)msg.obj;
if (address != null) {
mBluetoothService.createBond(address);
return;
@@ -78,6 +80,12 @@ class BluetoothEventLoop {
case EVENT_RESTART_BLUETOOTH:
mBluetoothService.restart();
break;
case EVENT_PAIRING_CONSENT_DELAYED_ACCEPT:
address = (String)msg.obj;
if (address != null) {
mBluetoothService.setPairingConfirmation(address, true);
}
break;
}
}
};
@@ -239,6 +247,7 @@ class BluetoothEventLoop {
addDevice(address, properties);
}
}
mBluetoothService.getBondState().setBondState(address, BluetoothDevice.BOND_BONDING);
return;
}
@@ -390,7 +399,32 @@ class BluetoothEventLoop {
return address;
}
private void onRequestConfirmation(String objectPath, int passkey, int nativeData) {
private void onRequestPairingConsent(String objectPath, int nativeData) {
String address = checkPairingRequestAndGetAddress(objectPath, nativeData);
if (address == null) return;
/* The link key will not be stored if the incoming request has MITM
* protection switched on. Unfortunately, some devices have MITM
* switched on even though their capabilities are NoInputNoOutput,
* so we may get this request many times. Also if we respond immediately,
* the other end is unable to handle it. Delay sending the message.
*/
if (mBluetoothService.getBondState().getBondState(address) == BluetoothDevice.BOND_BONDED) {
Message message = mHandler.obtainMessage(EVENT_PAIRING_CONSENT_DELAYED_ACCEPT);
message.obj = address;
mHandler.sendMessageDelayed(message, 1500);
return;
}
Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST);
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address));
intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
BluetoothDevice.PAIRING_VARIANT_CONSENT);
mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
return;
}
private void onRequestPasskeyConfirmation(String objectPath, int passkey, int nativeData) {
String address = checkPairingRequestAndGetAddress(objectPath, nativeData);
if (address == null) return;
@@ -398,7 +432,7 @@ class BluetoothEventLoop {
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address));
intent.putExtra(BluetoothDevice.EXTRA_PASSKEY, passkey);
intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
BluetoothDevice.PAIRING_VARIANT_CONFIRMATION);
BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION);
mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
return;
}
@@ -447,6 +481,18 @@ class BluetoothEventLoop {
return;
}
private void onDisplayPasskey(String objectPath, int passkey, int nativeData) {
String address = checkPairingRequestAndGetAddress(objectPath, nativeData);
if (address == null) return;
Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST);
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address));
intent.putExtra(BluetoothDevice.EXTRA_PASSKEY, passkey);
intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY);
mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
}
private boolean onAgentAuthorize(String objectPath, String deviceUuid) {
String address = mBluetoothService.getAddressFromObjectPath(objectPath);
if (address == null) {

View File

@@ -1266,5 +1266,4 @@ public class BluetoothService extends IBluetooth.Stub {
private native boolean setPairingConfirmationNative(String address, boolean confirm,
int nativeData);
private native boolean setDevicePropertyBooleanNative(String objectPath, String key, int value);
}

View File

@@ -52,7 +52,9 @@ static jmethodID method_onGetDeviceServiceChannelResult;
static jmethodID method_onRequestPinCode;
static jmethodID method_onRequestPasskey;
static jmethodID method_onRequestConfirmation;
static jmethodID method_onRequestPasskeyConfirmation;
static jmethodID method_onRequestPairingConsent;
static jmethodID method_onDisplayPasskey;
static jmethodID method_onAgentAuthorize;
static jmethodID method_onAgentCancel;
@@ -98,7 +100,11 @@ static void classInitNative(JNIEnv* env, jclass clazz) {
"(Ljava/lang/String;I)V");
method_onRequestPasskey = env->GetMethodID(clazz, "onRequestPasskey",
"(Ljava/lang/String;I)V");
method_onRequestConfirmation = env->GetMethodID(clazz, "onRequestConfirmation",
method_onRequestPasskeyConfirmation = env->GetMethodID(clazz, "onRequestPasskeyConfirmation",
"(Ljava/lang/String;II)V");
method_onRequestPairingConsent = env->GetMethodID(clazz, "onRequestPairingConsent",
"(Ljava/lang/String;I)V");
method_onDisplayPasskey = env->GetMethodID(clazz, "onDisplayPasskey",
"(Ljava/lang/String;II)V");
field_mNativeData = env->GetFieldID(clazz, "mNativeData", "I");
@@ -230,7 +236,7 @@ static jboolean setUpEventLoop(native_data_t *nat) {
const char * get_adapter_path(DBusConnection *conn) {
DBusMessage *msg, *reply = NULL;
DBusMessage *msg = NULL, *reply = NULL;
DBusError err;
const char *device_path = NULL;
int attempt = 0;
@@ -856,9 +862,7 @@ DBusHandlerResult agent_event_filter(DBusConnection *conn,
if (dbus_message_is_method_call(msg,
"org.bluez.Agent", "Cancel")) {
env->CallVoidMethod(nat->me, method_onAgentCancel);
// reply
DBusMessage *reply = dbus_message_new_method_return(msg);
if (!reply) {
@@ -938,6 +942,24 @@ DBusHandlerResult agent_event_filter(DBusConnection *conn,
env->NewStringUTF(object_path),
int(msg));
goto success;
} else if (dbus_message_is_method_call(msg,
"org.bluez.Agent", "DisplayPasskey")) {
char *object_path;
uint32_t passkey;
if (!dbus_message_get_args(msg, NULL,
DBUS_TYPE_OBJECT_PATH, &object_path,
DBUS_TYPE_UINT32, &passkey,
DBUS_TYPE_INVALID)) {
LOGE("%s: Invalid arguments for RequestPasskey() method", __FUNCTION__);
goto failure;
}
dbus_message_ref(msg); // increment refcount because we pass to java
env->CallVoidMethod(nat->me, method_onDisplayPasskey,
env->NewStringUTF(object_path),
passkey,
int(msg));
goto success;
} else if (dbus_message_is_method_call(msg,
"org.bluez.Agent", "RequestConfirmation")) {
char *object_path;
@@ -951,11 +973,26 @@ DBusHandlerResult agent_event_filter(DBusConnection *conn,
}
dbus_message_ref(msg); // increment refcount because we pass to java
env->CallVoidMethod(nat->me, method_onRequestConfirmation,
env->CallVoidMethod(nat->me, method_onRequestPasskeyConfirmation,
env->NewStringUTF(object_path),
passkey,
int(msg));
goto success;
} else if (dbus_message_is_method_call(msg,
"org.bluez.Agent", "RequestPairingConsent")) {
char *object_path;
if (!dbus_message_get_args(msg, NULL,
DBUS_TYPE_OBJECT_PATH, &object_path,
DBUS_TYPE_INVALID)) {
LOGE("%s: Invalid arguments for RequestPairingConsent() method", __FUNCTION__);
goto failure;
}
dbus_message_ref(msg); // increment refcount because we pass to java
env->CallVoidMethod(nat->me, method_onRequestPairingConsent,
env->NewStringUTF(object_path),
int(msg));
goto success;
} else if (dbus_message_is_method_call(msg,
"org.bluez.Agent", "Release")) {
// reply
@@ -992,6 +1029,8 @@ success:
#define BOND_RESULT_AUTH_CANCELED 3
#define BOND_RESULT_REMOTE_DEVICE_DOWN 4
#define BOND_RESULT_DISCOVERY_IN_PROGRESS 5
#define BOND_RESULT_AUTH_TIMEOUT 6
#define BOND_RESULT_REPEATED_ATTEMPTS 7
void onCreatePairedDeviceResult(DBusMessage *msg, void *user, void *n) {
LOGV(__FUNCTION__);
@@ -1037,6 +1076,12 @@ void onCreatePairedDeviceResult(DBusMessage *msg, void *user, void *n) {
!strcmp(err.message, "Discover in progress")) {
LOGV("... error = %s (%s)\n", err.name, err.message);
result = BOND_RESULT_DISCOVERY_IN_PROGRESS;
} else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.RepeatedAttempts")) {
LOGV("... error = %s (%s)\n", err.name, err.message);
result = BOND_RESULT_REPEATED_ATTEMPTS;
} else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AuthenticationTimeout")) {
LOGV("... error = %s (%s)\n", err.name, err.message);
result = BOND_RESULT_AUTH_TIMEOUT;
} else {
LOGE("%s: D-Bus error: %s (%s)\n", __FUNCTION__, err.name, err.message);
result = BOND_RESULT_ERROR;

View File

@@ -455,8 +455,8 @@ static jboolean setPairingConfirmationNative(JNIEnv *env, jobject object,
}
if (!reply) {
LOGE("%s: Cannot create message reply to RequestConfirmation to "
"D-Bus\n", __FUNCTION__);
LOGE("%s: Cannot create message reply to RequestPasskeyConfirmation or"
"RequestPairingConsent to D-Bus\n", __FUNCTION__);
dbus_message_unref(msg);
return JNI_FALSE;
}