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

Commit 2677fd7c authored by Jakub Pawlowski's avatar Jakub Pawlowski Committed by android-build-merger
Browse files

Merge "Bluetooth 5 AdvertisingSet implementation (2/4)"

am: 73698a26

Change-Id: I718747628310e4a9af5b580e0a9752c0194fbb28
parents b87e2d5a 73698a26
Loading
Loading
Loading
Loading
+156 −7
Original line number Diff line number Diff line
@@ -118,6 +118,14 @@ static jstring bdaddr2newjstr(JNIEnv* env, bt_bdaddr_t* bda) {
  return env->NewStringUTF(c_address);
}

static std::vector<uint8_t> toVector(JNIEnv* env, jbyteArray ba) {
  jbyte* data_data = env->GetByteArrayElements(ba, NULL);
  uint16_t data_len = (uint16_t)env->GetArrayLength(ba);
  std::vector<uint8_t> data_vec(data_data, data_data + data_len);
  env->ReleaseByteArrayElements(ba, data_data, JNI_ABORT);
  return data_vec;
}

namespace android {

/**
@@ -176,7 +184,13 @@ static jmethodID method_onServerMtuChanged;
 * Advertiser callback methods
 */
static jmethodID method_onAdvertisingSetStarted;
static jmethodID method_onAdvertisingSetEnabled;
static jmethodID method_onAdvertisingEnabled;
static jmethodID method_onAdvertisingDataSet;
static jmethodID method_onScanResponseDataSet;
static jmethodID method_onAdvertisingParametersUpdated;
static jmethodID method_onPeriodicAdvertisingParametersUpdated;
static jmethodID method_onPeriodicAdvertisingDataSet;
static jmethodID method_onPeriodicAdvertisingEnable;

/**
 * Static variables
@@ -1545,9 +1559,21 @@ static void gattServerSendResponseNative(JNIEnv* env, jobject object,

static void advertiseClassInitNative(JNIEnv* env, jclass clazz) {
  method_onAdvertisingSetStarted =
      env->GetMethodID(clazz, "onAdvertisingSetStarted", "(III)V");
  method_onAdvertisingSetEnabled =
      env->GetMethodID(clazz, "onAdvertisingSetEnabled", "(IZI)V");
      env->GetMethodID(clazz, "onAdvertisingSetStarted", "(IIII)V");
  method_onAdvertisingEnabled =
      env->GetMethodID(clazz, "onAdvertisingEnabled", "(IZI)V");
  method_onAdvertisingDataSet =
      env->GetMethodID(clazz, "onAdvertisingDataSet", "(II)V");
  method_onScanResponseDataSet =
      env->GetMethodID(clazz, "onScanResponseDataSet", "(II)V");
  method_onAdvertisingParametersUpdated =
      env->GetMethodID(clazz, "onAdvertisingParametersUpdated", "(III)V");
  method_onPeriodicAdvertisingParametersUpdated = env->GetMethodID(
      clazz, "onPeriodicAdvertisingParametersUpdated", "(II)V");
  method_onPeriodicAdvertisingDataSet =
      env->GetMethodID(clazz, "onPeriodicAdvertisingDataSet", "(II)V");
  method_onPeriodicAdvertisingEnable =
      env->GetMethodID(clazz, "onPeriodicAdvertisingEnable", "(IZI)V");
}

static void advertiseInitializeNative(JNIEnv* env, jobject object) {
@@ -1638,12 +1664,12 @@ static PeriodicAdvertisingParameters parsePeriodicParams(JNIEnv* env,
}

static void ble_advertising_set_started_cb(int reg_id, uint8_t advertiser_id,
                                           uint8_t status) {
                                           int8_t tx_power, uint8_t status) {
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj,
                               method_onAdvertisingSetStarted, reg_id,
                               advertiser_id, status);
                               advertiser_id, tx_power, status);
}

static void ble_advertising_set_timeout_cb(uint8_t advertiser_id,
@@ -1651,7 +1677,7 @@ static void ble_advertising_set_timeout_cb(uint8_t advertiser_id,
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj,
                               method_onAdvertisingSetEnabled, advertiser_id,
                               method_onAdvertisingEnabled, advertiser_id,
                               false, status);
}

@@ -1700,6 +1726,116 @@ static void stopAdvertisingSetNative(JNIEnv* env, jobject object,
  sGattIf->advertiser->Unregister(advertiser_id);
}

static void callJniCallback(jmethodID method, uint8_t advertiser_id,
                            uint8_t status) {
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj, method, advertiser_id,
                               status);
}

static void enableSetCb(uint8_t advertiser_id, bool enable, uint8_t status) {
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj,
                               method_onAdvertisingEnabled, advertiser_id,
                               enable, status);
}

static void enableAdvertisingSetNative(JNIEnv* env, jobject object,
                                       jint advertiser_id, jboolean enable,
                                       jint timeout) {
  if (!sGattIf) return;

  sGattIf->advertiser->Enable(
      advertiser_id, enable, base::Bind(&enableSetCb, advertiser_id, enable),
      timeout / 1000, base::Bind(&enableSetCb, advertiser_id, false));
}

static void setAdvertisingDataNative(JNIEnv* env, jobject object,
                                     jint advertiser_id, jbyteArray data) {
  if (!sGattIf) return;

  sGattIf->advertiser->SetData(
      advertiser_id, false, toVector(env, data),
      base::Bind(&callJniCallback, method_onAdvertisingDataSet, advertiser_id));
}

static void setScanResponseDataNative(JNIEnv* env, jobject object,
                                      jint advertiser_id, jbyteArray data) {
  if (!sGattIf) return;

  sGattIf->advertiser->SetData(
      advertiser_id, true, toVector(env, data),
      base::Bind(&callJniCallback, method_onScanResponseDataSet,
                 advertiser_id));
}

static void setAdvertisingParametersNativeCb(uint8_t advertiser_id,
                                             uint8_t status, int8_t tx_power) {
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  sCallbackEnv->CallVoidMethod(mCallbacksObj,
                               method_onAdvertisingParametersUpdated,
                               advertiser_id, tx_power, status);
}

static void setAdvertisingParametersNative(JNIEnv* env, jobject object,
                                           jint advertiser_id,
                                           jobject parameters) {
  if (!sGattIf) return;

  // TODO: must learn somehow wether scan response is set ?
  AdvertiseParameters params =
      parseParams(env, parameters, false /*TODO: put proper value here!!!*/);
  sGattIf->advertiser->SetParameters(
      advertiser_id, params,
      base::Bind(setAdvertisingParametersNativeCb, advertiser_id));
}

