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