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