diff options
-rw-r--r-- | src/com/android/bluetooth/gatt/CallbackInfo.java | 52 | ||||
-rw-r--r-- | src/com/android/bluetooth/gatt/ContextMap.java | 15 | ||||
-rw-r--r-- | src/com/android/bluetooth/gatt/GattService.java | 46 |
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); } } |