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, ¶ms);
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