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