static void setPeriodicAdvertisingParametersNative(
    JNIEnv* env, jobject object, jint advertiser_id,
    jobject periodic_parameters) {
  if (!sGattIf) return;

  PeriodicAdvertisingParameters periodicParams =
      parsePeriodicParams(env, periodic_parameters);
  sGattIf->advertiser->SetPeriodicAdvertisingParameters(
      advertiser_id, periodicParams,
      base::Bind(&callJniCallback,
                 method_onPeriodicAdvertisingParametersUpdated, advertiser_id));
}

static void setPeriodicAdvertisingDataNative(JNIEnv* env, jobject object,
                                             jint advertiser_id,
                                             jbyteArray data) {
  if (!sGattIf) return;

  sGattIf->advertiser->SetPeriodicAdvertisingData(
      advertiser_id, toVector(env, data),
      base::Bind(&callJniCallback, method_onPeriodicAdvertisingDataSet,
                 advertiser_id));
}

static void enablePeriodicSetCb(uint8_t advertiser_id, bool enable,
                                uint8_t status) {
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  sCallbackEnv->CallVoidMethod(mCallbacksObj,
                               method_onPeriodicAdvertisingEnable,
                               advertiser_id, enable, status);
}

static void setPeriodicAdvertisingEnableNative(JNIEnv* env, jobject object,
                                               jint advertiser_id,
                                               jboolean enable) {
  if (!sGattIf) return;

  sGattIf->advertiser->SetPeriodicAdvertisingEnable(
      advertiser_id, enable,
      base::Bind(&enablePeriodicSetCb, advertiser_id, enable));
}

