Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0dcff17b authored by Andre Eisenbach's avatar Andre Eisenbach Committed by Andre Eisenbach
Browse files

LE: Add notification sent and congestion callbacks (4/4)

This change introduces two new callbacks for applications to better
handle LE notification flow control and transport congestion. The
notification callback is invoked when the remote platform confirms an
indication or when a local notification has been passed to the
controller. No new notifications should be sent until a callback is
received.

Congestion callbacks are triggered when a GATT operation cannot be sent
to the local Bluetooth controller. Repeatedly calling
writeCharacteristic() for example will eventually trigger a congestion
callback. Applications cannot send additional data until a further
callback is received, indicating that the congestion has cleared up.

Change-Id: Ifa8de9c12d8d487e28fb5a1a5e05150a7fec90cb
parent b71a7f3f
Loading
Loading
Loading
Loading
+33 −2
Original line number Diff line number Diff line
@@ -165,6 +165,7 @@ static jmethodID method_onMultiAdvEnable;
static jmethodID method_onMultiAdvUpdate;
static jmethodID method_onMultiAdvSetAdvData;
static jmethodID method_onMultiAdvDisable;
static jmethodID method_onClientCongestion;

/**
 * Server callback methods
@@ -182,6 +183,8 @@ static jmethodID method_onResponseSendCompleted;
static jmethodID method_onAttributeRead;
static jmethodID method_onAttributeWrite;
static jmethodID method_onExecuteWrite;
static jmethodID method_onNotificationSent;
static jmethodID method_onServerCongestion;

/**
 * Static variables
@@ -480,6 +483,13 @@ void btgattc_multiadv_disable_cb(int client_if, int status)
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgattc_congestion_cb(int conn_id, bool congested)
{
    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientCongestion, conn_id, congested);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

static const btgatt_client_callbacks_t sGattClientCallbacks = {
    btgattc_register_app_cb,
    btgattc_scan_result_cb,
@@ -504,7 +514,8 @@ static const btgatt_client_callbacks_t sGattClientCallbacks = {
    btgattc_multiadv_enable_cb,
    btgattc_multiadv_update_cb,
    btgattc_multiadv_setadv_data_cb,
    btgattc_multiadv_disable_cb
    btgattc_multiadv_disable_cb,
    btgattc_congestion_cb
};


@@ -668,6 +679,21 @@ void btgatts_response_confirmation_cb(int status, int handle)
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgatts_indication_sent_cb(int conn_id, int status)
{
    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNotificationSent,
                                 conn_id, status);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgatts_congestion_cb(int conn_id, bool congested)
{
    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerCongestion, conn_id, congested);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

static const btgatt_server_callbacks_t sGattServerCallbacks = {
    btgatts_register_app_cb,
    btgatts_connection_cb,
@@ -681,7 +707,9 @@ static const btgatt_server_callbacks_t sGattServerCallbacks = {
    btgatts_request_read_cb,
    btgatts_request_write_cb,
    btgatts_request_exec_write_cb,
    btgatts_response_confirmation_cb
    btgatts_response_confirmation_cb,
    btgatts_indication_sent_cb,
    btgatts_congestion_cb
};

/**
@@ -726,6 +754,7 @@ static void classInitNative(JNIEnv* env, jclass clazz) {
    method_onMultiAdvUpdate = env->GetMethodID(clazz, "onClientUpdate", "(II)V");
    method_onMultiAdvSetAdvData = env->GetMethodID(clazz, "onClientData", "(II)V");
    method_onMultiAdvDisable = env->GetMethodID(clazz, "onClientDisable", "(II)V");
    method_onClientCongestion = env->GetMethodID(clazz, "onClientCongestion", "(IZ)V");

     // Server callbacks

@@ -742,6 +771,8 @@ static void classInitNative(JNIEnv* env, jclass clazz) {
    method_onAttributeRead= env->GetMethodID(clazz, "onAttributeRead", "(Ljava/lang/String;IIIIZ)V");
    method_onAttributeWrite= env->GetMethodID(clazz, "onAttributeWrite", "(Ljava/lang/String;IIIIIZZ[B)V");
    method_onExecuteWrite= env->GetMethodID(clazz, "onExecuteWrite", "(Ljava/lang/String;III)V");
    method_onNotificationSent = env->GetMethodID(clazz, "onNotificationSent", "(II)V");
    method_onServerCongestion = env->GetMethodID(clazz, "onServerCongestion", "(IZ)V");

    info("classInitNative: Success!");
}
+30 −0
Original line number Diff line number Diff line
@@ -1150,6 +1150,15 @@ public class GattService extends ProfileService {
        }
    }

    void onClientCongestion(int connId, boolean congested) throws RemoteException {
        if (DBG) Log.d(TAG, "onClientCongestion() - connId=" + connId + ", congested=" + congested);

        ClientMap.App app = mClientMap.getByConnId(connId);
        if (app != null) {
            app.callback.onConnectionCongested(mClientMap.addressByConnId(connId), congested);
        }
    }

    /**************************************************************************
     * GATT Service functions - Shared CLIENT/SERVER
     *************************************************************************/
@@ -1938,6 +1947,27 @@ public class GattService extends ProfileService {
        if (DBG) Log.d(TAG, "onResponseSendCompleted() handle=" + attrHandle);
    }

    void onNotificationSent(int connId, int status) throws RemoteException {
        if (DBG) Log.d(TAG, "onNotificationSent() connId=" + connId + ", status=" + status);

        String address = mServerMap.addressByConnId(connId);
        if (address == null) return;

        ServerMap.App app = mServerMap.getByConnId(connId);
        if (app == null) return;

        app.callback.onNotificationSent(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);
        }
    }

    /**************************************************************************
     * GATT Service functions - SERVER
     *************************************************************************/