Home | History | Annotate | Download | only in jni
      1 /*
      2  * Copyright (C) 2013 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #define LOG_TAG "BtGatt.JNI"
     18 
     19 #define LOG_NDEBUG 0
     20 
     21 #include "android_runtime/AndroidRuntime.h"
     22 #include "com_android_bluetooth.h"
     23 #include "hardware/bt_gatt.h"
     24 #include "utils/Log.h"
     25 
     26 #include <base/bind.h>
     27 #include <string.h>
     28 #include <memory>
     29 
     30 #include <cutils/log.h>
     31 #define info(fmt, ...) ALOGI("%s(L%d): " fmt, __func__, __LINE__, ##__VA_ARGS__)
     32 #define debug(fmt, ...) \
     33   ALOGD("%s(L%d): " fmt, __func__, __LINE__, ##__VA_ARGS__)
     34 #define warn(fmt, ...) \
     35   ALOGW("WARNING: %s(L%d): " fmt "##", __func__, __LINE__, ##__VA_ARGS__)
     36 #define error(fmt, ...) \
     37   ALOGE("ERROR: %s(L%d): " fmt "##", __func__, __LINE__, ##__VA_ARGS__)
     38 #define asrt(s) \
     39   if (!(s)) ALOGE("%s(L%d): ASSERT %s failed! ##", __func__, __LINE__, #s)
     40 
     41 #define BD_ADDR_LEN 6
     42 
     43 #define UUID_PARAMS(uuid) uuid_lsb(uuid), uuid_msb(uuid)
     44 
     45 static void set_uuid(uint8_t* uuid, jlong uuid_msb, jlong uuid_lsb) {
     46   for (int i = 0; i != 8; ++i) {
     47     uuid[i] = (uuid_lsb >> (8 * i)) & 0xFF;
     48     uuid[i + 8] = (uuid_msb >> (8 * i)) & 0xFF;
     49   }
     50 }
     51 
     52 static uint64_t uuid_lsb(const bt_uuid_t& uuid) {
     53   uint64_t lsb = 0;
     54 
     55   for (int i = 7; i >= 0; i--) {
     56     lsb <<= 8;
     57     lsb |= uuid.uu[i];
     58   }
     59 
     60   return lsb;
     61 }
     62 
     63 static uint64_t uuid_msb(const bt_uuid_t& uuid) {
     64   uint64_t msb = 0;
     65 
     66   for (int i = 15; i >= 8; i--) {
     67     msb <<= 8;
     68     msb |= uuid.uu[i];
     69   }
     70 
     71   return msb;
     72 }
     73 
     74 static RawAddress str2addr(JNIEnv* env, jstring address) {
     75   RawAddress bd_addr;
     76   const char* c_address = env->GetStringUTFChars(address, NULL);
     77   if (!c_address) return bd_addr;
     78 
     79   RawAddress::FromString(std::string(c_address), bd_addr);
     80   env->ReleaseStringUTFChars(address, c_address);
     81 
     82   return bd_addr;
     83 }
     84 
     85 static jstring bdaddr2newjstr(JNIEnv* env, const RawAddress* bda) {
     86   char c_address[32];
     87   snprintf(c_address, sizeof(c_address), "%02X:%02X:%02X:%02X:%02X:%02X",
     88            bda->address[0], bda->address[1], bda->address[2], bda->address[3],
     89            bda->address[4], bda->address[5]);
     90 
     91   return env->NewStringUTF(c_address);
     92 }
     93 
     94 static std::vector<uint8_t> toVector(JNIEnv* env, jbyteArray ba) {
     95   jbyte* data_data = env->GetByteArrayElements(ba, NULL);
     96   uint16_t data_len = (uint16_t)env->GetArrayLength(ba);
     97   std::vector<uint8_t> data_vec(data_data, data_data + data_len);
     98   env->ReleaseByteArrayElements(ba, data_data, JNI_ABORT);
     99   return data_vec;
    100 }
    101 
    102 namespace android {
    103 
    104 /**
    105  * Client callback methods
    106  */
    107 
    108 static jmethodID method_onClientRegistered;
    109 static jmethodID method_onScannerRegistered;
    110 static jmethodID method_onScanResult;
    111 static jmethodID method_onConnected;
    112 static jmethodID method_onDisconnected;
    113 static jmethodID method_onReadCharacteristic;
    114 static jmethodID method_onWriteCharacteristic;
    115 static jmethodID method_onExecuteCompleted;
    116 static jmethodID method_onSearchCompleted;
    117 static jmethodID method_onReadDescriptor;
    118 static jmethodID method_onWriteDescriptor;
    119 static jmethodID method_onNotify;
    120 static jmethodID method_onRegisterForNotifications;
    121 static jmethodID method_onReadRemoteRssi;
    122 static jmethodID method_onConfigureMTU;
    123 static jmethodID method_onScanFilterConfig;
    124 static jmethodID method_onScanFilterParamsConfigured;
    125 static jmethodID method_onScanFilterEnableDisabled;
    126 static jmethodID method_onClientCongestion;
    127 static jmethodID method_onBatchScanStorageConfigured;
    128 static jmethodID method_onBatchScanStartStopped;
    129 static jmethodID method_onBatchScanReports;
    130 static jmethodID method_onBatchScanThresholdCrossed;
    131 
    132 static jmethodID method_CreateonTrackAdvFoundLostObject;
    133 static jmethodID method_onTrackAdvFoundLost;
    134 static jmethodID method_onScanParamSetupCompleted;
    135 static jmethodID method_getSampleGattDbElement;
    136 static jmethodID method_onGetGattDb;
    137 static jmethodID method_onClientPhyUpdate;
    138 static jmethodID method_onClientPhyRead;
    139 static jmethodID method_onClientConnUpdate;
    140 
    141 /**
    142  * Server callback methods
    143  */
    144 static jmethodID method_onServerRegistered;
    145 static jmethodID method_onClientConnected;
    146 static jmethodID method_onServiceAdded;
    147 static jmethodID method_onServiceStopped;
    148 static jmethodID method_onServiceDeleted;
    149 static jmethodID method_onResponseSendCompleted;
    150 static jmethodID method_onServerReadCharacteristic;
    151 static jmethodID method_onServerReadDescriptor;
    152 static jmethodID method_onServerWriteCharacteristic;
    153 static jmethodID method_onServerWriteDescriptor;
    154 static jmethodID method_onExecuteWrite;
    155 static jmethodID method_onNotificationSent;
    156 static jmethodID method_onServerCongestion;
    157 static jmethodID method_onServerMtuChanged;
    158 static jmethodID method_onServerPhyUpdate;
    159 static jmethodID method_onServerPhyRead;
    160 static jmethodID method_onServerConnUpdate;
    161 
    162 /**
    163  * Advertiser callback methods
    164  */
    165 static jmethodID method_onAdvertisingSetStarted;
    166 static jmethodID method_onOwnAddressRead;
    167 static jmethodID method_onAdvertisingEnabled;
    168 static jmethodID method_onAdvertisingDataSet;
    169 static jmethodID method_onScanResponseDataSet;
    170 static jmethodID method_onAdvertisingParametersUpdated;
    171 static jmethodID method_onPeriodicAdvertisingParametersUpdated;
    172 static jmethodID method_onPeriodicAdvertisingDataSet;
    173 static jmethodID method_onPeriodicAdvertisingEnabled;
    174 
    175 /**
    176  * Periodic scanner callback methods
    177  */
    178 static jmethodID method_onSyncLost;
    179 static jmethodID method_onSyncReport;
    180 static jmethodID method_onSyncStarted;
    181 
    182 /**
    183  * Static variables
    184  */
    185 
    186 static const btgatt_interface_t* sGattIf = NULL;
    187 static jobject mCallbacksObj = NULL;
    188 static jobject mAdvertiseCallbacksObj = NULL;
    189 static jobject mPeriodicScanCallbacksObj = NULL;
    190 
    191 /**
    192  * BTA client callbacks
    193  */
    194 
    195 void btgattc_register_app_cb(int status, int clientIf,
    196                              const bt_uuid_t& app_uuid) {
    197   CallbackEnv sCallbackEnv(__func__);
    198   if (!sCallbackEnv.valid()) return;
    199   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientRegistered, status,
    200                                clientIf, UUID_PARAMS(app_uuid));
    201 }
    202 
    203 void btgattc_scan_result_cb(uint16_t event_type, uint8_t addr_type,
    204                             RawAddress* bda, uint8_t primary_phy,
    205                             uint8_t secondary_phy, uint8_t advertising_sid,
    206                             int8_t tx_power, int8_t rssi,
    207                             uint16_t periodic_adv_int,
    208                             std::vector<uint8_t> adv_data) {
    209   CallbackEnv sCallbackEnv(__func__);
    210   if (!sCallbackEnv.valid()) return;
    211 
    212   ScopedLocalRef<jstring> address(sCallbackEnv.get(),
    213                                   bdaddr2newjstr(sCallbackEnv.get(), bda));
    214   ScopedLocalRef<jbyteArray> jb(sCallbackEnv.get(),
    215                                 sCallbackEnv->NewByteArray(adv_data.size()));
    216   sCallbackEnv->SetByteArrayRegion(jb.get(), 0, adv_data.size(),
    217                                    (jbyte*)adv_data.data());
    218 
    219   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScanResult, event_type,
    220                                addr_type, address.get(), primary_phy,
    221                                secondary_phy, advertising_sid, tx_power, rssi,
    222                                periodic_adv_int, jb.get());
    223 }
    224 
    225 void btgattc_open_cb(int conn_id, int status, int clientIf,
    226                      const RawAddress& bda) {
    227   CallbackEnv sCallbackEnv(__func__);
    228   if (!sCallbackEnv.valid()) return;
    229 
    230   ScopedLocalRef<jstring> address(sCallbackEnv.get(),
    231                                   bdaddr2newjstr(sCallbackEnv.get(), &bda));
    232   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnected, clientIf,
    233                                conn_id, status, address.get());
    234 }
    235 
    236 void btgattc_close_cb(int conn_id, int status, int clientIf,
    237                       const RawAddress& bda) {
    238   CallbackEnv sCallbackEnv(__func__);
    239   if (!sCallbackEnv.valid()) return;
    240 
    241   ScopedLocalRef<jstring> address(sCallbackEnv.get(),
    242                                   bdaddr2newjstr(sCallbackEnv.get(), &bda));
    243   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onDisconnected, clientIf,
    244                                conn_id, status, address.get());
    245 }
    246 
    247 void btgattc_search_complete_cb(int conn_id, int status) {
    248   CallbackEnv sCallbackEnv(__func__);
    249   if (!sCallbackEnv.valid()) return;
    250 
    251   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onSearchCompleted, conn_id,
    252                                status);
    253 }
    254 
    255 void btgattc_register_for_notification_cb(int conn_id, int registered,
    256                                           int status, uint16_t handle) {
    257   CallbackEnv sCallbackEnv(__func__);
    258   if (!sCallbackEnv.valid()) return;
    259 
    260   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onRegisterForNotifications,
    261                                conn_id, status, registered, handle);
    262 }
    263 
    264 void btgattc_notify_cb(int conn_id, const btgatt_notify_params_t& p_data) {
    265   CallbackEnv sCallbackEnv(__func__);
    266   if (!sCallbackEnv.valid()) return;
    267 
    268   ScopedLocalRef<jstring> address(
    269       sCallbackEnv.get(), bdaddr2newjstr(sCallbackEnv.get(), &p_data.bda));
    270   ScopedLocalRef<jbyteArray> jb(sCallbackEnv.get(),
    271                                 sCallbackEnv->NewByteArray(p_data.len));
    272   sCallbackEnv->SetByteArrayRegion(jb.get(), 0, p_data.len,
    273                                    (jbyte*)p_data.value);
    274 
    275   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNotify, conn_id,
    276                                address.get(), p_data.handle, p_data.is_notify,
    277                                jb.get());
    278 }
    279 
    280 void btgattc_read_characteristic_cb(int conn_id, int status,
    281                                     btgatt_read_params_t* p_data) {
    282   CallbackEnv sCallbackEnv(__func__);
    283   if (!sCallbackEnv.valid()) return;
    284 
    285   ScopedLocalRef<jbyteArray> jb(sCallbackEnv.get(), NULL);
    286   if (status == 0) {  // Success
    287     jb.reset(sCallbackEnv->NewByteArray(p_data->value.len));
    288     sCallbackEnv->SetByteArrayRegion(jb.get(), 0, p_data->value.len,
    289                                      (jbyte*)p_data->value.value);
    290   } else {
    291     uint8_t value = 0;
    292     jb.reset(sCallbackEnv->NewByteArray(1));
    293     sCallbackEnv->SetByteArrayRegion(jb.get(), 0, 1, (jbyte*)&value);
    294   }
    295 
    296   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onReadCharacteristic,
    297                                conn_id, status, p_data->handle, jb.get());
    298 }
    299 
    300 void btgattc_write_characteristic_cb(int conn_id, int status, uint16_t handle) {
    301   CallbackEnv sCallbackEnv(__func__);
    302   if (!sCallbackEnv.valid()) return;
    303 
    304   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onWriteCharacteristic,
    305                                conn_id, status, handle);
    306 }
    307 
    308 void btgattc_execute_write_cb(int conn_id, int status) {
    309   CallbackEnv sCallbackEnv(__func__);
    310   if (!sCallbackEnv.valid()) return;
    311 
    312   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onExecuteCompleted,
    313                                conn_id, status);
    314 }
    315 
    316 void btgattc_read_descriptor_cb(int conn_id, int status,
    317                                 const btgatt_read_params_t& p_data) {
    318   CallbackEnv sCallbackEnv(__func__);
    319   if (!sCallbackEnv.valid()) return;
    320 
    321   ScopedLocalRef<jbyteArray> jb(sCallbackEnv.get(), NULL);
    322   if (p_data.value.len != 0) {
    323     jb.reset(sCallbackEnv->NewByteArray(p_data.value.len));
    324     sCallbackEnv->SetByteArrayRegion(jb.get(), 0, p_data.value.len,
    325                                      (jbyte*)p_data.value.value);
    326   } else {
    327     jb.reset(sCallbackEnv->NewByteArray(1));
    328   }
    329 
    330   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onReadDescriptor, conn_id,
    331                                status, p_data.handle, jb.get());
    332 }
    333 
    334 void btgattc_write_descriptor_cb(int conn_id, int status, uint16_t handle) {
    335   CallbackEnv sCallbackEnv(__func__);
    336   if (!sCallbackEnv.valid()) return;
    337 
    338   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onWriteDescriptor, conn_id,
    339                                status, handle);
    340 }
    341 
    342 void btgattc_remote_rssi_cb(int client_if, const RawAddress& bda, int rssi,
    343                             int status) {
    344   CallbackEnv sCallbackEnv(__func__);
    345   if (!sCallbackEnv.valid()) return;
    346 
    347   ScopedLocalRef<jstring> address(sCallbackEnv.get(),
    348                                   bdaddr2newjstr(sCallbackEnv.get(), &bda));
    349 
    350   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onReadRemoteRssi,
    351                                client_if, address.get(), rssi, status);
    352 }
    353 
    354 void btgattc_configure_mtu_cb(int conn_id, int status, int mtu) {
    355   CallbackEnv sCallbackEnv(__func__);
    356   if (!sCallbackEnv.valid()) return;
    357   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConfigureMTU, conn_id,
    358                                status, mtu);
    359 }
    360 
    361 void btgattc_congestion_cb(int conn_id, bool congested) {
    362   CallbackEnv sCallbackEnv(__func__);
    363   if (!sCallbackEnv.valid()) return;
    364   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientCongestion,
    365                                conn_id, congested);
    366 }
    367 
    368 void btgattc_batchscan_reports_cb(int client_if, int status, int report_format,
    369                                   int num_records, std::vector<uint8_t> data) {
    370   CallbackEnv sCallbackEnv(__func__);
    371   if (!sCallbackEnv.valid()) return;
    372   ScopedLocalRef<jbyteArray> jb(sCallbackEnv.get(),
    373                                 sCallbackEnv->NewByteArray(data.size()));
    374   sCallbackEnv->SetByteArrayRegion(jb.get(), 0, data.size(),
    375                                    (jbyte*)data.data());
    376 
    377   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onBatchScanReports, status,
    378                                client_if, report_format, num_records, jb.get());
    379 }
    380 
    381 void btgattc_batchscan_threshold_cb(int client_if) {
    382   CallbackEnv sCallbackEnv(__func__);
    383   if (!sCallbackEnv.valid()) return;
    384   sCallbackEnv->CallVoidMethod(mCallbacksObj,
    385                                method_onBatchScanThresholdCrossed, client_if);
    386 }
    387 
    388 void btgattc_track_adv_event_cb(btgatt_track_adv_info_t* p_adv_track_info) {
    389   CallbackEnv sCallbackEnv(__func__);
    390   if (!sCallbackEnv.valid()) return;
    391 
    392   ScopedLocalRef<jstring> address(
    393       sCallbackEnv.get(),
    394       bdaddr2newjstr(sCallbackEnv.get(), &p_adv_track_info->bd_addr));
    395 
    396   ScopedLocalRef<jbyteArray> jb_adv_pkt(
    397       sCallbackEnv.get(),
    398       sCallbackEnv->NewByteArray(p_adv_track_info->adv_pkt_len));
    399   ScopedLocalRef<jbyteArray> jb_scan_rsp(
    400       sCallbackEnv.get(),
    401       sCallbackEnv->NewByteArray(p_adv_track_info->scan_rsp_len));
    402 
    403   sCallbackEnv->SetByteArrayRegion(jb_adv_pkt.get(), 0,
    404                                    p_adv_track_info->adv_pkt_len,
    405                                    (jbyte*)p_adv_track_info->p_adv_pkt_data);
    406 
    407   sCallbackEnv->SetByteArrayRegion(jb_scan_rsp.get(), 0,
    408                                    p_adv_track_info->scan_rsp_len,
    409                                    (jbyte*)p_adv_track_info->p_scan_rsp_data);
    410 
    411   ScopedLocalRef<jobject> trackadv_obj(
    412       sCallbackEnv.get(),
    413       sCallbackEnv->CallObjectMethod(
    414           mCallbacksObj, method_CreateonTrackAdvFoundLostObject,
    415           p_adv_track_info->client_if, p_adv_track_info->adv_pkt_len,
    416           jb_adv_pkt.get(), p_adv_track_info->scan_rsp_len, jb_scan_rsp.get(),
    417           p_adv_track_info->filt_index, p_adv_track_info->advertiser_state,
    418           p_adv_track_info->advertiser_info_present, address.get(),
    419           p_adv_track_info->addr_type, p_adv_track_info->tx_power,
    420           p_adv_track_info->rssi_value, p_adv_track_info->time_stamp));
    421 
    422   if (NULL != trackadv_obj.get()) {
    423     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onTrackAdvFoundLost,
    424                                  trackadv_obj.get());
    425   }
    426 }
    427 
    428 void fillGattDbElementArray(JNIEnv* env, jobject* array,
    429                             const btgatt_db_element_t* db, int count) {
    430   // Because JNI uses a different class loader in the callback context, we
    431   // cannot simply get the class.
    432   // As a workaround, we have to make sure we obtain an object of the class
    433   // first, as this will cause
    434   // class loader to load it.
    435   ScopedLocalRef<jobject> objectForClass(
    436       env, env->CallObjectMethod(mCallbacksObj, method_getSampleGattDbElement));
    437   ScopedLocalRef<jclass> gattDbElementClazz(
    438       env, env->GetObjectClass(objectForClass.get()));
    439 
    440   jmethodID gattDbElementConstructor =
    441       env->GetMethodID(gattDbElementClazz.get(), "<init>", "()V");
    442 
    443   ScopedLocalRef<jclass> arrayListclazz(env,
    444                                         env->FindClass("java/util/ArrayList"));
    445   jmethodID arrayAdd =
    446       env->GetMethodID(arrayListclazz.get(), "add", "(Ljava/lang/Object;)Z");
    447 
    448   ScopedLocalRef<jclass> uuidClazz(env, env->FindClass("java/util/UUID"));
    449   jmethodID uuidConstructor =
    450       env->GetMethodID(uuidClazz.get(), "<init>", "(JJ)V");
    451 
    452   for (int i = 0; i < count; i++) {
    453     const btgatt_db_element_t& curr = db[i];
    454 
    455     ScopedLocalRef<jobject> element(
    456         env,
    457         env->NewObject(gattDbElementClazz.get(), gattDbElementConstructor));
    458 
    459     jfieldID fid = env->GetFieldID(gattDbElementClazz.get(), "id", "I");
    460     env->SetIntField(element.get(), fid, curr.id);
    461 
    462     fid = env->GetFieldID(gattDbElementClazz.get(), "attributeHandle", "I");
    463     env->SetIntField(element.get(), fid, curr.attribute_handle);
    464 
    465     ScopedLocalRef<jobject> uuid(
    466         env, env->NewObject(uuidClazz.get(), uuidConstructor,
    467                             uuid_msb(curr.uuid), uuid_lsb(curr.uuid)));
    468     fid = env->GetFieldID(gattDbElementClazz.get(), "uuid", "Ljava/util/UUID;");
    469     env->SetObjectField(element.get(), fid, uuid.get());
    470 
    471     fid = env->GetFieldID(gattDbElementClazz.get(), "type", "I");
    472     env->SetIntField(element.get(), fid, curr.type);
    473 
    474     fid = env->GetFieldID(gattDbElementClazz.get(), "attributeHandle", "I");
    475     env->SetIntField(element.get(), fid, curr.attribute_handle);
    476 
    477     fid = env->GetFieldID(gattDbElementClazz.get(), "startHandle", "I");
    478     env->SetIntField(element.get(), fid, curr.start_handle);
    479 
    480     fid = env->GetFieldID(gattDbElementClazz.get(), "endHandle", "I");
    481     env->SetIntField(element.get(), fid, curr.end_handle);
    482 
    483     fid = env->GetFieldID(gattDbElementClazz.get(), "properties", "I");
    484     env->SetIntField(element.get(), fid, curr.properties);
    485 
    486     env->CallBooleanMethod(*array, arrayAdd, element.get());
    487   }
    488 }
    489 
    490 void btgattc_get_gatt_db_cb(int conn_id, const btgatt_db_element_t* db,
    491                             int count) {
    492   CallbackEnv sCallbackEnv(__func__);
    493   if (!sCallbackEnv.valid()) return;
    494 
    495   jclass arrayListclazz = sCallbackEnv->FindClass("java/util/ArrayList");
    496   ScopedLocalRef<jobject> array(
    497       sCallbackEnv.get(),
    498       sCallbackEnv->NewObject(
    499           arrayListclazz,
    500           sCallbackEnv->GetMethodID(arrayListclazz, "<init>", "()V")));
    501 
    502   jobject arrayPtr = array.get();
    503   fillGattDbElementArray(sCallbackEnv.get(), &arrayPtr, db, count);
    504 
    505   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onGetGattDb, conn_id,
    506                                array.get());
    507 }
    508 
    509 void btgattc_phy_updated_cb(int conn_id, uint8_t tx_phy, uint8_t rx_phy,
    510                             uint8_t status) {
    511   CallbackEnv sCallbackEnv(__func__);
    512   if (!sCallbackEnv.valid()) return;
    513 
    514   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientPhyUpdate, conn_id,
    515                                tx_phy, rx_phy, status);
    516 }
    517 
    518 void btgattc_conn_updated_cb(int conn_id, uint16_t interval, uint16_t latency,
    519                              uint16_t timeout, uint8_t status) {
    520   CallbackEnv sCallbackEnv(__func__);
    521   if (!sCallbackEnv.valid()) return;
    522 
    523   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientConnUpdate,
    524                                conn_id, interval, latency, timeout, status);
    525 }
    526 
    527 static const btgatt_scanner_callbacks_t sGattScannerCallbacks = {
    528     btgattc_scan_result_cb,
    529     btgattc_batchscan_reports_cb,
    530     btgattc_batchscan_threshold_cb,
    531     btgattc_track_adv_event_cb,
    532 };
    533 
    534 static const btgatt_client_callbacks_t sGattClientCallbacks = {
    535     btgattc_register_app_cb,
    536     btgattc_open_cb,
    537     btgattc_close_cb,
    538     btgattc_search_complete_cb,
    539     btgattc_register_for_notification_cb,
    540     btgattc_notify_cb,
    541     btgattc_read_characteristic_cb,
    542     btgattc_write_characteristic_cb,
    543     btgattc_read_descriptor_cb,
    544     btgattc_write_descriptor_cb,
    545     btgattc_execute_write_cb,
    546     btgattc_remote_rssi_cb,
    547     btgattc_configure_mtu_cb,
    548     btgattc_congestion_cb,
    549     btgattc_get_gatt_db_cb,
    550     NULL, /* services_removed_cb */
    551     NULL, /* services_added_cb */
    552     btgattc_phy_updated_cb,
    553     btgattc_conn_updated_cb};
    554 
    555 /**
    556  * BTA server callbacks
    557  */
    558 
    559 void btgatts_register_app_cb(int status, int server_if, const bt_uuid_t& uuid) {
    560   CallbackEnv sCallbackEnv(__func__);
    561   if (!sCallbackEnv.valid()) return;
    562   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerRegistered, status,
    563                                server_if, UUID_PARAMS(uuid));
    564 }
    565 
    566 void btgatts_connection_cb(int conn_id, int server_if, int connected,
    567                            const RawAddress& bda) {
    568   CallbackEnv sCallbackEnv(__func__);
    569   if (!sCallbackEnv.valid()) return;
    570 
    571   ScopedLocalRef<jstring> address(sCallbackEnv.get(),
    572                                   bdaddr2newjstr(sCallbackEnv.get(), &bda));
    573   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientConnected,
    574                                address.get(), connected, conn_id, server_if);
    575 }
    576 
    577 void btgatts_service_added_cb(int status, int server_if,
    578                               std::vector<btgatt_db_element_t> service) {
    579   CallbackEnv sCallbackEnv(__func__);
    580   if (!sCallbackEnv.valid()) return;
    581 
    582   jclass arrayListclazz = sCallbackEnv->FindClass("java/util/ArrayList");
    583   ScopedLocalRef<jobject> array(
    584       sCallbackEnv.get(),
    585       sCallbackEnv->NewObject(
    586           arrayListclazz,
    587           sCallbackEnv->GetMethodID(arrayListclazz, "<init>", "()V")));
    588   jobject arrayPtr = array.get();
    589   fillGattDbElementArray(sCallbackEnv.get(), &arrayPtr, service.data(),
    590                          service.size());
    591 
    592   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceAdded, status,
    593                                server_if, array.get());
    594 }
    595 
    596 void btgatts_service_stopped_cb(int status, int server_if, int srvc_handle) {
    597   CallbackEnv sCallbackEnv(__func__);
    598   if (!sCallbackEnv.valid()) return;
    599   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceStopped, status,
    600                                server_if, srvc_handle);
    601 }
    602 
    603 void btgatts_service_deleted_cb(int status, int server_if, int srvc_handle) {
    604   CallbackEnv sCallbackEnv(__func__);
    605   if (!sCallbackEnv.valid()) return;
    606   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceDeleted, status,
    607                                server_if, srvc_handle);
    608 }
    609 
    610 void btgatts_request_read_characteristic_cb(int conn_id, int trans_id,
    611                                             const RawAddress& bda,
    612                                             int attr_handle, int offset,
    613                                             bool is_long) {
    614   CallbackEnv sCallbackEnv(__func__);
    615   if (!sCallbackEnv.valid()) return;
    616 
    617   ScopedLocalRef<jstring> address(sCallbackEnv.get(),
    618                                   bdaddr2newjstr(sCallbackEnv.get(), &bda));
    619   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerReadCharacteristic,
    620                                address.get(), conn_id, trans_id, attr_handle,
    621                                offset, is_long);
    622 }
    623 
    624 void btgatts_request_read_descriptor_cb(int conn_id, int trans_id,
    625                                         const RawAddress& bda, int attr_handle,
    626                                         int offset, bool is_long) {
    627   CallbackEnv sCallbackEnv(__func__);
    628   if (!sCallbackEnv.valid()) return;
    629 
    630   ScopedLocalRef<jstring> address(sCallbackEnv.get(),
    631                                   bdaddr2newjstr(sCallbackEnv.get(), &bda));
    632   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerReadDescriptor,
    633                                address.get(), conn_id, trans_id, attr_handle,
    634                                offset, is_long);
    635 }
    636 
    637 void btgatts_request_write_characteristic_cb(int conn_id, int trans_id,
    638                                              const RawAddress& bda,
    639                                              int attr_handle, int offset,
    640                                              bool need_rsp, bool is_prep,
    641                                              std::vector<uint8_t> value) {
    642   CallbackEnv sCallbackEnv(__func__);
    643   if (!sCallbackEnv.valid()) return;
    644 
    645   ScopedLocalRef<jstring> address(sCallbackEnv.get(),
    646                                   bdaddr2newjstr(sCallbackEnv.get(), &bda));
    647   ScopedLocalRef<jbyteArray> val(sCallbackEnv.get(),
    648                                  sCallbackEnv->NewByteArray(value.size()));
    649   if (val.get())
    650     sCallbackEnv->SetByteArrayRegion(val.get(), 0, value.size(),
    651                                      (jbyte*)value.data());
    652   sCallbackEnv->CallVoidMethod(
    653       mCallbacksObj, method_onServerWriteCharacteristic, address.get(), conn_id,
    654       trans_id, attr_handle, offset, value.size(), need_rsp, is_prep,
    655       val.get());
    656 }
    657 
    658 void btgatts_request_write_descriptor_cb(int conn_id, int trans_id,
    659                                          const RawAddress& bda, int attr_handle,
    660                                          int offset, bool need_rsp,
    661                                          bool is_prep,
    662                                          std::vector<uint8_t> value) {
    663   CallbackEnv sCallbackEnv(__func__);
    664   if (!sCallbackEnv.valid()) return;
    665 
    666   ScopedLocalRef<jstring> address(sCallbackEnv.get(),
    667                                   bdaddr2newjstr(sCallbackEnv.get(), &bda));
    668   ScopedLocalRef<jbyteArray> val(sCallbackEnv.get(),
    669                                  sCallbackEnv->NewByteArray(value.size()));
    670   if (val.get())
    671     sCallbackEnv->SetByteArrayRegion(val.get(), 0, value.size(),
    672                                      (jbyte*)value.data());
    673   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerWriteDescriptor,
    674                                address.get(), conn_id, trans_id, attr_handle,
    675                                offset, value.size(), need_rsp, is_prep,
    676                                val.get());
    677 }
    678 
    679 void btgatts_request_exec_write_cb(int conn_id, int trans_id,
    680                                    const RawAddress& bda, int exec_write) {
    681   CallbackEnv sCallbackEnv(__func__);
    682   if (!sCallbackEnv.valid()) return;
    683 
    684   ScopedLocalRef<jstring> address(sCallbackEnv.get(),
    685                                   bdaddr2newjstr(sCallbackEnv.get(), &bda));
    686   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onExecuteWrite,
    687                                address.get(), conn_id, trans_id, exec_write);
    688 }
    689 
    690 void btgatts_response_confirmation_cb(int status, int handle) {
    691   CallbackEnv sCallbackEnv(__func__);
    692   if (!sCallbackEnv.valid()) return;
    693   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onResponseSendCompleted,
    694                                status, handle);
    695 }
    696 
    697 void btgatts_indication_sent_cb(int conn_id, int status) {
    698   CallbackEnv sCallbackEnv(__func__);
    699   if (!sCallbackEnv.valid()) return;
    700   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNotificationSent,
    701                                conn_id, status);
    702 }
    703 
    704 void btgatts_congestion_cb(int conn_id, bool congested) {
    705   CallbackEnv sCallbackEnv(__func__);
    706   if (!sCallbackEnv.valid()) return;
    707   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerCongestion,
    708                                conn_id, congested);
    709 }
    710 
    711 void btgatts_mtu_changed_cb(int conn_id, int mtu) {
    712   CallbackEnv sCallbackEnv(__func__);
    713   if (!sCallbackEnv.valid()) return;
    714   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerMtuChanged,
    715                                conn_id, mtu);
    716 }
    717 
    718 void btgatts_phy_updated_cb(int conn_id, uint8_t tx_phy, uint8_t rx_phy,
    719                             uint8_t status) {
    720   CallbackEnv sCallbackEnv(__func__);
    721   if (!sCallbackEnv.valid()) return;
    722 
    723   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerPhyUpdate, conn_id,
    724                                tx_phy, rx_phy, status);
    725 }
    726 
    727 void btgatts_conn_updated_cb(int conn_id, uint16_t interval, uint16_t latency,
    728                              uint16_t timeout, uint8_t status) {
    729   CallbackEnv sCallbackEnv(__func__);
    730   if (!sCallbackEnv.valid()) return;
    731 
    732   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerConnUpdate,
    733                                conn_id, interval, latency, timeout, status);
    734 }
    735 
    736 static const btgatt_server_callbacks_t sGattServerCallbacks = {
    737     btgatts_register_app_cb,
    738     btgatts_connection_cb,
    739     btgatts_service_added_cb,
    740     btgatts_service_stopped_cb,
    741     btgatts_service_deleted_cb,
    742     btgatts_request_read_characteristic_cb,
    743     btgatts_request_read_descriptor_cb,
    744     btgatts_request_write_characteristic_cb,
    745     btgatts_request_write_descriptor_cb,
    746     btgatts_request_exec_write_cb,
    747     btgatts_response_confirmation_cb,
    748     btgatts_indication_sent_cb,
    749     btgatts_congestion_cb,
    750     btgatts_mtu_changed_cb,
    751     btgatts_phy_updated_cb,
    752     btgatts_conn_updated_cb};
    753 
    754 /**
    755  * GATT callbacks
    756  */
    757 
    758 static const btgatt_callbacks_t sGattCallbacks = {
    759     sizeof(btgatt_callbacks_t), &sGattClientCallbacks, &sGattServerCallbacks,
    760     &sGattScannerCallbacks,
    761 };
    762 
    763 /**
    764  * Native function definitions
    765  */
    766 static void classInitNative(JNIEnv* env, jclass clazz) {
    767   // Client callbacks
    768 
    769   method_onClientRegistered =
    770       env->GetMethodID(clazz, "onClientRegistered", "(IIJJ)V");
    771   method_onScannerRegistered =
    772       env->GetMethodID(clazz, "onScannerRegistered", "(IIJJ)V");
    773   method_onScanResult = env->GetMethodID(clazz, "onScanResult",
    774                                          "(IILjava/lang/String;IIIIII[B)V");
    775   method_onConnected =
    776       env->GetMethodID(clazz, "onConnected", "(IIILjava/lang/String;)V");
    777   method_onDisconnected =
    778       env->GetMethodID(clazz, "onDisconnected", "(IIILjava/lang/String;)V");
    779   method_onReadCharacteristic =
    780       env->GetMethodID(clazz, "onReadCharacteristic", "(III[B)V");
    781   method_onWriteCharacteristic =
    782       env->GetMethodID(clazz, "onWriteCharacteristic", "(III)V");
    783   method_onExecuteCompleted =
    784       env->GetMethodID(clazz, "onExecuteCompleted", "(II)V");
    785   method_onSearchCompleted =
    786       env->GetMethodID(clazz, "onSearchCompleted", "(II)V");
    787   method_onReadDescriptor =
    788       env->GetMethodID(clazz, "onReadDescriptor", "(III[B)V");
    789   method_onWriteDescriptor =
    790       env->GetMethodID(clazz, "onWriteDescriptor", "(III)V");
    791   method_onNotify =
    792       env->GetMethodID(clazz, "onNotify", "(ILjava/lang/String;IZ[B)V");
    793   method_onRegisterForNotifications =
    794       env->GetMethodID(clazz, "onRegisterForNotifications", "(IIII)V");
    795   method_onReadRemoteRssi =
    796       env->GetMethodID(clazz, "onReadRemoteRssi", "(ILjava/lang/String;II)V");
    797   method_onConfigureMTU = env->GetMethodID(clazz, "onConfigureMTU", "(III)V");
    798   method_onScanFilterConfig =
    799       env->GetMethodID(clazz, "onScanFilterConfig", "(IIIII)V");
    800   method_onScanFilterParamsConfigured =
    801       env->GetMethodID(clazz, "onScanFilterParamsConfigured", "(IIII)V");
    802   method_onScanFilterEnableDisabled =
    803       env->GetMethodID(clazz, "onScanFilterEnableDisabled", "(III)V");
    804   method_onClientCongestion =
    805       env->GetMethodID(clazz, "onClientCongestion", "(IZ)V");
    806   method_onBatchScanStorageConfigured =
    807       env->GetMethodID(clazz, "onBatchScanStorageConfigured", "(II)V");
    808   method_onBatchScanStartStopped =
    809       env->GetMethodID(clazz, "onBatchScanStartStopped", "(III)V");
    810   method_onBatchScanReports =
    811       env->GetMethodID(clazz, "onBatchScanReports", "(IIII[B)V");
    812   method_onBatchScanThresholdCrossed =
    813       env->GetMethodID(clazz, "onBatchScanThresholdCrossed", "(I)V");
    814   method_CreateonTrackAdvFoundLostObject =
    815       env->GetMethodID(clazz, "CreateonTrackAdvFoundLostObject",
    816                        "(II[BI[BIIILjava/lang/String;IIII)Lcom/android/"
    817                        "bluetooth/gatt/AdvtFilterOnFoundOnLostInfo;");
    818   method_onTrackAdvFoundLost = env->GetMethodID(
    819       clazz, "onTrackAdvFoundLost",
    820       "(Lcom/android/bluetooth/gatt/AdvtFilterOnFoundOnLostInfo;)V");
    821   method_onScanParamSetupCompleted =
    822       env->GetMethodID(clazz, "onScanParamSetupCompleted", "(II)V");
    823   method_getSampleGattDbElement =
    824       env->GetMethodID(clazz, "GetSampleGattDbElement",
    825                        "()Lcom/android/bluetooth/gatt/GattDbElement;");
    826   method_onGetGattDb =
    827       env->GetMethodID(clazz, "onGetGattDb", "(ILjava/util/ArrayList;)V");
    828   method_onClientPhyRead =
    829       env->GetMethodID(clazz, "onClientPhyRead", "(ILjava/lang/String;III)V");
    830   method_onClientPhyUpdate =
    831       env->GetMethodID(clazz, "onClientPhyUpdate", "(IIII)V");
    832   method_onClientConnUpdate =
    833       env->GetMethodID(clazz, "onClientConnUpdate", "(IIIII)V");
    834 
    835   // Server callbacks
    836 
    837   method_onServerRegistered =
    838       env->GetMethodID(clazz, "onServerRegistered", "(IIJJ)V");
    839   method_onClientConnected =
    840       env->GetMethodID(clazz, "onClientConnected", "(Ljava/lang/String;ZII)V");
    841   method_onServiceAdded =
    842       env->GetMethodID(clazz, "onServiceAdded", "(IILjava/util/List;)V");
    843   method_onServiceStopped =
    844       env->GetMethodID(clazz, "onServiceStopped", "(III)V");
    845   method_onServiceDeleted =
    846       env->GetMethodID(clazz, "onServiceDeleted", "(III)V");
    847   method_onResponseSendCompleted =
    848       env->GetMethodID(clazz, "onResponseSendCompleted", "(II)V");
    849   method_onServerReadCharacteristic = env->GetMethodID(
    850       clazz, "onServerReadCharacteristic", "(Ljava/lang/String;IIIIZ)V");
    851   method_onServerReadDescriptor = env->GetMethodID(
    852       clazz, "onServerReadDescriptor", "(Ljava/lang/String;IIIIZ)V");
    853   method_onServerWriteCharacteristic = env->GetMethodID(
    854       clazz, "onServerWriteCharacteristic", "(Ljava/lang/String;IIIIIZZ[B)V");
    855   method_onServerWriteDescriptor = env->GetMethodID(
    856       clazz, "onServerWriteDescriptor", "(Ljava/lang/String;IIIIIZZ[B)V");
    857   method_onExecuteWrite =
    858       env->GetMethodID(clazz, "onExecuteWrite", "(Ljava/lang/String;III)V");
    859   method_onNotificationSent =
    860       env->GetMethodID(clazz, "onNotificationSent", "(II)V");
    861   method_onServerCongestion =
    862       env->GetMethodID(clazz, "onServerCongestion", "(IZ)V");
    863   method_onServerMtuChanged = env->GetMethodID(clazz, "onMtuChanged", "(II)V");
    864   method_onServerPhyRead =
    865       env->GetMethodID(clazz, "onServerPhyRead", "(ILjava/lang/String;III)V");
    866   method_onServerPhyUpdate =
    867       env->GetMethodID(clazz, "onServerPhyUpdate", "(IIII)V");
    868   method_onServerConnUpdate =
    869       env->GetMethodID(clazz, "onServerConnUpdate", "(IIIII)V");
    870 
    871   info("classInitNative: Success!");
    872 }
    873 
    874 static const bt_interface_t* btIf;
    875 
    876 static void initializeNative(JNIEnv* env, jobject object) {
    877   if (btIf) return;
    878 
    879   btIf = getBluetoothInterface();
    880   if (btIf == NULL) {
    881     error("Bluetooth module is not loaded");
    882     return;
    883   }
    884 
    885   if (sGattIf != NULL) {
    886     ALOGW("Cleaning up Bluetooth GATT Interface before initializing...");
    887     sGattIf->cleanup();
    888     sGattIf = NULL;
    889   }
    890 
    891   if (mCallbacksObj != NULL) {
    892     ALOGW("Cleaning up Bluetooth GATT callback object");
    893     env->DeleteGlobalRef(mCallbacksObj);
    894     mCallbacksObj = NULL;
    895   }
    896 
    897   sGattIf =
    898       (btgatt_interface_t*)btIf->get_profile_interface(BT_PROFILE_GATT_ID);
    899   if (sGattIf == NULL) {
    900     error("Failed to get Bluetooth GATT Interface");
    901     return;
    902   }
    903 
    904   bt_status_t status = sGattIf->init(&sGattCallbacks);
    905   if (status != BT_STATUS_SUCCESS) {
    906     error("Failed to initialize Bluetooth GATT, status: %d", status);
    907     sGattIf = NULL;
    908     return;
    909   }
    910 
    911   mCallbacksObj = env->NewGlobalRef(object);
    912 }
    913 
    914 static void cleanupNative(JNIEnv* env, jobject object) {
    915   if (!btIf) return;
    916 
    917   if (sGattIf != NULL) {
    918     sGattIf->cleanup();
    919     sGattIf = NULL;
    920   }
    921 
    922   if (mCallbacksObj != NULL) {
    923     env->DeleteGlobalRef(mCallbacksObj);
    924     mCallbacksObj = NULL;
    925   }
    926   btIf = NULL;
    927 }
    928 
    929 /**
    930  * Native Client functions
    931  */
    932 
    933 static int gattClientGetDeviceTypeNative(JNIEnv* env, jobject object,
    934                                          jstring address) {
    935   if (!sGattIf) return 0;
    936   return sGattIf->client->get_device_type(str2addr(env, address));
    937 }
    938 
    939 static void gattClientRegisterAppNative(JNIEnv* env, jobject object,
    940                                         jlong app_uuid_lsb,
    941                                         jlong app_uuid_msb) {
    942   bt_uuid_t uuid;
    943 
    944   if (!sGattIf) return;
    945   set_uuid(uuid.uu, app_uuid_msb, app_uuid_lsb);
    946   sGattIf->client->register_client(uuid);
    947 }
    948 
    949 static void gattClientUnregisterAppNative(JNIEnv* env, jobject object,
    950                                           jint clientIf) {
    951   if (!sGattIf) return;
    952   sGattIf->client->unregister_client(clientIf);
    953 }
    954 
    955 void btgattc_register_scanner_cb(bt_uuid_t app_uuid, uint8_t scannerId,
    956                                  uint8_t status) {
    957   CallbackEnv sCallbackEnv(__func__);
    958   if (!sCallbackEnv.valid()) return;
    959   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScannerRegistered,
    960                                status, scannerId, UUID_PARAMS(app_uuid));
    961 }
    962 
    963 static void registerScannerNative(JNIEnv* env, jobject object,
    964                                   jlong app_uuid_lsb, jlong app_uuid_msb) {
    965   if (!sGattIf) return;
    966 
    967   bt_uuid_t uuid;
    968   set_uuid(uuid.uu, app_uuid_msb, app_uuid_lsb);
    969   sGattIf->scanner->RegisterScanner(
    970       base::Bind(&btgattc_register_scanner_cb, uuid));
    971 }
    972 
    973 static void unregisterScannerNative(JNIEnv* env, jobject object,
    974                                     jint scanner_id) {
    975   if (!sGattIf) return;
    976 
    977   sGattIf->scanner->Unregister(scanner_id);
    978 }
    979 
    980 static void gattClientScanNative(JNIEnv* env, jobject object, jboolean start) {
    981   if (!sGattIf) return;
    982   sGattIf->scanner->Scan(start);
    983 }
    984 
    985 static void gattClientConnectNative(JNIEnv* env, jobject object, jint clientif,
    986                                     jstring address, jboolean isDirect,
    987                                     jint transport, jboolean opportunistic,
    988                                     jint initiating_phys) {
    989   if (!sGattIf) return;
    990 
    991   sGattIf->client->connect(clientif, str2addr(env, address), isDirect,
    992                            transport, opportunistic, initiating_phys);
    993 }
    994 
    995 static void gattClientDisconnectNative(JNIEnv* env, jobject object,
    996                                        jint clientIf, jstring address,
    997                                        jint conn_id) {
    998   if (!sGattIf) return;
    999   sGattIf->client->disconnect(clientIf, str2addr(env, address), conn_id);
   1000 }
   1001 
   1002 static void gattClientSetPreferredPhyNative(JNIEnv* env, jobject object,
   1003                                             jint clientIf, jstring address,
   1004                                             jint tx_phy, jint rx_phy,
   1005                                             jint phy_options) {
   1006   if (!sGattIf) return;
   1007   sGattIf->client->set_preferred_phy(str2addr(env, address), tx_phy, rx_phy,
   1008                                      phy_options);
   1009 }
   1010 
   1011 static void readClientPhyCb(uint8_t clientIf, RawAddress bda, uint8_t tx_phy,
   1012                             uint8_t rx_phy, uint8_t status) {
   1013   CallbackEnv sCallbackEnv(__func__);
   1014   if (!sCallbackEnv.valid()) return;
   1015 
   1016   ScopedLocalRef<jstring> address(sCallbackEnv.get(),
   1017                                   bdaddr2newjstr(sCallbackEnv.get(), &bda));
   1018 
   1019   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientPhyRead, clientIf,
   1020                                address.get(), tx_phy, rx_phy, status);
   1021 }
   1022 
   1023 static void gattClientReadPhyNative(JNIEnv* env, jobject object, jint clientIf,
   1024                                     jstring address) {
   1025   if (!sGattIf) return;
   1026 
   1027   RawAddress bda = str2addr(env, address);
   1028   sGattIf->client->read_phy(bda, base::Bind(&readClientPhyCb, clientIf, bda));
   1029 }
   1030 
   1031 static void gattClientRefreshNative(JNIEnv* env, jobject object, jint clientIf,
   1032                                     jstring address) {
   1033   if (!sGattIf) return;
   1034 
   1035   sGattIf->client->refresh(clientIf, str2addr(env, address));
   1036 }
   1037 
   1038 static void gattClientSearchServiceNative(JNIEnv* env, jobject object,
   1039                                           jint conn_id, jboolean search_all,
   1040                                           jlong service_uuid_lsb,
   1041                                           jlong service_uuid_msb) {
   1042   if (!sGattIf) return;
   1043 
   1044   bt_uuid_t uuid;
   1045   set_uuid(uuid.uu, service_uuid_msb, service_uuid_lsb);
   1046   sGattIf->client->search_service(conn_id, search_all ? 0 : &uuid);
   1047 }
   1048 
   1049 static void gattClientDiscoverServiceByUuidNative(JNIEnv* env, jobject object,
   1050                                                   jint conn_id,
   1051                                                   jlong service_uuid_lsb,
   1052                                                   jlong service_uuid_msb) {
   1053   if (!sGattIf) return;
   1054 
   1055   bt_uuid_t uuid;
   1056   set_uuid(uuid.uu, service_uuid_msb, service_uuid_lsb);
   1057   sGattIf->client->btif_gattc_discover_service_by_uuid(conn_id, uuid);
   1058 }
   1059 
   1060 static void gattClientGetGattDbNative(JNIEnv* env, jobject object,
   1061                                       jint conn_id) {
   1062   if (!sGattIf) return;
   1063 
   1064   sGattIf->client->get_gatt_db(conn_id);
   1065 }
   1066 
   1067 static void gattClientReadCharacteristicNative(JNIEnv* env, jobject object,
   1068                                                jint conn_id, jint handle,
   1069                                                jint authReq) {
   1070   if (!sGattIf) return;
   1071 
   1072   sGattIf->client->read_characteristic(conn_id, handle, authReq);
   1073 }
   1074 
   1075 static void gattClientReadUsingCharacteristicUuidNative(
   1076     JNIEnv* env, jobject object, jint conn_id, jlong uuid_lsb, jlong uuid_msb,
   1077     jint s_handle, jint e_handle, jint authReq) {
   1078   if (!sGattIf) return;
   1079 
   1080   bt_uuid_t uuid;
   1081   set_uuid(uuid.uu, uuid_msb, uuid_lsb);
   1082   sGattIf->client->read_using_characteristic_uuid(conn_id, uuid, s_handle,
   1083                                                   e_handle, authReq);
   1084 }
   1085 
   1086 static void gattClientReadDescriptorNative(JNIEnv* env, jobject object,
   1087                                            jint conn_id, jint handle,
   1088                                            jint authReq) {
   1089   if (!sGattIf) return;
   1090 
   1091   sGattIf->client->read_descriptor(conn_id, handle, authReq);
   1092 }
   1093 
   1094 static void gattClientWriteCharacteristicNative(JNIEnv* env, jobject object,
   1095                                                 jint conn_id, jint handle,
   1096                                                 jint write_type, jint auth_req,
   1097                                                 jbyteArray value) {
   1098   if (!sGattIf) return;
   1099 
   1100   if (value == NULL) {
   1101     warn("gattClientWriteCharacteristicNative() ignoring NULL array");
   1102     return;
   1103   }
   1104 
   1105   uint16_t len = (uint16_t)env->GetArrayLength(value);
   1106   jbyte* p_value = env->GetByteArrayElements(value, NULL);
   1107   if (p_value == NULL) return;
   1108 
   1109   std::vector<uint8_t> vect_val(p_value, p_value + len);
   1110   env->ReleaseByteArrayElements(value, p_value, 0);
   1111 
   1112   sGattIf->client->write_characteristic(conn_id, handle, write_type, auth_req,
   1113                                         std::move(vect_val));
   1114 }
   1115 
   1116 static void gattClientExecuteWriteNative(JNIEnv* env, jobject object,
   1117                                          jint conn_id, jboolean execute) {
   1118   if (!sGattIf) return;
   1119   sGattIf->client->execute_write(conn_id, execute ? 1 : 0);
   1120 }
   1121 
   1122 static void gattClientWriteDescriptorNative(JNIEnv* env, jobject object,
   1123                                             jint conn_id, jint handle,
   1124                                             jint auth_req, jbyteArray value) {
   1125   if (!sGattIf) return;
   1126 
   1127   if (value == NULL) {
   1128     warn("gattClientWriteDescriptorNative() ignoring NULL array");
   1129     return;
   1130   }
   1131 
   1132   uint16_t len = (uint16_t)env->GetArrayLength(value);
   1133   jbyte* p_value = env->GetByteArrayElements(value, NULL);
   1134   if (p_value == NULL) return;
   1135 
   1136   std::vector<uint8_t> vect_val(p_value, p_value + len);
   1137   env->ReleaseByteArrayElements(value, p_value, 0);
   1138 
   1139   sGattIf->client->write_descriptor(conn_id, handle, auth_req,
   1140                                     std::move(vect_val));
   1141 }
   1142 
   1143 static void gattClientRegisterForNotificationsNative(
   1144     JNIEnv* env, jobject object, jint clientIf, jstring address, jint handle,
   1145     jboolean enable) {
   1146   if (!sGattIf) return;
   1147 
   1148   RawAddress bd_addr = str2addr(env, address);
   1149   if (enable)
   1150     sGattIf->client->register_for_notification(clientIf, bd_addr, handle);
   1151   else
   1152     sGattIf->client->deregister_for_notification(clientIf, bd_addr, handle);
   1153 }
   1154 
   1155 static void gattClientReadRemoteRssiNative(JNIEnv* env, jobject object,
   1156                                            jint clientif, jstring address) {
   1157   if (!sGattIf) return;
   1158 
   1159   sGattIf->client->read_remote_rssi(clientif, str2addr(env, address));
   1160 }
   1161 
   1162 void set_scan_params_cmpl_cb(int client_if, uint8_t status) {
   1163   CallbackEnv sCallbackEnv(__func__);
   1164   if (!sCallbackEnv.valid()) return;
   1165   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScanParamSetupCompleted,
   1166                                status, client_if);
   1167 }
   1168 
   1169 static void gattSetScanParametersNative(JNIEnv* env, jobject object,
   1170                                         jint client_if, jint scan_interval_unit,
   1171                                         jint scan_window_unit) {
   1172   if (!sGattIf) return;
   1173   sGattIf->scanner->SetScanParameters(
   1174       scan_interval_unit, scan_window_unit,
   1175       base::Bind(&set_scan_params_cmpl_cb, client_if));
   1176 }
   1177 
   1178 void scan_filter_param_cb(uint8_t client_if, uint8_t avbl_space, uint8_t action,
   1179                           uint8_t status) {
   1180   CallbackEnv sCallbackEnv(__func__);
   1181   if (!sCallbackEnv.valid()) return;
   1182   sCallbackEnv->CallVoidMethod(mCallbacksObj,
   1183                                method_onScanFilterParamsConfigured, action,
   1184                                status, client_if, avbl_space);
   1185 }
   1186 
   1187 static void gattClientScanFilterParamAddNative(JNIEnv* env, jobject object,
   1188                                                jobject params) {
   1189   if (!sGattIf) return;
   1190   const int add_scan_filter_params_action = 0;
   1191   auto filt_params = std::make_unique<btgatt_filt_param_setup_t>();
   1192 
   1193   jmethodID methodId = 0;
   1194   ScopedLocalRef<jclass> filtparam(env, env->GetObjectClass(params));
   1195 
   1196   methodId = env->GetMethodID(filtparam.get(), "getClientIf", "()I");
   1197   uint8_t client_if = env->CallIntMethod(params, methodId);
   1198 
   1199   methodId = env->GetMethodID(filtparam.get(), "getFiltIndex", "()I");
   1200   uint8_t filt_index = env->CallIntMethod(params, methodId);
   1201 
   1202   methodId = env->GetMethodID(filtparam.get(), "getFeatSeln", "()I");
   1203   filt_params->feat_seln = env->CallIntMethod(params, methodId);
   1204 
   1205   methodId = env->GetMethodID(filtparam.get(), "getListLogicType", "()I");
   1206   filt_params->list_logic_type = env->CallIntMethod(params, methodId);
   1207 
   1208   methodId = env->GetMethodID(filtparam.get(), "getFiltLogicType", "()I");
   1209   filt_params->filt_logic_type = env->CallIntMethod(params, methodId);
   1210 
   1211   methodId = env->GetMethodID(filtparam.get(), "getDelyMode", "()I");
   1212   filt_params->dely_mode = env->CallIntMethod(params, methodId);
   1213 
   1214   methodId = env->GetMethodID(filtparam.get(), "getFoundTimeout", "()I");
   1215   filt_params->found_timeout = env->CallIntMethod(params, methodId);
   1216 
   1217   methodId = env->GetMethodID(filtparam.get(), "getLostTimeout", "()I");
   1218   filt_params->lost_timeout = env->CallIntMethod(params, methodId);
   1219 
   1220   methodId = env->GetMethodID(filtparam.get(), "getFoundTimeOutCnt", "()I");
   1221   filt_params->found_timeout_cnt = env->CallIntMethod(params, methodId);
   1222 
   1223   methodId = env->GetMethodID(filtparam.get(), "getNumOfTrackEntries", "()I");
   1224   filt_params->num_of_tracking_entries = env->CallIntMethod(params, methodId);
   1225 
   1226   methodId = env->GetMethodID(filtparam.get(), "getRSSIHighValue", "()I");
   1227   filt_params->rssi_high_thres = env->CallIntMethod(params, methodId);
   1228 
   1229   methodId = env->GetMethodID(filtparam.get(), "getRSSILowValue", "()I");
   1230   filt_params->rssi_low_thres = env->CallIntMethod(params, methodId);
   1231 
   1232   sGattIf->scanner->ScanFilterParamSetup(
   1233       client_if, add_scan_filter_params_action, filt_index,
   1234       std::move(filt_params), base::Bind(&scan_filter_param_cb, client_if));
   1235 }
   1236 
   1237 static void gattClientScanFilterParamDeleteNative(JNIEnv* env, jobject object,
   1238                                                   jint client_if,
   1239                                                   jint filt_index) {
   1240   if (!sGattIf) return;
   1241   const int delete_scan_filter_params_action = 1;
   1242   sGattIf->scanner->ScanFilterParamSetup(
   1243       client_if, delete_scan_filter_params_action, filt_index, nullptr,
   1244       base::Bind(&scan_filter_param_cb, client_if));
   1245 }
   1246 
   1247 static void gattClientScanFilterParamClearAllNative(JNIEnv* env, jobject object,
   1248                                                     jint client_if) {
   1249   if (!sGattIf) return;
   1250   const int clear_scan_filter_params_action = 2;
   1251   sGattIf->scanner->ScanFilterParamSetup(
   1252       client_if, clear_scan_filter_params_action, 0 /* index, unused */,
   1253       nullptr, base::Bind(&scan_filter_param_cb, client_if));
   1254 }
   1255 
   1256 static void scan_filter_cfg_cb(uint8_t client_if, uint8_t filt_type,
   1257                                uint8_t avbl_space, uint8_t action,
   1258                                uint8_t status) {
   1259   CallbackEnv sCallbackEnv(__func__);
   1260   if (!sCallbackEnv.valid()) return;
   1261   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScanFilterConfig, action,
   1262                                status, client_if, filt_type, avbl_space);
   1263 }
   1264 
   1265 static void gattClientScanFilterAddRemoveNative(
   1266     JNIEnv* env, jobject object, jint client_if, jint action, jint filt_type,
   1267     jint filt_index, jint company_id, jint company_id_mask, jlong uuid_lsb,
   1268     jlong uuid_msb, jlong uuid_mask_lsb, jlong uuid_mask_msb, jstring name,
   1269     jstring address, jbyte addr_type, jbyteArray data, jbyteArray mask) {
   1270   switch (filt_type) {
   1271     case 0:  // BTM_BLE_PF_ADDR_FILTER
   1272     {
   1273       RawAddress bda = str2addr(env, address);
   1274       sGattIf->scanner->ScanFilterAddRemove(
   1275           action, filt_type, filt_index, 0, 0, NULL, NULL, &bda, addr_type, {},
   1276           {}, base::Bind(&scan_filter_cfg_cb, client_if));
   1277       break;
   1278     }
   1279 
   1280     case 1:  // BTM_BLE_PF_SRVC_DATA
   1281     {
   1282       jbyte* data_array = env->GetByteArrayElements(data, 0);
   1283       int data_len = env->GetArrayLength(data);
   1284       std::vector<uint8_t> vec_data(data_array, data_array + data_len);
   1285       env->ReleaseByteArrayElements(data, data_array, JNI_ABORT);
   1286 
   1287       jbyte* mask_array = env->GetByteArrayElements(mask, NULL);
   1288       uint16_t mask_len = (uint16_t)env->GetArrayLength(mask);
   1289       std::vector<uint8_t> vec_mask(mask_array, mask_array + mask_len);
   1290       env->ReleaseByteArrayElements(mask, mask_array, JNI_ABORT);
   1291 
   1292       sGattIf->scanner->ScanFilterAddRemove(
   1293           action, filt_type, filt_index, 0, 0, NULL, NULL, NULL, 0,
   1294           std::move(vec_data), std::move(vec_mask),
   1295           base::Bind(&scan_filter_cfg_cb, client_if));
   1296       break;
   1297     }
   1298 
   1299     case 2:  // BTM_BLE_PF_SRVC_UUID
   1300     case 3:  // BTM_BLE_PF_SRVC_SOL_UUID
   1301     {
   1302       bt_uuid_t uuid, uuid_mask;
   1303       set_uuid(uuid.uu, uuid_msb, uuid_lsb);
   1304       set_uuid(uuid_mask.uu, uuid_mask_msb, uuid_mask_lsb);
   1305       if (uuid_mask_lsb != 0 && uuid_mask_msb != 0)
   1306         sGattIf->scanner->ScanFilterAddRemove(
   1307             action, filt_type, filt_index, 0, 0, &uuid, &uuid_mask, NULL, 0, {},
   1308             {}, base::Bind(&scan_filter_cfg_cb, client_if));
   1309       else
   1310         sGattIf->scanner->ScanFilterAddRemove(
   1311             action, filt_type, filt_index, 0, 0, &uuid, NULL, NULL, 0, {}, {},
   1312             base::Bind(&scan_filter_cfg_cb, client_if));
   1313       break;
   1314     }
   1315 
   1316     case 4:  // BTM_BLE_PF_LOCAL_NAME
   1317     {
   1318       const char* c_name = env->GetStringUTFChars(name, NULL);
   1319       if (c_name != NULL && strlen(c_name) != 0) {
   1320         std::vector<uint8_t> vec_name(c_name, c_name + strlen(c_name));
   1321         env->ReleaseStringUTFChars(name, c_name);
   1322         sGattIf->scanner->ScanFilterAddRemove(
   1323             action, filt_type, filt_index, 0, 0, NULL, NULL, NULL, 0,
   1324             std::move(vec_name), {},
   1325             base::Bind(&scan_filter_cfg_cb, client_if));
   1326       }
   1327       break;
   1328     }
   1329 
   1330     case 5:  // BTM_BLE_PF_MANU_DATA
   1331     case 6:  // BTM_BLE_PF_SRVC_DATA_PATTERN
   1332     {
   1333       jbyte* data_array = env->GetByteArrayElements(data, 0);
   1334       int data_len = env->GetArrayLength(data);
   1335       std::vector<uint8_t> vec_data(data_array, data_array + data_len);
   1336       env->ReleaseByteArrayElements(data, data_array, JNI_ABORT);
   1337 
   1338       jbyte* mask_array = env->GetByteArrayElements(mask, NULL);
   1339       uint16_t mask_len = (uint16_t)env->GetArrayLength(mask);
   1340       std::vector<uint8_t> vec_mask(mask_array, mask_array + mask_len);
   1341       env->ReleaseByteArrayElements(mask, mask_array, JNI_ABORT);
   1342 
   1343       sGattIf->scanner->ScanFilterAddRemove(
   1344           action, filt_type, filt_index, company_id, company_id_mask, NULL,
   1345           NULL, NULL, 0, std::move(vec_data), std::move(vec_mask),
   1346           base::Bind(&scan_filter_cfg_cb, client_if));
   1347       break;
   1348     }
   1349 
   1350     default:
   1351       break;
   1352   }
   1353 }
   1354 
   1355 static void gattClientScanFilterAddNative(
   1356     JNIEnv* env, jobject object, jint client_if, jint filt_type,
   1357     jint filt_index, jint company_id, jint company_id_mask, jlong uuid_lsb,
   1358     jlong uuid_msb, jlong uuid_mask_lsb, jlong uuid_mask_msb, jstring name,
   1359     jstring address, jbyte addr_type, jbyteArray data, jbyteArray mask) {
   1360   if (!sGattIf) return;
   1361   int action = 0;
   1362   gattClientScanFilterAddRemoveNative(
   1363       env, object, client_if, action, filt_type, filt_index, company_id,
   1364       company_id_mask, uuid_lsb, uuid_msb, uuid_mask_lsb, uuid_mask_msb, name,
   1365       address, addr_type, data, mask);
   1366 }
   1367 
   1368 static void gattClientScanFilterDeleteNative(
   1369     JNIEnv* env, jobject object, jint client_if, jint filt_type,
   1370     jint filt_index, jint company_id, jint company_id_mask, jlong uuid_lsb,
   1371     jlong uuid_msb, jlong uuid_mask_lsb, jlong uuid_mask_msb, jstring name,
   1372     jstring address, jbyte addr_type, jbyteArray data, jbyteArray mask) {
   1373   if (!sGattIf) return;
   1374   int action = 1;
   1375   gattClientScanFilterAddRemoveNative(
   1376       env, object, client_if, action, filt_type, filt_index, company_id,
   1377       company_id_mask, uuid_lsb, uuid_msb, uuid_mask_lsb, uuid_mask_msb, name,
   1378       address, addr_type, data, mask);
   1379 }
   1380 
   1381 static void gattClientScanFilterClearNative(JNIEnv* env, jobject object,
   1382                                             jint client_if, jint filt_index) {
   1383   if (!sGattIf) return;
   1384   sGattIf->scanner->ScanFilterClear(filt_index,
   1385                                     base::Bind(&scan_filter_cfg_cb, client_if));
   1386 }
   1387 
   1388 void scan_enable_cb(uint8_t client_if, uint8_t action, uint8_t status) {
   1389   CallbackEnv sCallbackEnv(__func__);
   1390   if (!sCallbackEnv.valid()) return;
   1391   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScanFilterEnableDisabled,
   1392                                action, status, client_if);
   1393 }
   1394 
   1395 static void gattClientScanFilterEnableNative(JNIEnv* env, jobject object,
   1396                                              jint client_if, jboolean enable) {
   1397   if (!sGattIf) return;
   1398   sGattIf->scanner->ScanFilterEnable(enable,
   1399                                      base::Bind(&scan_enable_cb, client_if));
   1400 }
   1401 
   1402 static void gattClientConfigureMTUNative(JNIEnv* env, jobject object,
   1403                                          jint conn_id, jint mtu) {
   1404   if (!sGattIf) return;
   1405   sGattIf->client->configure_mtu(conn_id, mtu);
   1406 }
   1407 
   1408 static void gattConnectionParameterUpdateNative(JNIEnv* env, jobject object,
   1409                                                 jint client_if, jstring address,
   1410                                                 jint min_interval,
   1411                                                 jint max_interval, jint latency,
   1412                                                 jint timeout) {
   1413   if (!sGattIf) return;
   1414   sGattIf->client->conn_parameter_update(str2addr(env, address), min_interval,
   1415                                          max_interval, latency, timeout);
   1416 }
   1417 
   1418 void batchscan_cfg_storage_cb(uint8_t client_if, uint8_t status) {
   1419   CallbackEnv sCallbackEnv(__func__);
   1420   if (!sCallbackEnv.valid()) return;
   1421   sCallbackEnv->CallVoidMethod(
   1422       mCallbacksObj, method_onBatchScanStorageConfigured, status, client_if);
   1423 }
   1424 
   1425 static void gattClientConfigBatchScanStorageNative(
   1426     JNIEnv* env, jobject object, jint client_if, jint max_full_reports_percent,
   1427     jint max_trunc_reports_percent, jint notify_threshold_level_percent) {
   1428   if (!sGattIf) return;
   1429   sGattIf->scanner->BatchscanConfigStorage(
   1430       client_if, max_full_reports_percent, max_trunc_reports_percent,
   1431       notify_threshold_level_percent,
   1432       base::Bind(&batchscan_cfg_storage_cb, client_if));
   1433 }
   1434 
   1435 void batchscan_enable_cb(uint8_t client_if, uint8_t status) {
   1436   CallbackEnv sCallbackEnv(__func__);
   1437   if (!sCallbackEnv.valid()) return;
   1438   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onBatchScanStartStopped,
   1439                                0 /* unused */, status, client_if);
   1440 }
   1441 
   1442 static void gattClientStartBatchScanNative(JNIEnv* env, jobject object,
   1443                                            jint client_if, jint scan_mode,
   1444                                            jint scan_interval_unit,
   1445                                            jint scan_window_unit,
   1446                                            jint addr_type, jint discard_rule) {
   1447   if (!sGattIf) return;
   1448   sGattIf->scanner->BatchscanEnable(
   1449       scan_mode, scan_interval_unit, scan_window_unit, addr_type, discard_rule,
   1450       base::Bind(&batchscan_enable_cb, client_if));
   1451 }
   1452 
   1453 static void gattClientStopBatchScanNative(JNIEnv* env, jobject object,
   1454                                           jint client_if) {
   1455   if (!sGattIf) return;
   1456   sGattIf->scanner->BatchscanDisable(
   1457       base::Bind(&batchscan_enable_cb, client_if));
   1458 }
   1459 
   1460 static void gattClientReadScanReportsNative(JNIEnv* env, jobject object,
   1461                                             jint client_if, jint scan_type) {
   1462   if (!sGattIf) return;
   1463   sGattIf->scanner->BatchscanReadReports(client_if, scan_type);
   1464 }
   1465 
   1466 /**
   1467  * Native server functions
   1468  */
   1469 static void gattServerRegisterAppNative(JNIEnv* env, jobject object,
   1470                                         jlong app_uuid_lsb,
   1471                                         jlong app_uuid_msb) {
   1472   bt_uuid_t uuid;
   1473   if (!sGattIf) return;
   1474   set_uuid(uuid.uu, app_uuid_msb, app_uuid_lsb);
   1475   sGattIf->server->register_server(uuid);
   1476 }
   1477 
   1478 static void gattServerUnregisterAppNative(JNIEnv* env, jobject object,
   1479                                           jint serverIf) {
   1480   if (!sGattIf) return;
   1481   sGattIf->server->unregister_server(serverIf);
   1482 }
   1483 
   1484 static void gattServerConnectNative(JNIEnv* env, jobject object, jint server_if,
   1485                                     jstring address, jboolean is_direct,
   1486                                     jint transport) {
   1487   if (!sGattIf) return;
   1488 
   1489   RawAddress bd_addr = str2addr(env, address);
   1490   sGattIf->server->connect(server_if, bd_addr, is_direct, transport);
   1491 }
   1492 
   1493 static void gattServerDisconnectNative(JNIEnv* env, jobject object,
   1494                                        jint serverIf, jstring address,
   1495                                        jint conn_id) {
   1496   if (!sGattIf) return;
   1497   sGattIf->server->disconnect(serverIf, str2addr(env, address), conn_id);
   1498 }
   1499 
   1500 static void gattServerSetPreferredPhyNative(JNIEnv* env, jobject object,
   1501                                             jint serverIf, jstring address,
   1502                                             jint tx_phy, jint rx_phy,
   1503                                             jint phy_options) {
   1504   if (!sGattIf) return;
   1505   RawAddress bda = str2addr(env, address);
   1506   sGattIf->server->set_preferred_phy(bda, tx_phy, rx_phy, phy_options);
   1507 }
   1508 
   1509 static void readServerPhyCb(uint8_t serverIf, RawAddress bda, uint8_t tx_phy,
   1510                             uint8_t rx_phy, uint8_t status) {
   1511   CallbackEnv sCallbackEnv(__func__);
   1512   if (!sCallbackEnv.valid()) return;
   1513 
   1514   ScopedLocalRef<jstring> address(sCallbackEnv.get(),
   1515                                   bdaddr2newjstr(sCallbackEnv.get(), &bda));
   1516 
   1517   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerPhyRead, serverIf,
   1518                                address.get(), tx_phy, rx_phy, status);
   1519 }
   1520 
   1521 static void gattServerReadPhyNative(JNIEnv* env, jobject object, jint serverIf,
   1522                                     jstring address) {
   1523   if (!sGattIf) return;
   1524 
   1525   RawAddress bda = str2addr(env, address);
   1526   sGattIf->server->read_phy(bda, base::Bind(&readServerPhyCb, serverIf, bda));
   1527 }
   1528 
   1529 static void gattServerAddServiceNative(JNIEnv* env, jobject object,
   1530                                        jint server_if,
   1531                                        jobject gatt_db_elements) {
   1532   if (!sGattIf) return;
   1533 
   1534   jclass arrayListclazz = env->FindClass("java/util/List");
   1535   jmethodID arrayGet =
   1536       env->GetMethodID(arrayListclazz, "get", "(I)Ljava/lang/Object;");
   1537   jmethodID arraySize = env->GetMethodID(arrayListclazz, "size", "()I");
   1538 
   1539   int count = env->CallIntMethod(gatt_db_elements, arraySize);
   1540   std::vector<btgatt_db_element_t> db;
   1541 
   1542   jclass uuidClazz = env->FindClass("java/util/UUID");
   1543   jmethodID uuidGetMsb =
   1544       env->GetMethodID(uuidClazz, "getMostSignificantBits", "()J");
   1545   jmethodID uuidGetLsb =
   1546       env->GetMethodID(uuidClazz, "getLeastSignificantBits", "()J");
   1547 
   1548   jobject objectForClass =
   1549       env->CallObjectMethod(mCallbacksObj, method_getSampleGattDbElement);
   1550   jclass gattDbElementClazz = env->GetObjectClass(objectForClass);
   1551 
   1552   for (int i = 0; i < count; i++) {
   1553     btgatt_db_element_t curr;
   1554 
   1555     jint index = i;
   1556     ScopedLocalRef<jobject> element(
   1557         env, env->CallObjectMethod(gatt_db_elements, arrayGet, index));
   1558 
   1559     jfieldID fid;
   1560 
   1561     fid = env->GetFieldID(gattDbElementClazz, "id", "I");
   1562     curr.id = env->GetIntField(element.get(), fid);
   1563 
   1564     fid = env->GetFieldID(gattDbElementClazz, "uuid", "Ljava/util/UUID;");
   1565     ScopedLocalRef<jobject> uuid(env, env->GetObjectField(element.get(), fid));
   1566 
   1567     jlong uuid_msb = env->CallLongMethod(uuid.get(), uuidGetMsb);
   1568     jlong uuid_lsb = env->CallLongMethod(uuid.get(), uuidGetLsb);
   1569     set_uuid(curr.uuid.uu, uuid_msb, uuid_lsb);
   1570 
   1571     fid = env->GetFieldID(gattDbElementClazz, "type", "I");
   1572     curr.type =
   1573         (bt_gatt_db_attribute_type_t)env->GetIntField(element.get(), fid);
   1574 
   1575     fid = env->GetFieldID(gattDbElementClazz, "attributeHandle", "I");
   1576     curr.attribute_handle = env->GetIntField(element.get(), fid);
   1577 
   1578     fid = env->GetFieldID(gattDbElementClazz, "startHandle", "I");
   1579     curr.start_handle = env->GetIntField(element.get(), fid);
   1580 
   1581     fid = env->GetFieldID(gattDbElementClazz, "endHandle", "I");
   1582     curr.end_handle = env->GetIntField(element.get(), fid);
   1583 
   1584     fid = env->GetFieldID(gattDbElementClazz, "properties", "I");
   1585     curr.properties = env->GetIntField(element.get(), fid);
   1586 
   1587     fid = env->GetFieldID(gattDbElementClazz, "permissions", "I");
   1588     curr.permissions = env->GetIntField(element.get(), fid);
   1589 
   1590     db.push_back(curr);
   1591   }
   1592 
   1593   sGattIf->server->add_service(server_if, std::move(db));
   1594 }
   1595 
   1596 static void gattServerStopServiceNative(JNIEnv* env, jobject object,
   1597                                         jint server_if, jint svc_handle) {
   1598   if (!sGattIf) return;
   1599   sGattIf->server->stop_service(server_if, svc_handle);
   1600 }
   1601 
   1602 static void gattServerDeleteServiceNative(JNIEnv* env, jobject object,
   1603                                           jint server_if, jint svc_handle) {
   1604   if (!sGattIf) return;
   1605   sGattIf->server->delete_service(server_if, svc_handle);
   1606 }
   1607 
   1608 static void gattServerSendIndicationNative(JNIEnv* env, jobject object,
   1609                                            jint server_if, jint attr_handle,
   1610                                            jint conn_id, jbyteArray val) {
   1611   if (!sGattIf) return;
   1612 
   1613   jbyte* array = env->GetByteArrayElements(val, 0);
   1614   int val_len = env->GetArrayLength(val);
   1615 
   1616   std::vector<uint8_t> vect_val((uint8_t*)array, (uint8_t*)array + val_len);
   1617   env->ReleaseByteArrayElements(val, array, JNI_ABORT);
   1618 
   1619   sGattIf->server->send_indication(server_if, attr_handle, conn_id,
   1620                                    /*confirm*/ 1, std::move(vect_val));
   1621 }
   1622 
   1623 static void gattServerSendNotificationNative(JNIEnv* env, jobject object,
   1624                                              jint server_if, jint attr_handle,
   1625                                              jint conn_id, jbyteArray val) {
   1626   if (!sGattIf) return;
   1627 
   1628   jbyte* array = env->GetByteArrayElements(val, 0);
   1629   int val_len = env->GetArrayLength(val);
   1630 
   1631   std::vector<uint8_t> vect_val((uint8_t*)array, (uint8_t*)array + val_len);
   1632   env->ReleaseByteArrayElements(val, array, JNI_ABORT);
   1633 
   1634   sGattIf->server->send_indication(server_if, attr_handle, conn_id,
   1635                                    /*confirm*/ 0, std::move(vect_val));
   1636 }
   1637 
   1638 static void gattServerSendResponseNative(JNIEnv* env, jobject object,
   1639                                          jint server_if, jint conn_id,
   1640                                          jint trans_id, jint status,
   1641                                          jint handle, jint offset,
   1642                                          jbyteArray val, jint auth_req) {
   1643   if (!sGattIf) return;
   1644 
   1645   btgatt_response_t response;
   1646 
   1647   response.attr_value.handle = handle;
   1648   response.attr_value.auth_req = auth_req;
   1649   response.attr_value.offset = offset;
   1650   response.attr_value.len = 0;
   1651 
   1652   if (val != NULL) {
   1653     response.attr_value.len = (uint16_t)env->GetArrayLength(val);
   1654     jbyte* array = env->GetByteArrayElements(val, 0);
   1655 
   1656     for (int i = 0; i != response.attr_value.len; ++i)
   1657       response.attr_value.value[i] = (uint8_t)array[i];
   1658     env->ReleaseByteArrayElements(val, array, JNI_ABORT);
   1659   }
   1660 
   1661   sGattIf->server->send_response(conn_id, trans_id, status, response);
   1662 }
   1663 
   1664 static void advertiseClassInitNative(JNIEnv* env, jclass clazz) {
   1665   method_onAdvertisingSetStarted =
   1666       env->GetMethodID(clazz, "onAdvertisingSetStarted", "(IIII)V");
   1667   method_onOwnAddressRead =
   1668       env->GetMethodID(clazz, "onOwnAddressRead", "(IILjava/lang/String;)V");
   1669   method_onAdvertisingEnabled =
   1670       env->GetMethodID(clazz, "onAdvertisingEnabled", "(IZI)V");
   1671   method_onAdvertisingDataSet =
   1672       env->GetMethodID(clazz, "onAdvertisingDataSet", "(II)V");
   1673   method_onScanResponseDataSet =
   1674       env->GetMethodID(clazz, "onScanResponseDataSet", "(II)V");
   1675   method_onAdvertisingParametersUpdated =
   1676       env->GetMethodID(clazz, "onAdvertisingParametersUpdated", "(III)V");
   1677   method_onPeriodicAdvertisingParametersUpdated = env->GetMethodID(
   1678       clazz, "onPeriodicAdvertisingParametersUpdated", "(II)V");
   1679   method_onPeriodicAdvertisingDataSet =
   1680       env->GetMethodID(clazz, "onPeriodicAdvertisingDataSet", "(II)V");
   1681   method_onPeriodicAdvertisingEnabled =
   1682       env->GetMethodID(clazz, "onPeriodicAdvertisingEnabled", "(IZI)V");
   1683 }
   1684 
   1685 static void advertiseInitializeNative(JNIEnv* env, jobject object) {
   1686   if (mAdvertiseCallbacksObj != NULL) {
   1687     ALOGW("Cleaning up Advertise callback object");
   1688     env->DeleteGlobalRef(mAdvertiseCallbacksObj);
   1689     mAdvertiseCallbacksObj = NULL;
   1690   }
   1691 
   1692   mAdvertiseCallbacksObj = env->NewGlobalRef(object);
   1693 }
   1694 
   1695 static void advertiseCleanupNative(JNIEnv* env, jobject object) {
   1696   if (mAdvertiseCallbacksObj != NULL) {
   1697     env->DeleteGlobalRef(mAdvertiseCallbacksObj);
   1698     mAdvertiseCallbacksObj = NULL;
   1699   }
   1700 }
   1701 
   1702 static uint32_t INTERVAL_MAX = 0xFFFFFF;
   1703 // Always give controller 31.25ms difference between min and max
   1704 static uint32_t INTERVAL_DELTA = 50;
   1705 
   1706 static AdvertiseParameters parseParams(JNIEnv* env, jobject i) {
   1707   AdvertiseParameters p;
   1708 
   1709   jclass clazz = env->GetObjectClass(i);
   1710   jmethodID methodId;
   1711 
   1712   methodId = env->GetMethodID(clazz, "isConnectable", "()Z");
   1713   jboolean isConnectable = env->CallBooleanMethod(i, methodId);
   1714   methodId = env->GetMethodID(clazz, "isScannable", "()Z");
   1715   jboolean isScannable = env->CallBooleanMethod(i, methodId);
   1716   methodId = env->GetMethodID(clazz, "isLegacy", "()Z");
   1717   jboolean isLegacy = env->CallBooleanMethod(i, methodId);
   1718   methodId = env->GetMethodID(clazz, "isAnonymous", "()Z");
   1719   jboolean isAnonymous = env->CallBooleanMethod(i, methodId);
   1720   methodId = env->GetMethodID(clazz, "includeTxPower", "()Z");
   1721   jboolean includeTxPower = env->CallBooleanMethod(i, methodId);
   1722   methodId = env->GetMethodID(clazz, "getPrimaryPhy", "()I");
   1723   uint8_t primaryPhy = env->CallIntMethod(i, methodId);
   1724   methodId = env->GetMethodID(clazz, "getSecondaryPhy", "()I");
   1725   uint8_t secondaryPhy = env->CallIntMethod(i, methodId);
   1726   methodId = env->GetMethodID(clazz, "getInterval", "()I");
   1727   uint32_t interval = env->CallIntMethod(i, methodId);
   1728   methodId = env->GetMethodID(clazz, "getTxPowerLevel", "()I");
   1729   int8_t txPowerLevel = env->CallIntMethod(i, methodId);
   1730 
   1731   uint16_t props = 0;
   1732   if (isConnectable) props |= 0x01;
   1733   if (isScannable) props |= 0x02;
   1734   if (isLegacy) props |= 0x10;
   1735   if (isAnonymous) props |= 0x20;
   1736   if (includeTxPower) props |= 0x40;
   1737 
   1738   if (interval > INTERVAL_MAX - INTERVAL_DELTA) {
   1739     interval = INTERVAL_MAX - INTERVAL_DELTA;
   1740   }
   1741 
   1742   p.advertising_event_properties = props;
   1743   p.min_interval = interval;
   1744   p.max_interval = interval + INTERVAL_DELTA;
   1745   p.channel_map = 0x07; /* all channels */
   1746   p.tx_power = txPowerLevel;
   1747   p.primary_advertising_phy = primaryPhy;
   1748   p.secondary_advertising_phy = secondaryPhy;
   1749   p.scan_request_notification_enable = false;
   1750   return p;
   1751 }
   1752 
   1753 static PeriodicAdvertisingParameters parsePeriodicParams(JNIEnv* env,
   1754                                                          jobject i) {
   1755   PeriodicAdvertisingParameters p;
   1756 
   1757   if (i == NULL) {
   1758     p.enable = false;
   1759     return p;
   1760   }
   1761 
   1762   jclass clazz = env->GetObjectClass(i);
   1763   jmethodID methodId;
   1764 
   1765   methodId = env->GetMethodID(clazz, "getIncludeTxPower", "()Z");
   1766   jboolean includeTxPower = env->CallBooleanMethod(i, methodId);
   1767   methodId = env->GetMethodID(clazz, "getInterval", "()I");
   1768   uint16_t interval = env->CallIntMethod(i, methodId);
   1769 
   1770   p.enable = true;
   1771   p.min_interval = interval;
   1772   p.max_interval = interval + 16; /* 20ms difference betwen min and max */
   1773   uint16_t props = 0;
   1774   if (includeTxPower) props |= 0x40;
   1775   p.periodic_advertising_properties = props;
   1776   return p;
   1777 }
   1778 
   1779 static void ble_advertising_set_started_cb(int reg_id, uint8_t advertiser_id,
   1780                                            int8_t tx_power, uint8_t status) {
   1781   CallbackEnv sCallbackEnv(__func__);
   1782   if (!sCallbackEnv.valid()) return;
   1783   sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj,
   1784                                method_onAdvertisingSetStarted, reg_id,
   1785                                advertiser_id, tx_power, status);
   1786 }
   1787 
   1788 static void ble_advertising_set_timeout_cb(uint8_t advertiser_id,
   1789                                            uint8_t status) {
   1790   CallbackEnv sCallbackEnv(__func__);
   1791   if (!sCallbackEnv.valid()) return;
   1792   sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj,
   1793                                method_onAdvertisingEnabled, advertiser_id,
   1794                                false, status);
   1795 }
   1796 
   1797 static void startAdvertisingSetNative(JNIEnv* env, jobject object,
   1798                                       jobject parameters, jbyteArray adv_data,
   1799                                       jbyteArray scan_resp,
   1800                                       jobject periodic_parameters,
   1801                                       jbyteArray periodic_data, jint duration,
   1802                                       jint maxExtAdvEvents, jint reg_id) {
   1803   if (!sGattIf) return;
   1804 
   1805   jbyte* scan_resp_data = env->GetByteArrayElements(scan_resp, NULL);
   1806   uint16_t scan_resp_len = (uint16_t)env->GetArrayLength(scan_resp);
   1807   std::vector<uint8_t> scan_resp_vec(scan_resp_data,
   1808                                      scan_resp_data + scan_resp_len);
   1809   env->ReleaseByteArrayElements(scan_resp, scan_resp_data, JNI_ABORT);
   1810 
   1811   AdvertiseParameters params = parseParams(env, parameters);
   1812   PeriodicAdvertisingParameters periodicParams =
   1813       parsePeriodicParams(env, periodic_parameters);
   1814 
   1815   jbyte* adv_data_data = env->GetByteArrayElements(adv_data, NULL);
   1816   uint16_t adv_data_len = (uint16_t)env->GetArrayLength(adv_data);
   1817   std::vector<uint8_t> data_vec(adv_data_data, adv_data_data + adv_data_len);
   1818   env->ReleaseByteArrayElements(adv_data, adv_data_data, JNI_ABORT);
   1819 
   1820   jbyte* periodic_data_data = env->GetByteArrayElements(periodic_data, NULL);
   1821   uint16_t periodic_data_len = (uint16_t)env->GetArrayLength(periodic_data);
   1822   std::vector<uint8_t> periodic_data_vec(
   1823       periodic_data_data, periodic_data_data + periodic_data_len);
   1824   env->ReleaseByteArrayElements(periodic_data, periodic_data_data, JNI_ABORT);
   1825 
   1826   sGattIf->advertiser->StartAdvertisingSet(
   1827       base::Bind(&ble_advertising_set_started_cb, reg_id), params, data_vec,
   1828       scan_resp_vec, periodicParams, periodic_data_vec, duration,
   1829       maxExtAdvEvents, base::Bind(ble_advertising_set_timeout_cb));
   1830 }
   1831 
   1832 static void stopAdvertisingSetNative(JNIEnv* env, jobject object,
   1833                                      jint advertiser_id) {
   1834   if (!sGattIf) return;
   1835 
   1836   sGattIf->advertiser->Unregister(advertiser_id);
   1837 }
   1838 
   1839 static void getOwnAddressCb(uint8_t advertiser_id, uint8_t address_type,
   1840                             RawAddress address) {
   1841   CallbackEnv sCallbackEnv(__func__);
   1842   if (!sCallbackEnv.valid()) return;
   1843 
   1844   ScopedLocalRef<jstring> addr(sCallbackEnv.get(),
   1845                                bdaddr2newjstr(sCallbackEnv.get(), &address));
   1846   sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj, method_onOwnAddressRead,
   1847                                advertiser_id, address_type, addr.get());
   1848 }
   1849 
   1850 static void getOwnAddressNative(JNIEnv* env, jobject object,
   1851                                 jint advertiser_id) {
   1852   if (!sGattIf) return;
   1853   sGattIf->advertiser->GetOwnAddress(
   1854       advertiser_id, base::Bind(&getOwnAddressCb, advertiser_id));
   1855 }
   1856 
   1857 static void callJniCallback(jmethodID method, uint8_t advertiser_id,
   1858                             uint8_t status) {
   1859   CallbackEnv sCallbackEnv(__func__);
   1860   if (!sCallbackEnv.valid()) return;
   1861   sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj, method, advertiser_id,
   1862                                status);
   1863 }
   1864 
   1865 static void enableSetCb(uint8_t advertiser_id, bool enable, uint8_t status) {
   1866   CallbackEnv sCallbackEnv(__func__);
   1867   if (!sCallbackEnv.valid()) return;
   1868   sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj,
   1869                                method_onAdvertisingEnabled, advertiser_id,
   1870                                enable, status);
   1871 }
   1872 
   1873 static void enableAdvertisingSetNative(JNIEnv* env, jobject object,
   1874                                        jint advertiser_id, jboolean enable,
   1875                                        jint duration, jint maxExtAdvEvents) {
   1876   if (!sGattIf) return;
   1877 
   1878   sGattIf->advertiser->Enable(advertiser_id, enable,
   1879                               base::Bind(&enableSetCb, advertiser_id, enable),
   1880                               duration, maxExtAdvEvents,
   1881                               base::Bind(&enableSetCb, advertiser_id, false));
   1882 }
   1883 
   1884 static void setAdvertisingDataNative(JNIEnv* env, jobject object,
   1885                                      jint advertiser_id, jbyteArray data) {
   1886   if (!sGattIf) return;
   1887 
   1888   sGattIf->advertiser->SetData(
   1889       advertiser_id, false, toVector(env, data),
   1890       base::Bind(&callJniCallback, method_onAdvertisingDataSet, advertiser_id));
   1891 }
   1892 
   1893 static void setScanResponseDataNative(JNIEnv* env, jobject object,
   1894                                       jint advertiser_id, jbyteArray data) {
   1895   if (!sGattIf) return;
   1896 
   1897   sGattIf->advertiser->SetData(
   1898       advertiser_id, true, toVector(env, data),
   1899       base::Bind(&callJniCallback, method_onScanResponseDataSet,
   1900                  advertiser_id));
   1901 }
   1902 
   1903 static void setAdvertisingParametersNativeCb(uint8_t advertiser_id,
   1904                                              uint8_t status, int8_t tx_power) {
   1905   CallbackEnv sCallbackEnv(__func__);
   1906   if (!sCallbackEnv.valid()) return;
   1907   sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj,
   1908                                method_onAdvertisingParametersUpdated,
   1909                                advertiser_id, tx_power, status);
   1910 }
   1911 
   1912 static void setAdvertisingParametersNative(JNIEnv* env, jobject object,
   1913                                            jint advertiser_id,
   1914                                            jobject parameters) {
   1915   if (!sGattIf) return;
   1916 
   1917   AdvertiseParameters params = parseParams(env, parameters);
   1918   sGattIf->advertiser->SetParameters(
   1919       advertiser_id, params,
   1920       base::Bind(&setAdvertisingParametersNativeCb, advertiser_id));
   1921 }
   1922 
   1923 static void setPeriodicAdvertisingParametersNative(
   1924     JNIEnv* env, jobject object, jint advertiser_id,
   1925     jobject periodic_parameters) {
   1926   if (!sGattIf) return;
   1927 
   1928   PeriodicAdvertisingParameters periodicParams =
   1929       parsePeriodicParams(env, periodic_parameters);
   1930   sGattIf->advertiser->SetPeriodicAdvertisingParameters(
   1931       advertiser_id, periodicParams,
   1932       base::Bind(&callJniCallback,
   1933                  method_onPeriodicAdvertisingParametersUpdated, advertiser_id));
   1934 }
   1935 
   1936 static void setPeriodicAdvertisingDataNative(JNIEnv* env, jobject object,
   1937                                              jint advertiser_id,
   1938                                              jbyteArray data) {
   1939   if (!sGattIf) return;
   1940 
   1941   sGattIf->advertiser->SetPeriodicAdvertisingData(
   1942       advertiser_id, toVector(env, data),
   1943       base::Bind(&callJniCallback, method_onPeriodicAdvertisingDataSet,
   1944                  advertiser_id));
   1945 }
   1946 
   1947 static void enablePeriodicSetCb(uint8_t advertiser_id, bool enable,
   1948                                 uint8_t status) {
   1949   CallbackEnv sCallbackEnv(__func__);
   1950   if (!sCallbackEnv.valid()) return;
   1951   sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj,
   1952                                method_onPeriodicAdvertisingEnabled,
   1953                                advertiser_id, enable, status);
   1954 }
   1955 
   1956 static void setPeriodicAdvertisingEnableNative(JNIEnv* env, jobject object,
   1957                                                jint advertiser_id,
   1958                                                jboolean enable) {
   1959   if (!sGattIf) return;
   1960 
   1961   sGattIf->advertiser->SetPeriodicAdvertisingEnable(
   1962       advertiser_id, enable,
   1963       base::Bind(&enablePeriodicSetCb, advertiser_id, enable));
   1964 }
   1965 
   1966 static void periodicScanClassInitNative(JNIEnv* env, jclass clazz) {
   1967   method_onSyncStarted =
   1968       env->GetMethodID(clazz, "onSyncStarted", "(IIIILjava/lang/String;III)V");
   1969   method_onSyncReport = env->GetMethodID(clazz, "onSyncReport", "(IIII[B)V");
   1970   method_onSyncLost = env->GetMethodID(clazz, "onSyncLost", "(I)V");
   1971 }
   1972 
   1973 static void periodicScanInitializeNative(JNIEnv* env, jobject object) {
   1974   if (mPeriodicScanCallbacksObj != NULL) {
   1975     ALOGW("Cleaning up periodic scan callback object");
   1976     env->DeleteGlobalRef(mPeriodicScanCallbacksObj);
   1977     mPeriodicScanCallbacksObj = NULL;
   1978   }
   1979 
   1980   mPeriodicScanCallbacksObj = env->NewGlobalRef(object);
   1981 }
   1982 
   1983 static void periodicScanCleanupNative(JNIEnv* env, jobject object) {
   1984   if (mPeriodicScanCallbacksObj != NULL) {
   1985     env->DeleteGlobalRef(mPeriodicScanCallbacksObj);
   1986     mPeriodicScanCallbacksObj = NULL;
   1987   }
   1988 }
   1989 
   1990 static void onSyncStarted(int reg_id, uint8_t status, uint16_t sync_handle,
   1991                           uint8_t sid, uint8_t address_type, RawAddress address,
   1992                           uint8_t phy, uint16_t interval) {
   1993   CallbackEnv sCallbackEnv(__func__);
   1994   if (!sCallbackEnv.valid()) return;
   1995 
   1996   sCallbackEnv->CallVoidMethod(mPeriodicScanCallbacksObj, method_onSyncStarted,
   1997                                reg_id, sync_handle, sid, address_type, address,
   1998                                phy, interval, status);
   1999 }
   2000 
   2001 static void onSyncReport(uint16_t sync_handle, int8_t tx_power, int8_t rssi,
   2002                          uint8_t data_status, std::vector<uint8_t> data) {
   2003   CallbackEnv sCallbackEnv(__func__);
   2004   if (!sCallbackEnv.valid()) return;
   2005 
   2006   ScopedLocalRef<jbyteArray> jb(sCallbackEnv.get(),
   2007                                 sCallbackEnv->NewByteArray(data.size()));
   2008   sCallbackEnv->SetByteArrayRegion(jb.get(), 0, data.size(),
   2009                                    (jbyte*)data.data());
   2010 
   2011   sCallbackEnv->CallVoidMethod(mPeriodicScanCallbacksObj, method_onSyncReport,
   2012                                sync_handle, tx_power, rssi, data_status,
   2013                                jb.get());
   2014 }
   2015 
   2016 static void onSyncLost(uint16_t sync_handle) {
   2017   CallbackEnv sCallbackEnv(__func__);
   2018   if (!sCallbackEnv.valid()) return;
   2019 
   2020   sCallbackEnv->CallVoidMethod(mPeriodicScanCallbacksObj, method_onSyncLost,
   2021                                sync_handle);
   2022 }
   2023 
   2024 static void startSyncNative(JNIEnv* env, jobject object, jint sid,
   2025                             jstring address, jint skip, jint timeout,
   2026                             jint reg_id) {
   2027   if (!sGattIf) return;
   2028 
   2029   sGattIf->scanner->StartSync(sid, str2addr(env, address), skip, timeout,
   2030                               base::Bind(&onSyncStarted, reg_id),
   2031                               base::Bind(&onSyncReport),
   2032                               base::Bind(&onSyncLost));
   2033 }
   2034 
   2035 static void stopSyncNative(int sync_handle) {
   2036   if (!sGattIf) return;
   2037 
   2038   sGattIf->scanner->StopSync(sync_handle);
   2039 }
   2040 
   2041 static void gattTestNative(JNIEnv* env, jobject object, jint command,
   2042                            jlong uuid1_lsb, jlong uuid1_msb, jstring bda1,
   2043                            jint p1, jint p2, jint p3, jint p4, jint p5) {
   2044   if (!sGattIf) return;
   2045 
   2046   RawAddress bt_bda1 = str2addr(env, bda1);
   2047 
   2048   bt_uuid_t uuid1;
   2049   set_uuid(uuid1.uu, uuid1_msb, uuid1_lsb);
   2050 
   2051   btgatt_test_params_t params;
   2052   params.bda1 = &bt_bda1;
   2053   params.uuid1 = &uuid1;
   2054   params.u1 = p1;
   2055   params.u2 = p2;
   2056   params.u3 = p3;
   2057   params.u4 = p4;
   2058   params.u5 = p5;
   2059   sGattIf->client->test_command(command, params);
   2060 }
   2061 
   2062 /**
   2063  * JNI function definitinos
   2064  */
   2065 
   2066 // JNI functions defined in AdvertiseManager class.
   2067 static JNINativeMethod sAdvertiseMethods[] = {
   2068     {"classInitNative", "()V", (void*)advertiseClassInitNative},
   2069     {"initializeNative", "()V", (void*)advertiseInitializeNative},
   2070     {"cleanupNative", "()V", (void*)advertiseCleanupNative},
   2071     {"startAdvertisingSetNative",
   2072      "(Landroid/bluetooth/le/AdvertisingSetParameters;[B[BLandroid/bluetooth/"
   2073      "le/PeriodicAdvertisingParameters;[BIII)V",
   2074      (void*)startAdvertisingSetNative},
   2075     {"getOwnAddressNative", "(I)V", (void*)getOwnAddressNative},
   2076     {"stopAdvertisingSetNative", "(I)V", (void*)stopAdvertisingSetNative},
   2077     {"enableAdvertisingSetNative", "(IZII)V",
   2078      (void*)enableAdvertisingSetNative},
   2079     {"setAdvertisingDataNative", "(I[B)V", (void*)setAdvertisingDataNative},
   2080     {"setScanResponseDataNative", "(I[B)V", (void*)setScanResponseDataNative},
   2081     {"setAdvertisingParametersNative",
   2082      "(ILandroid/bluetooth/le/AdvertisingSetParameters;)V",
   2083      (void*)setAdvertisingParametersNative},
   2084     {"setPeriodicAdvertisingParametersNative",
   2085      "(ILandroid/bluetooth/le/PeriodicAdvertisingParameters;)V",
   2086      (void*)setPeriodicAdvertisingParametersNative},
   2087     {"setPeriodicAdvertisingDataNative", "(I[B)V",
   2088      (void*)setPeriodicAdvertisingDataNative},
   2089     {"setPeriodicAdvertisingEnableNative", "(IZ)V",
   2090      (void*)setPeriodicAdvertisingEnableNative},
   2091 };
   2092 
   2093 // JNI functions defined in PeriodicScanManager class.
   2094 static JNINativeMethod sPeriodicScanMethods[] = {
   2095     {"classInitNative", "()V", (void*)periodicScanClassInitNative},
   2096     {"initializeNative", "()V", (void*)periodicScanInitializeNative},
   2097     {"cleanupNative", "()V", (void*)periodicScanCleanupNative},
   2098     {"startSyncNative", "(ILjava/lang/String;III)V", (void*)startSyncNative},
   2099     {"stopSyncNative", "(I)V", (void*)stopSyncNative},
   2100 };
   2101 
   2102 // JNI functions defined in ScanManager class.
   2103 static JNINativeMethod sScanMethods[] = {
   2104     {"registerScannerNative", "(JJ)V", (void*)registerScannerNative},
   2105     {"unregisterScannerNative", "(I)V", (void*)unregisterScannerNative},
   2106     {"gattClientScanNative", "(Z)V", (void*)gattClientScanNative},
   2107     // Batch scan JNI functions.
   2108     {"gattClientConfigBatchScanStorageNative", "(IIII)V",
   2109      (void*)gattClientConfigBatchScanStorageNative},
   2110     {"gattClientStartBatchScanNative", "(IIIIII)V",
   2111      (void*)gattClientStartBatchScanNative},
   2112     {"gattClientStopBatchScanNative", "(I)V",
   2113      (void*)gattClientStopBatchScanNative},
   2114     {"gattClientReadScanReportsNative", "(II)V",
   2115      (void*)gattClientReadScanReportsNative},
   2116     // Scan filter JNI functions.
   2117     {"gattClientScanFilterParamAddNative",
   2118      "(Lcom/android/bluetooth/gatt/FilterParams;)V",
   2119      (void*)gattClientScanFilterParamAddNative},
   2120     {"gattClientScanFilterParamDeleteNative", "(II)V",
   2121      (void*)gattClientScanFilterParamDeleteNative},
   2122     {"gattClientScanFilterParamClearAllNative", "(I)V",
   2123      (void*)gattClientScanFilterParamClearAllNative},
   2124     {"gattClientScanFilterAddNative",
   2125      "(IIIIIJJJJLjava/lang/String;Ljava/lang/String;B[B[B)V",
   2126      (void*)gattClientScanFilterAddNative},
   2127     {"gattClientScanFilterDeleteNative",
   2128      "(IIIIIJJJJLjava/lang/String;Ljava/lang/String;B[B[B)V",
   2129      (void*)gattClientScanFilterDeleteNative},
   2130     {"gattClientScanFilterClearNative", "(II)V",
   2131      (void*)gattClientScanFilterClearNative},
   2132     {"gattClientScanFilterEnableNative", "(IZ)V",
   2133      (void*)gattClientScanFilterEnableNative},
   2134     {"gattSetScanParametersNative", "(III)V",
   2135      (void*)gattSetScanParametersNative},
   2136 };
   2137 
   2138 // JNI functions defined in GattService class.
   2139 static JNINativeMethod sMethods[] = {
   2140     {"classInitNative", "()V", (void*)classInitNative},
   2141     {"initializeNative", "()V", (void*)initializeNative},
   2142     {"cleanupNative", "()V", (void*)cleanupNative},
   2143     {"gattClientGetDeviceTypeNative", "(Ljava/lang/String;)I",
   2144      (void*)gattClientGetDeviceTypeNative},
   2145     {"gattClientRegisterAppNative", "(JJ)V",
   2146      (void*)gattClientRegisterAppNative},
   2147     {"gattClientUnregisterAppNative", "(I)V",
   2148      (void*)gattClientUnregisterAppNative},
   2149     {"gattClientConnectNative", "(ILjava/lang/String;ZIZI)V",
   2150      (void*)gattClientConnectNative},
   2151     {"gattClientDisconnectNative", "(ILjava/lang/String;I)V",
   2152      (void*)gattClientDisconnectNative},
   2153     {"gattClientSetPreferredPhyNative", "(ILjava/lang/String;III)V",
   2154      (void*)gattClientSetPreferredPhyNative},
   2155     {"gattClientReadPhyNative", "(ILjava/lang/String;)V",
   2156      (void*)gattClientReadPhyNative},
   2157     {"gattClientRefreshNative", "(ILjava/lang/String;)V",
   2158      (void*)gattClientRefreshNative},
   2159     {"gattClientSearchServiceNative", "(IZJJ)V",
   2160      (void*)gattClientSearchServiceNative},
   2161     {"gattClientDiscoverServiceByUuidNative", "(IJJ)V",
   2162      (void*)gattClientDiscoverServiceByUuidNative},
   2163     {"gattClientGetGattDbNative", "(I)V", (void*)gattClientGetGattDbNative},
   2164     {"gattClientReadCharacteristicNative", "(III)V",
   2165      (void*)gattClientReadCharacteristicNative},
   2166     {"gattClientReadUsingCharacteristicUuidNative", "(IJJIII)V",
   2167      (void*)gattClientReadUsingCharacteristicUuidNative},
   2168     {"gattClientReadDescriptorNative", "(III)V",
   2169      (void*)gattClientReadDescriptorNative},
   2170     {"gattClientWriteCharacteristicNative", "(IIII[B)V",
   2171      (void*)gattClientWriteCharacteristicNative},
   2172     {"gattClientWriteDescriptorNative", "(III[B)V",
   2173      (void*)gattClientWriteDescriptorNative},
   2174     {"gattClientExecuteWriteNative", "(IZ)V",
   2175      (void*)gattClientExecuteWriteNative},
   2176     {"gattClientRegisterForNotificationsNative", "(ILjava/lang/String;IZ)V",
   2177      (void*)gattClientRegisterForNotificationsNative},
   2178     {"gattClientReadRemoteRssiNative", "(ILjava/lang/String;)V",
   2179      (void*)gattClientReadRemoteRssiNative},
   2180     {"gattClientConfigureMTUNative", "(II)V",
   2181      (void*)gattClientConfigureMTUNative},
   2182     {"gattConnectionParameterUpdateNative", "(ILjava/lang/String;IIII)V",
   2183      (void*)gattConnectionParameterUpdateNative},
   2184     {"gattServerRegisterAppNative", "(JJ)V",
   2185      (void*)gattServerRegisterAppNative},
   2186     {"gattServerUnregisterAppNative", "(I)V",
   2187      (void*)gattServerUnregisterAppNative},
   2188     {"gattServerConnectNative", "(ILjava/lang/String;ZI)V",
   2189      (void*)gattServerConnectNative},
   2190     {"gattServerDisconnectNative", "(ILjava/lang/String;I)V",
   2191      (void*)gattServerDisconnectNative},
   2192     {"gattServerSetPreferredPhyNative", "(ILjava/lang/String;III)V",
   2193      (void*)gattServerSetPreferredPhyNative},
   2194     {"gattServerReadPhyNative", "(ILjava/lang/String;)V",
   2195      (void*)gattServerReadPhyNative},
   2196     {"gattServerAddServiceNative", "(ILjava/util/List;)V",
   2197      (void*)gattServerAddServiceNative},
   2198     {"gattServerStopServiceNative", "(II)V",
   2199      (void*)gattServerStopServiceNative},
   2200     {"gattServerDeleteServiceNative", "(II)V",
   2201      (void*)gattServerDeleteServiceNative},
   2202     {"gattServerSendIndicationNative", "(III[B)V",
   2203      (void*)gattServerSendIndicationNative},
   2204     {"gattServerSendNotificationNative", "(III[B)V",
   2205      (void*)gattServerSendNotificationNative},
   2206     {"gattServerSendResponseNative", "(IIIIII[BI)V",
   2207      (void*)gattServerSendResponseNative},
   2208 
   2209     {"gattTestNative", "(IJJLjava/lang/String;IIIII)V", (void*)gattTestNative},
   2210 };
   2211 
   2212 int register_com_android_bluetooth_gatt(JNIEnv* env) {
   2213   int register_success = jniRegisterNativeMethods(
   2214       env, "com/android/bluetooth/gatt/ScanManager$ScanNative", sScanMethods,
   2215       NELEM(sScanMethods));
   2216   register_success &= jniRegisterNativeMethods(
   2217       env, "com/android/bluetooth/gatt/AdvertiseManager", sAdvertiseMethods,
   2218       NELEM(sAdvertiseMethods));
   2219   register_success &= jniRegisterNativeMethods(
   2220       env, "com/android/bluetooth/gatt/PeriodicScanManager",
   2221       sPeriodicScanMethods, NELEM(sPeriodicScanMethods));
   2222   return register_success &
   2223          jniRegisterNativeMethods(env, "com/android/bluetooth/gatt/GattService",
   2224                                   sMethods, NELEM(sMethods));
   2225 }
   2226 }
   2227