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