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 CHAR_ID_PARAMS(char_ptr) \
     48     char_ptr->inst_id, \
     49     UUID_PARAMS((&char_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     CHAR_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_onReadDescrExtProp;
    153 static jmethodID method_onReadDescriptor;
    154 static jmethodID method_onWriteDescriptor;
    155 static jmethodID method_onNotify;
    156 static jmethodID method_onGetCharacteristic;
    157 static jmethodID method_onGetDescriptor;
    158 static jmethodID method_onGetIncludedService;
    159 static jmethodID method_onRegisterForNotifications;
    160 static jmethodID method_onReadRemoteRssi;
    161 
    162 /**
    163  * Server callback methods
    164  */
    165 static jmethodID method_onServerRegistered;
    166 static jmethodID method_onClientConnected;
    167 static jmethodID method_onServiceAdded;
    168 static jmethodID method_onIncludedServiceAdded;
    169 static jmethodID method_onCharacteristicAdded;
    170 static jmethodID method_onDescriptorAdded;
    171 static jmethodID method_onServiceStarted;
    172 static jmethodID method_onServiceStopped;
    173 static jmethodID method_onServiceDeleted;
    174 static jmethodID method_onResponseSendCompleted;
    175 static jmethodID method_onAttributeRead;
    176 static jmethodID method_onAttributeWrite;
    177 static jmethodID method_onExecuteWrite;
    178 
    179 /**
    180  * Static variables
    181  */
    182 
    183 static const btgatt_interface_t *sGattIf = NULL;
    184 static jobject mCallbacksObj = NULL;
    185 static JNIEnv *sCallbackEnv = NULL;
    186 
    187 static bool checkCallbackThread() {
    188     sCallbackEnv = getCallbackEnv();
    189 
    190     JNIEnv* env = AndroidRuntime::getJNIEnv();
    191     if (sCallbackEnv != env || sCallbackEnv == NULL) return false;
    192     return true;
    193 }
    194 
    195 /**
    196  * BTA client callbacks
    197  */
    198 
    199 void btgattc_register_app_cb(int status, int clientIf, bt_uuid_t *app_uuid)
    200 {
    201     CHECK_CALLBACK_ENV
    202     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientRegistered, status,
    203         clientIf, UUID_PARAMS(app_uuid));
    204     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    205 }
    206 
    207 void btgattc_scan_result_cb(bt_bdaddr_t* bda, int rssi, uint8_t* adv_data)
    208 {
    209     CHECK_CALLBACK_ENV
    210 
    211     char c_address[32];
    212     snprintf(c_address, sizeof(c_address),"%02X:%02X:%02X:%02X:%02X:%02X",
    213         bda->address[0], bda->address[1], bda->address[2],
    214         bda->address[3], bda->address[4], bda->address[5]);
    215 
    216     jstring address = sCallbackEnv->NewStringUTF(c_address);
    217     jbyteArray jb = sCallbackEnv->NewByteArray(62);
    218     sCallbackEnv->SetByteArrayRegion(jb, 0, 62, (jbyte *) adv_data);
    219 
    220     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScanResult
    221         , address, rssi, jb);
    222 
    223     sCallbackEnv->DeleteLocalRef(address);
    224     sCallbackEnv->DeleteLocalRef(jb);
    225     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    226 }
    227 
    228 void btgattc_open_cb(int conn_id, int status, int clientIf, bt_bdaddr_t* bda)
    229 {
    230     CHECK_CALLBACK_ENV
    231 
    232     char c_address[32];
    233     snprintf(c_address, sizeof(c_address),"%02X:%02X:%02X:%02X:%02X:%02X",
    234         bda->address[0], bda->address[1], bda->address[2],
    235         bda->address[3], bda->address[4], bda->address[5]);
    236 
    237     jstring address = sCallbackEnv->NewStringUTF(c_address);
    238     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnected,
    239         clientIf, conn_id, status, address);
    240     sCallbackEnv->DeleteLocalRef(address);
    241     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    242 }
    243 
    244 void btgattc_close_cb(int conn_id, int status, int clientIf, bt_bdaddr_t* bda)
    245 {
    246     CHECK_CALLBACK_ENV
    247     char c_address[32];
    248     snprintf(c_address, sizeof(c_address),"%02X:%02X:%02X:%02X:%02X:%02X",
    249         bda->address[0], bda->address[1], bda->address[2],
    250         bda->address[3], bda->address[4], bda->address[5]);
    251 
    252     jstring address = sCallbackEnv->NewStringUTF(c_address);
    253     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onDisconnected,
    254         clientIf, conn_id, status, address);
    255     sCallbackEnv->DeleteLocalRef(address);
    256     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    257 }
    258 
    259 void btgattc_search_complete_cb(int conn_id, int status)
    260 {
    261     CHECK_CALLBACK_ENV
    262     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onSearchCompleted,
    263                                  conn_id, status);
    264     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    265 }
    266 
    267 void btgattc_search_result_cb(int conn_id, btgatt_srvc_id_t *srvc_id)
    268 {
    269     CHECK_CALLBACK_ENV
    270     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onSearchResult, conn_id,
    271         SRVC_ID_PARAMS(srvc_id));
    272     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    273 }
    274 
    275 void btgattc_get_characteristic_cb(int conn_id, int status,
    276                 btgatt_srvc_id_t *srvc_id, btgatt_char_id_t *char_id,
    277                 int char_prop)
    278 {
    279     CHECK_CALLBACK_ENV
    280     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onGetCharacteristic
    281         , conn_id, status, SRVC_ID_PARAMS(srvc_id), CHAR_ID_PARAMS(char_id)
    282         , char_prop);
    283     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    284 }
    285 
    286 void btgattc_get_descriptor_cb(int conn_id, int status,
    287                 btgatt_srvc_id_t *srvc_id, btgatt_char_id_t *char_id,
    288                 bt_uuid_t *descr_id)
    289 {
    290     CHECK_CALLBACK_ENV
    291     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onGetDescriptor
    292         , conn_id, status, SRVC_ID_PARAMS(srvc_id), CHAR_ID_PARAMS(char_id)
    293         , UUID_PARAMS(descr_id));
    294     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    295 }
    296 
    297 void btgattc_get_included_service_cb(int conn_id, int status,
    298                 btgatt_srvc_id_t *srvc_id, btgatt_srvc_id_t *incl_srvc_id)
    299 {
    300     CHECK_CALLBACK_ENV
    301     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onGetIncludedService
    302         , conn_id, status, SRVC_ID_PARAMS(srvc_id), SRVC_ID_PARAMS(incl_srvc_id));
    303     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    304 }
    305 
    306 void btgattc_register_for_notification_cb(int conn_id, int registered, int status,
    307                                           btgatt_srvc_id_t *srvc_id, btgatt_char_id_t *char_id)
    308 {
    309     CHECK_CALLBACK_ENV
    310     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onRegisterForNotifications
    311         , conn_id, status, registered, SRVC_ID_PARAMS(srvc_id), CHAR_ID_PARAMS(char_id));
    312     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    313 }
    314 
    315 void btgattc_notify_cb(int conn_id, btgatt_notify_params_t *p_data)
    316 {
    317     CHECK_CALLBACK_ENV
    318 
    319     char c_address[32];
    320     snprintf(c_address, sizeof(c_address), "%02X:%02X:%02X:%02X:%02X:%02X",
    321         p_data->bda.address[0], p_data->bda.address[1], p_data->bda.address[2],
    322         p_data->bda.address[3], p_data->bda.address[4], p_data->bda.address[5]);
    323 
    324     jstring address = sCallbackEnv->NewStringUTF(c_address);
    325     jbyteArray jb = sCallbackEnv->NewByteArray(p_data->len);
    326     sCallbackEnv->SetByteArrayRegion(jb, 0, p_data->len, (jbyte *) p_data->value);
    327 
    328     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNotify
    329         , conn_id, address, SRVC_ID_PARAMS((&p_data->srvc_id))
    330         , CHAR_ID_PARAMS((&p_data->char_id)), p_data->is_notify, jb);
    331 
    332     sCallbackEnv->DeleteLocalRef(address);
    333     sCallbackEnv->DeleteLocalRef(jb);
    334     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    335 }
    336 
    337 void btgattc_read_characteristic_cb(int conn_id, int status, btgatt_read_params_t *p_data)
    338 {
    339     CHECK_CALLBACK_ENV
    340 
    341     jbyteArray jb;
    342     if ( status == 0 )      //successful
    343     {
    344         jb = sCallbackEnv->NewByteArray(p_data->value.len);
    345         sCallbackEnv->SetByteArrayRegion(jb, 0, p_data->value.len,
    346             (jbyte *) p_data->value.value);
    347     } else {
    348         uint8_t value = 0;
    349         jb = sCallbackEnv->NewByteArray(1);
    350         sCallbackEnv->SetByteArrayRegion(jb, 0, 1, (jbyte *) &value);
    351     }
    352 
    353     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onReadCharacteristic
    354         , conn_id, status, SRVC_ID_PARAMS((&p_data->srvc_id))
    355         , CHAR_ID_PARAMS((&p_data->char_id)), p_data->value_type, jb);
    356     sCallbackEnv->DeleteLocalRef(jb);
    357     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    358 }
    359 
    360 void btgattc_write_characteristic_cb(int conn_id, int status, btgatt_write_params_t *p_data)
    361 {
    362     CHECK_CALLBACK_ENV
    363     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onWriteCharacteristic
    364         , conn_id, status, SRVC_ID_PARAMS((&p_data->srvc_id))
    365         , CHAR_ID_PARAMS((&p_data->char_id)));
    366     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    367 }
    368 
    369 void btgattc_execute_write_cb(int conn_id, int status)
    370 {
    371     CHECK_CALLBACK_ENV
    372     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onExecuteCompleted
    373         , conn_id, status);
    374     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    375 }
    376 
    377 void btgattc_read_descriptor_cb(int conn_id, int status, btgatt_read_params_t *p_data)
    378 {
    379     CHECK_CALLBACK_ENV
    380 
    381     jbyteArray jb;
    382     if ( p_data->value.len != 0 )
    383     {
    384         jb = sCallbackEnv->NewByteArray(p_data->value.len);
    385         sCallbackEnv->SetByteArrayRegion(jb, 0, p_data->value.len,
    386                                 (jbyte *) p_data->value.value);
    387     } else {
    388         jb = sCallbackEnv->NewByteArray(1);
    389     }
    390 
    391     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onReadDescriptor
    392         , conn_id, status, SRVC_ID_PARAMS((&p_data->srvc_id))
    393         , CHAR_ID_PARAMS((&p_data->char_id)), UUID_PARAMS((&p_data->descr_id))
    394         , p_data->value_type, jb);
    395 
    396     sCallbackEnv->DeleteLocalRef(jb);
    397     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    398 }
    399 
    400 void btgattc_write_descriptor_cb(int conn_id, int status, btgatt_write_params_t *p_data)
    401 {
    402     CHECK_CALLBACK_ENV
    403     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onWriteDescriptor
    404         , conn_id, status, SRVC_ID_PARAMS((&p_data->srvc_id))
    405         , CHAR_ID_PARAMS((&p_data->char_id)), UUID_PARAMS((&p_data->descr_id)));
    406     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    407 }
    408 
    409 void btgattc_remote_rssi_cb(int client_if,bt_bdaddr_t* bda, int rssi, int status)
    410 {
    411     CHECK_CALLBACK_ENV
    412 
    413     char c_address[32];
    414     snprintf(c_address, sizeof(c_address),"%02X:%02X:%02X:%02X:%02X:%02X",
    415         bda->address[0], bda->address[1], bda->address[2],
    416         bda->address[3], bda->address[4], bda->address[5]);
    417     jstring address = sCallbackEnv->NewStringUTF(c_address);
    418     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onReadRemoteRssi,
    419        client_if, address, rssi, status);
    420     sCallbackEnv->DeleteLocalRef(address);
    421     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    422 }
    423 
    424 static const btgatt_client_callbacks_t sGattClientCallbacks = {
    425     btgattc_register_app_cb,
    426     btgattc_scan_result_cb,
    427     btgattc_open_cb,
    428     btgattc_close_cb,
    429     btgattc_search_complete_cb,
    430     btgattc_search_result_cb,
    431     btgattc_get_characteristic_cb,
    432     btgattc_get_descriptor_cb,
    433     btgattc_get_included_service_cb,
    434     btgattc_register_for_notification_cb,
    435     btgattc_notify_cb,
    436     btgattc_read_characteristic_cb,
    437     btgattc_write_characteristic_cb,
    438     btgattc_read_descriptor_cb,
    439     btgattc_write_descriptor_cb,
    440     btgattc_execute_write_cb,
    441     btgattc_remote_rssi_cb
    442 };
    443 
    444 
    445 /**
    446  * BTA server callbacks
    447  */
    448 
    449 void btgatts_register_app_cb(int status, int server_if, bt_uuid_t *uuid)
    450 {
    451     CHECK_CALLBACK_ENV
    452     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerRegistered
    453         , status, server_if, UUID_PARAMS(uuid));
    454     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    455 }
    456 
    457 void btgatts_connection_cb(int conn_id, int server_if, int connected, bt_bdaddr_t *bda)
    458 {
    459     CHECK_CALLBACK_ENV
    460 
    461     char c_address[32];
    462     sprintf(c_address, "%02X:%02X:%02X:%02X:%02X:%02X",
    463             bda->address[0], bda->address[1], bda->address[2],
    464             bda->address[3], bda->address[4], bda->address[5]);
    465 
    466     jstring address = sCallbackEnv->NewStringUTF(c_address);
    467     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientConnected,
    468                                  address, connected, conn_id, server_if);
    469     sCallbackEnv->DeleteLocalRef(address);
    470     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    471 }
    472 
    473 void btgatts_service_added_cb(int status, int server_if,
    474                               btgatt_srvc_id_t *srvc_id, int srvc_handle)
    475 {
    476     CHECK_CALLBACK_ENV
    477     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceAdded, status,
    478                                  server_if, SRVC_ID_PARAMS(srvc_id),
    479                                  srvc_handle);
    480     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    481 }
    482 
    483 void btgatts_included_service_added_cb(int status, int server_if,
    484                                    int srvc_handle,
    485                                    int incl_srvc_handle)
    486 {
    487     CHECK_CALLBACK_ENV
    488     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onIncludedServiceAdded,
    489                                  status, server_if, srvc_handle, incl_srvc_handle);
    490     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    491 }
    492 
    493 void btgatts_characteristic_added_cb(int status, int server_if, bt_uuid_t *char_id,
    494                                      int srvc_handle, int char_handle)
    495 {
    496     CHECK_CALLBACK_ENV
    497     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onCharacteristicAdded,
    498                                  status, server_if, UUID_PARAMS(char_id),
    499                                  srvc_handle, char_handle);
    500     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    501 }
    502 
    503 void btgatts_descriptor_added_cb(int status, int server_if,
    504                                  bt_uuid_t *descr_id, int srvc_handle,
    505                                  int descr_handle)
    506 {
    507     CHECK_CALLBACK_ENV
    508     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onDescriptorAdded,
    509                                  status, server_if, UUID_PARAMS(descr_id),
    510                                  srvc_handle, descr_handle);
    511     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    512 }
    513 
    514 void btgatts_service_started_cb(int status, int server_if, int srvc_handle)
    515 {
    516     CHECK_CALLBACK_ENV
    517     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceStarted, status,
    518                                  server_if, srvc_handle);
    519     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    520 }
    521 
    522 void btgatts_service_stopped_cb(int status, int server_if, int srvc_handle)
    523 {
    524     CHECK_CALLBACK_ENV
    525     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceStopped, status,
    526                                  server_if, srvc_handle);
    527     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    528 }
    529 
    530 void btgatts_service_deleted_cb(int status, int server_if, int srvc_handle)
    531 {
    532     CHECK_CALLBACK_ENV
    533     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceDeleted, status,
    534                                  server_if, srvc_handle);
    535     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    536 }
    537 
    538 void btgatts_request_read_cb(int conn_id, int trans_id, bt_bdaddr_t *bda,
    539                              int attr_handle, int offset, bool is_long)
    540 {
    541     CHECK_CALLBACK_ENV
    542 
    543     char c_address[32];
    544     sprintf(c_address, "%02X:%02X:%02X:%02X:%02X:%02X",
    545             bda->address[0], bda->address[1], bda->address[2],
    546             bda->address[3], bda->address[4], bda->address[5]);
    547 
    548     jstring address = sCallbackEnv->NewStringUTF(c_address);
    549     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAttributeRead,
    550                                  address, conn_id, trans_id, attr_handle,
    551                                  offset, is_long);
    552     sCallbackEnv->DeleteLocalRef(address);
    553     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    554 }
    555 
    556 void btgatts_request_write_cb(int conn_id, int trans_id,
    557                               bt_bdaddr_t *bda, int attr_handle,
    558                               int offset, int length,
    559                               bool need_rsp, bool is_prep, uint8_t* value)
    560 {
    561     CHECK_CALLBACK_ENV
    562 
    563     char c_address[32];
    564     sprintf(c_address, "%02X:%02X:%02X:%02X:%02X:%02X",
    565             bda->address[0], bda->address[1], bda->address[2],
    566             bda->address[3], bda->address[4], bda->address[5]);
    567 
    568     jstring address = sCallbackEnv->NewStringUTF(c_address);
    569 
    570     jbyteArray val = sCallbackEnv->NewByteArray(length);
    571     if (val) sCallbackEnv->SetByteArrayRegion(val, 0, length, (jbyte*)value);
    572     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAttributeWrite,
    573                                  address, conn_id, trans_id, attr_handle,
    574                                  offset, length, need_rsp, is_prep, val);
    575     sCallbackEnv->DeleteLocalRef(address);
    576     sCallbackEnv->DeleteLocalRef(val);
    577     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    578 }
    579 
    580 void btgatts_request_exec_write_cb(int conn_id, int trans_id,
    581                                    bt_bdaddr_t *bda, int exec_write)
    582 {
    583     CHECK_CALLBACK_ENV
    584 
    585     char c_address[32];
    586     sprintf(c_address, "%02X:%02X:%02X:%02X:%02X:%02X",
    587             bda->address[0], bda->address[1], bda->address[2],
    588             bda->address[3], bda->address[4], bda->address[5]);
    589 
    590     jstring address = sCallbackEnv->NewStringUTF(c_address);
    591     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onExecuteWrite,
    592                                  address, conn_id, trans_id, exec_write);
    593     sCallbackEnv->DeleteLocalRef(address);
    594     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    595 }
    596 
    597 void btgatts_response_confirmation_cb(int status, int handle)
    598 {
    599     CHECK_CALLBACK_ENV
    600     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onResponseSendCompleted,
    601                                  status, handle);
    602     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    603 }
    604 
    605 static const btgatt_server_callbacks_t sGattServerCallbacks = {
    606     btgatts_register_app_cb,
    607     btgatts_connection_cb,
    608     btgatts_service_added_cb,
    609     btgatts_included_service_added_cb,
    610     btgatts_characteristic_added_cb,
    611     btgatts_descriptor_added_cb,
    612     btgatts_service_started_cb,
    613     btgatts_service_stopped_cb,
    614     btgatts_service_deleted_cb,
    615     btgatts_request_read_cb,
    616     btgatts_request_write_cb,
    617     btgatts_request_exec_write_cb,
    618     btgatts_response_confirmation_cb
    619 };
    620 
    621 /**
    622  * GATT callbacks
    623  */
    624 
    625 static const btgatt_callbacks_t sGattCallbacks = {
    626     sizeof(btgatt_callbacks_t),
    627     &sGattClientCallbacks,
    628     &sGattServerCallbacks
    629 };
    630 
    631 /**
    632  * Native function definitions
    633  */
    634 
    635 static void classInitNative(JNIEnv* env, jclass clazz) {
    636 
    637     // Client callbacks
    638 
    639     method_onClientRegistered = env->GetMethodID(clazz, "onClientRegistered", "(IIJJ)V");
    640     method_onScanResult = env->GetMethodID(clazz, "onScanResult", "(Ljava/lang/String;I[B)V");
    641     method_onConnected   = env->GetMethodID(clazz, "onConnected", "(IIILjava/lang/String;)V");
    642     method_onDisconnected = env->GetMethodID(clazz, "onDisconnected", "(IIILjava/lang/String;)V");
    643     method_onReadCharacteristic = env->GetMethodID(clazz, "onReadCharacteristic", "(IIIIJJIJJI[B)V");
    644     method_onWriteCharacteristic = env->GetMethodID(clazz, "onWriteCharacteristic", "(IIIIJJIJJ)V");
    645     method_onExecuteCompleted = env->GetMethodID(clazz, "onExecuteCompleted",  "(II)V");
    646     method_onSearchCompleted = env->GetMethodID(clazz, "onSearchCompleted",  "(II)V");
    647     method_onSearchResult = env->GetMethodID(clazz, "onSearchResult", "(IIIJJ)V");
    648     method_onReadDescriptor = env->GetMethodID(clazz, "onReadDescriptor", "(IIIIJJIJJJJI[B)V");
    649     method_onWriteDescriptor = env->GetMethodID(clazz, "onWriteDescriptor", "(IIIIJJIJJJJ)V");
    650     method_onNotify = env->GetMethodID(clazz, "onNotify", "(ILjava/lang/String;IIJJIJJZ[B)V");
    651     method_onGetCharacteristic = env->GetMethodID(clazz, "onGetCharacteristic", "(IIIIJJIJJI)V");
    652     method_onGetDescriptor = env->GetMethodID(clazz, "onGetDescriptor", "(IIIIJJIJJJJ)V");
    653     method_onGetIncludedService = env->GetMethodID(clazz, "onGetIncludedService", "(IIIIJJIIJJ)V");
    654     method_onRegisterForNotifications = env->GetMethodID(clazz, "onRegisterForNotifications", "(IIIIIJJIJJ)V");
    655     method_onReadRemoteRssi = env->GetMethodID(clazz, "onReadRemoteRssi", "(ILjava/lang/String;II)V");
    656 
    657      // Server callbacks
    658 
    659     method_onServerRegistered = env->GetMethodID(clazz, "onServerRegistered", "(IIJJ)V");
    660     method_onClientConnected = env->GetMethodID(clazz, "onClientConnected", "(Ljava/lang/String;ZII)V");
    661     method_onServiceAdded = env->GetMethodID(clazz, "onServiceAdded", "(IIIIJJI)V");
    662     method_onIncludedServiceAdded = env->GetMethodID(clazz, "onIncludedServiceAdded", "(IIII)V");
    663     method_onCharacteristicAdded  = env->GetMethodID(clazz, "onCharacteristicAdded", "(IIJJII)V");
    664     method_onDescriptorAdded = env->GetMethodID(clazz, "onDescriptorAdded", "(IIJJII)V");
    665     method_onServiceStarted = env->GetMethodID(clazz, "onServiceStarted", "(III)V");
    666     method_onServiceStopped = env->GetMethodID(clazz, "onServiceStopped", "(III)V");
    667     method_onServiceDeleted = env->GetMethodID(clazz, "onServiceDeleted", "(III)V");
    668     method_onResponseSendCompleted = env->GetMethodID(clazz, "onResponseSendCompleted", "(II)V");
    669     method_onAttributeRead= env->GetMethodID(clazz, "onAttributeRead", "(Ljava/lang/String;IIIIZ)V");
    670     method_onAttributeWrite= env->GetMethodID(clazz, "onAttributeWrite", "(Ljava/lang/String;IIIIIZZ[B)V");
    671     method_onExecuteWrite= env->GetMethodID(clazz, "onExecuteWrite", "(Ljava/lang/String;III)V");
    672 
    673     info("classInitNative: Success!");
    674 }
    675 
    676 static const bt_interface_t* btIf;
    677 
    678 static void initializeNative(JNIEnv *env, jobject object) {
    679     if(btIf)
    680         return;
    681 
    682     if ( (btIf = getBluetoothInterface()) == NULL) {
    683         error("Bluetooth module is not loaded");
    684         return;
    685     }
    686 
    687     if (sGattIf != NULL) {
    688          ALOGW("Cleaning up Bluetooth GATT Interface before initializing...");
    689          sGattIf->cleanup();
    690          sGattIf = NULL;
    691     }
    692 
    693     if (mCallbacksObj != NULL) {
    694          ALOGW("Cleaning up Bluetooth GATT callback object");
    695          env->DeleteGlobalRef(mCallbacksObj);
    696          mCallbacksObj = NULL;
    697     }
    698 
    699     if ( (sGattIf = (btgatt_interface_t *)
    700           btIf->get_profile_interface(BT_PROFILE_GATT_ID)) == NULL) {
    701         error("Failed to get Bluetooth GATT Interface");
    702         return;
    703     }
    704 
    705     bt_status_t status;
    706     if ( (status = sGattIf->init(&sGattCallbacks)) != BT_STATUS_SUCCESS) {
    707         error("Failed to initialize Bluetooth GATT, status: %d", status);
    708         sGattIf = NULL;
    709         return;
    710     }
    711 
    712     mCallbacksObj = env->NewGlobalRef(object);
    713 }
    714 
    715 static void cleanupNative(JNIEnv *env, jobject object) {
    716     bt_status_t status;
    717     if (!btIf) return;
    718 
    719     if (sGattIf != NULL) {
    720         sGattIf->cleanup();
    721         sGattIf = NULL;
    722     }
    723 
    724     if (mCallbacksObj != NULL) {
    725         env->DeleteGlobalRef(mCallbacksObj);
    726         mCallbacksObj = NULL;
    727     }
    728     btIf = NULL;
    729 }
    730 
    731 /**
    732  * Native Client functions
    733  */
    734 
    735 static int gattClientGetDeviceTypeNative(JNIEnv* env, jobject object, jstring address)
    736 {
    737     if (!sGattIf) return 0;
    738     bt_bdaddr_t bda;
    739     jstr2bdaddr(env, &bda, address);
    740     return sGattIf->client->get_device_type(&bda);
    741 }
    742 
    743 static void gattClientRegisterAppNative(JNIEnv* env, jobject object,
    744                                         jlong app_uuid_lsb, jlong app_uuid_msb )
    745 {
    746     bt_uuid_t uuid;
    747 
    748     if (!sGattIf) return;
    749     set_uuid(uuid.uu, app_uuid_msb, app_uuid_lsb);
    750     sGattIf->client->register_client(&uuid);
    751 }
    752 
    753 static void gattClientUnregisterAppNative(JNIEnv* env, jobject object, jint clientIf)
    754 {
    755     if (!sGattIf) return;
    756     sGattIf->client->unregister_client(clientIf);
    757 }
    758 
    759 static void gattClientScanNative(JNIEnv* env, jobject object, jint clientIf, jboolean start)
    760 {
    761     if (!sGattIf) return;
    762     sGattIf->client->scan(clientIf, start);
    763 }
    764 
    765 static void gattClientConnectNative(JNIEnv* env, jobject object, jint clientif,
    766                                  jstring address, jboolean isDirect)
    767 {
    768     if (!sGattIf) return;
    769 
    770     bt_bdaddr_t bda;
    771     jstr2bdaddr(env, &bda, address);
    772     sGattIf->client->connect(clientif, &bda, isDirect);
    773 }
    774 
    775 static void gattClientDisconnectNative(JNIEnv* env, jobject object, jint clientIf,
    776                                   jstring address, jint conn_id)
    777 {
    778     if (!sGattIf) return;
    779     bt_bdaddr_t bda;
    780     jstr2bdaddr(env, &bda, address);
    781     sGattIf->client->disconnect(clientIf, &bda, conn_id);
    782 }
    783 
    784 static void gattClientRefreshNative(JNIEnv* env, jobject object, jint clientIf,
    785                                     jstring address)
    786 {
    787     if (!sGattIf) return;
    788 
    789     bt_bdaddr_t bda;
    790     jstr2bdaddr(env, &bda, address);
    791     sGattIf->client->refresh(clientIf, &bda);
    792 }
    793 
    794 static void gattClientSearchServiceNative(JNIEnv* env, jobject object, jint conn_id,
    795             jboolean search_all, jlong service_uuid_lsb, jlong service_uuid_msb)
    796 {
    797     if (!sGattIf) return;
    798 
    799     bt_uuid_t uuid;
    800     set_uuid(uuid.uu, service_uuid_msb, service_uuid_lsb);
    801     sGattIf->client->search_service(conn_id, search_all ? 0 : &uuid);
    802 }
    803 
    804 static void gattClientGetCharacteristicNative(JNIEnv* env, jobject object,
    805     jint conn_id,
    806     jint  service_type, jint  service_id_inst_id,
    807     jlong service_id_uuid_lsb, jlong service_id_uuid_msb,
    808     jint  char_id_inst_id,
    809     jlong char_id_uuid_lsb, jlong char_id_uuid_msb)
    810 {
    811     if (!sGattIf) return;
    812 
    813     btgatt_srvc_id_t srvc_id;
    814     srvc_id.id.inst_id = (uint8_t) service_id_inst_id;
    815     srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
    816 
    817     set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);
    818 
    819     btgatt_char_id_t char_id;
    820     char_id.inst_id = (uint8_t) char_id_inst_id;
    821     set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb);
    822 
    823     if (char_id_uuid_lsb == 0)
    824     {
    825         sGattIf->client->get_characteristic(conn_id, &srvc_id, 0);
    826     } else {
    827         sGattIf->client->get_characteristic(conn_id, &srvc_id, &char_id);
    828     }
    829 }
    830 
    831 static void gattClientGetDescriptorNative(JNIEnv* env, jobject object,
    832     jint conn_id,
    833     jint  service_type, jint  service_id_inst_id,
    834     jlong service_id_uuid_lsb, jlong service_id_uuid_msb,
    835     jint  char_id_inst_id,
    836     jlong char_id_uuid_lsb, jlong char_id_uuid_msb,
    837     jlong descr_id_uuid_lsb, jlong descr_id_uuid_msb)
    838 {
    839     if (!sGattIf) return;
    840 
    841     btgatt_srvc_id_t srvc_id;
    842     srvc_id.id.inst_id = (uint8_t) service_id_inst_id;
    843     srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
    844     set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);
    845 
    846     btgatt_char_id_t char_id;
    847     char_id.inst_id = (uint8_t) char_id_inst_id;
    848     set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb);
    849 
    850     bt_uuid_t descr_id;
    851     set_uuid(descr_id.uu, descr_id_uuid_msb, descr_id_uuid_lsb);
    852 
    853     if (descr_id_uuid_lsb == 0)
    854     {
    855         sGattIf->client->get_descriptor(conn_id, &srvc_id, &char_id, 0);
    856     } else {
    857         sGattIf->client->get_descriptor(conn_id, &srvc_id, &char_id, &descr_id);
    858     }
    859 }
    860 
    861 static void gattClientGetIncludedServiceNative(JNIEnv* env, jobject object,
    862     jint conn_id, jint service_type, jint service_id_inst_id,
    863     jlong service_id_uuid_lsb, jlong service_id_uuid_msb,
    864     jint incl_service_id_inst_id, jint incl_service_type,
    865     jlong incl_service_id_uuid_lsb, jlong incl_service_id_uuid_msb)
    866 {
    867     if (!sGattIf) return;
    868 
    869     btgatt_srvc_id_t srvc_id;
    870     srvc_id.id.inst_id = (uint8_t) service_id_inst_id;
    871     srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
    872     set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);
    873 
    874     btgatt_srvc_id_t  incl_srvc_id;
    875     incl_srvc_id.id.inst_id = (uint8_t) incl_service_id_inst_id;
    876     incl_srvc_id.is_primary = (incl_service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
    877     set_uuid(incl_srvc_id.id.uuid.uu, incl_service_id_uuid_msb, incl_service_id_uuid_lsb);
    878 
    879     if (incl_service_id_uuid_lsb == 0)
    880     {
    881         sGattIf->client->get_included_service(conn_id, &srvc_id, 0);
    882     } else {
    883         sGattIf->client->get_included_service(conn_id, &srvc_id, &incl_srvc_id);
    884     }
    885 }
    886 
    887 static void gattClientReadCharacteristicNative(JNIEnv* env, jobject object,
    888     jint conn_id, jint  service_type, jint  service_id_inst_id,
    889     jlong service_id_uuid_lsb, jlong service_id_uuid_msb,
    890     jint  char_id_inst_id,
    891     jlong char_id_uuid_lsb, jlong char_id_uuid_msb,
    892     jint authReq)
    893 {
    894     if (!sGattIf) return;
    895 
    896     btgatt_srvc_id_t srvc_id;
    897     srvc_id.id.inst_id = (uint8_t) service_id_inst_id;
    898     srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
    899     set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);
    900 
    901     btgatt_char_id_t char_id;
    902     char_id.inst_id = (uint8_t) char_id_inst_id;
    903     set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb);
    904 
    905     sGattIf->client->read_characteristic(conn_id, &srvc_id, &char_id, authReq);
    906 }
    907 
    908 static void gattClientReadDescriptorNative(JNIEnv* env, jobject object,
    909     jint conn_id, jint  service_type, jint  service_id_inst_id,
    910     jlong service_id_uuid_lsb, jlong service_id_uuid_msb,
    911     jint  char_id_inst_id,
    912     jlong char_id_uuid_lsb, jlong char_id_uuid_msb,
    913     jlong descr_id_uuid_lsb, jlong descr_id_uuid_msb,
    914     jint authReq)
    915 {
    916     if (!sGattIf) return;
    917 
    918     btgatt_srvc_id_t srvc_id;
    919     srvc_id.id.inst_id = (uint8_t) service_id_inst_id;
    920     srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
    921     set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);
    922 
    923     btgatt_char_id_t char_id;
    924     char_id.inst_id = (uint8_t) char_id_inst_id;
    925     set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb);
    926 
    927     bt_uuid_t descr_id;
    928     set_uuid(descr_id.uu, descr_id_uuid_msb, descr_id_uuid_lsb);
    929 
    930     sGattIf->client->read_descriptor(conn_id, &srvc_id, &char_id, &descr_id, authReq);
    931 }
    932 
    933 static void gattClientWriteCharacteristicNative(JNIEnv* env, jobject object,
    934     jint conn_id, jint  service_type, jint  service_id_inst_id,
    935     jlong service_id_uuid_lsb, jlong service_id_uuid_msb,
    936     jint  char_id_inst_id,
    937     jlong char_id_uuid_lsb, jlong char_id_uuid_msb,
    938     jint write_type, jint auth_req, jbyteArray value)
    939 {
    940     if (!sGattIf) return;
    941 
    942     btgatt_srvc_id_t srvc_id;
    943     srvc_id.id.inst_id = (uint8_t) service_id_inst_id;
    944     srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
    945     set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);
    946 
    947     btgatt_char_id_t char_id;
    948     char_id.inst_id = (uint8_t) char_id_inst_id;
    949     set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb);
    950 
    951     uint16_t len = (uint16_t) env->GetArrayLength(value);
    952     jbyte *p_value = env->GetByteArrayElements(value, NULL);
    953     if (p_value == NULL) return;
    954 
    955     sGattIf->client->write_characteristic(conn_id, &srvc_id, &char_id,
    956                                     write_type, len, auth_req, (char*)p_value);
    957     env->ReleaseByteArrayElements(value, p_value, 0);
    958 }
    959 
    960 static void gattClientExecuteWriteNative(JNIEnv* env, jobject object,
    961     jint conn_id, jboolean execute)
    962 {
    963     if (!sGattIf) return;
    964     sGattIf->client->execute_write(conn_id, execute ? 1 : 0);
    965 }
    966 
    967 static void gattClientWriteDescriptorNative(JNIEnv* env, jobject object,
    968     jint conn_id, jint  service_type, jint service_id_inst_id,
    969     jlong service_id_uuid_lsb, jlong service_id_uuid_msb,
    970     jint char_id_inst_id,
    971     jlong char_id_uuid_lsb, jlong char_id_uuid_msb,
    972     jlong descr_id_uuid_lsb, jlong descr_id_uuid_msb,
    973     jint write_type, jint auth_req, jbyteArray value)
    974 {
    975     if (!sGattIf) return;
    976 
    977     btgatt_srvc_id_t srvc_id;
    978     srvc_id.id.inst_id = (uint8_t) service_id_inst_id;
    979     srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
    980     set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);
    981 
    982     btgatt_char_id_t char_id;
    983     char_id.inst_id = (uint8_t) char_id_inst_id;
    984     set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb);
    985 
    986     bt_uuid_t descr_id;
    987     set_uuid(descr_id.uu, descr_id_uuid_msb, descr_id_uuid_lsb);
    988 
    989     uint16_t len = (uint16_t) env->GetArrayLength(value);
    990     jbyte *p_value = env->GetByteArrayElements(value, NULL);
    991     if (p_value == NULL) return;
    992 
    993     sGattIf->client->write_descriptor(conn_id, &srvc_id, &char_id, &descr_id,
    994                                     write_type, len, auth_req, (char*)p_value);
    995     env->ReleaseByteArrayElements(value, p_value, 0);
    996 }
    997 
    998 static void gattClientRegisterForNotificationsNative(JNIEnv* env, jobject object,
    999     jint clientIf, jstring address,
   1000     jint  service_type, jint service_id_inst_id,
   1001     jlong service_id_uuid_lsb, jlong service_id_uuid_msb,
   1002     jint char_id_inst_id,
   1003     jlong char_id_uuid_lsb, jlong char_id_uuid_msb,
   1004     jboolean enable)
   1005 {
   1006     if (!sGattIf) return;
   1007 
   1008     btgatt_srvc_id_t srvc_id;
   1009     srvc_id.id.inst_id = (uint8_t) service_id_inst_id;
   1010     srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
   1011     set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);
   1012 
   1013     btgatt_char_id_t char_id;
   1014     char_id.inst_id = (uint8_t) char_id_inst_id;
   1015     set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb);
   1016 
   1017     bt_bdaddr_t bd_addr;
   1018     const char *c_address = env->GetStringUTFChars(address, NULL);
   1019     bd_addr_str_to_addr(c_address, bd_addr.address);
   1020 
   1021     if (enable)
   1022         sGattIf->client->register_for_notification(clientIf, &bd_addr, &srvc_id, &char_id);
   1023     else
   1024         sGattIf->client->deregister_for_notification(clientIf, &bd_addr, &srvc_id, &char_id);
   1025 }
   1026 
   1027 static void gattClientReadRemoteRssiNative(JNIEnv* env, jobject object, jint clientif,
   1028                                  jstring address)
   1029 {
   1030     if (!sGattIf) return;
   1031 
   1032     bt_bdaddr_t bda;
   1033     jstr2bdaddr(env, &bda, address);
   1034 
   1035     sGattIf->client->read_remote_rssi(clientif, &bda);
   1036 }
   1037 
   1038 
   1039 /**
   1040  * Native server functions
   1041  */
   1042 static void gattServerRegisterAppNative(JNIEnv* env, jobject object,
   1043                                         jlong app_uuid_lsb, jlong app_uuid_msb )
   1044 {
   1045     bt_uuid_t uuid;
   1046     if (!sGattIf) return;
   1047     set_uuid(uuid.uu, app_uuid_msb, app_uuid_lsb);
   1048     sGattIf->server->register_server(&uuid);
   1049 }
   1050 
   1051 static void gattServerUnregisterAppNative(JNIEnv* env, jobject object, jint serverIf)
   1052 {
   1053     if (!sGattIf) return;
   1054     sGattIf->server->unregister_server(serverIf);
   1055 }
   1056 
   1057 static void gattServerConnectNative(JNIEnv *env, jobject object,
   1058                                  jint server_if, jstring address, jboolean is_direct)
   1059 {
   1060     if (!sGattIf) return;
   1061 
   1062     bt_bdaddr_t bd_addr;
   1063     const char *c_address = env->GetStringUTFChars(address, NULL);
   1064     bd_addr_str_to_addr(c_address, bd_addr.address);
   1065 
   1066     sGattIf->server->connect(server_if, &bd_addr, is_direct);
   1067 }
   1068 
   1069 static void gattServerDisconnectNative(JNIEnv* env, jobject object, jint serverIf,
   1070                                   jstring address, jint conn_id)
   1071 {
   1072     if (!sGattIf) return;
   1073     bt_bdaddr_t bda;
   1074     jstr2bdaddr(env, &bda, address);
   1075     sGattIf->server->disconnect(serverIf, &bda, conn_id);
   1076 }
   1077 
   1078 static void gattServerAddServiceNative (JNIEnv *env, jobject object,
   1079         jint server_if, jint service_type, jint service_id_inst_id,
   1080         jlong service_id_uuid_lsb, jlong service_id_uuid_msb,
   1081         jint num_handles)
   1082 {
   1083     if (!sGattIf) return;
   1084 
   1085     btgatt_srvc_id_t srvc_id;
   1086     srvc_id.id.inst_id = (uint8_t) service_id_inst_id;
   1087     srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
   1088     set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);
   1089 
   1090     sGattIf->server->add_service(server_if, &srvc_id, num_handles);
   1091 }
   1092 
   1093 static void gattServerAddIncludedServiceNative (JNIEnv *env, jobject object,
   1094         jint server_if, jint svc_handle, jint included_svc_handle)
   1095 {
   1096     if (!sGattIf) return;
   1097     sGattIf->server->add_included_service(server_if, svc_handle,
   1098                                           included_svc_handle);
   1099 }
   1100 
   1101 static void gattServerAddCharacteristicNative (JNIEnv *env, jobject object,
   1102         jint server_if, jint svc_handle,
   1103         jlong char_uuid_lsb, jlong char_uuid_msb,
   1104         jint properties, jint permissions)
   1105 {
   1106     if (!sGattIf) return;
   1107 
   1108     bt_uuid_t uuid;
   1109     set_uuid(uuid.uu, char_uuid_msb, char_uuid_lsb);
   1110 
   1111     sGattIf->server->add_characteristic(server_if, svc_handle,
   1112                                         &uuid, properties, permissions);
   1113 }
   1114 
   1115 static void gattServerAddDescriptorNative (JNIEnv *env, jobject object,
   1116         jint server_if, jint svc_handle,
   1117         jlong desc_uuid_lsb, jlong desc_uuid_msb,
   1118         jint permissions)
   1119 {
   1120     if (!sGattIf) return;
   1121 
   1122     bt_uuid_t uuid;
   1123     set_uuid(uuid.uu, desc_uuid_msb, desc_uuid_lsb);
   1124 
   1125     sGattIf->server->add_descriptor(server_if, svc_handle, &uuid, permissions);
   1126 }
   1127 
   1128 static void gattServerStartServiceNative (JNIEnv *env, jobject object,
   1129         jint server_if, jint svc_handle, jint transport )
   1130 {
   1131     if (!sGattIf) return;
   1132     sGattIf->server->start_service(server_if, svc_handle, transport);
   1133 }
   1134 
   1135 static void gattServerStopServiceNative (JNIEnv *env, jobject object,
   1136                                          jint server_if, jint svc_handle)
   1137 {
   1138     if (!sGattIf) return;
   1139     sGattIf->server->stop_service(server_if, svc_handle);
   1140 }
   1141 
   1142 static void gattServerDeleteServiceNative (JNIEnv *env, jobject object,
   1143                                            jint server_if, jint svc_handle)
   1144 {
   1145     if (!sGattIf) return;
   1146     sGattIf->server->delete_service(server_if, svc_handle);
   1147 }
   1148 
   1149 static void gattServerSendIndicationNative (JNIEnv *env, jobject object,
   1150         jint server_if, jint attr_handle, jint conn_id, jbyteArray val)
   1151 {
   1152     if (!sGattIf) return;
   1153 
   1154     jbyte* array = env->GetByteArrayElements(val, 0);
   1155     int val_len = env->GetArrayLength(val);
   1156 
   1157     sGattIf->server->send_indication(server_if, attr_handle, conn_id, val_len,
   1158                                      /*confirm*/ 1, (char*)array);
   1159     env->ReleaseByteArrayElements(val, array, JNI_ABORT);
   1160 }
   1161 
   1162 static void gattServerSendNotificationNative (JNIEnv *env, jobject object,
   1163         jint server_if, jint attr_handle, jint conn_id, jbyteArray val)
   1164 {
   1165     if (!sGattIf) return;
   1166 
   1167     jbyte* array = env->GetByteArrayElements(val, 0);
   1168     int val_len = env->GetArrayLength(val);
   1169 
   1170     sGattIf->server->send_indication(server_if, attr_handle, conn_id, val_len,
   1171                                      /*confirm*/ 0, (char*)array);
   1172     env->ReleaseByteArrayElements(val, array, JNI_ABORT);
   1173 }
   1174 
   1175 static void gattServerSendResponseNative (JNIEnv *env, jobject object,
   1176         jint server_if, jint conn_id, jint trans_id, jint status,
   1177         jint handle, jint offset, jbyteArray val, jint auth_req)
   1178 {
   1179     if (!sGattIf) return;
   1180 
   1181     btgatt_response_t response;
   1182 
   1183     response.attr_value.handle = handle;
   1184     response.attr_value.auth_req = auth_req;
   1185     response.attr_value.offset = offset;
   1186     response.attr_value.len = 0;
   1187 
   1188     if (val != NULL)
   1189     {
   1190         response.attr_value.len = (uint16_t) env->GetArrayLength(val);
   1191         jbyte* array = env->GetByteArrayElements(val, 0);
   1192 
   1193         for (int i = 0; i != response.attr_value.len; ++i)
   1194             response.attr_value.value[i] = (uint8_t) array[i];
   1195         env->ReleaseByteArrayElements(val, array, JNI_ABORT);
   1196     }
   1197 
   1198     sGattIf->server->send_response(conn_id, trans_id, status, &response);
   1199 }
   1200 
   1201 static void gattTestNative(JNIEnv *env, jobject object, jint command,
   1202                            jlong uuid1_lsb, jlong uuid1_msb, jstring bda1,
   1203                            jint p1, jint p2, jint p3, jint p4, jint p5 )
   1204 {
   1205     if (!sGattIf) return;
   1206 
   1207     bt_bdaddr_t bt_bda1;
   1208     jstr2bdaddr(env, &bt_bda1, bda1);
   1209 
   1210     bt_uuid_t uuid1;
   1211     set_uuid(uuid1.uu, uuid1_msb, uuid1_lsb);
   1212 
   1213     btgatt_test_params_t params;
   1214     params.bda1 = &bt_bda1;
   1215     params.uuid1 = &uuid1;
   1216     params.u1 = p1;
   1217     params.u2 = p2;
   1218     params.u3 = p3;
   1219     params.u4 = p4;
   1220     params.u5 = p5;
   1221     sGattIf->client->test_command(command, &params);
   1222 }
   1223 
   1224 /**
   1225  * JNI function definitinos
   1226  */
   1227 
   1228 static JNINativeMethod sMethods[] = {
   1229     {"classInitNative", "()V", (void *) classInitNative},
   1230     {"initializeNative", "()V", (void *) initializeNative},
   1231     {"cleanupNative", "()V", (void *) cleanupNative},
   1232 
   1233     {"gattClientGetDeviceTypeNative", "(Ljava/lang/String;)I", (void *) gattClientGetDeviceTypeNative},
   1234     {"gattClientRegisterAppNative", "(JJ)V", (void *) gattClientRegisterAppNative},
   1235     {"gattClientUnregisterAppNative", "(I)V", (void *) gattClientUnregisterAppNative},
   1236     {"gattClientScanNative", "(IZ)V", (void *) gattClientScanNative},
   1237     {"gattClientConnectNative", "(ILjava/lang/String;Z)V", (void *) gattClientConnectNative},
   1238     {"gattClientDisconnectNative", "(ILjava/lang/String;I)V", (void *) gattClientDisconnectNative},
   1239     {"gattClientRefreshNative", "(ILjava/lang/String;)V", (void *) gattClientRefreshNative},
   1240     {"gattClientSearchServiceNative", "(IZJJ)V", (void *) gattClientSearchServiceNative},
   1241     {"gattClientGetCharacteristicNative", "(IIIJJIJJ)V", (void *) gattClientGetCharacteristicNative},
   1242     {"gattClientGetDescriptorNative", "(IIIJJIJJJJ)V", (void *) gattClientGetDescriptorNative},
   1243     {"gattClientGetIncludedServiceNative", "(IIIJJIIJJ)V", (void *) gattClientGetIncludedServiceNative},
   1244     {"gattClientReadCharacteristicNative", "(IIIJJIJJI)V", (void *) gattClientReadCharacteristicNative},
   1245     {"gattClientReadDescriptorNative", "(IIIJJIJJJJI)V", (void *) gattClientReadDescriptorNative},
   1246     {"gattClientWriteCharacteristicNative", "(IIIJJIJJII[B)V", (void *) gattClientWriteCharacteristicNative},
   1247     {"gattClientWriteDescriptorNative", "(IIIJJIJJJJII[B)V", (void *) gattClientWriteDescriptorNative},
   1248     {"gattClientExecuteWriteNative", "(IZ)V", (void *) gattClientExecuteWriteNative},
   1249     {"gattClientRegisterForNotificationsNative", "(ILjava/lang/String;IIJJIJJZ)V", (void *) gattClientRegisterForNotificationsNative},
   1250     {"gattClientReadRemoteRssiNative", "(ILjava/lang/String;)V", (void *) gattClientReadRemoteRssiNative},
   1251 
   1252     {"gattServerRegisterAppNative", "(JJ)V", (void *) gattServerRegisterAppNative},
   1253     {"gattServerUnregisterAppNative", "(I)V", (void *) gattServerUnregisterAppNative},
   1254     {"gattServerConnectNative", "(ILjava/lang/String;Z)V", (void *) gattServerConnectNative},
   1255     {"gattServerDisconnectNative", "(ILjava/lang/String;I)V", (void *) gattServerDisconnectNative},
   1256     {"gattServerAddServiceNative", "(IIIJJI)V", (void *) gattServerAddServiceNative},
   1257     {"gattServerAddIncludedServiceNative", "(III)V", (void *) gattServerAddIncludedServiceNative},
   1258     {"gattServerAddCharacteristicNative", "(IIJJII)V", (void *) gattServerAddCharacteristicNative},
   1259     {"gattServerAddDescriptorNative", "(IIJJI)V", (void *) gattServerAddDescriptorNative},
   1260     {"gattServerStartServiceNative", "(III)V", (void *) gattServerStartServiceNative},
   1261     {"gattServerStopServiceNative", "(II)V", (void *) gattServerStopServiceNative},
   1262     {"gattServerDeleteServiceNative", "(II)V", (void *) gattServerDeleteServiceNative},
   1263     {"gattServerSendIndicationNative", "(III[B)V", (void *) gattServerSendIndicationNative},
   1264     {"gattServerSendNotificationNative", "(III[B)V", (void *) gattServerSendNotificationNative},
   1265     {"gattServerSendResponseNative", "(IIIIII[BI)V", (void *) gattServerSendResponseNative},
   1266 
   1267     {"gattTestNative", "(IJJLjava/lang/String;IIIII)V", (void *) gattTestNative},
   1268 };
   1269 
   1270 int register_com_android_bluetooth_gatt(JNIEnv* env)
   1271 {
   1272     return jniRegisterNativeMethods(env, "com/android/bluetooth/gatt/GattService",
   1273                                     sMethods, NELEM(sMethods));
   1274 }
   1275 
   1276 }
   1277