• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
set_uuid(uint8_t * uuid,jlong uuid_msb,jlong uuid_lsb)57 static void set_uuid(uint8_t* uuid, jlong uuid_msb, jlong uuid_lsb)
58 {
59     for (int i = 0; i != 8; ++i)
60     {
61         uuid[i]     = (uuid_lsb >> (8 * i)) & 0xFF;
62         uuid[i + 8] = (uuid_msb >> (8 * i)) & 0xFF;
63     }
64 }
65 
uuid_lsb(const bt_uuid_t * uuid)66 static 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 
uuid_msb(const bt_uuid_t * uuid)80 static 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 
bd_addr_str_to_addr(const char * str,uint8_t * bd_addr)94 static void bd_addr_str_to_addr(const char* str, uint8_t *bd_addr)
95 {
96     int    i;
97     char   c;
98 
99     c = *str++;
100     for (i = 0; i < BD_ADDR_LEN; i++)
101     {
102         if (c >= '0' && c <= '9')
103             bd_addr[i] = c - '0';
104         else if (c >= 'a' && c <= 'z')
105             bd_addr[i] = c - 'a' + 10;
106         else   // (c >= 'A' && c <= 'Z')
107             bd_addr[i] = c - 'A' + 10;
108 
109         c = *str++;
110         if (c != ':')
111         {
112             bd_addr[i] <<= 4;
113             if (c >= '0' && c <= '9')
114                 bd_addr[i] |= c - '0';
115             else if (c >= 'a' && c <= 'z')
116                 bd_addr[i] |= c - 'a' + 10;
117             else   // (c >= 'A' && c <= 'Z')
118                 bd_addr[i] |= c - 'A' + 10;
119 
120             c = *str++;
121         }
122 
123         c = *str++;
124     }
125 }
126 
jstr2bdaddr(JNIEnv * env,bt_bdaddr_t * bda,jstring address)127 static void jstr2bdaddr(JNIEnv* env, bt_bdaddr_t *bda, jstring address)
128 {
129     const char* c_bda = env->GetStringUTFChars(address, NULL);
130     if (c_bda != NULL && bda != NULL && strlen(c_bda) == 17)
131     {
132         bd_addr_str_to_addr(c_bda, bda->address);
133         env->ReleaseStringUTFChars(address, c_bda);
134     }
135 }
136 
137 namespace android {
138 
139 /**
140  * Client callback methods
141  */
142 
143 static jmethodID method_onClientRegistered;
144 static jmethodID method_onScanResult;
145 static jmethodID method_onConnected;
146 static jmethodID method_onDisconnected;
147 static jmethodID method_onReadCharacteristic;
148 static jmethodID method_onWriteCharacteristic;
149 static jmethodID method_onExecuteCompleted;
150 static jmethodID method_onSearchCompleted;
151 static jmethodID method_onReadDescriptor;
152 static jmethodID method_onWriteDescriptor;
153 static jmethodID method_onNotify;
154 static jmethodID method_onRegisterForNotifications;
155 static jmethodID method_onReadRemoteRssi;
156 static jmethodID method_onAdvertiseCallback;
157 static jmethodID method_onConfigureMTU;
158 static jmethodID method_onScanFilterConfig;
159 static jmethodID method_onScanFilterParamsConfigured;
160 static jmethodID method_onScanFilterEnableDisabled;
161 static jmethodID method_onMultiAdvEnable;
162 static jmethodID method_onMultiAdvUpdate;
163 static jmethodID method_onMultiAdvSetAdvData;
164 static jmethodID method_onMultiAdvDisable;
165 static jmethodID method_onClientCongestion;
166 static jmethodID method_onBatchScanStorageConfigured;
167 static jmethodID method_onBatchScanStartStopped;
168 static jmethodID method_onBatchScanReports;
169 static jmethodID method_onBatchScanThresholdCrossed;
170 
171 static jmethodID method_CreateonTrackAdvFoundLostObject;
172 static jmethodID method_onTrackAdvFoundLost;
173 static jmethodID method_onScanParamSetupCompleted;
174 static jmethodID method_getSampleGattDbElement;
175 static jmethodID method_onGetGattDb;
176 
177 /**
178  * Server callback methods
179  */
180 static jmethodID method_onServerRegistered;
181 static jmethodID method_onClientConnected;
182 static jmethodID method_onServiceAdded;
183 static jmethodID method_onIncludedServiceAdded;
184 static jmethodID method_onCharacteristicAdded;
185 static jmethodID method_onDescriptorAdded;
186 static jmethodID method_onServiceStarted;
187 static jmethodID method_onServiceStopped;
188 static jmethodID method_onServiceDeleted;
189 static jmethodID method_onResponseSendCompleted;
190 static jmethodID method_onAttributeRead;
191 static jmethodID method_onAttributeWrite;
192 static jmethodID method_onExecuteWrite;
193 static jmethodID method_onNotificationSent;
194 static jmethodID method_onServerCongestion;
195 static jmethodID method_onServerMtuChanged;
196 
197 /**
198  * Static variables
199  */
200 
201 static const btgatt_interface_t *sGattIf = NULL;
202 static jobject mCallbacksObj = NULL;
203 static JNIEnv *sCallbackEnv = NULL;
204 
checkCallbackThread()205 static 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 
btgattc_register_app_cb(int status,int clientIf,bt_uuid_t * app_uuid)217 void 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 
btgattc_scan_result_cb(bt_bdaddr_t * bda,int rssi,uint8_t * adv_data)225 void 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 
btgattc_open_cb(int conn_id,int status,int clientIf,bt_bdaddr_t * bda)246 void 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 
btgattc_close_cb(int conn_id,int status,int clientIf,bt_bdaddr_t * bda)262 void 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 
btgattc_search_complete_cb(int conn_id,int status)277 void 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 
btgattc_register_for_notification_cb(int conn_id,int registered,int status,uint16_t handle)285 void 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 
btgattc_notify_cb(int conn_id,btgatt_notify_params_t * p_data)293 void 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 
btgattc_read_characteristic_cb(int conn_id,int status,btgatt_read_params_t * p_data)314 void 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 
btgattc_write_characteristic_cb(int conn_id,int status,uint16_t handle)336 void 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 
btgattc_execute_write_cb(int conn_id,int status)344 void 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 
btgattc_read_descriptor_cb(int conn_id,int status,btgatt_read_params_t * p_data)352 void 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 
btgattc_write_descriptor_cb(int conn_id,int status,uint16_t handle)373 void 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 
btgattc_remote_rssi_cb(int client_if,bt_bdaddr_t * bda,int rssi,int status)381 void 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 
btgattc_advertise_cb(int status,int client_if)396 void 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 
btgattc_configure_mtu_cb(int conn_id,int status,int mtu)403 void 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 
btgattc_scan_filter_cfg_cb(int action,int client_if,int status,int filt_type,int avbl_space)411 void 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 
btgattc_scan_filter_param_cb(int action,int client_if,int status,int avbl_space)420 void 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 
btgattc_scan_filter_status_cb(int action,int client_if,int status)428 void 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 
btgattc_multiadv_enable_cb(int client_if,int status)436 void 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 
btgattc_multiadv_update_cb(int client_if,int status)443 void 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 
btgattc_multiadv_setadv_data_cb(int client_if,int status)450 void 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 
btgattc_multiadv_disable_cb(int client_if,int status)457 void 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 
btgattc_congestion_cb(int conn_id,bool congested)464 void 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 
btgattc_batchscan_cfg_storage_cb(int client_if,int status)471 void 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 
btgattc_batchscan_startstop_cb(int startstop_action,int client_if,int status)478 void 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 
btgattc_batchscan_reports_cb(int client_if,int status,int report_format,int num_records,int data_len,uint8_t * p_rep_data)486 void 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 
btgattc_batchscan_threshold_cb(int client_if)499 void 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 
btgattc_track_adv_event_cb(btgatt_track_adv_info_t * p_adv_track_info)506 void 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 
btgattc_scan_parameter_setup_completed_cb(int client_if,btgattc_error_t status)546 void 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 
btgattc_get_gatt_db_cb(int conn_id,btgatt_db_element_t * db,int count)553 void 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 
615 static 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 
btgatts_register_app_cb(int status,int server_if,bt_uuid_t * uuid)655 void 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 
btgatts_connection_cb(int conn_id,int server_if,int connected,bt_bdaddr_t * bda)663 void 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 
btgatts_service_added_cb(int status,int server_if,btgatt_srvc_id_t * srvc_id,int srvc_handle)679 void 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 
btgatts_included_service_added_cb(int status,int server_if,int srvc_handle,int incl_srvc_handle)689 void 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 
btgatts_characteristic_added_cb(int status,int server_if,bt_uuid_t * char_id,int srvc_handle,int char_handle)699 void 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 
btgatts_descriptor_added_cb(int status,int server_if,bt_uuid_t * descr_id,int srvc_handle,int descr_handle)709 void 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 
btgatts_service_started_cb(int status,int server_if,int srvc_handle)720 void 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 
btgatts_service_stopped_cb(int status,int server_if,int srvc_handle)728 void 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 
btgatts_service_deleted_cb(int status,int server_if,int srvc_handle)736 void 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 
btgatts_request_read_cb(int conn_id,int trans_id,bt_bdaddr_t * bda,int attr_handle,int offset,bool is_long)744 void 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 
btgatts_request_write_cb(int conn_id,int trans_id,bt_bdaddr_t * bda,int attr_handle,int offset,int length,bool need_rsp,bool is_prep,uint8_t * value)762 void 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 
btgatts_request_exec_write_cb(int conn_id,int trans_id,bt_bdaddr_t * bda,int exec_write)786 void 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 
btgatts_response_confirmation_cb(int status,int handle)803 void 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 
btgatts_indication_sent_cb(int conn_id,int status)811 void 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 
btgatts_congestion_cb(int conn_id,bool congested)819 void 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 
btgatts_mtu_changed_cb(int conn_id,int mtu)826 void 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 
833 static 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 
856 static const btgatt_callbacks_t sGattCallbacks = {
857     sizeof(btgatt_callbacks_t),
858     &sGattClientCallbacks,
859     &sGattServerCallbacks
860 };
861 
862 /**
863  * Native function definitions
864  */
classInitNative(JNIEnv * env,jclass clazz)865 static 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 
925 static const bt_interface_t* btIf;
926 
initializeNative(JNIEnv * env,jobject object)927 static 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 
cleanupNative(JNIEnv * env,jobject object)964 static 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 
gattClientGetDeviceTypeNative(JNIEnv * env,jobject object,jstring address)983 static 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 
gattClientRegisterAppNative(JNIEnv * env,jobject object,jlong app_uuid_lsb,jlong app_uuid_msb)991 static 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 
gattClientUnregisterAppNative(JNIEnv * env,jobject object,jint clientIf)1001 static void gattClientUnregisterAppNative(JNIEnv* env, jobject object, jint clientIf)
1002 {
1003     if (!sGattIf) return;
1004     sGattIf->client->unregister_client(clientIf);
1005 }
1006 
gattClientScanNative(JNIEnv * env,jobject object,jboolean start)1007 static void gattClientScanNative(JNIEnv* env, jobject object, jboolean start)
1008 {
1009     if (!sGattIf) return;
1010     sGattIf->client->scan(start);
1011 }
1012 
gattClientConnectNative(JNIEnv * env,jobject object,jint clientif,jstring address,jboolean isDirect,jint transport)1013 static 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 
gattClientDisconnectNative(JNIEnv * env,jobject object,jint clientIf,jstring address,jint conn_id)1023 static 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 
gattClientRefreshNative(JNIEnv * env,jobject object,jint clientIf,jstring address)1032 static 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 
gattClientSearchServiceNative(JNIEnv * env,jobject object,jint conn_id,jboolean search_all,jlong service_uuid_lsb,jlong service_uuid_msb)1042 static 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 
gattClientGetGattDbNative(JNIEnv * env,jobject object,jint conn_id)1052 static 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 
gattClientReadCharacteristicNative(JNIEnv * env,jobject object,jint conn_id,jint handle,jint authReq)1060 static 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 
gattClientReadDescriptorNative(JNIEnv * env,jobject object,jint conn_id,jint handle,jint authReq)1068 static 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 
gattClientWriteCharacteristicNative(JNIEnv * env,jobject object,jint conn_id,jint handle,jint write_type,jint auth_req,jbyteArray value)1076 static 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 
gattClientExecuteWriteNative(JNIEnv * env,jobject object,jint conn_id,jboolean execute)1094 static 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 
gattClientWriteDescriptorNative(JNIEnv * env,jobject object,jint conn_id,jint handle,jint write_type,jint auth_req,jbyteArray value)1101 static 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 
gattClientRegisterForNotificationsNative(JNIEnv * env,jobject object,jint clientIf,jstring address,jint handle,jboolean enable)1119 static 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 
gattClientReadRemoteRssiNative(JNIEnv * env,jobject object,jint clientif,jstring address)1134 static 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 
gattAdvertiseNative(JNIEnv * env,jobject object,jint client_if,jboolean start)1145 static 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 
gattSetAdvDataNative(JNIEnv * env,jobject object,jint client_if,jboolean setScanRsp,jboolean inclName,jboolean inclTxPower,jint minInterval,jint maxInterval,jint appearance,jbyteArray manufacturerData,jbyteArray serviceData,jbyteArray serviceUuid)1152 static 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 
gattSetScanParametersNative(JNIEnv * env,jobject object,jint client_if,jint scan_interval_unit,jint scan_window_unit)1177 static 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 
gattClientScanFilterParamAddNative(JNIEnv * env,jobject object,jobject params)1185 static 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 
gattClientScanFilterParamDeleteNative(JNIEnv * env,jobject object,jint client_if,jint filt_index)1236 static 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 
gattClientScanFilterParamClearAllNative(JNIEnv * env,jobject object,jint client_if)1249 static 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 
gattClientScanFilterAddRemoveNative(JNIEnv * env,jobject object,jint client_if,jint action,jint filt_type,jint filt_index,jint company_id,jint company_id_mask,jlong uuid_lsb,jlong uuid_msb,jlong uuid_mask_lsb,jlong uuid_mask_msb,jstring name,jstring address,jbyte addr_type,jbyteArray data,jbyteArray mask)1260 static 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 
gattClientScanFilterAddNative(JNIEnv * env,jobject object,jint client_if,jint filt_type,jint filt_index,jint company_id,jint company_id_mask,jlong uuid_lsb,jlong uuid_msb,jlong uuid_mask_lsb,jlong uuid_mask_msb,jstring name,jstring address,jbyte addr_type,jbyteArray data,jbyteArray mask)1338 static 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 
gattClientScanFilterDeleteNative(JNIEnv * env,jobject object,jint client_if,jint filt_type,jint filt_index,jint company_id,jint company_id_mask,jlong uuid_lsb,jlong uuid_msb,jlong uuid_mask_lsb,jlong uuid_mask_msb,jstring name,jstring address,jbyte addr_type,jbyteArray data,jbyteArray mask)1351 static 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 
gattClientScanFilterClearNative(JNIEnv * env,jobject object,jint client_if,jint filt_index)1363 static 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 
gattClientScanFilterEnableNative(JNIEnv * env,jobject object,jint client_if,jboolean enable)1370 static 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 
gattClientConfigureMTUNative(JNIEnv * env,jobject object,jint conn_id,jint mtu)1377 static 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 
gattConnectionParameterUpdateNative(JNIEnv * env,jobject object,jint client_if,jstring address,jint min_interval,jint max_interval,jint latency,jint timeout)1384 static 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 
gattClientEnableAdvNative(JNIEnv * env,jobject object,jint client_if,jint min_interval,jint max_interval,jint adv_type,jint chnl_map,jint tx_power,jint timeout_s)1393 static 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 
gattClientUpdateAdvNative(JNIEnv * env,jobject object,jint client_if,jint min_interval,jint max_interval,jint adv_type,jint chnl_map,jint tx_power,jint timeout_s)1403 static 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 
gattClientSetAdvDataNative(JNIEnv * env,jobject object,jint client_if,jboolean set_scan_rsp,jboolean incl_name,jboolean incl_txpower,jint appearance,jbyteArray manufacturer_data,jbyteArray service_data,jbyteArray service_uuid)1413 static 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 
gattClientDisableAdvNative(JNIEnv * env,jobject object,jint client_if)1437 static void gattClientDisableAdvNative(JNIEnv* env, jobject object, jint client_if)
1438 {
1439     if (!sGattIf) return;
1440     sGattIf->client->multi_adv_disable(client_if);
1441 }
1442 
gattClientConfigBatchScanStorageNative(JNIEnv * env,jobject object,jint client_if,jint max_full_reports_percent,jint max_trunc_reports_percent,jint notify_threshold_level_percent)1443 static 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 
gattClientStartBatchScanNative(JNIEnv * env,jobject object,jint client_if,jint scan_mode,jint scan_interval_unit,jint scan_window_unit,jint addr_type,jint discard_rule)1452 static 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 
gattClientStopBatchScanNative(JNIEnv * env,jobject object,jint client_if)1461 static 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 
gattClientReadScanReportsNative(JNIEnv * env,jobject object,jint client_if,jint scan_type)1467 static 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  */
gattServerRegisterAppNative(JNIEnv * env,jobject object,jlong app_uuid_lsb,jlong app_uuid_msb)1477 static 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 
gattServerUnregisterAppNative(JNIEnv * env,jobject object,jint serverIf)1486 static void gattServerUnregisterAppNative(JNIEnv* env, jobject object, jint serverIf)
1487 {
1488     if (!sGattIf) return;
1489     sGattIf->server->unregister_server(serverIf);
1490 }
1491 
gattServerConnectNative(JNIEnv * env,jobject object,jint server_if,jstring address,jboolean is_direct,jint transport)1492 static 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 
gattServerDisconnectNative(JNIEnv * env,jobject object,jint serverIf,jstring address,jint conn_id)1504 static 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 
gattServerAddServiceNative(JNIEnv * env,jobject object,jint server_if,jint service_type,jint service_id_inst_id,jlong service_id_uuid_lsb,jlong service_id_uuid_msb,jint num_handles)1513 static 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 
gattServerAddIncludedServiceNative(JNIEnv * env,jobject object,jint server_if,jint svc_handle,jint included_svc_handle)1528 static 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 
gattServerAddCharacteristicNative(JNIEnv * env,jobject object,jint server_if,jint svc_handle,jlong char_uuid_lsb,jlong char_uuid_msb,jint properties,jint permissions)1536 static 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 
gattServerAddDescriptorNative(JNIEnv * env,jobject object,jint server_if,jint svc_handle,jlong desc_uuid_lsb,jlong desc_uuid_msb,jint permissions)1550 static 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 
gattServerStartServiceNative(JNIEnv * env,jobject object,jint server_if,jint svc_handle,jint transport)1563 static 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 
gattServerStopServiceNative(JNIEnv * env,jobject object,jint server_if,jint svc_handle)1570 static 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 
gattServerDeleteServiceNative(JNIEnv * env,jobject object,jint server_if,jint svc_handle)1577 static 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 
gattServerSendIndicationNative(JNIEnv * env,jobject object,jint server_if,jint attr_handle,jint conn_id,jbyteArray val)1584 static 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 
gattServerSendNotificationNative(JNIEnv * env,jobject object,jint server_if,jint attr_handle,jint conn_id,jbyteArray val)1597 static 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 
gattServerSendResponseNative(JNIEnv * env,jobject object,jint server_if,jint conn_id,jint trans_id,jint status,jint handle,jint offset,jbyteArray val,jint auth_req)1610 static 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 
gattTestNative(JNIEnv * env,jobject object,jint command,jlong uuid1_lsb,jlong uuid1_msb,jstring bda1,jint p1,jint p2,jint p3,jint p4,jint p5)1636 static 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.
1664 static 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.
1674 static 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.
1693 static 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 
register_com_android_bluetooth_gatt(JNIEnv * env)1732 int 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