summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/com/android/bluetooth/gatt/CallbackInfo.java52
-rw-r--r--src/com/android/bluetooth/gatt/ContextMap.java15
-rw-r--r--src/com/android/bluetooth/gatt/GattService.java46
3 files changed, 105 insertions, 8 deletions
diff --git a/src/com/android/bluetooth/gatt/CallbackInfo.java b/src/com/android/bluetooth/gatt/CallbackInfo.java
new file mode 100644
index 000000000..25dfd4cc1
--- /dev/null
+++ b/src/com/android/bluetooth/gatt/CallbackInfo.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.bluetooth.gatt;
+
+import java.util.UUID;
+
+/**
+ * Helper class that keeps track of callback parameters for app callbacks.
+ * These are held during congestion and reported when congestion clears.
+ * @hide
+ */
+/*package*/
+
+class CallbackInfo {
+ String address;
+ int status;
+ int srvcType;
+ int srvcInstId;
+ UUID srvcUuid;
+ int charInstId;
+ UUID charUuid;
+
+ CallbackInfo(String address, int status, int srvcType, int srvcInstId,
+ UUID srvcUuid, int charInstId, UUID charUuid) {
+ this.address = address;
+ this.status = status;
+ this.srvcType = srvcType;
+ this.srvcInstId = srvcInstId;
+ this.srvcUuid = srvcUuid;
+ this.charInstId = charInstId;
+ this.charUuid = charUuid;
+ }
+
+ CallbackInfo(String address, int status) {
+ this.address = address;
+ this.status = status;
+ }
+}
+
diff --git a/src/com/android/bluetooth/gatt/ContextMap.java b/src/com/android/bluetooth/gatt/ContextMap.java
index 62a488a36..65f8dce89 100644
--- a/src/com/android/bluetooth/gatt/ContextMap.java
+++ b/src/com/android/bluetooth/gatt/ContextMap.java
@@ -67,6 +67,12 @@ import java.util.UUID;
/** Death receipient */
private IBinder.DeathRecipient mDeathRecipient;
+ /** Flag to signal that transport is congested */
+ Boolean isCongested = false;
+
+ /** Internal callback info queue, waiting to be send on congestion clear */
+ private List<CallbackInfo> congestionQueue = new ArrayList<CallbackInfo>();
+
/**
* Creates a new app context.
*/
@@ -101,6 +107,15 @@ import java.util.UUID;
}
}
}
+
+ void queueCallback(CallbackInfo callbackInfo) {
+ congestionQueue.add(callbackInfo);
+ }
+
+ CallbackInfo popQueuedCallback() {
+ if (congestionQueue.size() == 0) return null;
+ return congestionQueue.remove(0);
+ }
}
/** Our internal application list */
diff --git a/src/com/android/bluetooth/gatt/GattService.java b/src/com/android/bluetooth/gatt/GattService.java
index 8c2115ce0..982fd16e7 100644
--- a/src/com/android/bluetooth/gatt/GattService.java
+++ b/src/com/android/bluetooth/gatt/GattService.java
@@ -849,10 +849,19 @@ public class GattService extends ProfileService {
+ ", status=" + status);
ClientMap.App app = mClientMap.getByConnId(connId);
- if (app != null) {
+ if (app == null) return;
+
+ if (!app.isCongested) {
app.callback.onCharacteristicWrite(address, status, srvcType,
- srvcInstId, new ParcelUuid(srvcUuid),
- charInstId, new ParcelUuid(charUuid));
+ srvcInstId, new ParcelUuid(srvcUuid),
+ charInstId, new ParcelUuid(charUuid));
+ } else {
+ if (status == BluetoothGatt.GATT_CONNECTION_CONGESTED) {
+ status = BluetoothGatt.GATT_SUCCESS;
+ }
+ CallbackInfo callbackInfo = new CallbackInfo(address, status, srvcType,
+ srvcInstId, srvcUuid, charInstId, charUuid);
+ app.queueCallback(callbackInfo);
}
}
@@ -1213,11 +1222,20 @@ public class GattService extends ProfileService {
}
void onClientCongestion(int connId, boolean congested) throws RemoteException {
- if (DBG) Log.d(TAG, "onClientCongestion() - connId=" + connId + ", congested=" + congested);
+ if (VDBG) Log.d(TAG, "onClientCongestion() - connId=" + connId + ", congested=" + congested);
ClientMap.App app = mClientMap.getByConnId(connId);
+
if (app != null) {
- app.callback.onConnectionCongested(mClientMap.addressByConnId(connId), congested);
+ app.isCongested = congested;
+ while(!app.isCongested) {
+ CallbackInfo callbackInfo = app.popQueuedCallback();
+ if (callbackInfo == null) return;
+ app.callback.onCharacteristicWrite(callbackInfo.address,
+ callbackInfo.status, callbackInfo.srvcType,
+ callbackInfo.srvcInstId, new ParcelUuid(callbackInfo.srvcUuid),
+ callbackInfo.charInstId, new ParcelUuid(callbackInfo.charUuid));
+ }
}
}
@@ -1783,15 +1801,27 @@ public class GattService extends ProfileService {
ServerMap.App app = mServerMap.getByConnId(connId);
if (app == null) return;
- app.callback.onNotificationSent(address, status);
+ if (!app.isCongested) {
+ app.callback.onNotificationSent(address, status);
+ } else {
+ if (status == BluetoothGatt.GATT_CONNECTION_CONGESTED) {
+ status = BluetoothGatt.GATT_SUCCESS;
+ }
+ app.queueCallback(new CallbackInfo(address, status));
+ }
}
void onServerCongestion(int connId, boolean congested) throws RemoteException {
if (DBG) Log.d(TAG, "onServerCongestion() - connId=" + connId + ", congested=" + congested);
ServerMap.App app = mServerMap.getByConnId(connId);
- if (app != null) {
- app.callback.onConnectionCongested(mServerMap.addressByConnId(connId), congested);
+ if (app == null) return;
+
+ app.isCongested = congested;
+ while(!app.isCongested) {
+ CallbackInfo callbackInfo = app.popQueuedCallback();
+ if (callbackInfo == null) return;
+ app.callback.onNotificationSent(callbackInfo.address, callbackInfo.status);
}
}