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