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