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 
     18 #define LOG_TAG "BtGatt.JNI"
     19 
     20 #define LOG_NDEBUG 0
     21 
     22 #define CHECK_CALLBACK_ENV                                                      \
     23    if (!checkCallbackThread()) {                                                \
     24        error("Callback: '%s' is not called on the correct thread", __FUNCTION__);\
     25        return;                                                                  \
     26    }
     27 
     28 #include "com_android_bluetooth.h"
     29 #include "hardware/bt_gatt.h"
     30 #include "utils/Log.h"
     31 #include "android_runtime/AndroidRuntime.h"
     32 
     33 #include <string.h>
     34 
     35 #include <cutils/log.h>
     36 #define info(fmt, ...)  ALOGI ("%s(L%d): " fmt,__FUNCTION__, __LINE__,  ## __VA_ARGS__)
     37 #define debug(fmt, ...) ALOGD ("%s(L%d): " fmt,__FUNCTION__, __LINE__,  ## __VA_ARGS__)
     38 #define warn(fmt, ...) ALOGW ("WARNING: %s(L%d): " fmt "##",__FUNCTION__, __LINE__, ## __VA_ARGS__)
     39 #define error(fmt, ...) ALOGE ("ERROR: %s(L%d): " fmt "##",__FUNCTION__, __LINE__, ## __VA_ARGS__)
     40 #define asrt(s) if(!(s)) ALOGE ("%s(L%d): ASSERT %s failed! ##",__FUNCTION__, __LINE__, #s)
     41 
     42 #define BD_ADDR_LEN 6
     43 
     44 #define UUID_PARAMS(uuid_ptr) \
     45     uuid_lsb(uuid_ptr),  uuid_msb(uuid_ptr)
     46 
     47 #define GATT_ID_PARAMS(attr_ptr) \
     48     attr_ptr->inst_id, \
     49     UUID_PARAMS((&attr_ptr->uuid))
     50 
     51 #define SRVC_ID_PARAMS(srvc_ptr) \
     52     (srvc_ptr->is_primary ? \
     53     BTGATT_SERVICE_TYPE_PRIMARY : BTGATT_SERVICE_TYPE_SECONDARY), \
     54     GATT_ID_PARAMS((&srvc_ptr->id))
     55 
     56 
     57 static void set_uuid(uint8_t* uuid, jlong uuid_msb, jlong uuid_lsb)
     58 {
     59     for (int i = 0; i != 8; ++i)
     60     {
     61         uuid[i]     = (uuid_lsb >> (8 * i)) & 0xFF;
     62         uuid[i + 8] = (uuid_msb >> (8 * i)) & 0xFF;
     63     }
     64 }
     65 
     66 static uint64_t uuid_lsb(bt_uuid_t* uuid)
     67 {
     68     uint64_t  lsb = 0;
     69     int i;
     70 
     71     for (i = 7; i >= 0; i--)
     72     {
     73         lsb <<= 8;
     74         lsb |= uuid->uu[i];
     75     }
     76 
     77     return lsb;
     78 }
     79 
     80 static uint64_t uuid_msb(bt_uuid_t* uuid)
     81 {
     82     uint64_t msb = 0;
     83     int i;
     84 
     85     for (i = 15; i >= 8; i--)
     86     {
     87         msb <<= 8;
     88         msb |= uuid->uu[i];
     89     }
     90 
     91     return msb;
     92 }
     93 
     94 static void bd_addr_str_to_addr(const char* str, uint8_t *bd_addr)
     95 {
     96     int    i;
     97     char   c;
     98 
     99     c = *str++;
    100     for (i = 0; i < BD_ADDR_LEN; i++)
    101     {
    102         if (c >= '0' && c <= '9')
    103             bd_addr[i] = c - '0';
    104         else if (c >= 'a' && c <= 'z')
    105             bd_addr[i] = c - 'a' + 10;
    106         else   // (c >= 'A' && c <= 'Z')
    107             bd_addr[i] = c - 'A' + 10;
    108 
    109         c = *str++;
    110         if (c != ':')
    111         {
    112             bd_addr[i] <<= 4;
    113             if (c >= '0' && c <= '9')
    114                 bd_addr[i] |= c - '0';
    115             else if (c >= 'a' && c <= 'z')
    116                 bd_addr[i] |= c - 'a' + 10;
    117             else   // (c >= 'A' && c <= 'Z')
    118                 bd_addr[i] |= c - 'A' + 10;
    119 
    120             c = *str++;
    121         }
    122 
    123         c = *str++;
    124     }
    125 }
    126 
    127 static void jstr2bdaddr(JNIEnv* env, bt_bdaddr_t *bda, jstring address)
    128 {
    129     const char* c_bda = env->GetStringUTFChars(address, NULL);
    130     if (c_bda != NULL && bda != NULL && strlen(c_bda) == 17)
    131     {
    132         bd_addr_str_to_addr(c_bda, bda->address);
    133         env->ReleaseStringUTFChars(address, c_bda);
    134     }
    135 }
    136 
    137 namespace android {
    138 
    139 /**
    140  * Client callback methods
    141  */
    142 
    143 static jmethodID method_onClientRegistered;
    144 static jmethodID method_onScanResult;
    145 static jmethodID method_onConnected;
    146 static jmethodID method_onDisconnected;
    147 static jmethodID method_onReadCharacteristic;
    148 static jmethodID method_onWriteCharacteristic;
    149 static jmethodID method_onExecuteCompleted;
    150 static jmethodID method_onSearchCompleted;
    151 static jmethodID method_onSearchResult;
    152 static jmethodID method_onReadDescriptor;
    153 static jmethodID method_onWriteDescriptor;
    154 static jmethodID method_onNotify;
    155 static jmethodID method_onGetCharacteristic;
    156 static jmethodID method_onGetDescriptor;
    157 static jmethodID method_onGetIncludedService;
    158 static jmethodID method_onRegisterForNotifications;
    159 static jmethodID method_onReadRemoteRssi;
    160 static jmethodID method_onAdvertiseCallback;
    161 static jmethodID method_onConfigureMTU;
    162 static jmethodID method_onScanFilterConfig;
    163 static jmethodID method_onScanFilterParamsConfigured;
    164 static jmethodID method_onScanFilterEnableDisabled;
    165 static jmethodID method_onMultiAdvEnable;
    166 static jmethodID method_onMultiAdvUpdate;
    167 static jmethodID method_onMultiAdvSetAdvData;
    168 static jmethodID method_onMultiAdvDisable;
    169 static jmethodID method_onClientCongestion;
    170 static jmethodID method_onBatchScanStorageConfigured;
    171 static jmethodID method_onBatchScanStartStopped;
    172 static jmethodID method_onBatchScanReports;
    173 static jmethodID method_onBatchScanThresholdCrossed;
    174 
    175 static jmethodID method_CreateonTrackAdvFoundLostObject;
    176 static jmethodID method_onTrackAdvFoundLost;
    177 static jmethodID method_onScanParamSetupCompleted;
    178 
    179 /**
    180  * Server callback methods
    181  */
    182 static jmethodID method_onServerRegistered;
    183 static jmethodID method_onClientConnected;
    184 static jmethodID method_onServiceAdded;
    185 static jmethodID method_onIncludedServiceAdded;
    186 static jmethodID method_onCharacteristicAdded;
    187 static jmethodID method_onDescriptorAdded;
    188 static jmethodID method_onServiceStarted;
    189 static jmethodID method_onServiceStopped;
    190 static jmethodID method_onServiceDeleted;
    191 static jmethodID method_onResponseSendCompleted;
    192 static jmethodID method_onAttributeRead;
    193 static jmethodID method_onAttributeWrite;
    194 static jmethodID method_onExecuteWrite;
    195 static jmethodID method_onNotificationSent;
    196 static jmethodID method_onServerCongestion;
    197 static jmethodID method_onServerMtuChanged;
    198 
    199 /**
    200  * Static variables
    201  */
    202 
    203 static const btgatt_interface_t *sGattIf = NULL;
    204 static jobject mCallbacksObj = NULL;
    205 static JNIEnv *sCallbackEnv = NULL;
    206 
    207 static bool checkCallbackThread() {
    208     sCallbackEnv = getCallbackEnv();
    209 
    210     JNIEnv* env = AndroidRuntime::getJNIEnv();
    211     if (sCallbackEnv != env || sCallbackEnv == NULL) return false;
    212     return true;
    213 }
    214 
    215 /**
    216  * BTA client callbacks
    217  */
    218 
    219 void btgattc_register_app_cb(int status, int clientIf, bt_uuid_t *app_uuid)
    220 {
    221     CHECK_CALLBACK_ENV
    222     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientRegistered, status,
    223         clientIf, UUID_PARAMS(app_uuid));
    224     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    225 }
    226 
    227 void btgattc_scan_result_cb(bt_bdaddr_t* bda, int rssi, uint8_t* adv_data)
    228 {
    229     CHECK_CALLBACK_ENV
    230 
    231     char c_address[32];
    232     snprintf(c_address, sizeof(c_address),"%02X:%02X:%02X:%02X:%02X:%02X",
    233         bda->address[0], bda->address[1], bda->address[2],
    234         bda->address[3], bda->address[4], bda->address[5]);
    235 
    236     jstring address = sCallbackEnv->NewStringUTF(c_address);
    237     jbyteArray jb = sCallbackEnv->NewByteArray(62);
    238     sCallbackEnv->SetByteArrayRegion(jb, 0, 62, (jbyte *) adv_data);
    239 
    240     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScanResult
    241         , address, rssi, jb);
    242 
    243     sCallbackEnv->DeleteLocalRef(address);
    244     sCallbackEnv->DeleteLocalRef(jb);
    245     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    246 }
    247 
    248 void btgattc_open_cb(int conn_id, int status, int clientIf, bt_bdaddr_t* bda)
    249 {
    250     CHECK_CALLBACK_ENV
    251 
    252     char c_address[32];
    253     snprintf(c_address, sizeof(c_address),"%02X:%02X:%02X:%02X:%02X:%02X",
    254         bda->address[0], bda->address[1], bda->address[2],
    255         bda->address[3], bda->address[4], bda->address[5]);
    256 
    257     jstring address = sCallbackEnv->NewStringUTF(c_address);
    258     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnected,
    259         clientIf, conn_id, status, address);
    260     sCallbackEnv->DeleteLocalRef(address);
    261     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    262 }
    263 
    264 void btgattc_close_cb(int conn_id, int status, int clientIf, bt_bdaddr_t* bda)
    265 {
    266     CHECK_CALLBACK_ENV
    267     char c_address[32];
    268     snprintf(c_address, sizeof(c_address),"%02X:%02X:%02X:%02X:%02X:%02X",
    269         bda->address[0], bda->address[1], bda->address[2],
    270         bda->address[3], bda->address[4], bda->address[5]);
    271 
    272     jstring address = sCallbackEnv->NewStringUTF(c_address);
    273     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onDisconnected,
    274         clientIf, conn_id, status, address);
    275     sCallbackEnv->DeleteLocalRef(address);
    276     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    277 }
    278 
    279 void btgattc_search_complete_cb(int conn_id, int status)
    280 {
    281     CHECK_CALLBACK_ENV
    282     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onSearchCompleted,
    283                                  conn_id, status);
    284     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    285 }
    286 
    287 void btgattc_search_result_cb(int conn_id, btgatt_srvc_id_t *srvc_id)
    288 {
    289     CHECK_CALLBACK_ENV
    290     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onSearchResult, conn_id,
    291         SRVC_ID_PARAMS(srvc_id));
    292     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    293 }
    294 
    295 void btgattc_get_characteristic_cb(int conn_id, int status,
    296                 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
    297                 int char_prop)
    298 {
    299     CHECK_CALLBACK_ENV
    300     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onGetCharacteristic
    301         , conn_id, status, SRVC_ID_PARAMS(srvc_id), GATT_ID_PARAMS(char_id)
    302         , char_prop);
    303     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    304 }
    305 
    306 void btgattc_get_descriptor_cb(int conn_id, int status,
    307                 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
    308                 btgatt_gatt_id_t *descr_id)
    309 {
    310     CHECK_CALLBACK_ENV
    311     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onGetDescriptor
    312         , conn_id, status, SRVC_ID_PARAMS(srvc_id), GATT_ID_PARAMS(char_id)
    313         , GATT_ID_PARAMS(descr_id));
    314     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    315 }
    316 
    317 void btgattc_get_included_service_cb(int conn_id, int status,
    318                 btgatt_srvc_id_t *srvc_id, btgatt_srvc_id_t *incl_srvc_id)
    319 {
    320     CHECK_CALLBACK_ENV
    321     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onGetIncludedService
    322         , conn_id, status, SRVC_ID_PARAMS(srvc_id), SRVC_ID_PARAMS(incl_srvc_id));
    323     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    324 }
    325 
    326 void btgattc_register_for_notification_cb(int conn_id, int registered, int status,
    327                                           btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id)
    328 {
    329     CHECK_CALLBACK_ENV
    330     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onRegisterForNotifications
    331         , conn_id, status, registered, SRVC_ID_PARAMS(srvc_id), GATT_ID_PARAMS(char_id));
    332     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    333 }
    334 
    335 void btgattc_notify_cb(int conn_id, btgatt_notify_params_t *p_data)
    336 {
    337     CHECK_CALLBACK_ENV
    338 
    339     char c_address[32];
    340     snprintf(c_address, sizeof(c_address), "%02X:%02X:%02X:%02X:%02X:%02X",
    341         p_data->bda.address[0], p_data->bda.address[1], p_data->bda.address[2],
    342         p_data->bda.address[3], p_data->bda.address[4], p_data->bda.address[5]);
    343 
    344     jstring address = sCallbackEnv->NewStringUTF(c_address);
    345     jbyteArray jb = sCallbackEnv->NewByteArray(p_data->len);
    346     sCallbackEnv->SetByteArrayRegion(jb, 0, p_data->len, (jbyte *) p_data->value);
    347 
    348     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNotify
    349         , conn_id, address, SRVC_ID_PARAMS((&p_data->srvc_id))
    350         , GATT_ID_PARAMS((&p_data->char_id)), p_data->is_notify, jb);
    351 
    352     sCallbackEnv->DeleteLocalRef(address);
    353     sCallbackEnv->DeleteLocalRef(jb);
    354     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    355 }
    356 
    357 void btgattc_read_characteristic_cb(int conn_id, int status, btgatt_read_params_t *p_data)
    358 {
    359     CHECK_CALLBACK_ENV
    360 
    361     jbyteArray jb;
    362     if ( status == 0 )      //successful
    363     {
    364         jb = sCallbackEnv->NewByteArray(p_data->value.len);
    365         sCallbackEnv->SetByteArrayRegion(jb, 0, p_data->value.len,
    366             (jbyte *) p_data->value.value);
    367     } else {
    368         uint8_t value = 0;
    369         jb = sCallbackEnv->NewByteArray(1);
    370         sCallbackEnv->SetByteArrayRegion(jb, 0, 1, (jbyte *) &value);
    371     }
    372 
    373     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onReadCharacteristic
    374         , conn_id, status, SRVC_ID_PARAMS((&p_data->srvc_id))
    375         , GATT_ID_PARAMS((&p_data->char_id)), p_data->value_type, jb);
    376     sCallbackEnv->DeleteLocalRef(jb);
    377     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    378 }
    379 
    380 void btgattc_write_characteristic_cb(int conn_id, int status, btgatt_write_params_t *p_data)
    381 {
    382     CHECK_CALLBACK_ENV
    383     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onWriteCharacteristic
    384         , conn_id, status, SRVC_ID_PARAMS((&p_data->srvc_id))
    385         , GATT_ID_PARAMS((&p_data->char_id)));
    386     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    387 }
    388 
    389 void btgattc_execute_write_cb(int conn_id, int status)
    390 {
    391     CHECK_CALLBACK_ENV
    392     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onExecuteCompleted
    393         , conn_id, status);
    394     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    395 }
    396 
    397 void btgattc_read_descriptor_cb(int conn_id, int status, btgatt_read_params_t *p_data)
    398 {
    399     CHECK_CALLBACK_ENV
    400 
    401     jbyteArray jb;
    402     if ( p_data->value.len != 0 )
    403     {
    404         jb = sCallbackEnv->NewByteArray(p_data->value.len);
    405         sCallbackEnv->SetByteArrayRegion(jb, 0, p_data->value.len,
    406                                 (jbyte *) p_data->value.value);
    407     } else {
    408         jb = sCallbackEnv->NewByteArray(1);
    409     }
    410 
    411     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onReadDescriptor
    412         , conn_id, status, SRVC_ID_PARAMS((&p_data->srvc_id))
    413         , GATT_ID_PARAMS((&p_data->char_id)), GATT_ID_PARAMS((&p_data->descr_id))
    414         , p_data->value_type, jb);
    415 
    416     sCallbackEnv->DeleteLocalRef(jb);
    417     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    418 }
    419 
    420 void btgattc_write_descriptor_cb(int conn_id, int status, btgatt_write_params_t *p_data)
    421 {
    422     CHECK_CALLBACK_ENV
    423     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onWriteDescriptor
    424         , conn_id, status, SRVC_ID_PARAMS((&p_data->srvc_id))
    425         , GATT_ID_PARAMS((&p_data->char_id))
    426         , GATT_ID_PARAMS((&p_data->descr_id)));
    427     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    428 }
    429 
    430 void btgattc_remote_rssi_cb(int client_if,bt_bdaddr_t* bda, int rssi, int status)
    431 {
    432     CHECK_CALLBACK_ENV
    433 
    434     char c_address[32];
    435     snprintf(c_address, sizeof(c_address),"%02X:%02X:%02X:%02X:%02X:%02X",
    436         bda->address[0], bda->address[1], bda->address[2],
    437         bda->address[3], bda->address[4], bda->address[5]);
    438     jstring address = sCallbackEnv->NewStringUTF(c_address);
    439     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onReadRemoteRssi,
    440        client_if, address, rssi, status);
    441     sCallbackEnv->DeleteLocalRef(address);
    442     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    443 }
    444 
    445 void btgattc_advertise_cb(int status, int client_if)
    446 {
    447     CHECK_CALLBACK_ENV
    448     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAdvertiseCallback, status, client_if);
    449     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    450 }
    451 
    452 void btgattc_configure_mtu_cb(int conn_id, int status, int mtu)
    453 {
    454     CHECK_CALLBACK_ENV
    455     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConfigureMTU,
    456                                  conn_id, status, mtu);
    457     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    458 }
    459 
    460 void btgattc_scan_filter_cfg_cb(int action, int client_if, int status, int filt_type,
    461                                 int avbl_space)
    462 {
    463     CHECK_CALLBACK_ENV
    464     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScanFilterConfig,
    465                                  action, status, client_if, filt_type, avbl_space);
    466     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    467 }
    468 
    469 void btgattc_scan_filter_param_cb(int action, int client_if, int status, int avbl_space)
    470 {
    471     CHECK_CALLBACK_ENV
    472     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScanFilterParamsConfigured,
    473             action, status, client_if, avbl_space);
    474     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    475 }
    476 
    477 void btgattc_scan_filter_status_cb(int action, int client_if, int status)
    478 {
    479     CHECK_CALLBACK_ENV
    480     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScanFilterEnableDisabled,
    481             action, status, client_if);
    482     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    483 }
    484 
    485 void btgattc_multiadv_enable_cb(int client_if, int status)
    486 {
    487     CHECK_CALLBACK_ENV
    488     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onMultiAdvEnable, status,client_if);
    489     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    490 }
    491 
    492 void btgattc_multiadv_update_cb(int client_if, int status)
    493 {
    494     CHECK_CALLBACK_ENV
    495     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onMultiAdvUpdate, status, client_if);
    496     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    497 }
    498 
    499 void btgattc_multiadv_setadv_data_cb(int client_if, int status)
    500 {
    501     CHECK_CALLBACK_ENV
    502     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onMultiAdvSetAdvData, status, client_if);
    503     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    504 }
    505 
    506 void btgattc_multiadv_disable_cb(int client_if, int status)
    507 {
    508     CHECK_CALLBACK_ENV
    509     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onMultiAdvDisable, status, client_if);
    510     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    511 }
    512 
    513 void btgattc_congestion_cb(int conn_id, bool congested)
    514 {
    515     CHECK_CALLBACK_ENV
    516     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientCongestion, conn_id, congested);
    517     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    518 }
    519 
    520 void btgattc_batchscan_cfg_storage_cb(int client_if, int status)
    521 {
    522     CHECK_CALLBACK_ENV
    523     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onBatchScanStorageConfigured, status, client_if);
    524     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    525 }
    526 
    527 void btgattc_batchscan_startstop_cb(int startstop_action, int client_if, int status)
    528 {
    529     CHECK_CALLBACK_ENV
    530     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onBatchScanStartStopped, startstop_action,
    531                                  status, client_if);
    532     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    533 }
    534 
    535 void btgattc_batchscan_reports_cb(int client_if, int status, int report_format,
    536                         int num_records, int data_len, uint8_t *p_rep_data)
    537 {
    538     CHECK_CALLBACK_ENV
    539     jbyteArray jb = sCallbackEnv->NewByteArray(data_len);
    540     sCallbackEnv->SetByteArrayRegion(jb, 0, data_len, (jbyte *) p_rep_data);
    541 
    542     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onBatchScanReports, status, client_if,
    543                                 report_format, num_records, jb);
    544     sCallbackEnv->DeleteLocalRef(jb);
    545     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    546 }
    547 
    548 void btgattc_batchscan_threshold_cb(int client_if)
    549 {
    550     CHECK_CALLBACK_ENV
    551     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onBatchScanThresholdCrossed, client_if);
    552     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    553 }
    554 
    555 void btgattc_track_adv_event_cb(btgatt_track_adv_info_t *p_adv_track_info)
    556 {
    557     CHECK_CALLBACK_ENV
    558     char c_address[32];
    559     jobject trackadv_obj = NULL;
    560 
    561     snprintf(c_address, sizeof(c_address),"%02X:%02X:%02X:%02X:%02X:%02X",
    562         p_adv_track_info->bd_addr.address[0], p_adv_track_info->bd_addr.address[1],
    563         p_adv_track_info->bd_addr.address[2], p_adv_track_info->bd_addr.address[3],
    564         p_adv_track_info->bd_addr.address[4], p_adv_track_info->bd_addr.address[5]);
    565 
    566     jstring address = sCallbackEnv->NewStringUTF(c_address);
    567 
    568     jbyteArray jb_adv_pkt = sCallbackEnv->NewByteArray(p_adv_track_info->adv_pkt_len);
    569     jbyteArray jb_scan_rsp = sCallbackEnv->NewByteArray(p_adv_track_info->scan_rsp_len);
    570 
    571     sCallbackEnv->SetByteArrayRegion(jb_adv_pkt, 0, p_adv_track_info->adv_pkt_len,
    572                                      (jbyte *) p_adv_track_info->p_adv_pkt_data);
    573 
    574     sCallbackEnv->SetByteArrayRegion(jb_scan_rsp, 0, p_adv_track_info->scan_rsp_len,
    575                                      (jbyte *) p_adv_track_info->p_scan_rsp_data);
    576 
    577     trackadv_obj = sCallbackEnv->CallObjectMethod(mCallbacksObj, method_CreateonTrackAdvFoundLostObject,
    578                     p_adv_track_info->client_if, p_adv_track_info->adv_pkt_len, jb_adv_pkt,
    579                     p_adv_track_info->scan_rsp_len, jb_scan_rsp, p_adv_track_info->filt_index,
    580                     p_adv_track_info->advertiser_state, p_adv_track_info->advertiser_info_present,
    581                     address, p_adv_track_info->addr_type, p_adv_track_info->tx_power,
    582                     p_adv_track_info->rssi_value, p_adv_track_info->time_stamp);
    583 
    584     if (NULL != trackadv_obj) {
    585         sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onTrackAdvFoundLost, trackadv_obj);
    586         sCallbackEnv->DeleteLocalRef(trackadv_obj);
    587     }
    588     sCallbackEnv->DeleteLocalRef(address);
    589     sCallbackEnv->DeleteLocalRef(jb_adv_pkt);
    590     sCallbackEnv->DeleteLocalRef(jb_scan_rsp);
    591 
    592     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    593 }
    594 
    595 void btgattc_scan_parameter_setup_completed_cb(int client_if, btgattc_error_t status)
    596 {
    597     CHECK_CALLBACK_ENV
    598     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScanParamSetupCompleted, status, client_if);
    599     checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
    600 }
    601 
    602 static const btgatt_client_callbacks_t sGattClientCallbacks = {
    603     btgattc_register_app_cb,
    604     btgattc_scan_result_cb,
    605     btgattc_open_cb,
    606     btgattc_close_cb,
    607     btgattc_search_complete_cb,
    608     btgattc_search_result_cb,
    609     btgattc_get_characteristic_cb,
    610     btgattc_get_descriptor_cb,
    611     btgattc_get_included_service_cb,
    612     btgattc_register_for_notification_cb,
    613     btgattc_notify_cb,
    614     btgattc_read_characteristic_cb,
    615     btgattc_write_characteristic_cb,
    616     btgattc_read_descriptor_cb,
    617     btgattc_write_descriptor_cb,
    618     btgattc_execute_write_cb,
    619     btgattc_remote_rssi_cb,
    620     btgattc_advertise_cb,
    621     btgattc_configure_mtu_cb,
    622     btgattc_scan_filter_cfg_cb,
    623     btgattc_scan_filter_param_cb,
    624     btgattc_scan_filter_status_cb,
    625     btgattc_multiadv_enable_cb,
    626     btgattc_multiadv_update_cb,
    627     btgattc_multiadv_setadv_data_cb,
    628     btgattc_multiadv_disable_cb,
    629     btgattc_congestion_cb,
    630     btgattc_batchscan_cfg_storage_cb,
    631     btgattc_batchscan_startstop_cb,
    632     btgattc_batchscan_reports_cb,
    633     btgattc_batchscan_threshold_cb,
    634     btgattc_track_adv_event_cb,
    635     btgattc_scan_parameter_setup_completed_cb
    636 };
    637 
    638 
    639 /**
    640  * BTA server callbacks
    641  */
    642 
    643 void btgatts_register_app_cb(int status, int server_if, bt_uuid_t *uuid)
    644 {
    645     CHECK_CALLBACK_ENV
    646     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerRegistered
    647         , status, server_if, UUID_PARAMS(uuid));
    648     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    649 }
    650 
    651 void btgatts_connection_cb(int conn_id, int server_if, int connected, bt_bdaddr_t *bda)
    652 {
    653     CHECK_CALLBACK_ENV
    654 
    655     char c_address[32];
    656     sprintf(c_address, "%02X:%02X:%02X:%02X:%02X:%02X",
    657             bda->address[0], bda->address[1], bda->address[2],
    658             bda->address[3], bda->address[4], bda->address[5]);
    659 
    660     jstring address = sCallbackEnv->NewStringUTF(c_address);
    661     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientConnected,
    662                                  address, connected, conn_id, server_if);
    663     sCallbackEnv->DeleteLocalRef(address);
    664     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    665 }
    666 
    667 void btgatts_service_added_cb(int status, int server_if,
    668                               btgatt_srvc_id_t *srvc_id, int srvc_handle)
    669 {
    670     CHECK_CALLBACK_ENV
    671     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceAdded, status,
    672                                  server_if, SRVC_ID_PARAMS(srvc_id),
    673                                  srvc_handle);
    674     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    675 }
    676 
    677 void btgatts_included_service_added_cb(int status, int server_if,
    678                                    int srvc_handle,
    679                                    int incl_srvc_handle)
    680 {
    681     CHECK_CALLBACK_ENV
    682     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onIncludedServiceAdded,
    683                                  status, server_if, srvc_handle, incl_srvc_handle);
    684     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    685 }
    686 
    687 void btgatts_characteristic_added_cb(int status, int server_if, bt_uuid_t *char_id,
    688                                      int srvc_handle, int char_handle)
    689 {
    690     CHECK_CALLBACK_ENV
    691     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onCharacteristicAdded,
    692                                  status, server_if, UUID_PARAMS(char_id),
    693                                  srvc_handle, char_handle);
    694     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    695 }
    696 
    697 void btgatts_descriptor_added_cb(int status, int server_if,
    698                                  bt_uuid_t *descr_id, int srvc_handle,
    699                                  int descr_handle)
    700 {
    701     CHECK_CALLBACK_ENV
    702     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onDescriptorAdded,
    703                                  status, server_if, UUID_PARAMS(descr_id),
    704                                  srvc_handle, descr_handle);
    705     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    706 }
    707 
    708 void btgatts_service_started_cb(int status, int server_if, int srvc_handle)
    709 {
    710     CHECK_CALLBACK_ENV
    711     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceStarted, status,
    712                                  server_if, srvc_handle);
    713     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    714 }
    715 
    716 void btgatts_service_stopped_cb(int status, int server_if, int srvc_handle)
    717 {
    718     CHECK_CALLBACK_ENV
    719     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceStopped, status,
    720                                  server_if, srvc_handle);
    721     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    722 }
    723 
    724 void btgatts_service_deleted_cb(int status, int server_if, int srvc_handle)
    725 {
    726     CHECK_CALLBACK_ENV
    727     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceDeleted, status,
    728                                  server_if, srvc_handle);
    729     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    730 }
    731 
    732 void btgatts_request_read_cb(int conn_id, int trans_id, bt_bdaddr_t *bda,
    733                              int attr_handle, int offset, bool is_long)
    734 {
    735     CHECK_CALLBACK_ENV
    736 
    737     char c_address[32];
    738     sprintf(c_address, "%02X:%02X:%02X:%02X:%02X:%02X",
    739             bda->address[0], bda->address[1], bda->address[2],
    740             bda->address[3], bda->address[4], bda->address[5]);
    741 
    742     jstring address = sCallbackEnv->NewStringUTF(c_address);
    743     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAttributeRead,
    744                                  address, conn_id, trans_id, attr_handle,
    745                                  offset, is_long);
    746     sCallbackEnv->DeleteLocalRef(address);
    747     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    748 }
    749 
    750 void btgatts_request_write_cb(int conn_id, int trans_id,
    751                               bt_bdaddr_t *bda, int attr_handle,
    752                               int offset, int length,
    753                               bool need_rsp, bool is_prep, uint8_t* value)
    754 {
    755     CHECK_CALLBACK_ENV
    756 
    757     char c_address[32];
    758     sprintf(c_address, "%02X:%02X:%02X:%02X:%02X:%02X",
    759             bda->address[0], bda->address[1], bda->address[2],
    760             bda->address[3], bda->address[4], bda->address[5]);
    761 
    762     jstring address = sCallbackEnv->NewStringUTF(c_address);
    763 
    764     jbyteArray val = sCallbackEnv->NewByteArray(length);
    765     if (val) sCallbackEnv->SetByteArrayRegion(val, 0, length, (jbyte*)value);
    766     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAttributeWrite,
    767                                  address, conn_id, trans_id, attr_handle,
    768                                  offset, length, need_rsp, is_prep, val);
    769     sCallbackEnv->DeleteLocalRef(address);
    770     sCallbackEnv->DeleteLocalRef(val);
    771     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    772 }
    773 
    774 void btgatts_request_exec_write_cb(int conn_id, int trans_id,
    775                                    bt_bdaddr_t *bda, int exec_write)
    776 {
    777     CHECK_CALLBACK_ENV
    778 
    779     char c_address[32];
    780     sprintf(c_address, "%02X:%02X:%02X:%02X:%02X:%02X",
    781             bda->address[0], bda->address[1], bda->address[2],
    782             bda->address[3], bda->address[4], bda->address[5]);
    783 
    784     jstring address = sCallbackEnv->NewStringUTF(c_address);
    785     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onExecuteWrite,
    786                                  address, conn_id, trans_id, exec_write);
    787     sCallbackEnv->DeleteLocalRef(address);
    788     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    789 }
    790 
    791 void btgatts_response_confirmation_cb(int status, int handle)
    792 {
    793     CHECK_CALLBACK_ENV
    794     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onResponseSendCompleted,
    795                                  status, handle);
    796     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    797 }
    798 
    799 void btgatts_indication_sent_cb(int conn_id, int status)
    800 {
    801     CHECK_CALLBACK_ENV
    802     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNotificationSent,
    803                                  conn_id, status);
    804     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    805 }
    806 
    807 void btgatts_congestion_cb(int conn_id, bool congested)
    808 {
    809     CHECK_CALLBACK_ENV
    810     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerCongestion, conn_id, congested);
    811     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    812 }
    813 
    814 void btgatts_mtu_changed_cb(int conn_id, int mtu)
    815 {
    816     CHECK_CALLBACK_ENV
    817     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerMtuChanged, conn_id, mtu);
    818     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    819 }
    820 
    821 static const btgatt_server_callbacks_t sGattServerCallbacks = {
    822     btgatts_register_app_cb,
    823     btgatts_connection_cb,
    824     btgatts_service_added_cb,
    825     btgatts_included_service_added_cb,
    826     btgatts_characteristic_added_cb,
    827     btgatts_descriptor_added_cb,
    828     btgatts_service_started_cb,
    829     btgatts_service_stopped_cb,
    830     btgatts_service_deleted_cb,
    831     btgatts_request_read_cb,
    832     btgatts_request_write_cb,
    833     btgatts_request_exec_write_cb,
    834     btgatts_response_confirmation_cb,
    835     btgatts_indication_sent_cb,
    836     btgatts_congestion_cb,
    837     btgatts_mtu_changed_cb
    838 };
    839 
    840 /**
    841  * GATT callbacks
    842  */
    843 
    844 static const btgatt_callbacks_t sGattCallbacks = {
    845     sizeof(btgatt_callbacks_t),
    846     &sGattClientCallbacks,
    847     &sGattServerCallbacks
    848 };
    849 
    850 /**
    851  * Native function definitions
    852  */
    853 static void classInitNative(JNIEnv* env, jclass clazz) {
    854 
    855     // Client callbacks
    856 
    857     method_onClientRegistered = env->GetMethodID(clazz, "onClientRegistered", "(IIJJ)V");
    858     method_onScanResult = env->GetMethodID(clazz, "onScanResult", "(Ljava/lang/String;I[B)V");
    859     method_onConnected   = env->GetMethodID(clazz, "onConnected", "(IIILjava/lang/String;)V");
    860     method_onDisconnected = env->GetMethodID(clazz, "onDisconnected", "(IIILjava/lang/String;)V");
    861     method_onReadCharacteristic = env->GetMethodID(clazz, "onReadCharacteristic", "(IIIIJJIJJI[B)V");
    862     method_onWriteCharacteristic = env->GetMethodID(clazz, "onWriteCharacteristic", "(IIIIJJIJJ)V");
    863     method_onExecuteCompleted = env->GetMethodID(clazz, "onExecuteCompleted",  "(II)V");
    864     method_onSearchCompleted = env->GetMethodID(clazz, "onSearchCompleted",  "(II)V");
    865     method_onSearchResult = env->GetMethodID(clazz, "onSearchResult", "(IIIJJ)V");
    866     method_onReadDescriptor = env->GetMethodID(clazz, "onReadDescriptor", "(IIIIJJIJJIJJI[B)V");
    867     method_onWriteDescriptor = env->GetMethodID(clazz, "onWriteDescriptor", "(IIIIJJIJJIJJ)V");
    868     method_onNotify = env->GetMethodID(clazz, "onNotify", "(ILjava/lang/String;IIJJIJJZ[B)V");
    869     method_onGetCharacteristic = env->GetMethodID(clazz, "onGetCharacteristic", "(IIIIJJIJJI)V");
    870     method_onGetDescriptor = env->GetMethodID(clazz, "onGetDescriptor", "(IIIIJJIJJIJJ)V");
    871     method_onGetIncludedService = env->GetMethodID(clazz, "onGetIncludedService", "(IIIIJJIIJJ)V");
    872     method_onRegisterForNotifications = env->GetMethodID(clazz, "onRegisterForNotifications", "(IIIIIJJIJJ)V");
    873     method_onReadRemoteRssi = env->GetMethodID(clazz, "onReadRemoteRssi", "(ILjava/lang/String;II)V");
    874     method_onConfigureMTU = env->GetMethodID(clazz, "onConfigureMTU", "(III)V");
    875     method_onAdvertiseCallback = env->GetMethodID(clazz, "onAdvertiseCallback", "(II)V");
    876     method_onScanFilterConfig = env->GetMethodID(clazz, "onScanFilterConfig", "(IIIII)V");
    877     method_onScanFilterParamsConfigured = env->GetMethodID(clazz, "onScanFilterParamsConfigured", "(IIII)V");
    878     method_onScanFilterEnableDisabled = env->GetMethodID(clazz, "onScanFilterEnableDisabled", "(III)V");
    879     method_onMultiAdvEnable = env->GetMethodID(clazz, "onAdvertiseInstanceEnabled", "(II)V");
    880     method_onMultiAdvUpdate = env->GetMethodID(clazz, "onAdvertiseDataUpdated", "(II)V");
    881     method_onMultiAdvSetAdvData = env->GetMethodID(clazz, "onAdvertiseDataSet", "(II)V");
    882     method_onMultiAdvDisable = env->GetMethodID(clazz, "onAdvertiseInstanceDisabled", "(II)V");
    883     method_onClientCongestion = env->GetMethodID(clazz, "onClientCongestion", "(IZ)V");
    884     method_onBatchScanStorageConfigured = env->GetMethodID(clazz, "onBatchScanStorageConfigured", "(II)V");
    885     method_onBatchScanStartStopped = env->GetMethodID(clazz, "onBatchScanStartStopped", "(III)V");
    886     method_onBatchScanReports = env->GetMethodID(clazz, "onBatchScanReports", "(IIII[B)V");
    887     method_onBatchScanThresholdCrossed = env->GetMethodID(clazz, "onBatchScanThresholdCrossed", "(I)V");
    888     method_CreateonTrackAdvFoundLostObject = env->GetMethodID(clazz, "CreateonTrackAdvFoundLostObject", "(II[BI[BIIILjava/lang/String;IIII)Lcom/android/bluetooth/gatt/AdvtFilterOnFoundOnLostInfo;");
    889     method_onTrackAdvFoundLost = env->GetMethodID(clazz, "onTrackAdvFoundLost",
    890                                                          "(Lcom/android/bluetooth/gatt/AdvtFilterOnFoundOnLostInfo;)V");
    891     method_onScanParamSetupCompleted = env->GetMethodID(clazz, "onScanParamSetupCompleted", "(II)V");
    892 
    893     // Server callbacks
    894 
    895     method_onServerRegistered = env->GetMethodID(clazz, "onServerRegistered", "(IIJJ)V");
    896     method_onClientConnected = env->GetMethodID(clazz, "onClientConnected", "(Ljava/lang/String;ZII)V");
    897     method_onServiceAdded = env->GetMethodID(clazz, "onServiceAdded", "(IIIIJJI)V");
    898     method_onIncludedServiceAdded = env->GetMethodID(clazz, "onIncludedServiceAdded", "(IIII)V");
    899     method_onCharacteristicAdded  = env->GetMethodID(clazz, "onCharacteristicAdded", "(IIJJII)V");
    900     method_onDescriptorAdded = env->GetMethodID(clazz, "onDescriptorAdded", "(IIJJII)V");
    901     method_onServiceStarted = env->GetMethodID(clazz, "onServiceStarted", "(III)V");
    902     method_onServiceStopped = env->GetMethodID(clazz, "onServiceStopped", "(III)V");
    903     method_onServiceDeleted = env->GetMethodID(clazz, "onServiceDeleted", "(III)V");
    904     method_onResponseSendCompleted = env->GetMethodID(clazz, "onResponseSendCompleted", "(II)V");
    905     method_onAttributeRead= env->GetMethodID(clazz, "onAttributeRead", "(Ljava/lang/String;IIIIZ)V");
    906     method_onAttributeWrite= env->GetMethodID(clazz, "onAttributeWrite", "(Ljava/lang/String;IIIIIZZ[B)V");
    907     method_onExecuteWrite= env->GetMethodID(clazz, "onExecuteWrite", "(Ljava/lang/String;III)V");
    908     method_onNotificationSent = env->GetMethodID(clazz, "onNotificationSent", "(II)V");
    909     method_onServerCongestion = env->GetMethodID(clazz, "onServerCongestion", "(IZ)V");
    910     method_onServerMtuChanged = env->GetMethodID(clazz, "onMtuChanged", "(II)V");
    911 
    912     info("classInitNative: Success!");
    913 }
    914 
    915 static const bt_interface_t* btIf;
    916 
    917 static void initializeNative(JNIEnv *env, jobject object) {
    918     if(btIf)
    919         return;
    920 
    921     if ( (btIf = getBluetoothInterface()) == NULL) {
    922         error("Bluetooth module is not loaded");
    923         return;
    924     }
    925 
    926     if (sGattIf != NULL) {
    927          ALOGW("Cleaning up Bluetooth GATT Interface before initializing...");
    928          sGattIf->cleanup();
    929          sGattIf = NULL;
    930     }
    931 
    932     if (mCallbacksObj != NULL) {
    933          ALOGW("Cleaning up Bluetooth GATT callback object");
    934          env->DeleteGlobalRef(mCallbacksObj);
    935          mCallbacksObj = NULL;
    936     }
    937 
    938     if ( (sGattIf = (btgatt_interface_t *)
    939           btIf->get_profile_interface(BT_PROFILE_GATT_ID)) == NULL) {
    940         error("Failed to get Bluetooth GATT Interface");
    941         return;
    942     }
    943 
    944     bt_status_t status;
    945     if ( (status = sGattIf->init(&sGattCallbacks)) != BT_STATUS_SUCCESS) {
    946         error("Failed to initialize Bluetooth GATT, status: %d", status);
    947         sGattIf = NULL;
    948         return;
    949     }
    950 
    951     mCallbacksObj = env->NewGlobalRef(object);
    952 }
    953 
    954 static void cleanupNative(JNIEnv *env, jobject object) {
    955     bt_status_t status;
    956     if (!btIf) return;
    957 
    958     if (sGattIf != NULL) {
    959         sGattIf->cleanup();
    960         sGattIf = NULL;
    961     }
    962 
    963     if (mCallbacksObj != NULL) {
    964         env->DeleteGlobalRef(mCallbacksObj);
    965         mCallbacksObj = NULL;
    966     }
    967     btIf = NULL;
    968 }
    969 
    970 /**
    971  * Native Client functions
    972  */
    973 
    974 static int gattClientGetDeviceTypeNative(JNIEnv* env, jobject object, jstring address)
    975 {
    976     if (!sGattIf) return 0;
    977     bt_bdaddr_t bda;
    978     jstr2bdaddr(env, &bda, address);
    979     return sGattIf->client->get_device_type(&bda);
    980 }
    981 
    982 static void gattClientRegisterAppNative(JNIEnv* env, jobject object,
    983                                         jlong app_uuid_lsb, jlong app_uuid_msb )
    984 {
    985     bt_uuid_t uuid;
    986 
    987     if (!sGattIf) return;
    988     set_uuid(uuid.uu, app_uuid_msb, app_uuid_lsb);
    989     sGattIf->client->register_client(&uuid);
    990 }
    991 
    992 static void gattClientUnregisterAppNative(JNIEnv* env, jobject object, jint clientIf)
    993 {
    994     if (!sGattIf) return;
    995     sGattIf->client->unregister_client(clientIf);
    996 }
    997 
    998 static void gattClientScanNative(JNIEnv* env, jobject object, jboolean start)
    999 {
   1000     if (!sGattIf) return;
   1001     sGattIf->client->scan(start);
   1002 }
   1003 
   1004 static void gattClientConnectNative(JNIEnv* env, jobject object, jint clientif,
   1005                                  jstring address, jboolean isDirect, jint transport)
   1006 {
   1007     if (!sGattIf) return;
   1008 
   1009     bt_bdaddr_t bda;
   1010     jstr2bdaddr(env, &bda, address);
   1011     sGattIf->client->connect(clientif, &bda, isDirect, transport);
   1012 }
   1013 
   1014 static void gattClientDisconnectNative(JNIEnv* env, jobject object, jint clientIf,
   1015                                   jstring address, jint conn_id)
   1016 {
   1017     if (!sGattIf) return;
   1018     bt_bdaddr_t bda;
   1019     jstr2bdaddr(env, &bda, address);
   1020     sGattIf->client->disconnect(clientIf, &bda, conn_id);
   1021 }
   1022 
   1023 static void gattClientRefreshNative(JNIEnv* env, jobject object, jint clientIf,
   1024                                     jstring address)
   1025 {
   1026     if (!sGattIf) return;
   1027 
   1028     bt_bdaddr_t bda;
   1029     jstr2bdaddr(env, &bda, address);
   1030     sGattIf->client->refresh(clientIf, &bda);
   1031 }
   1032 
   1033 static void gattClientSearchServiceNative(JNIEnv* env, jobject object, jint conn_id,
   1034             jboolean search_all, jlong service_uuid_lsb, jlong service_uuid_msb)
   1035 {
   1036     if (!sGattIf) return;
   1037 
   1038     bt_uuid_t uuid;
   1039     set_uuid(uuid.uu, service_uuid_msb, service_uuid_lsb);
   1040     sGattIf->client->search_service(conn_id, search_all ? 0 : &uuid);
   1041 }
   1042 
   1043 static void gattClientGetCharacteristicNative(JNIEnv* env, jobject object,
   1044     jint conn_id,
   1045     jint  service_type, jint  service_id_inst_id,
   1046     jlong service_id_uuid_lsb, jlong service_id_uuid_msb,
   1047     jint  char_id_inst_id,
   1048     jlong char_id_uuid_lsb, jlong char_id_uuid_msb)
   1049 {
   1050     if (!sGattIf) return;
   1051 
   1052     btgatt_srvc_id_t srvc_id;
   1053     srvc_id.id.inst_id = (uint8_t) service_id_inst_id;
   1054     srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
   1055 
   1056     set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);
   1057 
   1058     btgatt_gatt_id_t char_id;
   1059     char_id.inst_id = (uint8_t) char_id_inst_id;
   1060     set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb);
   1061 
   1062     if (char_id_uuid_lsb == 0)
   1063     {
   1064         sGattIf->client->get_characteristic(conn_id, &srvc_id, 0);
   1065     } else {
   1066         sGattIf->client->get_characteristic(conn_id, &srvc_id, &char_id);
   1067     }
   1068 }
   1069 
   1070 static void gattClientGetDescriptorNative(JNIEnv* env, jobject object,
   1071     jint conn_id,
   1072     jint  service_type, jint  service_id_inst_id,
   1073     jlong service_id_uuid_lsb, jlong service_id_uuid_msb,
   1074     jint  char_id_inst_id,
   1075     jlong char_id_uuid_lsb, jlong char_id_uuid_msb,
   1076     jint descr_id_inst_id,
   1077     jlong descr_id_uuid_lsb, jlong descr_id_uuid_msb)
   1078 {
   1079     if (!sGattIf) return;
   1080 
   1081     btgatt_srvc_id_t srvc_id;
   1082     srvc_id.id.inst_id = (uint8_t) service_id_inst_id;
   1083     srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
   1084     set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);
   1085 
   1086     btgatt_gatt_id_t char_id;
   1087     char_id.inst_id = (uint8_t) char_id_inst_id;
   1088     set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb);
   1089 
   1090     btgatt_gatt_id_t descr_id;
   1091     descr_id.inst_id = (uint8_t) descr_id_inst_id;
   1092     set_uuid(descr_id.uuid.uu, descr_id_uuid_msb, descr_id_uuid_lsb);
   1093 
   1094     if (descr_id_uuid_lsb == 0)
   1095     {
   1096         sGattIf->client->get_descriptor(conn_id, &srvc_id, &char_id, 0);
   1097     } else {
   1098         sGattIf->client->get_descriptor(conn_id, &srvc_id, &char_id, &descr_id);
   1099     }
   1100 }
   1101 
   1102 static void gattClientGetIncludedServiceNative(JNIEnv* env, jobject object,
   1103     jint conn_id, jint service_type, jint service_id_inst_id,
   1104     jlong service_id_uuid_lsb, jlong service_id_uuid_msb,
   1105     jint incl_service_id_inst_id, jint incl_service_type,
   1106     jlong incl_service_id_uuid_lsb, jlong incl_service_id_uuid_msb)
   1107 {
   1108     if (!sGattIf) return;
   1109 
   1110     btgatt_srvc_id_t srvc_id;
   1111     srvc_id.id.inst_id = (uint8_t) service_id_inst_id;
   1112     srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
   1113     set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);
   1114 
   1115     btgatt_srvc_id_t  incl_srvc_id;
   1116     incl_srvc_id.id.inst_id = (uint8_t) incl_service_id_inst_id;
   1117     incl_srvc_id.is_primary = (incl_service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
   1118     set_uuid(incl_srvc_id.id.uuid.uu, incl_service_id_uuid_msb, incl_service_id_uuid_lsb);
   1119 
   1120     if (incl_service_id_uuid_lsb == 0)
   1121     {
   1122         sGattIf->client->get_included_service(conn_id, &srvc_id, 0);
   1123     } else {
   1124         sGattIf->client->get_included_service(conn_id, &srvc_id, &incl_srvc_id);
   1125     }
   1126 }
   1127 
   1128 static void gattClientReadCharacteristicNative(JNIEnv* env, jobject object,
   1129     jint conn_id, jint  service_type, jint  service_id_inst_id,
   1130     jlong service_id_uuid_lsb, jlong service_id_uuid_msb,
   1131     jint  char_id_inst_id,
   1132     jlong char_id_uuid_lsb, jlong char_id_uuid_msb,
   1133     jint authReq)
   1134 {
   1135     if (!sGattIf) return;
   1136 
   1137     btgatt_srvc_id_t srvc_id;
   1138     srvc_id.id.inst_id = (uint8_t) service_id_inst_id;
   1139     srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
   1140     set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);
   1141 
   1142     btgatt_gatt_id_t char_id;
   1143     char_id.inst_id = (uint8_t) char_id_inst_id;
   1144     set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb);
   1145 
   1146     sGattIf->client->read_characteristic(conn_id, &srvc_id, &char_id, authReq);
   1147 }
   1148 
   1149 static void gattClientReadDescriptorNative(JNIEnv* env, jobject object,
   1150     jint conn_id, jint  service_type, jint  service_id_inst_id,
   1151     jlong service_id_uuid_lsb, jlong service_id_uuid_msb,
   1152     jint  char_id_inst_id,
   1153     jlong char_id_uuid_lsb, jlong char_id_uuid_msb,
   1154     jint descr_id_inst_id,
   1155     jlong descr_id_uuid_lsb, jlong descr_id_uuid_msb,
   1156     jint authReq)
   1157 {
   1158     if (!sGattIf) return;
   1159 
   1160     btgatt_srvc_id_t srvc_id;
   1161     srvc_id.id.inst_id = (uint8_t) service_id_inst_id;
   1162     srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
   1163     set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);
   1164 
   1165     btgatt_gatt_id_t char_id;
   1166     char_id.inst_id = (uint8_t) char_id_inst_id;
   1167     set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb);
   1168 
   1169     btgatt_gatt_id_t descr_id;
   1170     descr_id.inst_id = (uint8_t) descr_id_inst_id;
   1171     set_uuid(descr_id.uuid.uu, descr_id_uuid_msb, descr_id_uuid_lsb);
   1172 
   1173     sGattIf->client->read_descriptor(conn_id, &srvc_id, &char_id, &descr_id, authReq);
   1174 }
   1175 
   1176 static void gattClientWriteCharacteristicNative(JNIEnv* env, jobject object,
   1177     jint conn_id, jint  service_type, jint  service_id_inst_id,
   1178     jlong service_id_uuid_lsb, jlong service_id_uuid_msb,
   1179     jint  char_id_inst_id,
   1180     jlong char_id_uuid_lsb, jlong char_id_uuid_msb,
   1181     jint write_type, jint auth_req, jbyteArray value)
   1182 {
   1183     if (!sGattIf) return;
   1184 
   1185     if (value == NULL) {
   1186         warn("gattClientWriteCharacteristicNative() ignoring NULL array");
   1187         return;
   1188     }
   1189 
   1190     btgatt_srvc_id_t srvc_id;
   1191     srvc_id.id.inst_id = (uint8_t) service_id_inst_id;
   1192     srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
   1193     set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);
   1194 
   1195     btgatt_gatt_id_t char_id;
   1196     char_id.inst_id = (uint8_t) char_id_inst_id;
   1197     set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb);
   1198 
   1199     uint16_t len = (uint16_t) env->GetArrayLength(value);
   1200     jbyte *p_value = env->GetByteArrayElements(value, NULL);
   1201     if (p_value == NULL) return;
   1202 
   1203     sGattIf->client->write_characteristic(conn_id, &srvc_id, &char_id,
   1204                                     write_type, len, auth_req, (char*)p_value);
   1205     env->ReleaseByteArrayElements(value, p_value, 0);
   1206 }
   1207 
   1208 static void gattClientExecuteWriteNative(JNIEnv* env, jobject object,
   1209     jint conn_id, jboolean execute)
   1210 {
   1211     if (!sGattIf) return;
   1212     sGattIf->client->execute_write(conn_id, execute ? 1 : 0);
   1213 }
   1214 
   1215 static void gattClientWriteDescriptorNative(JNIEnv* env, jobject object,
   1216     jint conn_id, jint  service_type, jint service_id_inst_id,
   1217     jlong service_id_uuid_lsb, jlong service_id_uuid_msb,
   1218     jint char_id_inst_id,
   1219     jlong char_id_uuid_lsb, jlong char_id_uuid_msb,
   1220     jint descr_id_inst_id,
   1221     jlong descr_id_uuid_lsb, jlong descr_id_uuid_msb,
   1222     jint write_type, jint auth_req, jbyteArray value)
   1223 {
   1224     if (!sGattIf) return;
   1225 
   1226     if (value == NULL) {
   1227         warn("gattClientWriteDescriptorNative() ignoring NULL array");
   1228         return;
   1229     }
   1230 
   1231     btgatt_srvc_id_t srvc_id;
   1232     srvc_id.id.inst_id = (uint8_t) service_id_inst_id;
   1233     srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
   1234     set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);
   1235 
   1236     btgatt_gatt_id_t char_id;
   1237     char_id.inst_id = (uint8_t) char_id_inst_id;
   1238     set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb);
   1239 
   1240     btgatt_gatt_id_t descr_id;
   1241     descr_id.inst_id = (uint8_t) descr_id_inst_id;
   1242     set_uuid(descr_id.uuid.uu, descr_id_uuid_msb, descr_id_uuid_lsb);
   1243 
   1244     uint16_t len = (uint16_t) env->GetArrayLength(value);
   1245     jbyte *p_value = env->GetByteArrayElements(value, NULL);
   1246     if (p_value == NULL) return;
   1247 
   1248     sGattIf->client->write_descriptor(conn_id, &srvc_id, &char_id, &descr_id,
   1249                                     write_type, len, auth_req, (char*)p_value);
   1250     env->ReleaseByteArrayElements(value, p_value, 0);
   1251 }
   1252 
   1253 static void gattClientRegisterForNotificationsNative(JNIEnv* env, jobject object,
   1254     jint clientIf, jstring address,
   1255     jint  service_type, jint service_id_inst_id,
   1256     jlong service_id_uuid_lsb, jlong service_id_uuid_msb,
   1257     jint char_id_inst_id,
   1258     jlong char_id_uuid_lsb, jlong char_id_uuid_msb,
   1259     jboolean enable)
   1260 {
   1261     if (!sGattIf) return;
   1262 
   1263     btgatt_srvc_id_t srvc_id;
   1264     srvc_id.id.inst_id = (uint8_t) service_id_inst_id;
   1265     srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
   1266     set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);
   1267 
   1268     btgatt_gatt_id_t char_id;
   1269     char_id.inst_id = (uint8_t) char_id_inst_id;
   1270     set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb);
   1271 
   1272     bt_bdaddr_t bd_addr;
   1273     const char *c_address = env->GetStringUTFChars(address, NULL);
   1274     bd_addr_str_to_addr(c_address, bd_addr.address);
   1275 
   1276     if (enable)
   1277         sGattIf->client->register_for_notification(clientIf, &bd_addr, &srvc_id, &char_id);
   1278     else
   1279         sGattIf->client->deregister_for_notification(clientIf, &bd_addr, &srvc_id, &char_id);
   1280 }
   1281 
   1282 static void gattClientReadRemoteRssiNative(JNIEnv* env, jobject object, jint clientif,
   1283                                  jstring address)
   1284 {
   1285     if (!sGattIf) return;
   1286 
   1287     bt_bdaddr_t bda;
   1288     jstr2bdaddr(env, &bda, address);
   1289 
   1290     sGattIf->client->read_remote_rssi(clientif, &bda);
   1291 }
   1292 
   1293 static void gattAdvertiseNative(JNIEnv *env, jobject object,
   1294         jint client_if, jboolean start)
   1295 {
   1296     if (!sGattIf) return;
   1297     sGattIf->client->listen(client_if, start);
   1298 }
   1299 
   1300 static void gattSetAdvDataNative(JNIEnv *env, jobject object, jint client_if,
   1301         jboolean setScanRsp, jboolean inclName, jboolean inclTxPower, jint minInterval,
   1302         jint maxInterval, jint appearance, jbyteArray manufacturerData, jbyteArray serviceData,
   1303         jbyteArray serviceUuid)
   1304 {
   1305     if (!sGattIf) return;
   1306     jbyte* arr_data = env->GetByteArrayElements(manufacturerData, NULL);
   1307     uint16_t arr_len = (uint16_t) env->GetArrayLength(manufacturerData);
   1308 
   1309     jbyte* service_data = env->GetByteArrayElements(serviceData, NULL);
   1310     uint16_t service_data_len = (uint16_t) env->GetArrayLength(serviceData);
   1311 
   1312     jbyte* service_uuid = env->GetByteArrayElements(serviceUuid, NULL);
   1313     uint16_t service_uuid_len = (uint16_t) env->GetArrayLength(serviceUuid);
   1314 
   1315     sGattIf->client->set_adv_data(client_if, setScanRsp, inclName, inclTxPower,
   1316         minInterval, maxInterval, appearance, arr_len, (char*)arr_data,
   1317         service_data_len, (char*)service_data, service_uuid_len,
   1318         (char*)service_uuid);
   1319 
   1320     env->ReleaseByteArrayElements(manufacturerData, arr_data, JNI_ABORT);
   1321     env->ReleaseByteArrayElements(serviceData, service_data, JNI_ABORT);
   1322     env->ReleaseByteArrayElements(serviceUuid, service_uuid, JNI_ABORT);
   1323 }
   1324 
   1325 static void gattSetScanParametersNative(JNIEnv* env, jobject object,
   1326                                         jint client_if, jint scan_interval_unit,
   1327                                         jint scan_window_unit)
   1328 {
   1329     if (!sGattIf) return;
   1330     sGattIf->client->set_scan_parameters(client_if, scan_interval_unit, scan_window_unit);
   1331 }
   1332 
   1333 static void gattClientScanFilterParamAddNative(JNIEnv* env, jobject object, jobject params)
   1334 {
   1335     if (!sGattIf) return;
   1336     const int add_scan_filter_params_action = 0;
   1337     btgatt_filt_param_setup_t filt_params;
   1338 
   1339     jmethodID methodId = 0;
   1340     jclass filtparam = env->GetObjectClass(params);
   1341 
   1342     methodId = env->GetMethodID(filtparam, "getClientIf", "()I");
   1343     filt_params.client_if = env->CallIntMethod(params, methodId);;
   1344 
   1345     filt_params.action = add_scan_filter_params_action;
   1346 
   1347     methodId = env->GetMethodID(filtparam, "getFiltIndex", "()I");
   1348     filt_params.filt_index = env->CallIntMethod(params, methodId);;
   1349 
   1350     methodId = env->GetMethodID(filtparam, "getFeatSeln", "()I");
   1351     filt_params.feat_seln = env->CallIntMethod(params, methodId);;
   1352 
   1353     methodId = env->GetMethodID(filtparam, "getListLogicType", "()I");
   1354     filt_params.list_logic_type = env->CallIntMethod(params, methodId);
   1355 
   1356     methodId = env->GetMethodID(filtparam, "getFiltLogicType", "()I");
   1357     filt_params.filt_logic_type = env->CallIntMethod(params, methodId);
   1358 
   1359     methodId = env->GetMethodID(filtparam, "getDelyMode", "()I");
   1360     filt_params.dely_mode = env->CallIntMethod(params, methodId);
   1361 
   1362     methodId = env->GetMethodID(filtparam, "getFoundTimeout", "()I");
   1363     filt_params.found_timeout = env->CallIntMethod(params, methodId);
   1364 
   1365     methodId = env->GetMethodID(filtparam, "getLostTimeout", "()I");
   1366     filt_params.lost_timeout = env->CallIntMethod(params, methodId);
   1367 
   1368     methodId = env->GetMethodID(filtparam, "getFoundTimeOutCnt", "()I");
   1369     filt_params.found_timeout_cnt = env->CallIntMethod(params, methodId);
   1370 
   1371     methodId = env->GetMethodID(filtparam, "getNumOfTrackEntries", "()I");
   1372     filt_params.num_of_tracking_entries = env->CallIntMethod(params, methodId);
   1373 
   1374     methodId = env->GetMethodID(filtparam, "getRSSIHighValue", "()I");
   1375     filt_params.rssi_high_thres = env->CallIntMethod(params, methodId);
   1376 
   1377     methodId = env->GetMethodID(filtparam, "getRSSILowValue", "()I");
   1378     filt_params.rssi_low_thres = env->CallIntMethod(params, methodId);
   1379 
   1380     env->DeleteLocalRef(filtparam);
   1381     sGattIf->client->scan_filter_param_setup(filt_params);
   1382 }
   1383 
   1384 static void gattClientScanFilterParamDeleteNative(JNIEnv* env, jobject object,
   1385         jint client_if, jint filt_index)
   1386 {
   1387     if (!sGattIf) return;
   1388     const int delete_scan_filter_params_action = 1;
   1389     btgatt_filt_param_setup_t filt_params;
   1390     memset(&filt_params, 0, sizeof(btgatt_filt_param_setup_t));
   1391     filt_params.client_if = client_if;
   1392     filt_params.action = delete_scan_filter_params_action;
   1393     filt_params.filt_index = filt_index;
   1394     sGattIf->client->scan_filter_param_setup(filt_params);
   1395 }
   1396 
   1397 static void gattClientScanFilterParamClearAllNative(JNIEnv* env, jobject object, jint client_if)
   1398 {
   1399     if (!sGattIf) return;
   1400     const int clear_scan_filter_params_action = 2;
   1401     btgatt_filt_param_setup_t filt_params;
   1402     memset(&filt_params, 0, sizeof(btgatt_filt_param_setup_t));
   1403     filt_params.client_if = client_if;
   1404     filt_params.action = clear_scan_filter_params_action;
   1405     sGattIf->client->scan_filter_param_setup(filt_params);
   1406 }
   1407 
   1408 static void gattClientScanFilterAddRemoveNative(JNIEnv* env, jobject object,
   1409         jint client_if, jint action, jint filt_type, jint filt_index, jint company_id,
   1410         jint company_id_mask, jlong uuid_lsb,  jlong uuid_msb, jlong uuid_mask_lsb,
   1411         jlong uuid_mask_msb, jstring name, jstring address, jbyte addr_type,
   1412         jbyteArray data, jbyteArray mask)
   1413 {
   1414     switch(filt_type)
   1415     {
   1416         case 0: // BTM_BLE_PF_ADDR_FILTER
   1417         {
   1418             bt_bdaddr_t bda;
   1419             jstr2bdaddr(env, &bda, address);
   1420             sGattIf->client->scan_filter_add_remove(client_if, action, filt_type, filt_index, 0,
   1421                                              0, NULL, NULL, &bda, addr_type,0, NULL,0, NULL);
   1422             break;
   1423         }
   1424 
   1425         case 1: // BTM_BLE_PF_SRVC_DATA
   1426         {
   1427             jbyte* data_array = env->GetByteArrayElements(data, 0);
   1428             int data_len = env->GetArrayLength(data);
   1429             jbyte* mask_array = env->GetByteArrayElements(mask, NULL);
   1430             uint16_t mask_len = (uint16_t) env->GetArrayLength(mask);
   1431             sGattIf->client->scan_filter_add_remove(client_if, action, filt_type, filt_index,
   1432                0, 0, NULL, NULL, NULL, 0, data_len, (char*)data_array, mask_len,(char*) mask_array);
   1433             env->ReleaseByteArrayElements(data, data_array, JNI_ABORT);
   1434             env->ReleaseByteArrayElements(mask, mask_array, JNI_ABORT);
   1435             break;
   1436         }
   1437 
   1438         case 2: // BTM_BLE_PF_SRVC_UUID
   1439         case 3: // BTM_BLE_PF_SRVC_SOL_UUID
   1440         {
   1441             bt_uuid_t uuid, uuid_mask;
   1442             set_uuid(uuid.uu, uuid_msb, uuid_lsb);
   1443             set_uuid(uuid_mask.uu, uuid_mask_msb, uuid_mask_lsb);
   1444             if (uuid_mask_lsb != 0 && uuid_mask_msb != 0)
   1445                 sGattIf->client->scan_filter_add_remove(client_if, action, filt_type, filt_index,
   1446                                  0, 0, &uuid, &uuid_mask, NULL,0,0, NULL,0, NULL);
   1447             else
   1448                 sGattIf->client->scan_filter_add_remove(client_if, action, filt_type, filt_index,
   1449                                  0, 0, &uuid, NULL, NULL, 0,0, NULL,0, NULL);
   1450             break;
   1451         }
   1452 
   1453         case 4: // BTM_BLE_PF_LOCAL_NAME
   1454         {
   1455             const char* c_name = env->GetStringUTFChars(name, NULL);
   1456             if (c_name != NULL && strlen(c_name) != 0)
   1457             {
   1458                 sGattIf->client->scan_filter_add_remove(client_if, action, filt_type,
   1459                                  filt_index, 0, 0, NULL, NULL, NULL, 0, strlen(c_name),
   1460                                  (char*)c_name, 0, NULL);
   1461                 env->ReleaseStringUTFChars(name, c_name);
   1462             }
   1463             break;
   1464         }
   1465 
   1466         case 5: // BTM_BLE_PF_MANU_DATA
   1467         case 6: // BTM_BLE_PF_SRVC_DATA_PATTERN
   1468         {
   1469             jbyte* data_array = env->GetByteArrayElements(data, 0);
   1470             int data_len = env->GetArrayLength(data); // Array contains mask
   1471             jbyte* mask_array = env->GetByteArrayElements(mask, NULL);
   1472             uint16_t mask_len = (uint16_t) env->GetArrayLength(mask);
   1473             sGattIf->client->scan_filter_add_remove(client_if, action, filt_type, filt_index,
   1474                 company_id, company_id_mask, NULL, NULL, NULL, 0, data_len, (char*)data_array,
   1475                 mask_len, (char*) mask_array);
   1476             env->ReleaseByteArrayElements(data, data_array, JNI_ABORT);
   1477             env->ReleaseByteArrayElements(mask, mask_array, JNI_ABORT);
   1478             break;
   1479         }
   1480 
   1481         default:
   1482             break;
   1483     }
   1484 }
   1485 
   1486 static void gattClientScanFilterAddNative(JNIEnv* env, jobject object, jint client_if,
   1487                 jint filt_type, jint filt_index, jint company_id, jint company_id_mask,
   1488                 jlong uuid_lsb,  jlong uuid_msb, jlong uuid_mask_lsb, jlong uuid_mask_msb,
   1489                 jstring name, jstring address, jbyte addr_type, jbyteArray data, jbyteArray mask)
   1490 {
   1491     if (!sGattIf) return;
   1492     int action = 0;
   1493     gattClientScanFilterAddRemoveNative(env, object, client_if, action, filt_type, filt_index,
   1494                     company_id, company_id_mask, uuid_lsb, uuid_msb, uuid_mask_lsb, uuid_mask_msb,
   1495                     name, address, addr_type, data, mask);
   1496 
   1497 }
   1498 
   1499 static void gattClientScanFilterDeleteNative(JNIEnv* env, jobject object, jint client_if,
   1500                 jint filt_type, jint filt_index, jint company_id, jint company_id_mask,
   1501                 jlong uuid_lsb,  jlong uuid_msb, jlong uuid_mask_lsb, jlong uuid_mask_msb,
   1502                 jstring name, jstring address, jbyte addr_type, jbyteArray data, jbyteArray mask)
   1503 {
   1504     if (!sGattIf) return;
   1505     int action = 1;
   1506     gattClientScanFilterAddRemoveNative(env, object, client_if, action, filt_type, filt_index,
   1507                     company_id, company_id_mask, uuid_lsb, uuid_msb, uuid_mask_lsb, uuid_mask_msb,
   1508                     name, address, addr_type, data, mask);
   1509 }
   1510 
   1511 static void gattClientScanFilterClearNative(JNIEnv* env, jobject object, jint client_if,
   1512                         jint filt_index)
   1513 {
   1514     if (!sGattIf) return;
   1515     sGattIf->client->scan_filter_clear(client_if, filt_index);
   1516 }
   1517 
   1518 static void gattClientScanFilterEnableNative (JNIEnv* env, jobject object, jint client_if,
   1519                           jboolean enable)
   1520 {
   1521     if (!sGattIf) return;
   1522     sGattIf->client->scan_filter_enable(client_if, enable);
   1523 }
   1524 
   1525 static void gattClientConfigureMTUNative(JNIEnv *env, jobject object,
   1526         jint conn_id, jint mtu)
   1527 {
   1528     if (!sGattIf) return;
   1529     sGattIf->client->configure_mtu(conn_id, mtu);
   1530 }
   1531 
   1532 static void gattConnectionParameterUpdateNative(JNIEnv *env, jobject object, jint client_if,
   1533         jstring address, jint min_interval, jint max_interval, jint latency, jint timeout)
   1534 {
   1535     if (!sGattIf) return;
   1536     bt_bdaddr_t bda;
   1537     jstr2bdaddr(env, &bda, address);
   1538     sGattIf->client->conn_parameter_update(&bda, min_interval, max_interval, latency, timeout);
   1539 }
   1540 
   1541 static void gattClientEnableAdvNative(JNIEnv* env, jobject object, jint client_if,
   1542        jint min_interval, jint max_interval, jint adv_type, jint chnl_map, jint tx_power,
   1543        jint timeout_s)
   1544 {
   1545     if (!sGattIf) return;
   1546 
   1547     sGattIf->client->multi_adv_enable(client_if, min_interval, max_interval, adv_type, chnl_map,
   1548         tx_power, timeout_s);
   1549 }
   1550 
   1551 static void gattClientUpdateAdvNative(JNIEnv* env, jobject object, jint client_if,
   1552        jint min_interval, jint max_interval, jint adv_type, jint chnl_map, jint tx_power,
   1553        jint timeout_s)
   1554 {
   1555     if (!sGattIf) return;
   1556 
   1557     sGattIf->client->multi_adv_update(client_if, min_interval, max_interval, adv_type, chnl_map,
   1558         tx_power, timeout_s);
   1559 }
   1560 
   1561 static void gattClientSetAdvDataNative(JNIEnv* env, jobject object , jint client_if,
   1562         jboolean set_scan_rsp, jboolean incl_name, jboolean incl_txpower, jint appearance,
   1563         jbyteArray manufacturer_data,jbyteArray service_data, jbyteArray service_uuid)
   1564 {
   1565     if (!sGattIf) return;
   1566     jbyte* manu_data = env->GetByteArrayElements(manufacturer_data, NULL);
   1567     uint16_t manu_len = (uint16_t) env->GetArrayLength(manufacturer_data);
   1568 
   1569     jbyte* serv_data = env->GetByteArrayElements(service_data, NULL);
   1570     uint16_t serv_data_len = (uint16_t) env->GetArrayLength(service_data);
   1571 
   1572     jbyte* serv_uuid = env->GetByteArrayElements(service_uuid, NULL);
   1573     uint16_t serv_uuid_len = (uint16_t) env->GetArrayLength(service_uuid);
   1574 
   1575     sGattIf->client->multi_adv_set_inst_data(client_if, set_scan_rsp, incl_name,incl_txpower,
   1576                                              appearance, manu_len, (char*)manu_data,
   1577                                              serv_data_len, (char*)serv_data, serv_uuid_len,
   1578                                              (char*)serv_uuid);
   1579 
   1580     env->ReleaseByteArrayElements(manufacturer_data, manu_data, JNI_ABORT);
   1581     env->ReleaseByteArrayElements(service_data, serv_data, JNI_ABORT);
   1582     env->ReleaseByteArrayElements(service_uuid, serv_uuid, JNI_ABORT);
   1583 }
   1584 
   1585 static void gattClientDisableAdvNative(JNIEnv* env, jobject object, jint client_if)
   1586 {
   1587     if (!sGattIf) return;
   1588     sGattIf->client->multi_adv_disable(client_if);
   1589 }
   1590 
   1591 static void gattClientConfigBatchScanStorageNative(JNIEnv* env, jobject object, jint client_if,
   1592             jint max_full_reports_percent, jint max_trunc_reports_percent,
   1593             jint notify_threshold_level_percent)
   1594 {
   1595     if (!sGattIf) return;
   1596     sGattIf->client->batchscan_cfg_storage(client_if, max_full_reports_percent,
   1597             max_trunc_reports_percent, notify_threshold_level_percent);
   1598 }
   1599 
   1600 static void gattClientStartBatchScanNative(JNIEnv* env, jobject object, jint client_if,
   1601             jint scan_mode, jint scan_interval_unit, jint scan_window_unit, jint addr_type,
   1602             jint discard_rule)
   1603 {
   1604     if (!sGattIf) return;
   1605     sGattIf->client->batchscan_enb_batch_scan(client_if, scan_mode, scan_interval_unit,
   1606             scan_window_unit, addr_type, discard_rule);
   1607 }
   1608 
   1609 static void gattClientStopBatchScanNative(JNIEnv* env, jobject object, jint client_if)
   1610 {
   1611     if (!sGattIf) return;
   1612     sGattIf->client->batchscan_dis_batch_scan(client_if);
   1613 }
   1614 
   1615 static void gattClientReadScanReportsNative(JNIEnv* env, jobject object, jint client_if,
   1616         jint scan_type)
   1617 {
   1618     if (!sGattIf) return;
   1619     sGattIf->client->batchscan_read_reports(client_if, scan_type);
   1620 }
   1621 
   1622 /**
   1623  * Native server functions
   1624  */
   1625 static void gattServerRegisterAppNative(JNIEnv* env, jobject object,
   1626                                         jlong app_uuid_lsb, jlong app_uuid_msb )
   1627 {
   1628     bt_uuid_t uuid;
   1629     if (!sGattIf) return;
   1630     set_uuid(uuid.uu, app_uuid_msb, app_uuid_lsb);
   1631     sGattIf->server->register_server(&uuid);
   1632 }
   1633 
   1634 static void gattServerUnregisterAppNative(JNIEnv* env, jobject object, jint serverIf)
   1635 {
   1636     if (!sGattIf) return;
   1637     sGattIf->server->unregister_server(serverIf);
   1638 }
   1639 
   1640 static void gattServerConnectNative(JNIEnv *env, jobject object,
   1641                                  jint server_if, jstring address, jboolean is_direct, jint transport)
   1642 {
   1643     if (!sGattIf) return;
   1644 
   1645     bt_bdaddr_t bd_addr;
   1646     const char *c_address = env->GetStringUTFChars(address, NULL);
   1647     bd_addr_str_to_addr(c_address, bd_addr.address);
   1648 
   1649     sGattIf->server->connect(server_if, &bd_addr, is_direct, transport);
   1650 }
   1651 
   1652 static void gattServerDisconnectNative(JNIEnv* env, jobject object, jint serverIf,
   1653                                   jstring address, jint conn_id)
   1654 {
   1655     if (!sGattIf) return;
   1656     bt_bdaddr_t bda;
   1657     jstr2bdaddr(env, &bda, address);
   1658     sGattIf->server->disconnect(serverIf, &bda, conn_id);
   1659 }
   1660 
   1661 static void gattServerAddServiceNative (JNIEnv *env, jobject object,
   1662         jint server_if, jint service_type, jint service_id_inst_id,
   1663         jlong service_id_uuid_lsb, jlong service_id_uuid_msb,
   1664         jint num_handles)
   1665 {
   1666     if (!sGattIf) return;
   1667 
   1668     btgatt_srvc_id_t srvc_id;
   1669     srvc_id.id.inst_id = (uint8_t) service_id_inst_id;
   1670     srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
   1671     set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);
   1672 
   1673     sGattIf->server->add_service(server_if, &srvc_id, num_handles);
   1674 }
   1675 
   1676 static void gattServerAddIncludedServiceNative (JNIEnv *env, jobject object,
   1677         jint server_if, jint svc_handle, jint included_svc_handle)
   1678 {
   1679     if (!sGattIf) return;
   1680     sGattIf->server->add_included_service(server_if, svc_handle,
   1681                                           included_svc_handle);
   1682 }
   1683 
   1684 static void gattServerAddCharacteristicNative (JNIEnv *env, jobject object,
   1685         jint server_if, jint svc_handle,
   1686         jlong char_uuid_lsb, jlong char_uuid_msb,
   1687         jint properties, jint permissions)
   1688 {
   1689     if (!sGattIf) return;
   1690 
   1691     bt_uuid_t uuid;
   1692     set_uuid(uuid.uu, char_uuid_msb, char_uuid_lsb);
   1693 
   1694     sGattIf->server->add_characteristic(server_if, svc_handle,
   1695                                         &uuid, properties, permissions);
   1696 }
   1697 
   1698 static void gattServerAddDescriptorNative (JNIEnv *env, jobject object,
   1699         jint server_if, jint svc_handle,
   1700         jlong desc_uuid_lsb, jlong desc_uuid_msb,
   1701         jint permissions)
   1702 {
   1703     if (!sGattIf) return;
   1704 
   1705     bt_uuid_t uuid;
   1706     set_uuid(uuid.uu, desc_uuid_msb, desc_uuid_lsb);
   1707 
   1708     sGattIf->server->add_descriptor(server_if, svc_handle, &uuid, permissions);
   1709 }
   1710 
   1711 static void gattServerStartServiceNative (JNIEnv *env, jobject object,
   1712         jint server_if, jint svc_handle, jint transport )
   1713 {
   1714     if (!sGattIf) return;
   1715     sGattIf->server->start_service(server_if, svc_handle, transport);
   1716 }
   1717 
   1718 static void gattServerStopServiceNative (JNIEnv *env, jobject object,
   1719                                          jint server_if, jint svc_handle)
   1720 {
   1721     if (!sGattIf) return;
   1722     sGattIf->server->stop_service(server_if, svc_handle);
   1723 }
   1724 
   1725 static void gattServerDeleteServiceNative (JNIEnv *env, jobject object,
   1726                                            jint server_if, jint svc_handle)
   1727 {
   1728     if (!sGattIf) return;
   1729     sGattIf->server->delete_service(server_if, svc_handle);
   1730 }
   1731 
   1732 static void gattServerSendIndicationNative (JNIEnv *env, jobject object,
   1733         jint server_if, jint attr_handle, jint conn_id, jbyteArray val)
   1734 {
   1735     if (!sGattIf) return;
   1736 
   1737     jbyte* array = env->GetByteArrayElements(val, 0);
   1738     int val_len = env->GetArrayLength(val);
   1739 
   1740     sGattIf->server->send_indication(server_if, attr_handle, conn_id, val_len,
   1741                                      /*confirm*/ 1, (char*)array);
   1742     env->ReleaseByteArrayElements(val, array, JNI_ABORT);
   1743 }
   1744 
   1745 static void gattServerSendNotificationNative (JNIEnv *env, jobject object,
   1746         jint server_if, jint attr_handle, jint conn_id, jbyteArray val)
   1747 {
   1748     if (!sGattIf) return;
   1749 
   1750     jbyte* array = env->GetByteArrayElements(val, 0);
   1751     int val_len = env->GetArrayLength(val);
   1752 
   1753     sGattIf->server->send_indication(server_if, attr_handle, conn_id, val_len,
   1754                                      /*confirm*/ 0, (char*)array);
   1755     env->ReleaseByteArrayElements(val, array, JNI_ABORT);
   1756 }
   1757 
   1758 static void gattServerSendResponseNative (JNIEnv *env, jobject object,
   1759         jint server_if, jint conn_id, jint trans_id, jint status,
   1760         jint handle, jint offset, jbyteArray val, jint auth_req)
   1761 {
   1762     if (!sGattIf) return;
   1763 
   1764     btgatt_response_t response;
   1765 
   1766     response.attr_value.handle = handle;
   1767     response.attr_value.auth_req = auth_req;
   1768     response.attr_value.offset = offset;
   1769     response.attr_value.len = 0;
   1770 
   1771     if (val != NULL)
   1772     {
   1773         response.attr_value.len = (uint16_t) env->GetArrayLength(val);
   1774         jbyte* array = env->GetByteArrayElements(val, 0);
   1775 
   1776         for (int i = 0; i != response.attr_value.len; ++i)
   1777             response.attr_value.value[i] = (uint8_t) array[i];
   1778         env->ReleaseByteArrayElements(val, array, JNI_ABORT);
   1779     }
   1780 
   1781     sGattIf->server->send_response(conn_id, trans_id, status, &response);
   1782 }
   1783 
   1784 static void gattTestNative(JNIEnv *env, jobject object, jint command,
   1785                            jlong uuid1_lsb, jlong uuid1_msb, jstring bda1,
   1786                            jint p1, jint p2, jint p3, jint p4, jint p5 )
   1787 {
   1788     if (!sGattIf) return;
   1789 
   1790     bt_bdaddr_t bt_bda1;
   1791     jstr2bdaddr(env, &bt_bda1, bda1);
   1792 
   1793     bt_uuid_t uuid1;
   1794     set_uuid(uuid1.uu, uuid1_msb, uuid1_lsb);
   1795 
   1796     btgatt_test_params_t params;
   1797     params.bda1 = &bt_bda1;
   1798     params.uuid1 = &uuid1;
   1799     params.u1 = p1;
   1800     params.u2 = p2;
   1801     params.u3 = p3;
   1802     params.u4 = p4;
   1803     params.u5 = p5;
   1804     sGattIf->client->test_command(command, &params);
   1805 }
   1806 
   1807 /**
   1808  * JNI function definitinos
   1809  */
   1810 
   1811 // JNI functions defined in AdvertiseManager class.
   1812 static JNINativeMethod sAdvertiseMethods[] = {
   1813     {"gattClientEnableAdvNative", "(IIIIIII)V", (void *) gattClientEnableAdvNative},
   1814     {"gattClientUpdateAdvNative", "(IIIIIII)V", (void *) gattClientUpdateAdvNative},
   1815     {"gattClientSetAdvDataNative", "(IZZZI[B[B[B)V", (void *) gattClientSetAdvDataNative},
   1816     {"gattClientDisableAdvNative", "(I)V", (void *) gattClientDisableAdvNative},
   1817     {"gattSetAdvDataNative", "(IZZZIII[B[B[B)V", (void *) gattSetAdvDataNative},
   1818     {"gattAdvertiseNative", "(IZ)V", (void *) gattAdvertiseNative},
   1819 };
   1820 
   1821 // JNI functions defined in ScanManager class.
   1822 static JNINativeMethod sScanMethods[] = {
   1823     {"gattClientScanNative", "(Z)V", (void *) gattClientScanNative},
   1824     // Batch scan JNI functions.
   1825     {"gattClientConfigBatchScanStorageNative", "(IIII)V",(void *) gattClientConfigBatchScanStorageNative},
   1826     {"gattClientStartBatchScanNative", "(IIIIII)V", (void *) gattClientStartBatchScanNative},
   1827     {"gattClientStopBatchScanNative", "(I)V", (void *) gattClientStopBatchScanNative},
   1828     {"gattClientReadScanReportsNative", "(II)V", (void *) gattClientReadScanReportsNative},
   1829     // Scan filter JNI functions.
   1830     {"gattClientScanFilterParamAddNative", "(Lcom/android/bluetooth/gatt/FilterParams;)V", (void *) gattClientScanFilterParamAddNative},
   1831     {"gattClientScanFilterParamDeleteNative", "(II)V", (void *) gattClientScanFilterParamDeleteNative},
   1832     {"gattClientScanFilterParamClearAllNative", "(I)V", (void *) gattClientScanFilterParamClearAllNative},
   1833     {"gattClientScanFilterAddNative", "(IIIIIJJJJLjava/lang/String;Ljava/lang/String;B[B[B)V", (void *) gattClientScanFilterAddNative},
   1834     {"gattClientScanFilterDeleteNative", "(IIIIIJJJJLjava/lang/String;Ljava/lang/String;B[B[B)V", (void *) gattClientScanFilterDeleteNative},
   1835     {"gattClientScanFilterClearNative", "(II)V", (void *) gattClientScanFilterClearNative},
   1836     {"gattClientScanFilterEnableNative", "(IZ)V", (void *) gattClientScanFilterEnableNative},
   1837     {"gattSetScanParametersNative", "(III)V", (void *) gattSetScanParametersNative},
   1838 };
   1839 
   1840 // JNI functions defined in GattService class.
   1841 static JNINativeMethod sMethods[] = {
   1842     {"classInitNative", "()V", (void *) classInitNative},
   1843     {"initializeNative", "()V", (void *) initializeNative},
   1844     {"cleanupNative", "()V", (void *) cleanupNative},
   1845     {"gattClientGetDeviceTypeNative", "(Ljava/lang/String;)I", (void *) gattClientGetDeviceTypeNative},
   1846     {"gattClientRegisterAppNative", "(JJ)V", (void *) gattClientRegisterAppNative},
   1847     {"gattClientUnregisterAppNative", "(I)V", (void *) gattClientUnregisterAppNative},
   1848     {"gattClientConnectNative", "(ILjava/lang/String;ZI)V", (void *) gattClientConnectNative},
   1849     {"gattClientDisconnectNative", "(ILjava/lang/String;I)V", (void *) gattClientDisconnectNative},
   1850     {"gattClientRefreshNative", "(ILjava/lang/String;)V", (void *) gattClientRefreshNative},
   1851     {"gattClientSearchServiceNative", "(IZJJ)V", (void *) gattClientSearchServiceNative},
   1852     {"gattClientGetCharacteristicNative", "(IIIJJIJJ)V", (void *) gattClientGetCharacteristicNative},
   1853     {"gattClientGetDescriptorNative", "(IIIJJIJJIJJ)V", (void *) gattClientGetDescriptorNative},
   1854     {"gattClientGetIncludedServiceNative", "(IIIJJIIJJ)V", (void *) gattClientGetIncludedServiceNative},
   1855     {"gattClientReadCharacteristicNative", "(IIIJJIJJI)V", (void *) gattClientReadCharacteristicNative},
   1856     {"gattClientReadDescriptorNative", "(IIIJJIJJIJJI)V", (void *) gattClientReadDescriptorNative},
   1857     {"gattClientWriteCharacteristicNative", "(IIIJJIJJII[B)V", (void *) gattClientWriteCharacteristicNative},
   1858     {"gattClientWriteDescriptorNative", "(IIIJJIJJIJJII[B)V", (void *) gattClientWriteDescriptorNative},
   1859     {"gattClientExecuteWriteNative", "(IZ)V", (void *) gattClientExecuteWriteNative},
   1860     {"gattClientRegisterForNotificationsNative", "(ILjava/lang/String;IIJJIJJZ)V", (void *) gattClientRegisterForNotificationsNative},
   1861     {"gattClientReadRemoteRssiNative", "(ILjava/lang/String;)V", (void *) gattClientReadRemoteRssiNative},
   1862     {"gattClientConfigureMTUNative", "(II)V", (void *) gattClientConfigureMTUNative},
   1863     {"gattConnectionParameterUpdateNative", "(ILjava/lang/String;IIII)V", (void *) gattConnectionParameterUpdateNative},
   1864     {"gattServerRegisterAppNative", "(JJ)V", (void *) gattServerRegisterAppNative},
   1865     {"gattServerUnregisterAppNative", "(I)V", (void *) gattServerUnregisterAppNative},
   1866     {"gattServerConnectNative", "(ILjava/lang/String;ZI)V", (void *) gattServerConnectNative},
   1867     {"gattServerDisconnectNative", "(ILjava/lang/String;I)V", (void *) gattServerDisconnectNative},
   1868     {"gattServerAddServiceNative", "(IIIJJI)V", (void *) gattServerAddServiceNative},
   1869     {"gattServerAddIncludedServiceNative", "(III)V", (void *) gattServerAddIncludedServiceNative},
   1870     {"gattServerAddCharacteristicNative", "(IIJJII)V", (void *) gattServerAddCharacteristicNative},
   1871     {"gattServerAddDescriptorNative", "(IIJJI)V", (void *) gattServerAddDescriptorNative},
   1872     {"gattServerStartServiceNative", "(III)V", (void *) gattServerStartServiceNative},
   1873     {"gattServerStopServiceNative", "(II)V", (void *) gattServerStopServiceNative},
   1874     {"gattServerDeleteServiceNative", "(II)V", (void *) gattServerDeleteServiceNative},
   1875     {"gattServerSendIndicationNative", "(III[B)V", (void *) gattServerSendIndicationNative},
   1876     {"gattServerSendNotificationNative", "(III[B)V", (void *) gattServerSendNotificationNative},
   1877     {"gattServerSendResponseNative", "(IIIIII[BI)V", (void *) gattServerSendResponseNative},
   1878 
   1879     {"gattTestNative", "(IJJLjava/lang/String;IIIII)V", (void *) gattTestNative},
   1880 };
   1881 
   1882 int register_com_android_bluetooth_gatt(JNIEnv* env)
   1883 {
   1884     int register_success =
   1885         jniRegisterNativeMethods(env, "com/android/bluetooth/gatt/ScanManager$ScanNative",
   1886                 sScanMethods, NELEM(sScanMethods));
   1887     register_success &=
   1888         jniRegisterNativeMethods(env, "com/android/bluetooth/gatt/AdvertiseManager$AdvertiseNative",
   1889                 sAdvertiseMethods, NELEM(sAdvertiseMethods));
   1890     return register_success &
   1891         jniRegisterNativeMethods(env, "com/android/bluetooth/gatt/GattService",
   1892                 sMethods, NELEM(sMethods));
   1893 }
   1894 }
   1895