static void gattTestNative(JNIEnv* env, jobject object, jint command,
                           jlong uuid1_lsb, jlong uuid1_msb, jstring bda1,
                           jint p1, jint p2, jint p3, jint p4, jint p5) {
@@ -1736,6 +1872,19 @@ static JNINativeMethod sAdvertiseMethods[] = {
     "le/PeriodicAdvertisingParameters;[BII)V",
     (void*)startAdvertisingSetNative},
    {"stopAdvertisingSetNative", "(I)V", (void*)stopAdvertisingSetNative},
    {"enableAdvertisingSetNative", "(IZI)V", (void*)enableAdvertisingSetNative},
    {"setAdvertisingDataNative", "(I[B)V", (void*)setAdvertisingDataNative},
    {"setScanResponseDataNative", "(I[B)V", (void*)setScanResponseDataNative},
    {"setAdvertisingParametersNative",
     "(ILandroid/bluetooth/le/AdvertisingSetParameters;)V",
     (void*)setAdvertisingParametersNative},
    {"setPeriodicAdvertisingParametersNative",
     "(ILandroid/bluetooth/le/PeriodicAdvertisingParameters;)V",
     (void*)setPeriodicAdvertisingParametersNative},
    {"setPeriodicAdvertisingDataNative", "(I[B)V",
     (void*)setPeriodicAdvertisingDataNative},
    {"setPeriodicAdvertisingEnableNative", "(IZ)V",
     (void*)setPeriodicAdvertisingEnableNative},
};

