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