com_android_bluetooth_gatt.cpp revision f6eff2b71e9bc206f995e847e384507fb1c3e239
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_onReadDescriptor;
153static jmethodID method_onWriteDescriptor;
154static jmethodID method_onNotify;
155static jmethodID method_onGetCharacteristic;
156static jmethodID method_onGetDescriptor;
157static jmethodID method_onGetIncludedService;
158static jmethodID method_onRegisterForNotifications;
159static jmethodID method_onReadRemoteRssi;
160static jmethodID method_onAdvertiseCallback;
161static jmethodID method_onConfigureMTU;
162static jmethodID method_onScanFilterConfig;
163static jmethodID method_onScanFilterParamsConfigured;
164static jmethodID method_onScanFilterEnableDisabled;
165static jmethodID method_onMultiAdvEnable;
166static jmethodID method_onMultiAdvUpdate;
167static jmethodID method_onMultiAdvSetAdvData;
168static jmethodID method_onMultiAdvDisable;
169static jmethodID method_onClientCongestion;
170static jmethodID method_onBatchScanStorageConfigured;
171static jmethodID method_onBatchScanStartStopped;
172static jmethodID method_onBatchScanReports;
173static jmethodID method_onBatchScanThresholdCrossed;
174static jmethodID method_onTrackAdvFoundLost;
175
176/**
177 * Server callback methods
178 */
179static jmethodID method_onServerRegistered;
180static jmethodID method_onClientConnected;
181static jmethodID method_onServiceAdded;
182static jmethodID method_onIncludedServiceAdded;
183static jmethodID method_onCharacteristicAdded;
184static jmethodID method_onDescriptorAdded;
185static jmethodID method_onServiceStarted;
186static jmethodID method_onServiceStopped;
187static jmethodID method_onServiceDeleted;
188static jmethodID method_onResponseSendCompleted;
189static jmethodID method_onAttributeRead;
190static jmethodID method_onAttributeWrite;
191static jmethodID method_onExecuteWrite;
192static jmethodID method_onNotificationSent;
193static jmethodID method_onServerCongestion;
194
195/**
196 * Static variables
197 */
198
199static const btgatt_interface_t *sGattIf = NULL;
200static jobject mCallbacksObj = NULL;
201static JNIEnv *sCallbackEnv = NULL;
202
203static bool checkCallbackThread() {
204    sCallbackEnv = getCallbackEnv();
205
206    JNIEnv* env = AndroidRuntime::getJNIEnv();
207    if (sCallbackEnv != env || sCallbackEnv == NULL) return false;
208    return true;
209}
210
211/**
212 * BTA client callbacks
213 */
214
215void btgattc_register_app_cb(int status, int clientIf, bt_uuid_t *app_uuid)
216{
217    CHECK_CALLBACK_ENV
218    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientRegistered, status,
219        clientIf, UUID_PARAMS(app_uuid));
220    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
221}
222
223void btgattc_scan_result_cb(bt_bdaddr_t* bda, int rssi, uint8_t* adv_data)
224{
225    CHECK_CALLBACK_ENV
226
227    char c_address[32];
228    snprintf(c_address, sizeof(c_address),"%02X:%02X:%02X:%02X:%02X:%02X",
229        bda->address[0], bda->address[1], bda->address[2],
230        bda->address[3], bda->address[4], bda->address[5]);
231
232    jstring address = sCallbackEnv->NewStringUTF(c_address);
233    jbyteArray jb = sCallbackEnv->NewByteArray(62);
234    sCallbackEnv->SetByteArrayRegion(jb, 0, 62, (jbyte *) adv_data);
235
236    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScanResult
237        , address, rssi, jb);
238
239    sCallbackEnv->DeleteLocalRef(address);
240    sCallbackEnv->DeleteLocalRef(jb);
241    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
242}
243
244void btgattc_open_cb(int conn_id, int status, int clientIf, bt_bdaddr_t* bda)
245{
246    CHECK_CALLBACK_ENV
247
248    char c_address[32];
249    snprintf(c_address, sizeof(c_address),"%02X:%02X:%02X:%02X:%02X:%02X",
250        bda->address[0], bda->address[1], bda->address[2],
251        bda->address[3], bda->address[4], bda->address[5]);
252
253    jstring address = sCallbackEnv->NewStringUTF(c_address);
254    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnected,
255        clientIf, conn_id, status, address);
256    sCallbackEnv->DeleteLocalRef(address);
257    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
258}
259
260void btgattc_close_cb(int conn_id, int status, int clientIf, bt_bdaddr_t* bda)
261{
262    CHECK_CALLBACK_ENV
263    char c_address[32];
264    snprintf(c_address, sizeof(c_address),"%02X:%02X:%02X:%02X:%02X:%02X",
265        bda->address[0], bda->address[1], bda->address[2],
266        bda->address[3], bda->address[4], bda->address[5]);
267
268    jstring address = sCallbackEnv->NewStringUTF(c_address);
269    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onDisconnected,
270        clientIf, conn_id, status, address);
271    sCallbackEnv->DeleteLocalRef(address);
272    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
273}
274
275void btgattc_search_complete_cb(int conn_id, int status)
276{
277    CHECK_CALLBACK_ENV
278    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onSearchCompleted,
279                                 conn_id, status);
280    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
281}
282
283void btgattc_search_result_cb(int conn_id, btgatt_srvc_id_t *srvc_id)
284{
285    CHECK_CALLBACK_ENV
286    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onSearchResult, conn_id,
287        SRVC_ID_PARAMS(srvc_id));
288    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
289}
290
291void btgattc_get_characteristic_cb(int conn_id, int status,
292                btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
293                int char_prop)
294{
295    CHECK_CALLBACK_ENV
296    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onGetCharacteristic
297        , conn_id, status, SRVC_ID_PARAMS(srvc_id), GATT_ID_PARAMS(char_id)
298        , char_prop);
299    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
300}
301
302void btgattc_get_descriptor_cb(int conn_id, int status,
303                btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
304                btgatt_gatt_id_t *descr_id)
305{
306    CHECK_CALLBACK_ENV
307    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onGetDescriptor
308        , conn_id, status, SRVC_ID_PARAMS(srvc_id), GATT_ID_PARAMS(char_id)
309        , GATT_ID_PARAMS(descr_id));
310    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
311}
312
313void btgattc_get_included_service_cb(int conn_id, int status,
314                btgatt_srvc_id_t *srvc_id, btgatt_srvc_id_t *incl_srvc_id)
315{
316    CHECK_CALLBACK_ENV
317    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onGetIncludedService
318        , conn_id, status, SRVC_ID_PARAMS(srvc_id), SRVC_ID_PARAMS(incl_srvc_id));
319    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
320}
321
322void btgattc_register_for_notification_cb(int conn_id, int registered, int status,
323                                          btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id)
324{
325    CHECK_CALLBACK_ENV
326    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onRegisterForNotifications
327        , conn_id, status, registered, SRVC_ID_PARAMS(srvc_id), GATT_ID_PARAMS(char_id));
328    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
329}
330
331void btgattc_notify_cb(int conn_id, btgatt_notify_params_t *p_data)
332{
333    CHECK_CALLBACK_ENV
334
335    char c_address[32];
336    snprintf(c_address, sizeof(c_address), "%02X:%02X:%02X:%02X:%02X:%02X",
337        p_data->bda.address[0], p_data->bda.address[1], p_data->bda.address[2],
338        p_data->bda.address[3], p_data->bda.address[4], p_data->bda.address[5]);
339
340    jstring address = sCallbackEnv->NewStringUTF(c_address);
341    jbyteArray jb = sCallbackEnv->NewByteArray(p_data->len);
342    sCallbackEnv->SetByteArrayRegion(jb, 0, p_data->len, (jbyte *) p_data->value);
343
344    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNotify
345        , conn_id, address, SRVC_ID_PARAMS((&p_data->srvc_id))
346        , GATT_ID_PARAMS((&p_data->char_id)), p_data->is_notify, jb);
347
348    sCallbackEnv->DeleteLocalRef(address);
349    sCallbackEnv->DeleteLocalRef(jb);
350    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
351}
352
353void btgattc_read_characteristic_cb(int conn_id, int status, btgatt_read_params_t *p_data)
354{
355    CHECK_CALLBACK_ENV
356
357    jbyteArray jb;
358    if ( status == 0 )      //successful
359    {
360        jb = sCallbackEnv->NewByteArray(p_data->value.len);
361        sCallbackEnv->SetByteArrayRegion(jb, 0, p_data->value.len,
362            (jbyte *) p_data->value.value);
363    } else {
364        uint8_t value = 0;
365        jb = sCallbackEnv->NewByteArray(1);
366        sCallbackEnv->SetByteArrayRegion(jb, 0, 1, (jbyte *) &value);
367    }
368
369    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onReadCharacteristic
370        , conn_id, status, SRVC_ID_PARAMS((&p_data->srvc_id))
371        , GATT_ID_PARAMS((&p_data->char_id)), p_data->value_type, jb);
372    sCallbackEnv->DeleteLocalRef(jb);
373    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
374}
375
376void btgattc_write_characteristic_cb(int conn_id, int status, btgatt_write_params_t *p_data)
377{
378    CHECK_CALLBACK_ENV
379    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onWriteCharacteristic
380        , conn_id, status, SRVC_ID_PARAMS((&p_data->srvc_id))
381        , GATT_ID_PARAMS((&p_data->char_id)));
382    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
383}
384
385void btgattc_execute_write_cb(int conn_id, int status)
386{
387    CHECK_CALLBACK_ENV
388    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onExecuteCompleted
389        , conn_id, status);
390    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
391}
392
393void btgattc_read_descriptor_cb(int conn_id, int status, btgatt_read_params_t *p_data)
394{
395    CHECK_CALLBACK_ENV
396
397    jbyteArray jb;
398    if ( p_data->value.len != 0 )
399    {
400        jb = sCallbackEnv->NewByteArray(p_data->value.len);
401        sCallbackEnv->SetByteArrayRegion(jb, 0, p_data->value.len,
402                                (jbyte *) p_data->value.value);
403    } else {
404        jb = sCallbackEnv->NewByteArray(1);
405    }
406
407    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onReadDescriptor
408        , conn_id, status, SRVC_ID_PARAMS((&p_data->srvc_id))
409        , GATT_ID_PARAMS((&p_data->char_id)), GATT_ID_PARAMS((&p_data->descr_id))
410        , p_data->value_type, jb);
411
412    sCallbackEnv->DeleteLocalRef(jb);
413    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
414}
415
416void btgattc_write_descriptor_cb(int conn_id, int status, btgatt_write_params_t *p_data)
417{
418    CHECK_CALLBACK_ENV
419    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onWriteDescriptor
420        , conn_id, status, SRVC_ID_PARAMS((&p_data->srvc_id))
421        , GATT_ID_PARAMS((&p_data->char_id))
422        , GATT_ID_PARAMS((&p_data->descr_id)));
423    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
424}
425
426void btgattc_remote_rssi_cb(int client_if,bt_bdaddr_t* bda, int rssi, int status)
427{
428    CHECK_CALLBACK_ENV
429
430    char c_address[32];
431    snprintf(c_address, sizeof(c_address),"%02X:%02X:%02X:%02X:%02X:%02X",
432        bda->address[0], bda->address[1], bda->address[2],
433        bda->address[3], bda->address[4], bda->address[5]);
434    jstring address = sCallbackEnv->NewStringUTF(c_address);
435    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onReadRemoteRssi,
436       client_if, address, rssi, status);
437    sCallbackEnv->DeleteLocalRef(address);
438    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
439}
440
441void btgattc_advertise_cb(int status, int client_if)
442{
443    CHECK_CALLBACK_ENV
444    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAdvertiseCallback, status, client_if);
445    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
446}
447
448void btgattc_configure_mtu_cb(int conn_id, int status, int mtu)
449{
450    CHECK_CALLBACK_ENV
451    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConfigureMTU,
452                                 conn_id, status, mtu);
453    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
454}
455
456void btgattc_scan_filter_cfg_cb(int action, int client_if, int status, int filt_type,
457                                int avbl_space)
458{
459    CHECK_CALLBACK_ENV
460    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScanFilterConfig,
461                                 action, status, client_if, filt_type, avbl_space);
462    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
463}
464
465void btgattc_scan_filter_param_cb(int action, int client_if, int status, int avbl_space)
466{
467    CHECK_CALLBACK_ENV
468    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScanFilterParamsConfigured,
469            action, status, client_if, avbl_space);
470    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
471}
472
473void btgattc_scan_filter_status_cb(int action, int client_if, int status)
474{
475    CHECK_CALLBACK_ENV
476    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScanFilterEnableDisabled,
477            action, status, client_if);
478    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
479}
480
481void btgattc_multiadv_enable_cb(int client_if, int status)
482{
483    CHECK_CALLBACK_ENV
484    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onMultiAdvEnable, status,client_if);
485    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
486}
487
488void btgattc_multiadv_update_cb(int client_if, int status)
489{
490    CHECK_CALLBACK_ENV
491    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onMultiAdvUpdate, status, client_if);
492    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
493}
494
495void btgattc_multiadv_setadv_data_cb(int client_if, int status)
496{
497    CHECK_CALLBACK_ENV
498    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onMultiAdvSetAdvData, status, client_if);
499    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
500}
501
502void btgattc_multiadv_disable_cb(int client_if, int status)
503{
504    CHECK_CALLBACK_ENV
505    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onMultiAdvDisable, status, client_if);
506    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
507}
508
509void btgattc_congestion_cb(int conn_id, bool congested)
510{
511    CHECK_CALLBACK_ENV
512    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientCongestion, conn_id, congested);
513    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
514}
515
516void btgattc_batchscan_cfg_storage_cb(int client_if, int status)
517{
518    CHECK_CALLBACK_ENV
519    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onBatchScanStorageConfigured, status, client_if);
520    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
521}
522
523void btgattc_batchscan_startstop_cb(int startstop_action, int client_if, int status)
524{
525    CHECK_CALLBACK_ENV
526    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onBatchScanStartStopped, startstop_action,
527                                 status, client_if);
528    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
529}
530
531void btgattc_batchscan_reports_cb(int client_if, int status, int report_format,
532                        int num_records, int data_len, uint8_t *p_rep_data)
533{
534    CHECK_CALLBACK_ENV
535    jbyteArray jb = sCallbackEnv->NewByteArray(data_len);
536    sCallbackEnv->SetByteArrayRegion(jb, 0, data_len, (jbyte *) p_rep_data);
537
538    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onBatchScanReports, status, client_if,
539                                report_format, num_records, jb);
540    sCallbackEnv->DeleteLocalRef(jb);
541    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
542}
543
544void btgattc_batchscan_threshold_cb(int client_if)
545{
546    CHECK_CALLBACK_ENV
547    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onBatchScanThresholdCrossed, client_if);
548    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
549}
550
551void btgattc_track_adv_event_cb(int client_if, int filt_index, int addr_type,
552                                        bt_bdaddr_t* bda, int adv_state)
553{
554    CHECK_CALLBACK_ENV
555    char c_address[32];
556    snprintf(c_address, sizeof(c_address),"%02X:%02X:%02X:%02X:%02X:%02X",
557        bda->address[0], bda->address[1], bda->address[2],
558        bda->address[3], bda->address[4], bda->address[5]);
559    jstring address = sCallbackEnv->NewStringUTF(c_address);
560    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onTrackAdvFoundLost,
561                                    filt_index, addr_type, address, adv_state, client_if);
562    sCallbackEnv->DeleteLocalRef(address);
563    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
564}
565
566static const btgatt_client_callbacks_t sGattClientCallbacks = {
567    btgattc_register_app_cb,
568    btgattc_scan_result_cb,
569    btgattc_open_cb,
570    btgattc_close_cb,
571    btgattc_search_complete_cb,
572    btgattc_search_result_cb,
573    btgattc_get_characteristic_cb,
574    btgattc_get_descriptor_cb,
575    btgattc_get_included_service_cb,
576    btgattc_register_for_notification_cb,
577    btgattc_notify_cb,
578    btgattc_read_characteristic_cb,
579    btgattc_write_characteristic_cb,
580    btgattc_read_descriptor_cb,
581    btgattc_write_descriptor_cb,
582    btgattc_execute_write_cb,
583    btgattc_remote_rssi_cb,
584    btgattc_advertise_cb,
585    btgattc_configure_mtu_cb,
586    btgattc_scan_filter_cfg_cb,
587    btgattc_scan_filter_param_cb,
588    btgattc_scan_filter_status_cb,
589    btgattc_multiadv_enable_cb,
590    btgattc_multiadv_update_cb,
591    btgattc_multiadv_setadv_data_cb,
592    btgattc_multiadv_disable_cb,
593    btgattc_congestion_cb,
594    btgattc_batchscan_cfg_storage_cb,
595    btgattc_batchscan_startstop_cb,
596    btgattc_batchscan_reports_cb,
597    btgattc_batchscan_threshold_cb,
598    btgattc_track_adv_event_cb
599};
600
601
602/**
603 * BTA server callbacks
604 */
605
606void btgatts_register_app_cb(int status, int server_if, bt_uuid_t *uuid)
607{
608    CHECK_CALLBACK_ENV
609    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerRegistered
610        , status, server_if, UUID_PARAMS(uuid));
611    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
612}
613
614void btgatts_connection_cb(int conn_id, int server_if, int connected, bt_bdaddr_t *bda)
615{
616    CHECK_CALLBACK_ENV
617
618    char c_address[32];
619    sprintf(c_address, "%02X:%02X:%02X:%02X:%02X:%02X",
620            bda->address[0], bda->address[1], bda->address[2],
621            bda->address[3], bda->address[4], bda->address[5]);
622
623    jstring address = sCallbackEnv->NewStringUTF(c_address);
624    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientConnected,
625                                 address, connected, conn_id, server_if);
626    sCallbackEnv->DeleteLocalRef(address);
627    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
628}
629
630void btgatts_service_added_cb(int status, int server_if,
631                              btgatt_srvc_id_t *srvc_id, int srvc_handle)
632{
633    CHECK_CALLBACK_ENV
634    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceAdded, status,
635                                 server_if, SRVC_ID_PARAMS(srvc_id),
636                                 srvc_handle);
637    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
638}
639
640void btgatts_included_service_added_cb(int status, int server_if,
641                                   int srvc_handle,
642                                   int incl_srvc_handle)
643{
644    CHECK_CALLBACK_ENV
645    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onIncludedServiceAdded,
646                                 status, server_if, srvc_handle, incl_srvc_handle);
647    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
648}
649
650void btgatts_characteristic_added_cb(int status, int server_if, bt_uuid_t *char_id,
651                                     int srvc_handle, int char_handle)
652{
653    CHECK_CALLBACK_ENV
654    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onCharacteristicAdded,
655                                 status, server_if, UUID_PARAMS(char_id),
656                                 srvc_handle, char_handle);
657    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
658}
659
660void btgatts_descriptor_added_cb(int status, int server_if,
661                                 bt_uuid_t *descr_id, int srvc_handle,
662                                 int descr_handle)
663{
664    CHECK_CALLBACK_ENV
665    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onDescriptorAdded,
666                                 status, server_if, UUID_PARAMS(descr_id),
667                                 srvc_handle, descr_handle);
668    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
669}
670
671void btgatts_service_started_cb(int status, int server_if, int srvc_handle)
672{
673    CHECK_CALLBACK_ENV
674    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceStarted, status,
675                                 server_if, srvc_handle);
676    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
677}
678
679void btgatts_service_stopped_cb(int status, int server_if, int srvc_handle)
680{
681    CHECK_CALLBACK_ENV
682    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceStopped, status,
683                                 server_if, srvc_handle);
684    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
685}
686
687void btgatts_service_deleted_cb(int status, int server_if, int srvc_handle)
688{
689    CHECK_CALLBACK_ENV
690    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceDeleted, status,
691                                 server_if, srvc_handle);
692    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
693}
694
695void btgatts_request_read_cb(int conn_id, int trans_id, bt_bdaddr_t *bda,
696                             int attr_handle, int offset, bool is_long)
697{
698    CHECK_CALLBACK_ENV
699
700    char c_address[32];
701    sprintf(c_address, "%02X:%02X:%02X:%02X:%02X:%02X",
702            bda->address[0], bda->address[1], bda->address[2],
703            bda->address[3], bda->address[4], bda->address[5]);
704
705    jstring address = sCallbackEnv->NewStringUTF(c_address);
706    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAttributeRead,
707                                 address, conn_id, trans_id, attr_handle,
708                                 offset, is_long);
709    sCallbackEnv->DeleteLocalRef(address);
710    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
711}
712
713void btgatts_request_write_cb(int conn_id, int trans_id,
714                              bt_bdaddr_t *bda, int attr_handle,
715                              int offset, int length,
716                              bool need_rsp, bool is_prep, uint8_t* value)
717{
718    CHECK_CALLBACK_ENV
719
720    char c_address[32];
721    sprintf(c_address, "%02X:%02X:%02X:%02X:%02X:%02X",
722            bda->address[0], bda->address[1], bda->address[2],
723            bda->address[3], bda->address[4], bda->address[5]);
724
725    jstring address = sCallbackEnv->NewStringUTF(c_address);
726
727    jbyteArray val = sCallbackEnv->NewByteArray(length);
728    if (val) sCallbackEnv->SetByteArrayRegion(val, 0, length, (jbyte*)value);
729    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAttributeWrite,
730                                 address, conn_id, trans_id, attr_handle,
731                                 offset, length, need_rsp, is_prep, val);
732    sCallbackEnv->DeleteLocalRef(address);
733    sCallbackEnv->DeleteLocalRef(val);
734    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
735}
736
737void btgatts_request_exec_write_cb(int conn_id, int trans_id,
738                                   bt_bdaddr_t *bda, int exec_write)
739{
740    CHECK_CALLBACK_ENV
741
742    char c_address[32];
743    sprintf(c_address, "%02X:%02X:%02X:%02X:%02X:%02X",
744            bda->address[0], bda->address[1], bda->address[2],
745            bda->address[3], bda->address[4], bda->address[5]);
746
747    jstring address = sCallbackEnv->NewStringUTF(c_address);
748    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onExecuteWrite,
749                                 address, conn_id, trans_id, exec_write);
750    sCallbackEnv->DeleteLocalRef(address);
751    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
752}
753
754void btgatts_response_confirmation_cb(int status, int handle)
755{
756    CHECK_CALLBACK_ENV
757    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onResponseSendCompleted,
758                                 status, handle);
759    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
760}
761
762void btgatts_indication_sent_cb(int conn_id, int status)
763{
764    CHECK_CALLBACK_ENV
765    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNotificationSent,
766                                 conn_id, status);
767    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
768}
769
770void btgatts_congestion_cb(int conn_id, bool congested)
771{
772    CHECK_CALLBACK_ENV
773    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerCongestion, conn_id, congested);
774    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
775}
776
777static const btgatt_server_callbacks_t sGattServerCallbacks = {
778    btgatts_register_app_cb,
779    btgatts_connection_cb,
780    btgatts_service_added_cb,
781    btgatts_included_service_added_cb,
782    btgatts_characteristic_added_cb,
783    btgatts_descriptor_added_cb,
784    btgatts_service_started_cb,
785    btgatts_service_stopped_cb,
786    btgatts_service_deleted_cb,
787    btgatts_request_read_cb,
788    btgatts_request_write_cb,
789    btgatts_request_exec_write_cb,
790    btgatts_response_confirmation_cb,
791    btgatts_indication_sent_cb,
792    btgatts_congestion_cb
793};
794
795/**
796 * GATT callbacks
797 */
798
799static const btgatt_callbacks_t sGattCallbacks = {
800    sizeof(btgatt_callbacks_t),
801    &sGattClientCallbacks,
802    &sGattServerCallbacks
803};
804
805/**
806 * Native function definitions
807 */
808static void classInitNative(JNIEnv* env, jclass clazz) {
809
810    // Client callbacks
811
812    method_onClientRegistered = env->GetMethodID(clazz, "onClientRegistered", "(IIJJ)V");
813    method_onScanResult = env->GetMethodID(clazz, "onScanResult", "(Ljava/lang/String;I[B)V");
814    method_onConnected   = env->GetMethodID(clazz, "onConnected", "(IIILjava/lang/String;)V");
815    method_onDisconnected = env->GetMethodID(clazz, "onDisconnected", "(IIILjava/lang/String;)V");
816    method_onReadCharacteristic = env->GetMethodID(clazz, "onReadCharacteristic", "(IIIIJJIJJI[B)V");
817    method_onWriteCharacteristic = env->GetMethodID(clazz, "onWriteCharacteristic", "(IIIIJJIJJ)V");
818    method_onExecuteCompleted = env->GetMethodID(clazz, "onExecuteCompleted",  "(II)V");
819    method_onSearchCompleted = env->GetMethodID(clazz, "onSearchCompleted",  "(II)V");
820    method_onSearchResult = env->GetMethodID(clazz, "onSearchResult", "(IIIJJ)V");
821    method_onReadDescriptor = env->GetMethodID(clazz, "onReadDescriptor", "(IIIIJJIJJIJJI[B)V");
822    method_onWriteDescriptor = env->GetMethodID(clazz, "onWriteDescriptor", "(IIIIJJIJJIJJ)V");
823    method_onNotify = env->GetMethodID(clazz, "onNotify", "(ILjava/lang/String;IIJJIJJZ[B)V");
824    method_onGetCharacteristic = env->GetMethodID(clazz, "onGetCharacteristic", "(IIIIJJIJJI)V");
825    method_onGetDescriptor = env->GetMethodID(clazz, "onGetDescriptor", "(IIIIJJIJJIJJ)V");
826    method_onGetIncludedService = env->GetMethodID(clazz, "onGetIncludedService", "(IIIIJJIIJJ)V");
827    method_onRegisterForNotifications = env->GetMethodID(clazz, "onRegisterForNotifications", "(IIIIIJJIJJ)V");
828    method_onReadRemoteRssi = env->GetMethodID(clazz, "onReadRemoteRssi", "(ILjava/lang/String;II)V");
829    method_onConfigureMTU = env->GetMethodID(clazz, "onConfigureMTU", "(III)V");
830    method_onAdvertiseCallback = env->GetMethodID(clazz, "onAdvertiseCallback", "(II)V");
831    method_onScanFilterConfig = env->GetMethodID(clazz, "onScanFilterConfig", "(IIIII)V");
832    method_onScanFilterParamsConfigured = env->GetMethodID(clazz, "onScanFilterParamsConfigured", "(IIII)V");
833    method_onScanFilterEnableDisabled = env->GetMethodID(clazz, "onScanFilterEnableDisabled", "(III)V");
834    method_onMultiAdvEnable = env->GetMethodID(clazz, "onAdvertiseInstanceEnabled", "(II)V");
835    method_onMultiAdvUpdate = env->GetMethodID(clazz, "onAdvertiseDataUpdated", "(II)V");
836    method_onMultiAdvSetAdvData = env->GetMethodID(clazz, "onAdvertiseDataSet", "(II)V");
837    method_onMultiAdvDisable = env->GetMethodID(clazz, "onAdvertiseInstanceDisabled", "(II)V");
838    method_onClientCongestion = env->GetMethodID(clazz, "onClientCongestion", "(IZ)V");
839    method_onBatchScanStorageConfigured = env->GetMethodID(clazz, "onBatchScanStorageConfigured", "(II)V");
840    method_onBatchScanStartStopped = env->GetMethodID(clazz, "onBatchScanStartStopped", "(III)V");
841    method_onBatchScanReports = env->GetMethodID(clazz, "onBatchScanReports", "(IIII[B)V");
842    method_onBatchScanThresholdCrossed = env->GetMethodID(clazz, "onBatchScanThresholdCrossed", "(I)V");
843    method_onTrackAdvFoundLost = env->GetMethodID(clazz, "onTrackAdvFoundLost", "(IILjava/lang/String;II)V");
844
845     // Server callbacks
846
847    method_onServerRegistered = env->GetMethodID(clazz, "onServerRegistered", "(IIJJ)V");
848    method_onClientConnected = env->GetMethodID(clazz, "onClientConnected", "(Ljava/lang/String;ZII)V");
849    method_onServiceAdded = env->GetMethodID(clazz, "onServiceAdded", "(IIIIJJI)V");
850    method_onIncludedServiceAdded = env->GetMethodID(clazz, "onIncludedServiceAdded", "(IIII)V");
851    method_onCharacteristicAdded  = env->GetMethodID(clazz, "onCharacteristicAdded", "(IIJJII)V");
852    method_onDescriptorAdded = env->GetMethodID(clazz, "onDescriptorAdded", "(IIJJII)V");
853    method_onServiceStarted = env->GetMethodID(clazz, "onServiceStarted", "(III)V");
854    method_onServiceStopped = env->GetMethodID(clazz, "onServiceStopped", "(III)V");
855    method_onServiceDeleted = env->GetMethodID(clazz, "onServiceDeleted", "(III)V");
856    method_onResponseSendCompleted = env->GetMethodID(clazz, "onResponseSendCompleted", "(II)V");
857    method_onAttributeRead= env->GetMethodID(clazz, "onAttributeRead", "(Ljava/lang/String;IIIIZ)V");
858    method_onAttributeWrite= env->GetMethodID(clazz, "onAttributeWrite", "(Ljava/lang/String;IIIIIZZ[B)V");
859    method_onExecuteWrite= env->GetMethodID(clazz, "onExecuteWrite", "(Ljava/lang/String;III)V");
860    method_onNotificationSent = env->GetMethodID(clazz, "onNotificationSent", "(II)V");
861    method_onServerCongestion = env->GetMethodID(clazz, "onServerCongestion", "(IZ)V");
862
863    info("classInitNative: Success!");
864}
865
866static const bt_interface_t* btIf;
867
868static void initializeNative(JNIEnv *env, jobject object) {
869    if(btIf)
870        return;
871
872    if ( (btIf = getBluetoothInterface()) == NULL) {
873        error("Bluetooth module is not loaded");
874        return;
875    }
876
877    if (sGattIf != NULL) {
878         ALOGW("Cleaning up Bluetooth GATT Interface before initializing...");
879         sGattIf->cleanup();
880         sGattIf = NULL;
881    }
882
883    if (mCallbacksObj != NULL) {
884         ALOGW("Cleaning up Bluetooth GATT callback object");
885         env->DeleteGlobalRef(mCallbacksObj);
886         mCallbacksObj = NULL;
887    }
888
889    if ( (sGattIf = (btgatt_interface_t *)
890          btIf->get_profile_interface(BT_PROFILE_GATT_ID)) == NULL) {
891        error("Failed to get Bluetooth GATT Interface");
892        return;
893    }
894
895    bt_status_t status;
896    if ( (status = sGattIf->init(&sGattCallbacks)) != BT_STATUS_SUCCESS) {
897        error("Failed to initialize Bluetooth GATT, status: %d", status);
898        sGattIf = NULL;
899        return;
900    }
901
902    mCallbacksObj = env->NewGlobalRef(object);
903}
904
905static void cleanupNative(JNIEnv *env, jobject object) {
906    bt_status_t status;
907    if (!btIf) return;
908
909    if (sGattIf != NULL) {
910        sGattIf->cleanup();
911        sGattIf = NULL;
912    }
913
914    if (mCallbacksObj != NULL) {
915        env->DeleteGlobalRef(mCallbacksObj);
916        mCallbacksObj = NULL;
917    }
918    btIf = NULL;
919}
920
921/**
922 * Native Client functions
923 */
924
925static int gattClientGetDeviceTypeNative(JNIEnv* env, jobject object, jstring address)
926{
927    if (!sGattIf) return 0;
928    bt_bdaddr_t bda;
929    jstr2bdaddr(env, &bda, address);
930    return sGattIf->client->get_device_type(&bda);
931}
932
933static void gattClientRegisterAppNative(JNIEnv* env, jobject object,
934                                        jlong app_uuid_lsb, jlong app_uuid_msb )
935{
936    bt_uuid_t uuid;
937
938    if (!sGattIf) return;
939    set_uuid(uuid.uu, app_uuid_msb, app_uuid_lsb);
940    sGattIf->client->register_client(&uuid);
941}
942
943static void gattClientUnregisterAppNative(JNIEnv* env, jobject object, jint clientIf)
944{
945    if (!sGattIf) return;
946    sGattIf->client->unregister_client(clientIf);
947}
948
949static void gattClientScanNative(JNIEnv* env, jobject object, jboolean start)
950{
951    if (!sGattIf) return;
952    sGattIf->client->scan(start);
953}
954
955static void gattClientConnectNative(JNIEnv* env, jobject object, jint clientif,
956                                 jstring address, jboolean isDirect, jint transport)
957{
958    if (!sGattIf) return;
959
960    bt_bdaddr_t bda;
961    jstr2bdaddr(env, &bda, address);
962    sGattIf->client->connect(clientif, &bda, isDirect, transport);
963}
964
965static void gattClientDisconnectNative(JNIEnv* env, jobject object, jint clientIf,
966                                  jstring address, jint conn_id)
967{
968    if (!sGattIf) return;
969    bt_bdaddr_t bda;
970    jstr2bdaddr(env, &bda, address);
971    sGattIf->client->disconnect(clientIf, &bda, conn_id);
972}
973
974static void gattClientRefreshNative(JNIEnv* env, jobject object, jint clientIf,
975                                    jstring address)
976{
977    if (!sGattIf) return;
978
979    bt_bdaddr_t bda;
980    jstr2bdaddr(env, &bda, address);
981    sGattIf->client->refresh(clientIf, &bda);
982}
983
984static void gattClientSearchServiceNative(JNIEnv* env, jobject object, jint conn_id,
985            jboolean search_all, jlong service_uuid_lsb, jlong service_uuid_msb)
986{
987    if (!sGattIf) return;
988
989    bt_uuid_t uuid;
990    set_uuid(uuid.uu, service_uuid_msb, service_uuid_lsb);
991    sGattIf->client->search_service(conn_id, search_all ? 0 : &uuid);
992}
993
994static void gattClientGetCharacteristicNative(JNIEnv* env, jobject object,
995    jint conn_id,
996    jint  service_type, jint  service_id_inst_id,
997    jlong service_id_uuid_lsb, jlong service_id_uuid_msb,
998    jint  char_id_inst_id,
999    jlong char_id_uuid_lsb, jlong char_id_uuid_msb)
1000{
1001    if (!sGattIf) return;
1002
1003    btgatt_srvc_id_t srvc_id;
1004    srvc_id.id.inst_id = (uint8_t) service_id_inst_id;
1005    srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
1006
1007    set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);
1008
1009    btgatt_gatt_id_t char_id;
1010    char_id.inst_id = (uint8_t) char_id_inst_id;
1011    set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb);
1012
1013    if (char_id_uuid_lsb == 0)
1014    {
1015        sGattIf->client->get_characteristic(conn_id, &srvc_id, 0);
1016    } else {
1017        sGattIf->client->get_characteristic(conn_id, &srvc_id, &char_id);
1018    }
1019}
1020
1021static void gattClientGetDescriptorNative(JNIEnv* env, jobject object,
1022    jint conn_id,
1023    jint  service_type, jint  service_id_inst_id,
1024    jlong service_id_uuid_lsb, jlong service_id_uuid_msb,
1025    jint  char_id_inst_id,
1026    jlong char_id_uuid_lsb, jlong char_id_uuid_msb,
1027    jint descr_id_inst_id,
1028    jlong descr_id_uuid_lsb, jlong descr_id_uuid_msb)
1029{
1030    if (!sGattIf) return;
1031
1032    btgatt_srvc_id_t srvc_id;
1033    srvc_id.id.inst_id = (uint8_t) service_id_inst_id;
1034    srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
1035    set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);
1036
1037    btgatt_gatt_id_t char_id;
1038    char_id.inst_id = (uint8_t) char_id_inst_id;
1039    set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb);
1040
1041    btgatt_gatt_id_t descr_id;
1042    descr_id.inst_id = (uint8_t) descr_id_inst_id;
1043    set_uuid(descr_id.uuid.uu, descr_id_uuid_msb, descr_id_uuid_lsb);
1044
1045    if (descr_id_uuid_lsb == 0)
1046    {
1047        sGattIf->client->get_descriptor(conn_id, &srvc_id, &char_id, 0);
1048    } else {
1049        sGattIf->client->get_descriptor(conn_id, &srvc_id, &char_id, &descr_id);
1050    }
1051}
1052
1053static void gattClientGetIncludedServiceNative(JNIEnv* env, jobject object,
1054    jint conn_id, jint service_type, jint service_id_inst_id,
1055    jlong service_id_uuid_lsb, jlong service_id_uuid_msb,
1056    jint incl_service_id_inst_id, jint incl_service_type,
1057    jlong incl_service_id_uuid_lsb, jlong incl_service_id_uuid_msb)
1058{
1059    if (!sGattIf) return;
1060
1061    btgatt_srvc_id_t srvc_id;
1062    srvc_id.id.inst_id = (uint8_t) service_id_inst_id;
1063    srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
1064    set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);
1065
1066    btgatt_srvc_id_t  incl_srvc_id;
1067    incl_srvc_id.id.inst_id = (uint8_t) incl_service_id_inst_id;
1068    incl_srvc_id.is_primary = (incl_service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
1069    set_uuid(incl_srvc_id.id.uuid.uu, incl_service_id_uuid_msb, incl_service_id_uuid_lsb);
1070
1071    if (incl_service_id_uuid_lsb == 0)
1072    {
1073        sGattIf->client->get_included_service(conn_id, &srvc_id, 0);
1074    } else {
1075        sGattIf->client->get_included_service(conn_id, &srvc_id, &incl_srvc_id);
1076    }
1077}
1078
1079static void gattClientReadCharacteristicNative(JNIEnv* env, jobject object,
1080    jint conn_id, jint  service_type, jint  service_id_inst_id,
1081    jlong service_id_uuid_lsb, jlong service_id_uuid_msb,
1082    jint  char_id_inst_id,
1083    jlong char_id_uuid_lsb, jlong char_id_uuid_msb,
1084    jint authReq)
1085{
1086    if (!sGattIf) return;
1087
1088    btgatt_srvc_id_t srvc_id;
1089    srvc_id.id.inst_id = (uint8_t) service_id_inst_id;
1090    srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
1091    set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);
1092
1093    btgatt_gatt_id_t char_id;
1094    char_id.inst_id = (uint8_t) char_id_inst_id;
1095    set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb);
1096
1097    sGattIf->client->read_characteristic(conn_id, &srvc_id, &char_id, authReq);
1098}
1099
1100static void gattClientReadDescriptorNative(JNIEnv* env, jobject object,
1101    jint conn_id, jint  service_type, jint  service_id_inst_id,
1102    jlong service_id_uuid_lsb, jlong service_id_uuid_msb,
1103    jint  char_id_inst_id,
1104    jlong char_id_uuid_lsb, jlong char_id_uuid_msb,
1105    jint descr_id_inst_id,
1106    jlong descr_id_uuid_lsb, jlong descr_id_uuid_msb,
1107    jint authReq)
1108{
1109    if (!sGattIf) return;
1110
1111    btgatt_srvc_id_t srvc_id;
1112    srvc_id.id.inst_id = (uint8_t) service_id_inst_id;
1113    srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
1114    set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);
1115
1116    btgatt_gatt_id_t char_id;
1117    char_id.inst_id = (uint8_t) char_id_inst_id;
1118    set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb);
1119
1120    btgatt_gatt_id_t descr_id;
1121    descr_id.inst_id = (uint8_t) descr_id_inst_id;
1122    set_uuid(descr_id.uuid.uu, descr_id_uuid_msb, descr_id_uuid_lsb);
1123
1124    sGattIf->client->read_descriptor(conn_id, &srvc_id, &char_id, &descr_id, authReq);
1125}
1126
1127static void gattClientWriteCharacteristicNative(JNIEnv* env, jobject object,
1128    jint conn_id, jint  service_type, jint  service_id_inst_id,
1129    jlong service_id_uuid_lsb, jlong service_id_uuid_msb,
1130    jint  char_id_inst_id,
1131    jlong char_id_uuid_lsb, jlong char_id_uuid_msb,
1132    jint write_type, jint auth_req, jbyteArray value)
1133{
1134    if (!sGattIf) return;
1135
1136    btgatt_srvc_id_t srvc_id;
1137    srvc_id.id.inst_id = (uint8_t) service_id_inst_id;
1138    srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
1139    set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);
1140
1141    btgatt_gatt_id_t char_id;
1142    char_id.inst_id = (uint8_t) char_id_inst_id;
1143    set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb);
1144
1145    uint16_t len = (uint16_t) env->GetArrayLength(value);
1146    jbyte *p_value = env->GetByteArrayElements(value, NULL);
1147    if (p_value == NULL) return;
1148
1149    sGattIf->client->write_characteristic(conn_id, &srvc_id, &char_id,
1150                                    write_type, len, auth_req, (char*)p_value);
1151    env->ReleaseByteArrayElements(value, p_value, 0);
1152}
1153
1154static void gattClientExecuteWriteNative(JNIEnv* env, jobject object,
1155    jint conn_id, jboolean execute)
1156{
1157    if (!sGattIf) return;
1158    sGattIf->client->execute_write(conn_id, execute ? 1 : 0);
1159}
1160
1161static void gattClientWriteDescriptorNative(JNIEnv* env, jobject object,
1162    jint conn_id, jint  service_type, jint service_id_inst_id,
1163    jlong service_id_uuid_lsb, jlong service_id_uuid_msb,
1164    jint char_id_inst_id,
1165    jlong char_id_uuid_lsb, jlong char_id_uuid_msb,
1166    jint descr_id_inst_id,
1167    jlong descr_id_uuid_lsb, jlong descr_id_uuid_msb,
1168    jint write_type, jint auth_req, jbyteArray value)
1169{
1170    if (!sGattIf) return;
1171
1172    if (value == NULL) {
1173        warn("gattClientWriteDescriptorNative() ignoring NULL array");
1174        return;
1175    }
1176
1177    btgatt_srvc_id_t srvc_id;
1178    srvc_id.id.inst_id = (uint8_t) service_id_inst_id;
1179    srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
1180    set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);
1181
1182    btgatt_gatt_id_t char_id;
1183    char_id.inst_id = (uint8_t) char_id_inst_id;
1184    set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb);
1185
1186    btgatt_gatt_id_t descr_id;
1187    descr_id.inst_id = (uint8_t) descr_id_inst_id;
1188    set_uuid(descr_id.uuid.uu, descr_id_uuid_msb, descr_id_uuid_lsb);
1189
1190    uint16_t len = (uint16_t) env->GetArrayLength(value);
1191    jbyte *p_value = env->GetByteArrayElements(value, NULL);
1192    if (p_value == NULL) return;
1193
1194    sGattIf->client->write_descriptor(conn_id, &srvc_id, &char_id, &descr_id,
1195                                    write_type, len, auth_req, (char*)p_value);
1196    env->ReleaseByteArrayElements(value, p_value, 0);
1197}
1198
1199static void gattClientRegisterForNotificationsNative(JNIEnv* env, jobject object,
1200    jint clientIf, jstring address,
1201    jint  service_type, jint service_id_inst_id,
1202    jlong service_id_uuid_lsb, jlong service_id_uuid_msb,
1203    jint char_id_inst_id,
1204    jlong char_id_uuid_lsb, jlong char_id_uuid_msb,
1205    jboolean enable)
1206{
1207    if (!sGattIf) return;
1208
1209    btgatt_srvc_id_t srvc_id;
1210    srvc_id.id.inst_id = (uint8_t) service_id_inst_id;
1211    srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
1212    set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);
1213
1214    btgatt_gatt_id_t char_id;
1215    char_id.inst_id = (uint8_t) char_id_inst_id;
1216    set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb);
1217
1218    bt_bdaddr_t bd_addr;
1219    const char *c_address = env->GetStringUTFChars(address, NULL);
1220    bd_addr_str_to_addr(c_address, bd_addr.address);
1221
1222    if (enable)
1223        sGattIf->client->register_for_notification(clientIf, &bd_addr, &srvc_id, &char_id);
1224    else
1225        sGattIf->client->deregister_for_notification(clientIf, &bd_addr, &srvc_id, &char_id);
1226}
1227
1228static void gattClientReadRemoteRssiNative(JNIEnv* env, jobject object, jint clientif,
1229                                 jstring address)
1230{
1231    if (!sGattIf) return;
1232
1233    bt_bdaddr_t bda;
1234    jstr2bdaddr(env, &bda, address);
1235
1236    sGattIf->client->read_remote_rssi(clientif, &bda);
1237}
1238
1239static void gattAdvertiseNative(JNIEnv *env, jobject object,
1240        jint client_if, jboolean start)
1241{
1242    if (!sGattIf) return;
1243    sGattIf->client->listen(client_if, start);
1244}
1245
1246static void gattSetAdvDataNative(JNIEnv *env, jobject object, jint client_if,
1247        jboolean setScanRsp, jboolean inclName, jboolean inclTxPower, jint minInterval,
1248        jint maxInterval, jint appearance, jbyteArray manufacturerData, jbyteArray serviceData,
1249        jbyteArray serviceUuid)
1250{
1251    if (!sGattIf) return;
1252    jbyte* arr_data = env->GetByteArrayElements(manufacturerData, NULL);
1253    uint16_t arr_len = (uint16_t) env->GetArrayLength(manufacturerData);
1254
1255    jbyte* service_data = env->GetByteArrayElements(serviceData, NULL);
1256    uint16_t service_data_len = (uint16_t) env->GetArrayLength(serviceData);
1257
1258    jbyte* service_uuid = env->GetByteArrayElements(serviceUuid, NULL);
1259    uint16_t service_uuid_len = (uint16_t) env->GetArrayLength(serviceUuid);
1260
1261    sGattIf->client->set_adv_data(client_if, setScanRsp, inclName, inclTxPower,
1262        minInterval, maxInterval, appearance, arr_len, (char*)arr_data,
1263        service_data_len, (char*)service_data, service_uuid_len,
1264        (char*)service_uuid);
1265
1266    env->ReleaseByteArrayElements(manufacturerData, arr_data, JNI_ABORT);
1267    env->ReleaseByteArrayElements(serviceData, service_data, JNI_ABORT);
1268    env->ReleaseByteArrayElements(serviceUuid, service_uuid, JNI_ABORT);
1269}
1270
1271static void gattSetScanParametersNative(JNIEnv* env, jobject object,
1272                                        jint scan_interval_unit, jint scan_window_unit)
1273{
1274    if (!sGattIf) return;
1275    sGattIf->client->set_scan_parameters(scan_interval_unit, scan_window_unit);
1276}
1277
1278static void gattClientScanFilterParamAddNative(JNIEnv* env, jobject object,
1279        jint client_if, jint filt_index,
1280        jint feat_seln, jint list_logic_type, jint filt_logic_type,
1281        jint rssi_high_thres, jint rssi_low_thres,
1282        jint dely_mode, jint found_timeout, jint lost_timeout, jint found_timeout_cnt)
1283{
1284    if (!sGattIf) return;
1285    const int add_scan_filter_params_action = 0;
1286    sGattIf->client->scan_filter_param_setup(client_if, add_scan_filter_params_action, filt_index,
1287            feat_seln, list_logic_type, filt_logic_type,
1288            rssi_high_thres, rssi_low_thres,
1289            dely_mode, found_timeout, lost_timeout, found_timeout_cnt);
1290}
1291
1292static void gattClientScanFilterParamDeleteNative(JNIEnv* env, jobject object,
1293        jint client_if, jint filt_index)
1294{
1295    if (!sGattIf) return;
1296    const int delete_scan_filter_params_action = 1;
1297    sGattIf->client->scan_filter_param_setup(client_if, delete_scan_filter_params_action,
1298            filt_index, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1299}
1300
1301static void gattClientScanFilterParamClearAllNative(JNIEnv* env, jobject object, jint client_if)
1302{
1303    if (!sGattIf) return;
1304    const int clear_scan_filter_params_action = 2;
1305    sGattIf->client->scan_filter_param_setup(client_if, clear_scan_filter_params_action,
1306            0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1307}
1308
1309static void gattClientScanFilterAddRemoveNative(JNIEnv* env, jobject object,
1310        jint client_if, jint action, jint filt_type, jint filt_index, jint company_id,
1311        jint company_id_mask, jlong uuid_lsb,  jlong uuid_msb, jlong uuid_mask_lsb,
1312        jlong uuid_mask_msb, jstring name, jstring address, jbyte addr_type,
1313        jbyteArray data, jbyteArray mask)
1314{
1315    switch(filt_type)
1316    {
1317        case 0: // BTM_BLE_PF_ADDR_FILTER
1318        {
1319            bt_bdaddr_t bda;
1320            jstr2bdaddr(env, &bda, address);
1321            sGattIf->client->scan_filter_add_remove(client_if, action, filt_type, filt_index, 0,
1322                                             0, NULL, NULL, &bda, addr_type,0, NULL,0, NULL);
1323            break;
1324        }
1325
1326        case 1: // BTM_BLE_PF_SRVC_DATA
1327        {
1328            jbyte* data_array = env->GetByteArrayElements(data, 0);
1329            int data_len = env->GetArrayLength(data);
1330            jbyte* mask_array = env->GetByteArrayElements(mask, NULL);
1331            uint16_t mask_len = (uint16_t) env->GetArrayLength(mask);
1332            sGattIf->client->scan_filter_add_remove(client_if, action, filt_type, filt_index,
1333               0, 0, NULL, NULL, NULL, 0, data_len, (char*)data_array, mask_len,(char*) mask_array);
1334            env->ReleaseByteArrayElements(data, data_array, JNI_ABORT);
1335            env->ReleaseByteArrayElements(mask, mask_array, JNI_ABORT);
1336            break;
1337        }
1338
1339        case 2: // BTM_BLE_PF_SRVC_UUID
1340        case 3: // BTM_BLE_PF_SRVC_SOL_UUID
1341        {
1342            bt_uuid_t uuid, uuid_mask;
1343            set_uuid(uuid.uu, uuid_msb, uuid_lsb);
1344            set_uuid(uuid_mask.uu, uuid_mask_msb, uuid_mask_lsb);
1345            if (uuid_mask_lsb != 0 && uuid_mask_msb != 0)
1346                sGattIf->client->scan_filter_add_remove(client_if, action, filt_type, filt_index,
1347                                 0, 0, &uuid, &uuid_mask, NULL,0,0, NULL,0, NULL);
1348            else
1349                sGattIf->client->scan_filter_add_remove(client_if, action, filt_type, filt_index,
1350                                 0, 0, &uuid, NULL, NULL, 0,0, NULL,0, NULL);
1351            break;
1352        }
1353
1354        case 4: // BTM_BLE_PF_LOCAL_NAME
1355        {
1356            const char* c_name = env->GetStringUTFChars(name, NULL);
1357            if (c_name != NULL && strlen(c_name) != 0)
1358            {
1359                sGattIf->client->scan_filter_add_remove(client_if, action, filt_type,
1360                                 filt_index, 0, 0, NULL, NULL, NULL, 0, strlen(c_name),
1361                                 (char*)c_name, 0, NULL);
1362                env->ReleaseStringUTFChars(name, c_name);
1363            }
1364            break;
1365        }
1366
1367        case 5: // BTM_BLE_PF_MANU_DATA
1368        case 6: // BTM_BLE_PF_SRVC_DATA_PATTERN
1369        {
1370            jbyte* data_array = env->GetByteArrayElements(data, 0);
1371            int data_len = env->GetArrayLength(data); // Array contains mask
1372            jbyte* mask_array = env->GetByteArrayElements(mask, NULL);
1373            uint16_t mask_len = (uint16_t) env->GetArrayLength(mask);
1374            sGattIf->client->scan_filter_add_remove(client_if, action, filt_type, filt_index,
1375                company_id, company_id_mask, NULL, NULL, NULL, 0, data_len, (char*)data_array,
1376                mask_len, (char*) mask_array);
1377            env->ReleaseByteArrayElements(data, data_array, JNI_ABORT);
1378            env->ReleaseByteArrayElements(mask, mask_array, JNI_ABORT);
1379            break;
1380        }
1381
1382        default:
1383            break;
1384    }
1385}
1386
1387static void gattClientScanFilterAddNative(JNIEnv* env, jobject object, jint client_if,
1388                jint filt_type, jint filt_index, jint company_id, jint company_id_mask,
1389                jlong uuid_lsb,  jlong uuid_msb, jlong uuid_mask_lsb, jlong uuid_mask_msb,
1390                jstring name, jstring address, jbyte addr_type, jbyteArray data, jbyteArray mask)
1391{
1392    if (!sGattIf) return;
1393    int action = 0;
1394    gattClientScanFilterAddRemoveNative(env, object, client_if, action, filt_type, filt_index,
1395                    company_id, company_id_mask, uuid_lsb, uuid_msb, uuid_mask_lsb, uuid_mask_msb,
1396                    name, address, addr_type, data, mask);
1397
1398}
1399
1400static void gattClientScanFilterDeleteNative(JNIEnv* env, jobject object, jint client_if,
1401                jint filt_type, jint filt_index, jint company_id, jint company_id_mask,
1402                jlong uuid_lsb,  jlong uuid_msb, jlong uuid_mask_lsb, jlong uuid_mask_msb,
1403                jstring name, jstring address, jbyte addr_type, jbyteArray data, jbyteArray mask)
1404{
1405    if (!sGattIf) return;
1406    int action = 1;
1407    gattClientScanFilterAddRemoveNative(env, object, client_if, action, filt_type, filt_index,
1408                    company_id, company_id_mask, uuid_lsb, uuid_msb, uuid_mask_lsb, uuid_mask_msb,
1409                    name, address, addr_type, data, mask);
1410}
1411
1412static void gattClientScanFilterClearNative(JNIEnv* env, jobject object, jint client_if,
1413                        jint filt_index)
1414{
1415    if (!sGattIf) return;
1416    sGattIf->client->scan_filter_clear(client_if, filt_index);
1417}
1418
1419static void gattClientScanFilterEnableNative (JNIEnv* env, jobject object, jint client_if,
1420                          jboolean enable)
1421{
1422    if (!sGattIf) return;
1423    sGattIf->client->scan_filter_enable(client_if, enable);
1424}
1425
1426static void gattClientConfigureMTUNative(JNIEnv *env, jobject object,
1427        jint conn_id, jint mtu)
1428{
1429    if (!sGattIf) return;
1430    sGattIf->client->configure_mtu(conn_id, mtu);
1431}
1432
1433static void gattConnectionParameterUpdateNative(JNIEnv *env, jobject object, jint client_if,
1434        jstring address, jint min_interval, jint max_interval, jint latency, jint timeout)
1435{
1436    if (!sGattIf) return;
1437    bt_bdaddr_t bda;
1438    jstr2bdaddr(env, &bda, address);
1439    sGattIf->client->conn_parameter_update(&bda, min_interval, max_interval, latency, timeout);
1440}
1441
1442static void gattClientEnableAdvNative(JNIEnv* env, jobject object, jint client_if,
1443       jint min_interval, jint max_interval, jint adv_type, jint chnl_map, jint tx_power)
1444{
1445    if (!sGattIf) return;
1446
1447    sGattIf->client->multi_adv_enable(client_if, min_interval, max_interval, adv_type, chnl_map,
1448        tx_power);
1449}
1450
1451static void gattClientUpdateAdvNative(JNIEnv* env, jobject object, jint client_if,
1452       jint min_interval, jint max_interval, jint adv_type, jint chnl_map, jint tx_power)
1453{
1454    if (!sGattIf) return;
1455
1456    sGattIf->client->multi_adv_update(client_if, min_interval, max_interval, adv_type, chnl_map,
1457        tx_power);
1458}
1459
1460static void gattClientSetAdvDataNative(JNIEnv* env, jobject object , jint client_if,
1461        jboolean set_scan_rsp, jboolean incl_name, jboolean incl_txpower, jint appearance,
1462        jbyteArray manufacturer_data,jbyteArray service_data, jbyteArray service_uuid)
1463{
1464    if (!sGattIf) return;
1465    jbyte* manu_data = env->GetByteArrayElements(manufacturer_data, NULL);
1466    uint16_t manu_len = (uint16_t) env->GetArrayLength(manufacturer_data);
1467
1468    jbyte* serv_data = env->GetByteArrayElements(service_data, NULL);
1469    uint16_t serv_data_len = (uint16_t) env->GetArrayLength(service_data);
1470
1471    jbyte* serv_uuid = env->GetByteArrayElements(service_uuid, NULL);
1472    uint16_t serv_uuid_len = (uint16_t) env->GetArrayLength(service_uuid);
1473
1474    sGattIf->client->multi_adv_set_inst_data(client_if, set_scan_rsp, incl_name,incl_txpower,
1475                                             appearance, manu_len, (char*)manu_data,
1476                                             serv_data_len, (char*)serv_data, serv_uuid_len,
1477                                             (char*)serv_uuid);
1478
1479    env->ReleaseByteArrayElements(manufacturer_data, manu_data, JNI_ABORT);
1480    env->ReleaseByteArrayElements(service_data, serv_data, JNI_ABORT);
1481    env->ReleaseByteArrayElements(service_uuid, serv_uuid, JNI_ABORT);
1482}
1483
1484static void gattClientDisableAdvNative(JNIEnv* env, jobject object, jint client_if)
1485{
1486    if (!sGattIf) return;
1487    sGattIf->client->multi_adv_disable(client_if);
1488}
1489
1490static void gattClientConfigBatchScanStorageNative(JNIEnv* env, jobject object, jint client_if,
1491            jint max_full_reports_percent, jint max_trunc_reports_percent,
1492            jint notify_threshold_level_percent)
1493{
1494    if (!sGattIf) return;
1495    sGattIf->client->batchscan_cfg_storage(client_if, max_full_reports_percent,
1496            max_trunc_reports_percent, notify_threshold_level_percent);
1497}
1498
1499static void gattClientStartBatchScanNative(JNIEnv* env, jobject object, jint client_if,
1500            jint scan_mode, jint scan_interval_unit, jint scan_window_unit, jint addr_type,
1501            jint discard_rule)
1502{
1503    if (!sGattIf) return;
1504    sGattIf->client->batchscan_enb_batch_scan(client_if, scan_mode, scan_interval_unit,
1505            scan_window_unit, addr_type, discard_rule);
1506}
1507
1508static void gattClientStopBatchScanNative(JNIEnv* env, jobject object, jint client_if)
1509{
1510    if (!sGattIf) return;
1511    sGattIf->client->batchscan_dis_batch_scan(client_if);
1512}
1513
1514static void gattClientReadScanReportsNative(JNIEnv* env, jobject object, jint client_if,
1515        jint scan_type)
1516{
1517    if (!sGattIf) return;
1518    sGattIf->client->batchscan_read_reports(client_if, scan_type);
1519}
1520
1521/**
1522 * Native server functions
1523 */
1524static void gattServerRegisterAppNative(JNIEnv* env, jobject object,
1525                                        jlong app_uuid_lsb, jlong app_uuid_msb )
1526{
1527    bt_uuid_t uuid;
1528    if (!sGattIf) return;
1529    set_uuid(uuid.uu, app_uuid_msb, app_uuid_lsb);
1530    sGattIf->server->register_server(&uuid);
1531}
1532
1533static void gattServerUnregisterAppNative(JNIEnv* env, jobject object, jint serverIf)
1534{
1535    if (!sGattIf) return;
1536    sGattIf->server->unregister_server(serverIf);
1537}
1538
1539static void gattServerConnectNative(JNIEnv *env, jobject object,
1540                                 jint server_if, jstring address, jboolean is_direct, jint transport)
1541{
1542    if (!sGattIf) return;
1543
1544    bt_bdaddr_t bd_addr;
1545    const char *c_address = env->GetStringUTFChars(address, NULL);
1546    bd_addr_str_to_addr(c_address, bd_addr.address);
1547
1548    sGattIf->server->connect(server_if, &bd_addr, is_direct, transport);
1549}
1550
1551static void gattServerDisconnectNative(JNIEnv* env, jobject object, jint serverIf,
1552                                  jstring address, jint conn_id)
1553{
1554    if (!sGattIf) return;
1555    bt_bdaddr_t bda;
1556    jstr2bdaddr(env, &bda, address);
1557    sGattIf->server->disconnect(serverIf, &bda, conn_id);
1558}
1559
1560static void gattServerAddServiceNative (JNIEnv *env, jobject object,
1561        jint server_if, jint service_type, jint service_id_inst_id,
1562        jlong service_id_uuid_lsb, jlong service_id_uuid_msb,
1563        jint num_handles)
1564{
1565    if (!sGattIf) return;
1566
1567    btgatt_srvc_id_t srvc_id;
1568    srvc_id.id.inst_id = (uint8_t) service_id_inst_id;
1569    srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
1570    set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);
1571
1572    sGattIf->server->add_service(server_if, &srvc_id, num_handles);
1573}
1574
1575static void gattServerAddIncludedServiceNative (JNIEnv *env, jobject object,
1576        jint server_if, jint svc_handle, jint included_svc_handle)
1577{
1578    if (!sGattIf) return;
1579    sGattIf->server->add_included_service(server_if, svc_handle,
1580                                          included_svc_handle);
1581}
1582
1583static void gattServerAddCharacteristicNative (JNIEnv *env, jobject object,
1584        jint server_if, jint svc_handle,
1585        jlong char_uuid_lsb, jlong char_uuid_msb,
1586        jint properties, jint permissions)
1587{
1588    if (!sGattIf) return;
1589
1590    bt_uuid_t uuid;
1591    set_uuid(uuid.uu, char_uuid_msb, char_uuid_lsb);
1592
1593    sGattIf->server->add_characteristic(server_if, svc_handle,
1594                                        &uuid, properties, permissions);
1595}
1596
1597static void gattServerAddDescriptorNative (JNIEnv *env, jobject object,
1598        jint server_if, jint svc_handle,
1599        jlong desc_uuid_lsb, jlong desc_uuid_msb,
1600        jint permissions)
1601{
1602    if (!sGattIf) return;
1603
1604    bt_uuid_t uuid;
1605    set_uuid(uuid.uu, desc_uuid_msb, desc_uuid_lsb);
1606
1607    sGattIf->server->add_descriptor(server_if, svc_handle, &uuid, permissions);
1608}
1609
1610static void gattServerStartServiceNative (JNIEnv *env, jobject object,
1611        jint server_if, jint svc_handle, jint transport )
1612{
1613    if (!sGattIf) return;
1614    sGattIf->server->start_service(server_if, svc_handle, transport);
1615}
1616
1617static void gattServerStopServiceNative (JNIEnv *env, jobject object,
1618                                         jint server_if, jint svc_handle)
1619{
1620    if (!sGattIf) return;
1621    sGattIf->server->stop_service(server_if, svc_handle);
1622}
1623
1624static void gattServerDeleteServiceNative (JNIEnv *env, jobject object,
1625                                           jint server_if, jint svc_handle)
1626{
1627    if (!sGattIf) return;
1628    sGattIf->server->delete_service(server_if, svc_handle);
1629}
1630
1631static void gattServerSendIndicationNative (JNIEnv *env, jobject object,
1632        jint server_if, jint attr_handle, jint conn_id, jbyteArray val)
1633{
1634    if (!sGattIf) return;
1635
1636    jbyte* array = env->GetByteArrayElements(val, 0);
1637    int val_len = env->GetArrayLength(val);
1638
1639    sGattIf->server->send_indication(server_if, attr_handle, conn_id, val_len,
1640                                     /*confirm*/ 1, (char*)array);
1641    env->ReleaseByteArrayElements(val, array, JNI_ABORT);
1642}
1643
1644static void gattServerSendNotificationNative (JNIEnv *env, jobject object,
1645        jint server_if, jint attr_handle, jint conn_id, jbyteArray val)
1646{
1647    if (!sGattIf) return;
1648
1649    jbyte* array = env->GetByteArrayElements(val, 0);
1650    int val_len = env->GetArrayLength(val);
1651
1652    sGattIf->server->send_indication(server_if, attr_handle, conn_id, val_len,
1653                                     /*confirm*/ 0, (char*)array);
1654    env->ReleaseByteArrayElements(val, array, JNI_ABORT);
1655}
1656
1657static void gattServerSendResponseNative (JNIEnv *env, jobject object,
1658        jint server_if, jint conn_id, jint trans_id, jint status,
1659        jint handle, jint offset, jbyteArray val, jint auth_req)
1660{
1661    if (!sGattIf) return;
1662
1663    btgatt_response_t response;
1664
1665    response.attr_value.handle = handle;
1666    response.attr_value.auth_req = auth_req;
1667    response.attr_value.offset = offset;
1668    response.attr_value.len = 0;
1669
1670    if (val != NULL)
1671    {
1672        response.attr_value.len = (uint16_t) env->GetArrayLength(val);
1673        jbyte* array = env->GetByteArrayElements(val, 0);
1674
1675        for (int i = 0; i != response.attr_value.len; ++i)
1676            response.attr_value.value[i] = (uint8_t) array[i];
1677        env->ReleaseByteArrayElements(val, array, JNI_ABORT);
1678    }
1679
1680    sGattIf->server->send_response(conn_id, trans_id, status, &response);
1681}
1682
1683static void gattTestNative(JNIEnv *env, jobject object, jint command,
1684                           jlong uuid1_lsb, jlong uuid1_msb, jstring bda1,
1685                           jint p1, jint p2, jint p3, jint p4, jint p5 )
1686{
1687    if (!sGattIf) return;
1688
1689    bt_bdaddr_t bt_bda1;
1690    jstr2bdaddr(env, &bt_bda1, bda1);
1691
1692    bt_uuid_t uuid1;
1693    set_uuid(uuid1.uu, uuid1_msb, uuid1_lsb);
1694
1695    btgatt_test_params_t params;
1696    params.bda1 = &bt_bda1;
1697    params.uuid1 = &uuid1;
1698    params.u1 = p1;
1699    params.u2 = p2;
1700    params.u3 = p3;
1701    params.u4 = p4;
1702    params.u5 = p5;
1703    sGattIf->client->test_command(command, &params);
1704}
1705
1706/**
1707 * JNI function definitinos
1708 */
1709
1710// JNI functions defined in AdvertiseManager class.
1711static JNINativeMethod sAdvertiseMethods[] = {
1712    {"gattClientEnableAdvNative", "(IIIIII)V", (void *) gattClientEnableAdvNative},
1713    {"gattClientUpdateAdvNative", "(IIIIII)V", (void *) gattClientUpdateAdvNative},
1714    {"gattClientSetAdvDataNative", "(IZZZI[B[B[B)V", (void *) gattClientSetAdvDataNative},
1715    {"gattClientDisableAdvNative", "(I)V", (void *) gattClientDisableAdvNative},
1716};
1717
1718// JNI functions defined in ScanManager class.
1719static JNINativeMethod sScanMethods[] = {
1720    {"gattClientScanNative", "(Z)V", (void *) gattClientScanNative},
1721    // Batch scan JNI functions.
1722    {"gattClientConfigBatchScanStorageNative", "(IIII)V",(void *) gattClientConfigBatchScanStorageNative},
1723    {"gattClientStartBatchScanNative", "(IIIIII)V", (void *) gattClientStartBatchScanNative},
1724    {"gattClientStopBatchScanNative", "(I)V", (void *) gattClientStopBatchScanNative},
1725    {"gattClientReadScanReportsNative", "(II)V", (void *) gattClientReadScanReportsNative},
1726    // Scan filter JNI functions.
1727    {"gattClientScanFilterParamAddNative", "(IIIIIIIIIII)V", (void *) gattClientScanFilterParamAddNative},
1728    {"gattClientScanFilterParamDeleteNative", "(II)V", (void *) gattClientScanFilterParamDeleteNative},
1729    {"gattClientScanFilterParamClearAllNative", "(I)V", (void *) gattClientScanFilterParamClearAllNative},
1730    {"gattClientScanFilterAddNative", "(IIIIIJJJJLjava/lang/String;Ljava/lang/String;B[B[B)V", (void *) gattClientScanFilterAddNative},
1731    {"gattClientScanFilterDeleteNative", "(IIIIIJJJJLjava/lang/String;Ljava/lang/String;B[B[B)V", (void *) gattClientScanFilterDeleteNative},
1732    {"gattClientScanFilterClearNative", "(II)V", (void *) gattClientScanFilterClearNative},
1733    {"gattClientScanFilterEnableNative", "(IZ)V", (void *) gattClientScanFilterEnableNative},
1734};
1735
1736// JNI functions defined in GattService class.
1737static JNINativeMethod sMethods[] = {
1738    {"classInitNative", "()V", (void *) classInitNative},
1739    {"initializeNative", "()V", (void *) initializeNative},
1740    {"cleanupNative", "()V", (void *) cleanupNative},
1741    {"gattClientGetDeviceTypeNative", "(Ljava/lang/String;)I", (void *) gattClientGetDeviceTypeNative},
1742    {"gattClientRegisterAppNative", "(JJ)V", (void *) gattClientRegisterAppNative},
1743    {"gattClientUnregisterAppNative", "(I)V", (void *) gattClientUnregisterAppNative},
1744    {"gattClientConnectNative", "(ILjava/lang/String;ZI)V", (void *) gattClientConnectNative},
1745    {"gattClientDisconnectNative", "(ILjava/lang/String;I)V", (void *) gattClientDisconnectNative},
1746    {"gattClientRefreshNative", "(ILjava/lang/String;)V", (void *) gattClientRefreshNative},
1747    {"gattClientSearchServiceNative", "(IZJJ)V", (void *) gattClientSearchServiceNative},
1748    {"gattClientGetCharacteristicNative", "(IIIJJIJJ)V", (void *) gattClientGetCharacteristicNative},
1749    {"gattClientGetDescriptorNative", "(IIIJJIJJIJJ)V", (void *) gattClientGetDescriptorNative},
1750    {"gattClientGetIncludedServiceNative", "(IIIJJIIJJ)V", (void *) gattClientGetIncludedServiceNative},
1751    {"gattClientReadCharacteristicNative", "(IIIJJIJJI)V", (void *) gattClientReadCharacteristicNative},
1752    {"gattClientReadDescriptorNative", "(IIIJJIJJIJJI)V", (void *) gattClientReadDescriptorNative},
1753    {"gattClientWriteCharacteristicNative", "(IIIJJIJJII[B)V", (void *) gattClientWriteCharacteristicNative},
1754    {"gattClientWriteDescriptorNative", "(IIIJJIJJIJJII[B)V", (void *) gattClientWriteDescriptorNative},
1755    {"gattClientExecuteWriteNative", "(IZ)V", (void *) gattClientExecuteWriteNative},
1756    {"gattClientRegisterForNotificationsNative", "(ILjava/lang/String;IIJJIJJZ)V", (void *) gattClientRegisterForNotificationsNative},
1757    {"gattClientReadRemoteRssiNative", "(ILjava/lang/String;)V", (void *) gattClientReadRemoteRssiNative},
1758    {"gattAdvertiseNative", "(IZ)V", (void *) gattAdvertiseNative},
1759    {"gattClientConfigureMTUNative", "(II)V", (void *) gattClientConfigureMTUNative},
1760    {"gattConnectionParameterUpdateNative", "(ILjava/lang/String;IIII)V", (void *) gattConnectionParameterUpdateNative},
1761    {"gattServerRegisterAppNative", "(JJ)V", (void *) gattServerRegisterAppNative},
1762    {"gattServerUnregisterAppNative", "(I)V", (void *) gattServerUnregisterAppNative},
1763    {"gattServerConnectNative", "(ILjava/lang/String;ZI)V", (void *) gattServerConnectNative},
1764    {"gattServerDisconnectNative", "(ILjava/lang/String;I)V", (void *) gattServerDisconnectNative},
1765    {"gattServerAddServiceNative", "(IIIJJI)V", (void *) gattServerAddServiceNative},
1766    {"gattServerAddIncludedServiceNative", "(III)V", (void *) gattServerAddIncludedServiceNative},
1767    {"gattServerAddCharacteristicNative", "(IIJJII)V", (void *) gattServerAddCharacteristicNative},
1768    {"gattServerAddDescriptorNative", "(IIJJI)V", (void *) gattServerAddDescriptorNative},
1769    {"gattServerStartServiceNative", "(III)V", (void *) gattServerStartServiceNative},
1770    {"gattServerStopServiceNative", "(II)V", (void *) gattServerStopServiceNative},
1771    {"gattServerDeleteServiceNative", "(II)V", (void *) gattServerDeleteServiceNative},
1772    {"gattServerSendIndicationNative", "(III[B)V", (void *) gattServerSendIndicationNative},
1773    {"gattServerSendNotificationNative", "(III[B)V", (void *) gattServerSendNotificationNative},
1774    {"gattServerSendResponseNative", "(IIIIII[BI)V", (void *) gattServerSendResponseNative},
1775
1776    {"gattSetAdvDataNative", "(IZZZIII[B[B[B)V", (void *) gattSetAdvDataNative},
1777    {"gattSetScanParametersNative", "(II)V", (void *) gattSetScanParametersNative},
1778    {"gattTestNative", "(IJJLjava/lang/String;IIIII)V", (void *) gattTestNative},
1779};
1780
1781int register_com_android_bluetooth_gatt(JNIEnv* env)
1782{
1783    int register_success =
1784        jniRegisterNativeMethods(env, "com/android/bluetooth/gatt/ScanManager$ScanNative",
1785                sScanMethods, NELEM(sScanMethods));
1786    register_success &=
1787        jniRegisterNativeMethods(env, "com/android/bluetooth/gatt/AdvertiseManager$AdvertiseNative",
1788                sAdvertiseMethods, NELEM(sAdvertiseMethods));
1789    return register_success &
1790        jniRegisterNativeMethods(env, "com/android/bluetooth/gatt/GattService",
1791                sMethods, NELEM(sMethods));
1792}
1793}
1794