// JNI functions defined in ScanManager class.
+132 −4
Original line number Diff line number Diff line
@@ -134,7 +134,8 @@ class AdvertiseManager {
        return entry;
    }

    void onAdvertisingSetStarted(int reg_id, int advertiser_id, int status) throws Exception {
    void onAdvertisingSetStarted(int reg_id, int advertiser_id, int tx_power, int status)
            throws Exception {
        if (DBG)
            Log.d(TAG, "onAdvertisingSetStarted() - reg_id=" + reg_id + ", advertiser_id="
                            + advertiser_id + ", status=" + status);
@@ -158,10 +159,10 @@ class AdvertiseManager {
            mAdvertisers.remove(binder);
        }

        callback.onAdvertisingSetStarted(advertiser_id, status);
        callback.onAdvertisingSetStarted(advertiser_id, tx_power, status);
    }

    void onAdvertisingSetEnabled(int advertiser_id, boolean enable, int status) throws Exception {
    void onAdvertisingEnabled(int advertiser_id, boolean enable, int status) throws Exception {
        logd("onAdvertisingSetEnabled() - advertiser_id=" + advertiser_id + ", enable=" + enable
                + ", status=" + status);

@@ -222,6 +223,125 @@ class AdvertiseManager {
        stopAdvertisingSetNative(advertiser_id);
    }

    void enableAdvertisingSet(int advertiserId, boolean enable, int timeout) {
        enableAdvertisingSetNative(advertiserId, enable, timeout);
    }

    void setAdvertisingData(int advertiserId, AdvertiseData data) {
        String deviceName = AdapterService.getAdapterService().getName();
        setAdvertisingDataNative(
                advertiserId, AdvertiseHelper.advertiseDataToBytes(data, deviceName));
    }

    void setScanResponseData(int advertiserId, AdvertiseData data) {
        String deviceName = AdapterService.getAdapterService().getName();
        setScanResponseDataNative(
                advertiserId, AdvertiseHelper.advertiseDataToBytes(data, deviceName));
    }

    void setAdvertisingParameters(int advertiserId, AdvertisingSetParameters parameters) {
        setAdvertisingParametersNative(advertiserId, parameters);
    }

    void setPeriodicAdvertisingParameters(
            int advertiserId, PeriodicAdvertisingParameters parameters) {
        setPeriodicAdvertisingParametersNative(advertiserId, parameters);
    }

    void setPeriodicAdvertisingData(int advertiserId, AdvertiseData data) {
        String deviceName = AdapterService.getAdapterService().getName();
        setPeriodicAdvertisingDataNative(
                advertiserId, AdvertiseHelper.advertiseDataToBytes(data, deviceName));
    }

    void setPeriodicAdvertisingEnable(int advertiserId, boolean enable) {
        setPeriodicAdvertisingEnableNative(advertiserId, enable);
    }

    void onAdvertisingDataSet(int advertiser_id, int status) throws Exception {
        logd("onAdvertisingDataSet() advertiser_id=" + advertiser_id + ", status=" + status);

        Map.Entry<IBinder, AdvertiserInfo> entry = findAdvertiser(advertiser_id);
        if (entry == null) {
            Log.i(TAG, "onAdvertisingDataSet() - bad advertiser_id " + advertiser_id);
            return;
        }

        IAdvertisingSetCallback callback = entry.getValue().callback;
        callback.onAdvertisingDataSet(advertiser_id, status);
    }

    void onScanResponseDataSet(int advertiser_id, int status) throws Exception {
        logd("onScanResponseDataSet() advertiser_id=" + advertiser_id + ", status=" + status);

        Map.Entry<IBinder, AdvertiserInfo> entry = findAdvertiser(advertiser_id);
        if (entry == null) {
            Log.i(TAG, "onScanResponseDataSet() - bad advertiser_id " + advertiser_id);
            return;
        }

        IAdvertisingSetCallback callback = entry.getValue().callback;
        callback.onScanResponseDataSet(advertiser_id, status);
    }

    void onAdvertisingParametersUpdated(int advertiser_id, int tx_power, int status)
            throws Exception {
        logd("onAdvertisingParametersUpdated() advertiser_id=" + advertiser_id + ", tx_power="
                + tx_power + ", status=" + status);

        Map.Entry<IBinder, AdvertiserInfo> entry = findAdvertiser(advertiser_id);
        if (entry == null) {
            Log.i(TAG, "onAdvertisingParametersUpdated() - bad advertiser_id " + advertiser_id);
            return;
        }

        IAdvertisingSetCallback callback = entry.getValue().callback;
        callback.onAdvertisingParametersUpdated(advertiser_id, tx_power, status);
    }

    void onPeriodicAdvertisingParametersUpdated(int advertiser_id, int status) throws Exception {
        logd("onPeriodicAdvertisingParametersUpdated() advertiser_id=" + advertiser_id + ", status="
                + status);

        Map.Entry<IBinder, AdvertiserInfo> entry = findAdvertiser(advertiser_id);
        if (entry == null) {
            Log.i(TAG, "onPeriodicAdvertisingParametersUpdated() - bad advertiser_id "
                            + advertiser_id);
            return;
        }

        IAdvertisingSetCallback callback = entry.getValue().callback;
        callback.onPeriodicAdvertisingParametersUpdated(advertiser_id, status);
    }

    void onPeriodicAdvertisingDataSet(int advertiser_id, int status) throws Exception {
        logd("onPeriodicAdvertisingDataSet() advertiser_id=" + advertiser_id + ", status="
                + status);

        Map.Entry<IBinder, AdvertiserInfo> entry = findAdvertiser(advertiser_id);
        if (entry == null) {
            Log.i(TAG, "onPeriodicAdvertisingDataSet() - bad advertiser_id " + advertiser_id);
            return;
        }

        IAdvertisingSetCallback callback = entry.getValue().callback;
        callback.onPeriodicAdvertisingDataSet(advertiser_id, status);
    }

    void onPeriodicAdvertisingEnable(int advertiser_id, boolean enable, int status)
            throws Exception {
        logd("onPeriodicAdvertisingEnable() advertiser_id=" + advertiser_id + ", status=" + status);

        Map.Entry<IBinder, AdvertiserInfo> entry = findAdvertiser(advertiser_id);
        if (entry == null) {
            Log.i(TAG, "onAdvertisingSetEnable() - bad advertiser_id " + advertiser_id);
            return;
        }

        IAdvertisingSetCallback callback = entry.getValue().callback;
        callback.onPeriodicAdvertisingEnable(advertiser_id, enable, status);
    }

    private void logd(String s) {
        if (DBG) {
            Log.d(TAG, s);
@@ -239,6 +359,14 @@ class AdvertiseManager {
            byte[] advertiseData, byte[] scanResponse,
            PeriodicAdvertisingParameters periodicParameters, byte[] periodicData, int timeout,
            int reg_id);

    private native void stopAdvertisingSetNative(int advertiser_id);
    private native void enableAdvertisingSetNative(int advertiserId, boolean enable, int timeout);
    private native void setAdvertisingDataNative(int advertiserId, byte[] data);
    private native void setScanResponseDataNative(int advertiserId, byte[] data);
    private native void setAdvertisingParametersNative(
            int advertiserId, AdvertisingSetParameters parameters);
    private native void setPeriodicAdvertisingParametersNative(
            int advertiserId, PeriodicAdvertisingParameters parameters);
    private native void setPeriodicAdvertisingDataNative(int advertiserId, byte[] data);
    private native void setPeriodicAdvertisingEnableNative(int advertiserId, boolean enable);
}
+45 −11
Original line number Diff line number Diff line
@@ -559,48 +559,48 @@ public class GattService extends ProfileService {
            service.stopAdvertisingSet(callback);
        }

        public void enableAdverisingSet(int advertiserId, boolean enable, int timeout) {
        public void enableAdvertisingSet(int advertiserId, boolean enable, int timeout) {
            GattService service = getService();
            if (service == null) return;
            // TODO: implement
            service.enableAdvertisingSet(advertiserId, enable, timeout);
        }

        public void setAdvertisingData(int advertiserId, AdvertiseData data) {
            GattService service = getService();
            if (service == null) return;
            // TODO: implement
            service.setAdvertisingData(advertiserId, data);
        }

        public void setScanResponseData(int advertiserId, AdvertiseData data) {
            GattService service = getService();
            if (service == null) return;
            // TODO: implement
            service.setScanResponseData(advertiserId, data);
        }

        public void setAdvertisingParameters(
                int advertiserId, AdvertisingSetParameters parameters) {
            GattService service = getService();
            if (service == null) return;
            // TODO: implement
            service.setAdvertisingParameters(advertiserId, parameters);
        }

        public void setPeriodicAdvertisingParameters(
                int advertiserId, PeriodicAdvertisingParameters parameters) {
            GattService service = getService();
            if (service == null) return;
            // TODO: implement
            service.setPeriodicAdvertisingParameters(advertiserId, parameters);
        }

        public void setPeriodicAdvertisingData(int advertiserId, AdvertiseData data) {
            GattService service = getService();
            if (service == null) return;
            // TODO: implement
            service.setPeriodicAdvertisingData(advertiserId, data);
        }

        public void periodicAdvertisingEnable(int advertiserId, boolean enable) {
        public void setPeriodicAdvertisingEnable(int advertiserId, boolean enable) {
            GattService service = getService();
            if (service == null) return;
            // TODO: implement
            service.setPeriodicAdvertisingEnable(advertiserId, enable);
        }

        @Override
@@ -1423,17 +1423,51 @@ public class GattService extends ProfileService {
            AdvertiseData scanResponse, PeriodicAdvertisingParameters periodicParameters,
            AdvertiseData periodicData, int timeout, IAdvertisingSetCallback callback) {
        enforceAdminPermission();

        mAdvertiseManager.startAdvertisingSet(parameters, advertiseData, scanResponse,
                periodicParameters, periodicData, timeout, callback);
    }

    void stopAdvertisingSet(IAdvertisingSetCallback callback) {
        enforceAdminPermission();

        mAdvertiseManager.stopAdvertisingSet(callback);
    }

    void enableAdvertisingSet(int advertiserId, boolean enable, int timeout) {
        enforceAdminPermission();
        mAdvertiseManager.enableAdvertisingSet(advertiserId, enable, timeout);
    }

    void setAdvertisingData(int advertiserId, AdvertiseData data) {
        enforceAdminPermission();
        mAdvertiseManager.setAdvertisingData(advertiserId, data);
    }

    void setScanResponseData(int advertiserId, AdvertiseData data) {
        enforceAdminPermission();
        mAdvertiseManager.setScanResponseData(advertiserId, data);
    }

    void setAdvertisingParameters(int advertiserId, AdvertisingSetParameters parameters) {
        enforceAdminPermission();
        mAdvertiseManager.setAdvertisingParameters(advertiserId, parameters);
    }

    void setPeriodicAdvertisingParameters(
            int advertiserId, PeriodicAdvertisingParameters parameters) {
        enforceAdminPermission();
        mAdvertiseManager.setPeriodicAdvertisingParameters(advertiserId, parameters);
    }

    void setPeriodicAdvertisingData(int advertiserId, AdvertiseData data) {
        enforceAdminPermission();
        mAdvertiseManager.setPeriodicAdvertisingData(advertiserId, data);
    }

    void setPeriodicAdvertisingEnable(int advertiserId, boolean enable) {
        enforceAdminPermission();
        mAdvertiseManager.setPeriodicAdvertisingEnable(advertiserId, enable);
    }

    /**************************************************************************
     * GATT Service functions - CLIENT
     *************************************************************************/