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 #define LOG_TAG "BtGatt.JNI"
18
19 #define LOG_NDEBUG 0
20
21 #include "com_android_bluetooth.h"
22 #include "hardware/bt_gatt.h"
23 #include "utils/Log.h"
24
25 #include <base/bind.h>
26 #include <base/callback.h>
27 #include <string.h>
28 #include <array>
29 #include <memory>
30
31 #include <cutils/log.h>
32 #define info(fmt, ...) ALOGI("%s(L%d): " fmt, __func__, __LINE__, ##__VA_ARGS__)
33 #define debug(fmt, ...) \
34 ALOGD("%s(L%d): " fmt, __func__, __LINE__, ##__VA_ARGS__)
35 #define warn(fmt, ...) \
36 ALOGW("WARNING: %s(L%d): " fmt "##", __func__, __LINE__, ##__VA_ARGS__)
37 #define error(fmt, ...) \
38 ALOGE("ERROR: %s(L%d): " fmt "##", __func__, __LINE__, ##__VA_ARGS__)
39 #define asrt(s) \
40 if (!(s)) ALOGE("%s(L%d): ASSERT %s failed! ##", __func__, __LINE__, #s)
41
42 using bluetooth::Uuid;
43
44 #define UUID_PARAMS(uuid) uuid_lsb(uuid), uuid_msb(uuid)
45
from_java_uuid(jlong uuid_msb,jlong uuid_lsb)46 static Uuid from_java_uuid(jlong uuid_msb, jlong uuid_lsb) {
47 std::array<uint8_t, Uuid::kNumBytes128> uu;
48 for (int i = 0; i < 8; i++) {
49 uu[7 - i] = (uuid_msb >> (8 * i)) & 0xFF;
50 uu[15 - i] = (uuid_lsb >> (8 * i)) & 0xFF;
51 }
52 return Uuid::From128BitBE(uu);
53 }
54
uuid_lsb(const Uuid & uuid)55 static uint64_t uuid_lsb(const Uuid& uuid) {
56 uint64_t lsb = 0;
57
58 auto uu = uuid.To128BitBE();
59 for (int i = 8; i <= 15; i++) {
60 lsb <<= 8;
61 lsb |= uu[i];
62 }
63
64 return lsb;
65 }
66
uuid_msb(const Uuid & uuid)67 static uint64_t uuid_msb(const Uuid& uuid) {
68 uint64_t msb = 0;
69
70 auto uu = uuid.To128BitBE();
71 for (int i = 0; i <= 7; i++) {
72 msb <<= 8;
73 msb |= uu[i];
74 }
75
76 return msb;
77 }
78
str2addr(JNIEnv * env,jstring address)79 static RawAddress str2addr(JNIEnv* env, jstring address) {
80 RawAddress bd_addr;
81 const char* c_address = env->GetStringUTFChars(address, NULL);
82 if (!c_address) return bd_addr;
83
84 RawAddress::FromString(std::string(c_address), bd_addr);
85 env->ReleaseStringUTFChars(address, c_address);
86
87 return bd_addr;
88 }
89
bdaddr2newjstr(JNIEnv * env,const RawAddress * bda)90 static jstring bdaddr2newjstr(JNIEnv* env, const RawAddress* bda) {
91 char c_address[32];
92 snprintf(c_address, sizeof(c_address), "%02X:%02X:%02X:%02X:%02X:%02X",
93 bda->address[0], bda->address[1], bda->address[2], bda->address[3],
94 bda->address[4], bda->address[5]);
95
96 return env->NewStringUTF(c_address);
97 }
98
toVector(JNIEnv * env,jbyteArray ba)99 static std::vector<uint8_t> toVector(JNIEnv* env, jbyteArray ba) {
100 jbyte* data_data = env->GetByteArrayElements(ba, NULL);
101 uint16_t data_len = (uint16_t)env->GetArrayLength(ba);
102 std::vector<uint8_t> data_vec(data_data, data_data + data_len);
103 env->ReleaseByteArrayElements(ba, data_data, JNI_ABORT);
104 return data_vec;
105 }
106
107 namespace android {
108
109 /**
110 * Client callback methods
111 */
112
113 static jmethodID method_onClientRegistered;
114 static jmethodID method_onScannerRegistered;
115 static jmethodID method_onScanResult;
116 static jmethodID method_onConnected;
117 static jmethodID method_onDisconnected;
118 static jmethodID method_onReadCharacteristic;
119 static jmethodID method_onWriteCharacteristic;
120 static jmethodID method_onExecuteCompleted;
121 static jmethodID method_onSearchCompleted;
122 static jmethodID method_onReadDescriptor;
123 static jmethodID method_onWriteDescriptor;
124 static jmethodID method_onNotify;
125 static jmethodID method_onRegisterForNotifications;
126 static jmethodID method_onReadRemoteRssi;
127 static jmethodID method_onConfigureMTU;
128 static jmethodID method_onScanFilterConfig;
129 static jmethodID method_onScanFilterParamsConfigured;
130 static jmethodID method_onScanFilterEnableDisabled;
131 static jmethodID method_onClientCongestion;
132 static jmethodID method_onBatchScanStorageConfigured;
133 static jmethodID method_onBatchScanStartStopped;
134 static jmethodID method_onBatchScanReports;
135 static jmethodID method_onBatchScanThresholdCrossed;
136
137 static jmethodID method_createOnTrackAdvFoundLostObject;
138 static jmethodID method_onTrackAdvFoundLost;
139 static jmethodID method_onScanParamSetupCompleted;
140 static jmethodID method_getSampleGattDbElement;
141 static jmethodID method_onGetGattDb;
142 static jmethodID method_onClientPhyUpdate;
143 static jmethodID method_onClientPhyRead;
144 static jmethodID method_onClientConnUpdate;
145
146 /**
147 * Server callback methods
148 */
149 static jmethodID method_onServerRegistered;
150 static jmethodID method_onClientConnected;
151 static jmethodID method_onServiceAdded;
152 static jmethodID method_onServiceStopped;
153 static jmethodID method_onServiceDeleted;
154 static jmethodID method_onResponseSendCompleted;
155 static jmethodID method_onServerReadCharacteristic;
156 static jmethodID method_onServerReadDescriptor;
157 static jmethodID method_onServerWriteCharacteristic;
158 static jmethodID method_onServerWriteDescriptor;
159 static jmethodID method_onExecuteWrite;
160 static jmethodID method_onNotificationSent;
161 static jmethodID method_onServerCongestion;
162 static jmethodID method_onServerMtuChanged;
163 static jmethodID method_onServerPhyUpdate;
164 static jmethodID method_onServerPhyRead;
165 static jmethodID method_onServerConnUpdate;
166
167 /**
168 * Advertiser callback methods
169 */
170 static jmethodID method_onAdvertisingSetStarted;
171 static jmethodID method_onOwnAddressRead;
172 static jmethodID method_onAdvertisingEnabled;
173 static jmethodID method_onAdvertisingDataSet;
174 static jmethodID method_onScanResponseDataSet;
175 static jmethodID method_onAdvertisingParametersUpdated;
176 static jmethodID method_onPeriodicAdvertisingParametersUpdated;
177 static jmethodID method_onPeriodicAdvertisingDataSet;
178 static jmethodID method_onPeriodicAdvertisingEnabled;
179
180 /**
181 * Periodic scanner callback methods
182 */
183 static jmethodID method_onSyncLost;
184 static jmethodID method_onSyncReport;
185 static jmethodID method_onSyncStarted;
186
187 /**
188 * Static variables
189 */
190
191 static const btgatt_interface_t* sGattIf = NULL;
192 static jobject mCallbacksObj = NULL;
193 static jobject mAdvertiseCallbacksObj = NULL;
194 static jobject mPeriodicScanCallbacksObj = NULL;
195
196 /**
197 * BTA client callbacks
198 */
199
btgattc_register_app_cb(int status,int clientIf,const Uuid & app_uuid)200 void btgattc_register_app_cb(int status, int clientIf, const Uuid& app_uuid) {
201 CallbackEnv sCallbackEnv(__func__);
202 if (!sCallbackEnv.valid()) return;
203 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientRegistered, status,
204 clientIf, UUID_PARAMS(app_uuid));
205 }
206
btgattc_scan_result_cb(uint16_t event_type,uint8_t addr_type,RawAddress * bda,uint8_t primary_phy,uint8_t secondary_phy,uint8_t advertising_sid,int8_t tx_power,int8_t rssi,uint16_t periodic_adv_int,std::vector<uint8_t> adv_data)207 void btgattc_scan_result_cb(uint16_t event_type, uint8_t addr_type,
208 RawAddress* bda, uint8_t primary_phy,
209 uint8_t secondary_phy, uint8_t advertising_sid,
210 int8_t tx_power, int8_t rssi,
211 uint16_t periodic_adv_int,
212 std::vector<uint8_t> adv_data) {
213 CallbackEnv sCallbackEnv(__func__);
214 if (!sCallbackEnv.valid()) return;
215
216 ScopedLocalRef<jstring> address(sCallbackEnv.get(),
217 bdaddr2newjstr(sCallbackEnv.get(), bda));
218 ScopedLocalRef<jbyteArray> jb(sCallbackEnv.get(),
219 sCallbackEnv->NewByteArray(adv_data.size()));
220 sCallbackEnv->SetByteArrayRegion(jb.get(), 0, adv_data.size(),
221 (jbyte*)adv_data.data());
222
223 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScanResult, event_type,
224 addr_type, address.get(), primary_phy,
225 secondary_phy, advertising_sid, tx_power, rssi,
226 periodic_adv_int, jb.get());
227 }
228
btgattc_open_cb(int conn_id,int status,int clientIf,const RawAddress & bda)229 void btgattc_open_cb(int conn_id, int status, int clientIf,
230 const RawAddress& bda) {
231 CallbackEnv sCallbackEnv(__func__);
232 if (!sCallbackEnv.valid()) return;
233
234 ScopedLocalRef<jstring> address(sCallbackEnv.get(),
235 bdaddr2newjstr(sCallbackEnv.get(), &bda));
236 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnected, clientIf,
237 conn_id, status, address.get());
238 }
239
btgattc_close_cb(int conn_id,int status,int clientIf,const RawAddress & bda)240 void btgattc_close_cb(int conn_id, int status, int clientIf,
241 const RawAddress& bda) {
242 CallbackEnv sCallbackEnv(__func__);
243 if (!sCallbackEnv.valid()) return;
244
245 ScopedLocalRef<jstring> address(sCallbackEnv.get(),
246 bdaddr2newjstr(sCallbackEnv.get(), &bda));
247 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onDisconnected, clientIf,
248 conn_id, status, address.get());
249 }
250
btgattc_search_complete_cb(int conn_id,int status)251 void btgattc_search_complete_cb(int conn_id, int status) {
252 CallbackEnv sCallbackEnv(__func__);
253 if (!sCallbackEnv.valid()) return;
254
255 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onSearchCompleted, conn_id,
256 status);
257 }
258
btgattc_register_for_notification_cb(int conn_id,int registered,int status,uint16_t handle)259 void btgattc_register_for_notification_cb(int conn_id, int registered,
260 int status, uint16_t handle) {
261 CallbackEnv sCallbackEnv(__func__);
262 if (!sCallbackEnv.valid()) return;
263
264 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onRegisterForNotifications,
265 conn_id, status, registered, handle);
266 }
267
btgattc_notify_cb(int conn_id,const btgatt_notify_params_t & p_data)268 void btgattc_notify_cb(int conn_id, const btgatt_notify_params_t& p_data) {
269 CallbackEnv sCallbackEnv(__func__);
270 if (!sCallbackEnv.valid()) return;
271
272 ScopedLocalRef<jstring> address(
273 sCallbackEnv.get(), bdaddr2newjstr(sCallbackEnv.get(), &p_data.bda));
274 ScopedLocalRef<jbyteArray> jb(sCallbackEnv.get(),
275 sCallbackEnv->NewByteArray(p_data.len));
276 sCallbackEnv->SetByteArrayRegion(jb.get(), 0, p_data.len,
277 (jbyte*)p_data.value);
278
279 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNotify, conn_id,
280 address.get(), p_data.handle, p_data.is_notify,
281 jb.get());
282 }
283
btgattc_read_characteristic_cb(int conn_id,int status,btgatt_read_params_t * p_data)284 void btgattc_read_characteristic_cb(int conn_id, int status,
285 btgatt_read_params_t* p_data) {
286 CallbackEnv sCallbackEnv(__func__);
287 if (!sCallbackEnv.valid()) return;
288
289 ScopedLocalRef<jbyteArray> jb(sCallbackEnv.get(), NULL);
290 if (status == 0) { // Success
291 jb.reset(sCallbackEnv->NewByteArray(p_data->value.len));
292 sCallbackEnv->SetByteArrayRegion(jb.get(), 0, p_data->value.len,
293 (jbyte*)p_data->value.value);
294 } else {
295 uint8_t value = 0;
296 jb.reset(sCallbackEnv->NewByteArray(1));
297 sCallbackEnv->SetByteArrayRegion(jb.get(), 0, 1, (jbyte*)&value);
298 }
299
300 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onReadCharacteristic,
301 conn_id, status, p_data->handle, jb.get());
302 }
303
btgattc_write_characteristic_cb(int conn_id,int status,uint16_t handle)304 void btgattc_write_characteristic_cb(int conn_id, int status, uint16_t handle) {
305 CallbackEnv sCallbackEnv(__func__);
306 if (!sCallbackEnv.valid()) return;
307
308 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onWriteCharacteristic,
309 conn_id, status, handle);
310 }
311
btgattc_execute_write_cb(int conn_id,int status)312 void btgattc_execute_write_cb(int conn_id, int status) {
313 CallbackEnv sCallbackEnv(__func__);
314 if (!sCallbackEnv.valid()) return;
315
316 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onExecuteCompleted,
317 conn_id, status);
318 }
319
btgattc_read_descriptor_cb(int conn_id,int status,const btgatt_read_params_t & p_data)320 void btgattc_read_descriptor_cb(int conn_id, int status,
321 const btgatt_read_params_t& p_data) {
322 CallbackEnv sCallbackEnv(__func__);
323 if (!sCallbackEnv.valid()) return;
324
325 ScopedLocalRef<jbyteArray> jb(sCallbackEnv.get(), NULL);
326 if (p_data.value.len != 0) {
327 jb.reset(sCallbackEnv->NewByteArray(p_data.value.len));
328 sCallbackEnv->SetByteArrayRegion(jb.get(), 0, p_data.value.len,
329 (jbyte*)p_data.value.value);
330 } else {
331 jb.reset(sCallbackEnv->NewByteArray(1));
332 }
333
334 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onReadDescriptor, conn_id,
335 status, p_data.handle, jb.get());
336 }
337
btgattc_write_descriptor_cb(int conn_id,int status,uint16_t handle)338 void btgattc_write_descriptor_cb(int conn_id, int status, uint16_t handle) {
339 CallbackEnv sCallbackEnv(__func__);
340 if (!sCallbackEnv.valid()) return;
341
342 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onWriteDescriptor, conn_id,
343 status, handle);
344 }
345
btgattc_remote_rssi_cb(int client_if,const RawAddress & bda,int rssi,int status)346 void btgattc_remote_rssi_cb(int client_if, const RawAddress& bda, int rssi,
347 int status) {
348 CallbackEnv sCallbackEnv(__func__);
349 if (!sCallbackEnv.valid()) return;
350
351 ScopedLocalRef<jstring> address(sCallbackEnv.get(),
352 bdaddr2newjstr(sCallbackEnv.get(), &bda));
353
354 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onReadRemoteRssi,
355 client_if, address.get(), rssi, status);
356 }
357
btgattc_configure_mtu_cb(int conn_id,int status,int mtu)358 void btgattc_configure_mtu_cb(int conn_id, int status, int mtu) {
359 CallbackEnv sCallbackEnv(__func__);
360 if (!sCallbackEnv.valid()) return;
361 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConfigureMTU, conn_id,
362 status, mtu);
363 }
364
btgattc_congestion_cb(int conn_id,bool congested)365 void btgattc_congestion_cb(int conn_id, bool congested) {
366 CallbackEnv sCallbackEnv(__func__);
367 if (!sCallbackEnv.valid()) return;
368 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientCongestion,
369 conn_id, congested);
370 }
371
btgattc_batchscan_reports_cb(int client_if,int status,int report_format,int num_records,std::vector<uint8_t> data)372 void btgattc_batchscan_reports_cb(int client_if, int status, int report_format,
373 int num_records, std::vector<uint8_t> data) {
374 CallbackEnv sCallbackEnv(__func__);
375 if (!sCallbackEnv.valid()) return;
376 ScopedLocalRef<jbyteArray> jb(sCallbackEnv.get(),
377 sCallbackEnv->NewByteArray(data.size()));
378 sCallbackEnv->SetByteArrayRegion(jb.get(), 0, data.size(),
379 (jbyte*)data.data());
380
381 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onBatchScanReports, status,
382 client_if, report_format, num_records, jb.get());
383 }
384
btgattc_batchscan_threshold_cb(int client_if)385 void btgattc_batchscan_threshold_cb(int client_if) {
386 CallbackEnv sCallbackEnv(__func__);
387 if (!sCallbackEnv.valid()) return;
388 sCallbackEnv->CallVoidMethod(mCallbacksObj,
389 method_onBatchScanThresholdCrossed, client_if);
390 }
391
btgattc_track_adv_event_cb(btgatt_track_adv_info_t * p_adv_track_info)392 void btgattc_track_adv_event_cb(btgatt_track_adv_info_t* p_adv_track_info) {
393 CallbackEnv sCallbackEnv(__func__);
394 if (!sCallbackEnv.valid()) return;
395
396 ScopedLocalRef<jstring> address(
397 sCallbackEnv.get(),
398 bdaddr2newjstr(sCallbackEnv.get(), &p_adv_track_info->bd_addr));
399
400 ScopedLocalRef<jbyteArray> jb_adv_pkt(
401 sCallbackEnv.get(),
402 sCallbackEnv->NewByteArray(p_adv_track_info->adv_pkt_len));
403 ScopedLocalRef<jbyteArray> jb_scan_rsp(
404 sCallbackEnv.get(),
405 sCallbackEnv->NewByteArray(p_adv_track_info->scan_rsp_len));
406
407 sCallbackEnv->SetByteArrayRegion(jb_adv_pkt.get(), 0,
408 p_adv_track_info->adv_pkt_len,
409 (jbyte*)p_adv_track_info->p_adv_pkt_data);
410
411 sCallbackEnv->SetByteArrayRegion(jb_scan_rsp.get(), 0,
412 p_adv_track_info->scan_rsp_len,
413 (jbyte*)p_adv_track_info->p_scan_rsp_data);
414
415 ScopedLocalRef<jobject> trackadv_obj(
416 sCallbackEnv.get(),
417 sCallbackEnv->CallObjectMethod(
418 mCallbacksObj, method_createOnTrackAdvFoundLostObject,
419 p_adv_track_info->client_if, p_adv_track_info->adv_pkt_len,
420 jb_adv_pkt.get(), p_adv_track_info->scan_rsp_len, jb_scan_rsp.get(),
421 p_adv_track_info->filt_index, p_adv_track_info->advertiser_state,
422 p_adv_track_info->advertiser_info_present, address.get(),
423 p_adv_track_info->addr_type, p_adv_track_info->tx_power,
424 p_adv_track_info->rssi_value, p_adv_track_info->time_stamp));
425
426 if (NULL != trackadv_obj.get()) {
427 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onTrackAdvFoundLost,
428 trackadv_obj.get());
429 }
430 }
431
fillGattDbElementArray(JNIEnv * env,jobject * array,const btgatt_db_element_t * db,int count)432 void fillGattDbElementArray(JNIEnv* env, jobject* array,
433 const btgatt_db_element_t* db, int count) {
434 // Because JNI uses a different class loader in the callback context, we
435 // cannot simply get the class.
436 // As a workaround, we have to make sure we obtain an object of the class
437 // first, as this will cause
438 // class loader to load it.
439 ScopedLocalRef<jobject> objectForClass(
440 env, env->CallObjectMethod(mCallbacksObj, method_getSampleGattDbElement));
441 ScopedLocalRef<jclass> gattDbElementClazz(
442 env, env->GetObjectClass(objectForClass.get()));
443
444 jmethodID gattDbElementConstructor =
445 env->GetMethodID(gattDbElementClazz.get(), "<init>", "()V");
446
447 ScopedLocalRef<jclass> arrayListclazz(env,
448 env->FindClass("java/util/ArrayList"));
449 jmethodID arrayAdd =
450 env->GetMethodID(arrayListclazz.get(), "add", "(Ljava/lang/Object;)Z");
451
452 ScopedLocalRef<jclass> uuidClazz(env, env->FindClass("java/util/UUID"));
453 jmethodID uuidConstructor =
454 env->GetMethodID(uuidClazz.get(), "<init>", "(JJ)V");
455
456 for (int i = 0; i < count; i++) {
457 const btgatt_db_element_t& curr = db[i];
458
459 ScopedLocalRef<jobject> element(
460 env,
461 env->NewObject(gattDbElementClazz.get(), gattDbElementConstructor));
462
463 jfieldID fid = env->GetFieldID(gattDbElementClazz.get(), "id", "I");
464 env->SetIntField(element.get(), fid, curr.id);
465
466 fid = env->GetFieldID(gattDbElementClazz.get(), "attributeHandle", "I");
467 env->SetIntField(element.get(), fid, curr.attribute_handle);
468
469 ScopedLocalRef<jobject> uuid(
470 env, env->NewObject(uuidClazz.get(), uuidConstructor,
471 uuid_msb(curr.uuid), uuid_lsb(curr.uuid)));
472 fid = env->GetFieldID(gattDbElementClazz.get(), "uuid", "Ljava/util/UUID;");
473 env->SetObjectField(element.get(), fid, uuid.get());
474
475 fid = env->GetFieldID(gattDbElementClazz.get(), "type", "I");
476 env->SetIntField(element.get(), fid, curr.type);
477
478 fid = env->GetFieldID(gattDbElementClazz.get(), "attributeHandle", "I");
479 env->SetIntField(element.get(), fid, curr.attribute_handle);
480
481 fid = env->GetFieldID(gattDbElementClazz.get(), "startHandle", "I");
482 env->SetIntField(element.get(), fid, curr.start_handle);
483
484 fid = env->GetFieldID(gattDbElementClazz.get(), "endHandle", "I");
485 env->SetIntField(element.get(), fid, curr.end_handle);
486
487 fid = env->GetFieldID(gattDbElementClazz.get(), "properties", "I");
488 env->SetIntField(element.get(), fid, curr.properties);
489
490 env->CallBooleanMethod(*array, arrayAdd, element.get());
491 }
492 }
493
btgattc_get_gatt_db_cb(int conn_id,const btgatt_db_element_t * db,int count)494 void btgattc_get_gatt_db_cb(int conn_id, const btgatt_db_element_t* db,
495 int count) {
496 CallbackEnv sCallbackEnv(__func__);
497 if (!sCallbackEnv.valid()) return;
498
499 jclass arrayListclazz = sCallbackEnv->FindClass("java/util/ArrayList");
500 ScopedLocalRef<jobject> array(
501 sCallbackEnv.get(),
502 sCallbackEnv->NewObject(
503 arrayListclazz,
504 sCallbackEnv->GetMethodID(arrayListclazz, "<init>", "()V")));
505
506 jobject arrayPtr = array.get();
507 fillGattDbElementArray(sCallbackEnv.get(), &arrayPtr, db, count);
508
509 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onGetGattDb, conn_id,
510 array.get());
511 }
512
btgattc_phy_updated_cb(int conn_id,uint8_t tx_phy,uint8_t rx_phy,uint8_t status)513 void btgattc_phy_updated_cb(int conn_id, uint8_t tx_phy, uint8_t rx_phy,
514 uint8_t status) {
515 CallbackEnv sCallbackEnv(__func__);
516 if (!sCallbackEnv.valid()) return;
517
518 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientPhyUpdate, conn_id,
519 tx_phy, rx_phy, status);
520 }
521
btgattc_conn_updated_cb(int conn_id,uint16_t interval,uint16_t latency,uint16_t timeout,uint8_t status)522 void btgattc_conn_updated_cb(int conn_id, uint16_t interval, uint16_t latency,
523 uint16_t timeout, uint8_t status) {
524 CallbackEnv sCallbackEnv(__func__);
525 if (!sCallbackEnv.valid()) return;
526
527 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientConnUpdate,
528 conn_id, interval, latency, timeout, status);
529 }
530
531 static const btgatt_scanner_callbacks_t sGattScannerCallbacks = {
532 btgattc_scan_result_cb,
533 btgattc_batchscan_reports_cb,
534 btgattc_batchscan_threshold_cb,
535 btgattc_track_adv_event_cb,
536 };
537
538 static const btgatt_client_callbacks_t sGattClientCallbacks = {
539 btgattc_register_app_cb,
540 btgattc_open_cb,
541 btgattc_close_cb,
542 btgattc_search_complete_cb,
543 btgattc_register_for_notification_cb,
544 btgattc_notify_cb,
545 btgattc_read_characteristic_cb,
546 btgattc_write_characteristic_cb,
547 btgattc_read_descriptor_cb,
548 btgattc_write_descriptor_cb,
549 btgattc_execute_write_cb,
550 btgattc_remote_rssi_cb,
551 btgattc_configure_mtu_cb,
552 btgattc_congestion_cb,
553 btgattc_get_gatt_db_cb,
554 NULL, /* services_removed_cb */
555 NULL, /* services_added_cb */
556 btgattc_phy_updated_cb,
557 btgattc_conn_updated_cb};
558
559 /**
560 * BTA server callbacks
561 */
562
btgatts_register_app_cb(int status,int server_if,const Uuid & uuid)563 void btgatts_register_app_cb(int status, int server_if, const Uuid& uuid) {
564 CallbackEnv sCallbackEnv(__func__);
565 if (!sCallbackEnv.valid()) return;
566 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerRegistered, status,
567 server_if, UUID_PARAMS(uuid));
568 }
569
btgatts_connection_cb(int conn_id,int server_if,int connected,const RawAddress & bda)570 void btgatts_connection_cb(int conn_id, int server_if, int connected,
571 const RawAddress& bda) {
572 CallbackEnv sCallbackEnv(__func__);
573 if (!sCallbackEnv.valid()) return;
574
575 ScopedLocalRef<jstring> address(sCallbackEnv.get(),
576 bdaddr2newjstr(sCallbackEnv.get(), &bda));
577 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientConnected,
578 address.get(), connected, conn_id, server_if);
579 }
580
btgatts_service_added_cb(int status,int server_if,std::vector<btgatt_db_element_t> service)581 void btgatts_service_added_cb(int status, int server_if,
582 std::vector<btgatt_db_element_t> service) {
583 CallbackEnv sCallbackEnv(__func__);
584 if (!sCallbackEnv.valid()) return;
585
586 jclass arrayListclazz = sCallbackEnv->FindClass("java/util/ArrayList");
587 ScopedLocalRef<jobject> array(
588 sCallbackEnv.get(),
589 sCallbackEnv->NewObject(
590 arrayListclazz,
591 sCallbackEnv->GetMethodID(arrayListclazz, "<init>", "()V")));
592 jobject arrayPtr = array.get();
593 fillGattDbElementArray(sCallbackEnv.get(), &arrayPtr, service.data(),
594 service.size());
595
596 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceAdded, status,
597 server_if, array.get());
598 }
599
btgatts_service_stopped_cb(int status,int server_if,int srvc_handle)600 void btgatts_service_stopped_cb(int status, int server_if, int srvc_handle) {
601 CallbackEnv sCallbackEnv(__func__);
602 if (!sCallbackEnv.valid()) return;
603 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceStopped, status,
604 server_if, srvc_handle);
605 }
606
btgatts_service_deleted_cb(int status,int server_if,int srvc_handle)607 void btgatts_service_deleted_cb(int status, int server_if, int srvc_handle) {
608 CallbackEnv sCallbackEnv(__func__);
609 if (!sCallbackEnv.valid()) return;
610 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceDeleted, status,
611 server_if, srvc_handle);
612 }
613
btgatts_request_read_characteristic_cb(int conn_id,int trans_id,const RawAddress & bda,int attr_handle,int offset,bool is_long)614 void btgatts_request_read_characteristic_cb(int conn_id, int trans_id,
615 const RawAddress& bda,
616 int attr_handle, int offset,
617 bool is_long) {
618 CallbackEnv sCallbackEnv(__func__);
619 if (!sCallbackEnv.valid()) return;
620
621 ScopedLocalRef<jstring> address(sCallbackEnv.get(),
622 bdaddr2newjstr(sCallbackEnv.get(), &bda));
623 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerReadCharacteristic,
624 address.get(), conn_id, trans_id, attr_handle,
625 offset, is_long);
626 }
627
btgatts_request_read_descriptor_cb(int conn_id,int trans_id,const RawAddress & bda,int attr_handle,int offset,bool is_long)628 void btgatts_request_read_descriptor_cb(int conn_id, int trans_id,
629 const RawAddress& bda, int attr_handle,
630 int offset, bool is_long) {
631 CallbackEnv sCallbackEnv(__func__);
632 if (!sCallbackEnv.valid()) return;
633
634 ScopedLocalRef<jstring> address(sCallbackEnv.get(),
635 bdaddr2newjstr(sCallbackEnv.get(), &bda));
636 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerReadDescriptor,
637 address.get(), conn_id, trans_id, attr_handle,
638 offset, is_long);
639 }
640
btgatts_request_write_characteristic_cb(int conn_id,int trans_id,const RawAddress & bda,int attr_handle,int offset,bool need_rsp,bool is_prep,std::vector<uint8_t> value)641 void btgatts_request_write_characteristic_cb(int conn_id, int trans_id,
642 const RawAddress& bda,
643 int attr_handle, int offset,
644 bool need_rsp, bool is_prep,
645 std::vector<uint8_t> value) {
646 CallbackEnv sCallbackEnv(__func__);
647 if (!sCallbackEnv.valid()) return;
648
649 ScopedLocalRef<jstring> address(sCallbackEnv.get(),
650 bdaddr2newjstr(sCallbackEnv.get(), &bda));
651 ScopedLocalRef<jbyteArray> val(sCallbackEnv.get(),
652 sCallbackEnv->NewByteArray(value.size()));
653 if (val.get())
654 sCallbackEnv->SetByteArrayRegion(val.get(), 0, value.size(),
655 (jbyte*)value.data());
656 sCallbackEnv->CallVoidMethod(
657 mCallbacksObj, method_onServerWriteCharacteristic, address.get(), conn_id,
658 trans_id, attr_handle, offset, value.size(), need_rsp, is_prep,
659 val.get());
660 }
661
btgatts_request_write_descriptor_cb(int conn_id,int trans_id,const RawAddress & bda,int attr_handle,int offset,bool need_rsp,bool is_prep,std::vector<uint8_t> value)662 void btgatts_request_write_descriptor_cb(int conn_id, int trans_id,
663 const RawAddress& bda, int attr_handle,
664 int offset, bool need_rsp,
665 bool is_prep,
666 std::vector<uint8_t> value) {
667 CallbackEnv sCallbackEnv(__func__);
668 if (!sCallbackEnv.valid()) return;
669
670 ScopedLocalRef<jstring> address(sCallbackEnv.get(),
671 bdaddr2newjstr(sCallbackEnv.get(), &bda));
672 ScopedLocalRef<jbyteArray> val(sCallbackEnv.get(),
673 sCallbackEnv->NewByteArray(value.size()));
674 if (val.get())
675 sCallbackEnv->SetByteArrayRegion(val.get(), 0, value.size(),
676 (jbyte*)value.data());
677 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerWriteDescriptor,
678 address.get(), conn_id, trans_id, attr_handle,
679 offset, value.size(), need_rsp, is_prep,
680 val.get());
681 }
682
btgatts_request_exec_write_cb(int conn_id,int trans_id,const RawAddress & bda,int exec_write)683 void btgatts_request_exec_write_cb(int conn_id, int trans_id,
684 const RawAddress& bda, int exec_write) {
685 CallbackEnv sCallbackEnv(__func__);
686 if (!sCallbackEnv.valid()) return;
687
688 ScopedLocalRef<jstring> address(sCallbackEnv.get(),
689 bdaddr2newjstr(sCallbackEnv.get(), &bda));
690 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onExecuteWrite,
691 address.get(), conn_id, trans_id, exec_write);
692 }
693
btgatts_response_confirmation_cb(int status,int handle)694 void btgatts_response_confirmation_cb(int status, int handle) {
695 CallbackEnv sCallbackEnv(__func__);
696 if (!sCallbackEnv.valid()) return;
697 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onResponseSendCompleted,
698 status, handle);
699 }
700
btgatts_indication_sent_cb(int conn_id,int status)701 void btgatts_indication_sent_cb(int conn_id, int status) {
702 CallbackEnv sCallbackEnv(__func__);
703 if (!sCallbackEnv.valid()) return;
704 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNotificationSent,
705 conn_id, status);
706 }
707
btgatts_congestion_cb(int conn_id,bool congested)708 void btgatts_congestion_cb(int conn_id, bool congested) {
709 CallbackEnv sCallbackEnv(__func__);
710 if (!sCallbackEnv.valid()) return;
711 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerCongestion,
712 conn_id, congested);
713 }
714
btgatts_mtu_changed_cb(int conn_id,int mtu)715 void btgatts_mtu_changed_cb(int conn_id, int mtu) {
716 CallbackEnv sCallbackEnv(__func__);
717 if (!sCallbackEnv.valid()) return;
718 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerMtuChanged,
719 conn_id, mtu);
720 }
721
btgatts_phy_updated_cb(int conn_id,uint8_t tx_phy,uint8_t rx_phy,uint8_t status)722 void btgatts_phy_updated_cb(int conn_id, uint8_t tx_phy, uint8_t rx_phy,
723 uint8_t status) {
724 CallbackEnv sCallbackEnv(__func__);
725 if (!sCallbackEnv.valid()) return;
726
727 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerPhyUpdate, conn_id,
728 tx_phy, rx_phy, status);
729 }
730
btgatts_conn_updated_cb(int conn_id,uint16_t interval,uint16_t latency,uint16_t timeout,uint8_t status)731 void btgatts_conn_updated_cb(int conn_id, uint16_t interval, uint16_t latency,
732 uint16_t timeout, uint8_t status) {
733 CallbackEnv sCallbackEnv(__func__);
734 if (!sCallbackEnv.valid()) return;
735
736 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerConnUpdate,
737 conn_id, interval, latency, timeout, status);
738 }
739
740 static const btgatt_server_callbacks_t sGattServerCallbacks = {
741 btgatts_register_app_cb,
742 btgatts_connection_cb,
743 btgatts_service_added_cb,
744 btgatts_service_stopped_cb,
745 btgatts_service_deleted_cb,
746 btgatts_request_read_characteristic_cb,
747 btgatts_request_read_descriptor_cb,
748 btgatts_request_write_characteristic_cb,
749 btgatts_request_write_descriptor_cb,
750 btgatts_request_exec_write_cb,
751 btgatts_response_confirmation_cb,
752 btgatts_indication_sent_cb,
753 btgatts_congestion_cb,
754 btgatts_mtu_changed_cb,
755 btgatts_phy_updated_cb,
756 btgatts_conn_updated_cb};
757
758 /**
759 * GATT callbacks
760 */
761
762 static const btgatt_callbacks_t sGattCallbacks = {
763 sizeof(btgatt_callbacks_t), &sGattClientCallbacks, &sGattServerCallbacks,
764 &sGattScannerCallbacks,
765 };
766
767 /**
768 * Native function definitions
769 */
classInitNative(JNIEnv * env,jclass clazz)770 static void classInitNative(JNIEnv* env, jclass clazz) {
771 // Client callbacks
772
773 method_onClientRegistered =
774 env->GetMethodID(clazz, "onClientRegistered", "(IIJJ)V");
775 method_onScannerRegistered =
776 env->GetMethodID(clazz, "onScannerRegistered", "(IIJJ)V");
777 method_onScanResult = env->GetMethodID(clazz, "onScanResult",
778 "(IILjava/lang/String;IIIIII[B)V");
779 method_onConnected =
780 env->GetMethodID(clazz, "onConnected", "(IIILjava/lang/String;)V");
781 method_onDisconnected =
782 env->GetMethodID(clazz, "onDisconnected", "(IIILjava/lang/String;)V");
783 method_onReadCharacteristic =
784 env->GetMethodID(clazz, "onReadCharacteristic", "(III[B)V");
785 method_onWriteCharacteristic =
786 env->GetMethodID(clazz, "onWriteCharacteristic", "(III)V");
787 method_onExecuteCompleted =
788 env->GetMethodID(clazz, "onExecuteCompleted", "(II)V");
789 method_onSearchCompleted =
790 env->GetMethodID(clazz, "onSearchCompleted", "(II)V");
791 method_onReadDescriptor =
792 env->GetMethodID(clazz, "onReadDescriptor", "(III[B)V");
793 method_onWriteDescriptor =
794 env->GetMethodID(clazz, "onWriteDescriptor", "(III)V");
795 method_onNotify =
796 env->GetMethodID(clazz, "onNotify", "(ILjava/lang/String;IZ[B)V");
797 method_onRegisterForNotifications =
798 env->GetMethodID(clazz, "onRegisterForNotifications", "(IIII)V");
799 method_onReadRemoteRssi =
800 env->GetMethodID(clazz, "onReadRemoteRssi", "(ILjava/lang/String;II)V");
801 method_onConfigureMTU = env->GetMethodID(clazz, "onConfigureMTU", "(III)V");
802 method_onScanFilterConfig =
803 env->GetMethodID(clazz, "onScanFilterConfig", "(IIIII)V");
804 method_onScanFilterParamsConfigured =
805 env->GetMethodID(clazz, "onScanFilterParamsConfigured", "(IIII)V");
806 method_onScanFilterEnableDisabled =
807 env->GetMethodID(clazz, "onScanFilterEnableDisabled", "(III)V");
808 method_onClientCongestion =
809 env->GetMethodID(clazz, "onClientCongestion", "(IZ)V");
810 method_onBatchScanStorageConfigured =
811 env->GetMethodID(clazz, "onBatchScanStorageConfigured", "(II)V");
812 method_onBatchScanStartStopped =
813 env->GetMethodID(clazz, "onBatchScanStartStopped", "(III)V");
814 method_onBatchScanReports =
815 env->GetMethodID(clazz, "onBatchScanReports", "(IIII[B)V");
816 method_onBatchScanThresholdCrossed =
817 env->GetMethodID(clazz, "onBatchScanThresholdCrossed", "(I)V");
818 method_createOnTrackAdvFoundLostObject =
819 env->GetMethodID(clazz, "createOnTrackAdvFoundLostObject",
820 "(II[BI[BIIILjava/lang/String;IIII)Lcom/android/"
821 "bluetooth/gatt/AdvtFilterOnFoundOnLostInfo;");
822 method_onTrackAdvFoundLost = env->GetMethodID(
823 clazz, "onTrackAdvFoundLost",
824 "(Lcom/android/bluetooth/gatt/AdvtFilterOnFoundOnLostInfo;)V");
825 method_onScanParamSetupCompleted =
826 env->GetMethodID(clazz, "onScanParamSetupCompleted", "(II)V");
827 method_getSampleGattDbElement =
828 env->GetMethodID(clazz, "getSampleGattDbElement",
829 "()Lcom/android/bluetooth/gatt/GattDbElement;");
830 method_onGetGattDb =
831 env->GetMethodID(clazz, "onGetGattDb", "(ILjava/util/ArrayList;)V");
832 method_onClientPhyRead =
833 env->GetMethodID(clazz, "onClientPhyRead", "(ILjava/lang/String;III)V");
834 method_onClientPhyUpdate =
835 env->GetMethodID(clazz, "onClientPhyUpdate", "(IIII)V");
836 method_onClientConnUpdate =
837 env->GetMethodID(clazz, "onClientConnUpdate", "(IIIII)V");
838
839 // Server callbacks
840
841 method_onServerRegistered =
842 env->GetMethodID(clazz, "onServerRegistered", "(IIJJ)V");
843 method_onClientConnected =
844 env->GetMethodID(clazz, "onClientConnected", "(Ljava/lang/String;ZII)V");
845 method_onServiceAdded =
846 env->GetMethodID(clazz, "onServiceAdded", "(IILjava/util/List;)V");
847 method_onServiceStopped =
848 env->GetMethodID(clazz, "onServiceStopped", "(III)V");
849 method_onServiceDeleted =
850 env->GetMethodID(clazz, "onServiceDeleted", "(III)V");
851 method_onResponseSendCompleted =
852 env->GetMethodID(clazz, "onResponseSendCompleted", "(II)V");
853 method_onServerReadCharacteristic = env->GetMethodID(
854 clazz, "onServerReadCharacteristic", "(Ljava/lang/String;IIIIZ)V");
855 method_onServerReadDescriptor = env->GetMethodID(
856 clazz, "onServerReadDescriptor", "(Ljava/lang/String;IIIIZ)V");
857 method_onServerWriteCharacteristic = env->GetMethodID(
858 clazz, "onServerWriteCharacteristic", "(Ljava/lang/String;IIIIIZZ[B)V");
859 method_onServerWriteDescriptor = env->GetMethodID(
860 clazz, "onServerWriteDescriptor", "(Ljava/lang/String;IIIIIZZ[B)V");
861 method_onExecuteWrite =
862 env->GetMethodID(clazz, "onExecuteWrite", "(Ljava/lang/String;III)V");
863 method_onNotificationSent =
864 env->GetMethodID(clazz, "onNotificationSent", "(II)V");
865 method_onServerCongestion =
866 env->GetMethodID(clazz, "onServerCongestion", "(IZ)V");
867 method_onServerMtuChanged = env->GetMethodID(clazz, "onMtuChanged", "(II)V");
868 method_onServerPhyRead =
869 env->GetMethodID(clazz, "onServerPhyRead", "(ILjava/lang/String;III)V");
870 method_onServerPhyUpdate =
871 env->GetMethodID(clazz, "onServerPhyUpdate", "(IIII)V");
872 method_onServerConnUpdate =
873 env->GetMethodID(clazz, "onServerConnUpdate", "(IIIII)V");
874
875 info("classInitNative: Success!");
876 }
877
878 static const bt_interface_t* btIf;
879
initializeNative(JNIEnv * env,jobject object)880 static void initializeNative(JNIEnv* env, jobject object) {
881 if (btIf) return;
882
883 btIf = getBluetoothInterface();
884 if (btIf == NULL) {
885 error("Bluetooth module is not loaded");
886 return;
887 }
888
889 if (sGattIf != NULL) {
890 ALOGW("Cleaning up Bluetooth GATT Interface before initializing...");
891 sGattIf->cleanup();
892 sGattIf = NULL;
893 }
894
895 if (mCallbacksObj != NULL) {
896 ALOGW("Cleaning up Bluetooth GATT callback object");
897 env->DeleteGlobalRef(mCallbacksObj);
898 mCallbacksObj = NULL;
899 }
900
901 sGattIf =
902 (btgatt_interface_t*)btIf->get_profile_interface(BT_PROFILE_GATT_ID);
903 if (sGattIf == NULL) {
904 error("Failed to get Bluetooth GATT Interface");
905 return;
906 }
907
908 bt_status_t status = sGattIf->init(&sGattCallbacks);
909 if (status != BT_STATUS_SUCCESS) {
910 error("Failed to initialize Bluetooth GATT, status: %d", status);
911 sGattIf = NULL;
912 return;
913 }
914
915 mCallbacksObj = env->NewGlobalRef(object);
916 }
917
cleanupNative(JNIEnv * env,jobject object)918 static void cleanupNative(JNIEnv* env, jobject object) {
919 if (!btIf) return;
920
921 if (sGattIf != NULL) {
922 sGattIf->cleanup();
923 sGattIf = NULL;
924 }
925
926 if (mCallbacksObj != NULL) {
927 env->DeleteGlobalRef(mCallbacksObj);
928 mCallbacksObj = NULL;
929 }
930 btIf = NULL;
931 }
932
933 /**
934 * Native Client functions
935 */
936
gattClientGetDeviceTypeNative(JNIEnv * env,jobject object,jstring address)937 static int gattClientGetDeviceTypeNative(JNIEnv* env, jobject object,
938 jstring address) {
939 if (!sGattIf) return 0;
940 return sGattIf->client->get_device_type(str2addr(env, address));
941 }
942
gattClientRegisterAppNative(JNIEnv * env,jobject object,jlong app_uuid_lsb,jlong app_uuid_msb)943 static void gattClientRegisterAppNative(JNIEnv* env, jobject object,
944 jlong app_uuid_lsb,
945 jlong app_uuid_msb) {
946 if (!sGattIf) return;
947 Uuid uuid = from_java_uuid(app_uuid_msb, app_uuid_lsb);
948 sGattIf->client->register_client(uuid);
949 }
950
gattClientUnregisterAppNative(JNIEnv * env,jobject object,jint clientIf)951 static void gattClientUnregisterAppNative(JNIEnv* env, jobject object,
952 jint clientIf) {
953 if (!sGattIf) return;
954 sGattIf->client->unregister_client(clientIf);
955 }
956
btgattc_register_scanner_cb(const Uuid & app_uuid,uint8_t scannerId,uint8_t status)957 void btgattc_register_scanner_cb(const Uuid& app_uuid, uint8_t scannerId,
958 uint8_t status) {
959 CallbackEnv sCallbackEnv(__func__);
960 if (!sCallbackEnv.valid()) return;
961 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScannerRegistered,
962 status, scannerId, UUID_PARAMS(app_uuid));
963 }
964
registerScannerNative(JNIEnv * env,jobject object,jlong app_uuid_lsb,jlong app_uuid_msb)965 static void registerScannerNative(JNIEnv* env, jobject object,
966 jlong app_uuid_lsb, jlong app_uuid_msb) {
967 if (!sGattIf) return;
968
969 Uuid uuid = from_java_uuid(app_uuid_msb, app_uuid_lsb);
970 sGattIf->scanner->RegisterScanner(
971 base::Bind(&btgattc_register_scanner_cb, uuid));
972 }
973
unregisterScannerNative(JNIEnv * env,jobject object,jint scanner_id)974 static void unregisterScannerNative(JNIEnv* env, jobject object,
975 jint scanner_id) {
976 if (!sGattIf) return;
977
978 sGattIf->scanner->Unregister(scanner_id);
979 }
980
gattClientScanNative(JNIEnv * env,jobject object,jboolean start)981 static void gattClientScanNative(JNIEnv* env, jobject object, jboolean start) {
982 if (!sGattIf) return;
983 sGattIf->scanner->Scan(start);
984 }
985
gattClientConnectNative(JNIEnv * env,jobject object,jint clientif,jstring address,jboolean isDirect,jint transport,jboolean opportunistic,jint initiating_phys)986 static void gattClientConnectNative(JNIEnv* env, jobject object, jint clientif,
987 jstring address, jboolean isDirect,
988 jint transport, jboolean opportunistic,
989 jint initiating_phys) {
990 if (!sGattIf) return;
991
992 sGattIf->client->connect(clientif, str2addr(env, address), isDirect,
993 transport, opportunistic, initiating_phys);
994 }
995
gattClientDisconnectNative(JNIEnv * env,jobject object,jint clientIf,jstring address,jint conn_id)996 static void gattClientDisconnectNative(JNIEnv* env, jobject object,
997 jint clientIf, jstring address,
998 jint conn_id) {
999 if (!sGattIf) return;
1000 sGattIf->client->disconnect(clientIf, str2addr(env, address), conn_id);
1001 }
1002
gattClientSetPreferredPhyNative(JNIEnv * env,jobject object,jint clientIf,jstring address,jint tx_phy,jint rx_phy,jint phy_options)1003 static void gattClientSetPreferredPhyNative(JNIEnv* env, jobject object,
1004 jint clientIf, jstring address,
1005 jint tx_phy, jint rx_phy,
1006 jint phy_options) {
1007 if (!sGattIf) return;
1008 sGattIf->client->set_preferred_phy(str2addr(env, address), tx_phy, rx_phy,
1009 phy_options);
1010 }
1011
readClientPhyCb(uint8_t clientIf,RawAddress bda,uint8_t tx_phy,uint8_t rx_phy,uint8_t status)1012 static void readClientPhyCb(uint8_t clientIf, RawAddress bda, uint8_t tx_phy,
1013 uint8_t rx_phy, uint8_t status) {
1014 CallbackEnv sCallbackEnv(__func__);
1015 if (!sCallbackEnv.valid()) return;
1016
1017 ScopedLocalRef<jstring> address(sCallbackEnv.get(),
1018 bdaddr2newjstr(sCallbackEnv.get(), &bda));
1019
1020 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientPhyRead, clientIf,
1021 address.get(), tx_phy, rx_phy, status);
1022 }
1023
gattClientReadPhyNative(JNIEnv * env,jobject object,jint clientIf,jstring address)1024 static void gattClientReadPhyNative(JNIEnv* env, jobject object, jint clientIf,
1025 jstring address) {
1026 if (!sGattIf) return;
1027
1028 RawAddress bda = str2addr(env, address);
1029 sGattIf->client->read_phy(bda, base::Bind(&readClientPhyCb, clientIf, bda));
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 if (!sGattIf) return;
1035
1036 sGattIf->client->refresh(clientIf, str2addr(env, address));
1037 }
1038
gattClientSearchServiceNative(JNIEnv * env,jobject object,jint conn_id,jboolean search_all,jlong service_uuid_lsb,jlong service_uuid_msb)1039 static void gattClientSearchServiceNative(JNIEnv* env, jobject object,
1040 jint conn_id, jboolean search_all,
1041 jlong service_uuid_lsb,
1042 jlong service_uuid_msb) {
1043 if (!sGattIf) return;
1044
1045 Uuid uuid = from_java_uuid(service_uuid_msb, service_uuid_lsb);
1046 sGattIf->client->search_service(conn_id, search_all ? 0 : &uuid);
1047 }
1048
gattClientDiscoverServiceByUuidNative(JNIEnv * env,jobject object,jint conn_id,jlong service_uuid_lsb,jlong service_uuid_msb)1049 static void gattClientDiscoverServiceByUuidNative(JNIEnv* env, jobject object,
1050 jint conn_id,
1051 jlong service_uuid_lsb,
1052 jlong service_uuid_msb) {
1053 if (!sGattIf) return;
1054
1055 Uuid uuid = from_java_uuid(service_uuid_msb, service_uuid_lsb);
1056 sGattIf->client->btif_gattc_discover_service_by_uuid(conn_id, uuid);
1057 }
1058
gattClientGetGattDbNative(JNIEnv * env,jobject object,jint conn_id)1059 static void gattClientGetGattDbNative(JNIEnv* env, jobject object,
1060 jint conn_id) {
1061 if (!sGattIf) return;
1062
1063 sGattIf->client->get_gatt_db(conn_id);
1064 }
1065
gattClientReadCharacteristicNative(JNIEnv * env,jobject object,jint conn_id,jint handle,jint authReq)1066 static void gattClientReadCharacteristicNative(JNIEnv* env, jobject object,
1067 jint conn_id, jint handle,
1068 jint authReq) {
1069 if (!sGattIf) return;
1070
1071 sGattIf->client->read_characteristic(conn_id, handle, authReq);
1072 }
1073
gattClientReadUsingCharacteristicUuidNative(JNIEnv * env,jobject object,jint conn_id,jlong uuid_lsb,jlong uuid_msb,jint s_handle,jint e_handle,jint authReq)1074 static void gattClientReadUsingCharacteristicUuidNative(
1075 JNIEnv* env, jobject object, jint conn_id, jlong uuid_lsb, jlong uuid_msb,
1076 jint s_handle, jint e_handle, jint authReq) {
1077 if (!sGattIf) return;
1078
1079 Uuid uuid = from_java_uuid(uuid_msb, uuid_lsb);
1080 sGattIf->client->read_using_characteristic_uuid(conn_id, uuid, s_handle,
1081 e_handle, authReq);
1082 }
1083
gattClientReadDescriptorNative(JNIEnv * env,jobject object,jint conn_id,jint handle,jint authReq)1084 static void gattClientReadDescriptorNative(JNIEnv* env, jobject object,
1085 jint conn_id, jint handle,
1086 jint authReq) {
1087 if (!sGattIf) return;
1088
1089 sGattIf->client->read_descriptor(conn_id, handle, authReq);
1090 }
1091
gattClientWriteCharacteristicNative(JNIEnv * env,jobject object,jint conn_id,jint handle,jint write_type,jint auth_req,jbyteArray value)1092 static void gattClientWriteCharacteristicNative(JNIEnv* env, jobject object,
1093 jint conn_id, jint handle,
1094 jint write_type, jint auth_req,
1095 jbyteArray value) {
1096 if (!sGattIf) return;
1097
1098 if (value == NULL) {
1099 warn("gattClientWriteCharacteristicNative() ignoring NULL array");
1100 return;
1101 }
1102
1103 uint16_t len = (uint16_t)env->GetArrayLength(value);
1104 jbyte* p_value = env->GetByteArrayElements(value, NULL);
1105 if (p_value == NULL) return;
1106
1107 std::vector<uint8_t> vect_val(p_value, p_value + len);
1108 env->ReleaseByteArrayElements(value, p_value, 0);
1109
1110 sGattIf->client->write_characteristic(conn_id, handle, write_type, auth_req,
1111 std::move(vect_val));
1112 }
1113
gattClientExecuteWriteNative(JNIEnv * env,jobject object,jint conn_id,jboolean execute)1114 static void gattClientExecuteWriteNative(JNIEnv* env, jobject object,
1115 jint conn_id, jboolean execute) {
1116 if (!sGattIf) return;
1117 sGattIf->client->execute_write(conn_id, execute ? 1 : 0);
1118 }
1119
gattClientWriteDescriptorNative(JNIEnv * env,jobject object,jint conn_id,jint handle,jint auth_req,jbyteArray value)1120 static void gattClientWriteDescriptorNative(JNIEnv* env, jobject object,
1121 jint conn_id, jint handle,
1122 jint auth_req, jbyteArray value) {
1123 if (!sGattIf) return;
1124
1125 if (value == NULL) {
1126 warn("gattClientWriteDescriptorNative() ignoring NULL array");
1127 return;
1128 }
1129
1130 uint16_t len = (uint16_t)env->GetArrayLength(value);
1131 jbyte* p_value = env->GetByteArrayElements(value, NULL);
1132 if (p_value == NULL) return;
1133
1134 std::vector<uint8_t> vect_val(p_value, p_value + len);
1135 env->ReleaseByteArrayElements(value, p_value, 0);
1136
1137 sGattIf->client->write_descriptor(conn_id, handle, auth_req,
1138 std::move(vect_val));
1139 }
1140
gattClientRegisterForNotificationsNative(JNIEnv * env,jobject object,jint clientIf,jstring address,jint handle,jboolean enable)1141 static void gattClientRegisterForNotificationsNative(
1142 JNIEnv* env, jobject object, jint clientIf, jstring address, jint handle,
1143 jboolean enable) {
1144 if (!sGattIf) return;
1145
1146 RawAddress bd_addr = str2addr(env, address);
1147 if (enable)
1148 sGattIf->client->register_for_notification(clientIf, bd_addr, handle);
1149 else
1150 sGattIf->client->deregister_for_notification(clientIf, bd_addr, handle);
1151 }
1152
gattClientReadRemoteRssiNative(JNIEnv * env,jobject object,jint clientif,jstring address)1153 static void gattClientReadRemoteRssiNative(JNIEnv* env, jobject object,
1154 jint clientif, jstring address) {
1155 if (!sGattIf) return;
1156
1157 sGattIf->client->read_remote_rssi(clientif, str2addr(env, address));
1158 }
1159
set_scan_params_cmpl_cb(int client_if,uint8_t status)1160 void set_scan_params_cmpl_cb(int client_if, uint8_t status) {
1161 CallbackEnv sCallbackEnv(__func__);
1162 if (!sCallbackEnv.valid()) return;
1163 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScanParamSetupCompleted,
1164 status, client_if);
1165 }
1166
gattSetScanParametersNative(JNIEnv * env,jobject object,jint client_if,jint scan_interval_unit,jint scan_window_unit)1167 static void gattSetScanParametersNative(JNIEnv* env, jobject object,
1168 jint client_if, jint scan_interval_unit,
1169 jint scan_window_unit) {
1170 if (!sGattIf) return;
1171 sGattIf->scanner->SetScanParameters(
1172 scan_interval_unit, scan_window_unit,
1173 base::Bind(&set_scan_params_cmpl_cb, client_if));
1174 }
1175
scan_filter_param_cb(uint8_t client_if,uint8_t avbl_space,uint8_t action,uint8_t status)1176 void scan_filter_param_cb(uint8_t client_if, uint8_t avbl_space, uint8_t action,
1177 uint8_t status) {
1178 CallbackEnv sCallbackEnv(__func__);
1179 if (!sCallbackEnv.valid()) return;
1180 sCallbackEnv->CallVoidMethod(mCallbacksObj,
1181 method_onScanFilterParamsConfigured, action,
1182 status, client_if, avbl_space);
1183 }
1184
gattClientScanFilterParamAddNative(JNIEnv * env,jobject object,jobject params)1185 static void gattClientScanFilterParamAddNative(JNIEnv* env, jobject object,
1186 jobject params) {
1187 if (!sGattIf) return;
1188 const int add_scan_filter_params_action = 0;
1189 auto filt_params = std::make_unique<btgatt_filt_param_setup_t>();
1190
1191 jmethodID methodId = 0;
1192 ScopedLocalRef<jclass> filtparam(env, env->GetObjectClass(params));
1193
1194 methodId = env->GetMethodID(filtparam.get(), "getClientIf", "()I");
1195 uint8_t client_if = env->CallIntMethod(params, methodId);
1196
1197 methodId = env->GetMethodID(filtparam.get(), "getFiltIndex", "()I");
1198 uint8_t filt_index = env->CallIntMethod(params, methodId);
1199
1200 methodId = env->GetMethodID(filtparam.get(), "getFeatSeln", "()I");
1201 filt_params->feat_seln = env->CallIntMethod(params, methodId);
1202
1203 methodId = env->GetMethodID(filtparam.get(), "getListLogicType", "()I");
1204 filt_params->list_logic_type = env->CallIntMethod(params, methodId);
1205
1206 methodId = env->GetMethodID(filtparam.get(), "getFiltLogicType", "()I");
1207 filt_params->filt_logic_type = env->CallIntMethod(params, methodId);
1208
1209 methodId = env->GetMethodID(filtparam.get(), "getDelyMode", "()I");
1210 filt_params->dely_mode = env->CallIntMethod(params, methodId);
1211
1212 methodId = env->GetMethodID(filtparam.get(), "getFoundTimeout", "()I");
1213 filt_params->found_timeout = env->CallIntMethod(params, methodId);
1214
1215 methodId = env->GetMethodID(filtparam.get(), "getLostTimeout", "()I");
1216 filt_params->lost_timeout = env->CallIntMethod(params, methodId);
1217
1218 methodId = env->GetMethodID(filtparam.get(), "getFoundTimeOutCnt", "()I");
1219 filt_params->found_timeout_cnt = env->CallIntMethod(params, methodId);
1220
1221 methodId = env->GetMethodID(filtparam.get(), "getNumOfTrackEntries", "()I");
1222 filt_params->num_of_tracking_entries = env->CallIntMethod(params, methodId);
1223
1224 methodId = env->GetMethodID(filtparam.get(), "getRSSIHighValue", "()I");
1225 filt_params->rssi_high_thres = env->CallIntMethod(params, methodId);
1226
1227 methodId = env->GetMethodID(filtparam.get(), "getRSSILowValue", "()I");
1228 filt_params->rssi_low_thres = env->CallIntMethod(params, methodId);
1229
1230 sGattIf->scanner->ScanFilterParamSetup(
1231 client_if, add_scan_filter_params_action, filt_index,
1232 std::move(filt_params), base::Bind(&scan_filter_param_cb, client_if));
1233 }
1234
gattClientScanFilterParamDeleteNative(JNIEnv * env,jobject object,jint client_if,jint filt_index)1235 static void gattClientScanFilterParamDeleteNative(JNIEnv* env, jobject object,
1236 jint client_if,
1237 jint filt_index) {
1238 if (!sGattIf) return;
1239 const int delete_scan_filter_params_action = 1;
1240 sGattIf->scanner->ScanFilterParamSetup(
1241 client_if, delete_scan_filter_params_action, filt_index, nullptr,
1242 base::Bind(&scan_filter_param_cb, client_if));
1243 }
1244
gattClientScanFilterParamClearAllNative(JNIEnv * env,jobject object,jint client_if)1245 static void gattClientScanFilterParamClearAllNative(JNIEnv* env, jobject object,
1246 jint client_if) {
1247 if (!sGattIf) return;
1248 const int clear_scan_filter_params_action = 2;
1249 sGattIf->scanner->ScanFilterParamSetup(
1250 client_if, clear_scan_filter_params_action, 0 /* index, unused */,
1251 nullptr, base::Bind(&scan_filter_param_cb, client_if));
1252 }
1253
scan_filter_cfg_cb(uint8_t client_if,uint8_t filt_type,uint8_t avbl_space,uint8_t action,uint8_t status)1254 static void scan_filter_cfg_cb(uint8_t client_if, uint8_t filt_type,
1255 uint8_t avbl_space, uint8_t action,
1256 uint8_t status) {
1257 CallbackEnv sCallbackEnv(__func__);
1258 if (!sCallbackEnv.valid()) return;
1259 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScanFilterConfig, action,
1260 status, client_if, filt_type, avbl_space);
1261 }
1262
gattClientScanFilterAddNative(JNIEnv * env,jobject object,jint client_if,jobjectArray filters,jint filter_index)1263 static void gattClientScanFilterAddNative(JNIEnv* env, jobject object,
1264 jint client_if, jobjectArray filters,
1265 jint filter_index) {
1266 if (!sGattIf) return;
1267
1268 jclass uuidClazz = env->FindClass("java/util/UUID");
1269 jmethodID uuidGetMsb =
1270 env->GetMethodID(uuidClazz, "getMostSignificantBits", "()J");
1271 jmethodID uuidGetLsb =
1272 env->GetMethodID(uuidClazz, "getLeastSignificantBits", "()J");
1273
1274 std::vector<ApcfCommand> native_filters;
1275
1276 int numFilters = env->GetArrayLength(filters);
1277 if (numFilters == 0) {
1278 sGattIf->scanner->ScanFilterAdd(filter_index, std::move(native_filters),
1279 base::Bind(&scan_filter_cfg_cb, client_if));
1280 return;
1281 }
1282
1283 jclass entryClazz =
1284 env->GetObjectClass(env->GetObjectArrayElement(filters, 0));
1285
1286 jfieldID typeFid = env->GetFieldID(entryClazz, "type", "B");
1287 jfieldID addressFid =
1288 env->GetFieldID(entryClazz, "address", "Ljava/lang/String;");
1289 jfieldID addrTypeFid = env->GetFieldID(entryClazz, "addr_type", "B");
1290 jfieldID uuidFid = env->GetFieldID(entryClazz, "uuid", "Ljava/util/UUID;");
1291 jfieldID uuidMaskFid =
1292 env->GetFieldID(entryClazz, "uuid_mask", "Ljava/util/UUID;");
1293 jfieldID nameFid = env->GetFieldID(entryClazz, "name", "Ljava/lang/String;");
1294 jfieldID companyFid = env->GetFieldID(entryClazz, "company", "I");
1295 jfieldID companyMaskFid = env->GetFieldID(entryClazz, "company_mask", "I");
1296 jfieldID dataFid = env->GetFieldID(entryClazz, "data", "[B");
1297 jfieldID dataMaskFid = env->GetFieldID(entryClazz, "data_mask", "[B");
1298
1299 for (int i = 0; i < numFilters; ++i) {
1300 ApcfCommand curr;
1301
1302 ScopedLocalRef<jobject> current(env,
1303 env->GetObjectArrayElement(filters, i));
1304
1305 curr.type = env->GetByteField(current.get(), typeFid);
1306
1307 ScopedLocalRef<jstring> address(
1308 env, (jstring)env->GetObjectField(current.get(), addressFid));
1309 if (address.get() != NULL) {
1310 curr.address = str2addr(env, address.get());
1311 }
1312
1313 curr.addr_type = env->GetByteField(current.get(), addrTypeFid);
1314
1315 ScopedLocalRef<jobject> uuid(env,
1316 env->GetObjectField(current.get(), uuidFid));
1317 if (uuid.get() != NULL) {
1318 jlong uuid_msb = env->CallLongMethod(uuid.get(), uuidGetMsb);
1319 jlong uuid_lsb = env->CallLongMethod(uuid.get(), uuidGetLsb);
1320 curr.uuid = from_java_uuid(uuid_msb, uuid_lsb);
1321 }
1322
1323 ScopedLocalRef<jobject> uuid_mask(
1324 env, env->GetObjectField(current.get(), uuidMaskFid));
1325 if (uuid.get() != NULL) {
1326 jlong uuid_msb = env->CallLongMethod(uuid_mask.get(), uuidGetMsb);
1327 jlong uuid_lsb = env->CallLongMethod(uuid_mask.get(), uuidGetLsb);
1328 curr.uuid_mask = from_java_uuid(uuid_msb, uuid_lsb);
1329 }
1330
1331 ScopedLocalRef<jstring> name(
1332 env, (jstring)env->GetObjectField(current.get(), nameFid));
1333 if (name.get() != NULL) {
1334 const char* c_name = env->GetStringUTFChars(name.get(), NULL);
1335 if (c_name != NULL && strlen(c_name) != 0) {
1336 curr.name = std::vector<uint8_t>(c_name, c_name + strlen(c_name));
1337 env->ReleaseStringUTFChars(name.get(), c_name);
1338 }
1339 }
1340
1341 curr.company = env->GetIntField(current.get(), companyFid);
1342
1343 curr.company_mask = env->GetIntField(current.get(), companyMaskFid);
1344
1345 ScopedLocalRef<jbyteArray> data(
1346 env, (jbyteArray)env->GetObjectField(current.get(), dataFid));
1347 if (data.get() != NULL) {
1348 jbyte* data_array = env->GetByteArrayElements(data.get(), 0);
1349 int data_len = env->GetArrayLength(data.get());
1350 if (data_array && data_len) {
1351 curr.data = std::vector<uint8_t>(data_array, data_array + data_len);
1352 env->ReleaseByteArrayElements(data.get(), data_array, JNI_ABORT);
1353 }
1354 }
1355
1356 ScopedLocalRef<jbyteArray> data_mask(
1357 env, (jbyteArray)env->GetObjectField(current.get(), dataMaskFid));
1358 if (data_mask.get() != NULL) {
1359 jbyte* data_array = env->GetByteArrayElements(data_mask.get(), 0);
1360 int data_len = env->GetArrayLength(data_mask.get());
1361 if (data_array && data_len) {
1362 curr.data_mask =
1363 std::vector<uint8_t>(data_array, data_array + data_len);
1364 env->ReleaseByteArrayElements(data_mask.get(), data_array, JNI_ABORT);
1365 }
1366 }
1367 native_filters.push_back(curr);
1368 }
1369
1370 sGattIf->scanner->ScanFilterAdd(filter_index, std::move(native_filters),
1371 base::Bind(&scan_filter_cfg_cb, client_if));
1372 }
1373
gattClientScanFilterClearNative(JNIEnv * env,jobject object,jint client_if,jint filt_index)1374 static void gattClientScanFilterClearNative(JNIEnv* env, jobject object,
1375 jint client_if, jint filt_index) {
1376 if (!sGattIf) return;
1377 sGattIf->scanner->ScanFilterClear(filt_index,
1378 base::Bind(&scan_filter_cfg_cb, client_if));
1379 }
1380
scan_enable_cb(uint8_t client_if,uint8_t action,uint8_t status)1381 void scan_enable_cb(uint8_t client_if, uint8_t action, uint8_t status) {
1382 CallbackEnv sCallbackEnv(__func__);
1383 if (!sCallbackEnv.valid()) return;
1384 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScanFilterEnableDisabled,
1385 action, status, client_if);
1386 }
1387
gattClientScanFilterEnableNative(JNIEnv * env,jobject object,jint client_if,jboolean enable)1388 static void gattClientScanFilterEnableNative(JNIEnv* env, jobject object,
1389 jint client_if, jboolean enable) {
1390 if (!sGattIf) return;
1391 sGattIf->scanner->ScanFilterEnable(enable,
1392 base::Bind(&scan_enable_cb, client_if));
1393 }
1394
gattClientConfigureMTUNative(JNIEnv * env,jobject object,jint conn_id,jint mtu)1395 static void gattClientConfigureMTUNative(JNIEnv* env, jobject object,
1396 jint conn_id, jint mtu) {
1397 if (!sGattIf) return;
1398 sGattIf->client->configure_mtu(conn_id, mtu);
1399 }
1400
gattConnectionParameterUpdateNative(JNIEnv * env,jobject object,jint client_if,jstring address,jint min_interval,jint max_interval,jint latency,jint timeout,jint min_ce_len,jint max_ce_len)1401 static void gattConnectionParameterUpdateNative(JNIEnv* env, jobject object,
1402 jint client_if, jstring address,
1403 jint min_interval,
1404 jint max_interval, jint latency,
1405 jint timeout, jint min_ce_len,
1406 jint max_ce_len) {
1407 if (!sGattIf) return;
1408 sGattIf->client->conn_parameter_update(
1409 str2addr(env, address), min_interval, max_interval, latency, timeout,
1410 (uint16_t)min_ce_len, (uint16_t)max_ce_len);
1411 }
1412
batchscan_cfg_storage_cb(uint8_t client_if,uint8_t status)1413 void batchscan_cfg_storage_cb(uint8_t client_if, uint8_t status) {
1414 CallbackEnv sCallbackEnv(__func__);
1415 if (!sCallbackEnv.valid()) return;
1416 sCallbackEnv->CallVoidMethod(
1417 mCallbacksObj, method_onBatchScanStorageConfigured, status, client_if);
1418 }
1419
gattClientConfigBatchScanStorageNative(JNIEnv * env,jobject object,jint client_if,jint max_full_reports_percent,jint max_trunc_reports_percent,jint notify_threshold_level_percent)1420 static void gattClientConfigBatchScanStorageNative(
1421 JNIEnv* env, jobject object, jint client_if, jint max_full_reports_percent,
1422 jint max_trunc_reports_percent, jint notify_threshold_level_percent) {
1423 if (!sGattIf) return;
1424 sGattIf->scanner->BatchscanConfigStorage(
1425 client_if, max_full_reports_percent, max_trunc_reports_percent,
1426 notify_threshold_level_percent,
1427 base::Bind(&batchscan_cfg_storage_cb, client_if));
1428 }
1429
batchscan_enable_cb(uint8_t client_if,uint8_t status)1430 void batchscan_enable_cb(uint8_t client_if, uint8_t status) {
1431 CallbackEnv sCallbackEnv(__func__);
1432 if (!sCallbackEnv.valid()) return;
1433 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onBatchScanStartStopped,
1434 0 /* unused */, status, client_if);
1435 }
1436
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)1437 static void gattClientStartBatchScanNative(JNIEnv* env, jobject object,
1438 jint client_if, jint scan_mode,
1439 jint scan_interval_unit,
1440 jint scan_window_unit,
1441 jint addr_type, jint discard_rule) {
1442 if (!sGattIf) return;
1443 sGattIf->scanner->BatchscanEnable(
1444 scan_mode, scan_interval_unit, scan_window_unit, addr_type, discard_rule,
1445 base::Bind(&batchscan_enable_cb, client_if));
1446 }
1447
gattClientStopBatchScanNative(JNIEnv * env,jobject object,jint client_if)1448 static void gattClientStopBatchScanNative(JNIEnv* env, jobject object,
1449 jint client_if) {
1450 if (!sGattIf) return;
1451 sGattIf->scanner->BatchscanDisable(
1452 base::Bind(&batchscan_enable_cb, client_if));
1453 }
1454
gattClientReadScanReportsNative(JNIEnv * env,jobject object,jint client_if,jint scan_type)1455 static void gattClientReadScanReportsNative(JNIEnv* env, jobject object,
1456 jint client_if, jint scan_type) {
1457 if (!sGattIf) return;
1458 sGattIf->scanner->BatchscanReadReports(client_if, scan_type);
1459 }
1460
1461 /**
1462 * Native server functions
1463 */
gattServerRegisterAppNative(JNIEnv * env,jobject object,jlong app_uuid_lsb,jlong app_uuid_msb)1464 static void gattServerRegisterAppNative(JNIEnv* env, jobject object,
1465 jlong app_uuid_lsb,
1466 jlong app_uuid_msb) {
1467 if (!sGattIf) return;
1468 Uuid uuid = from_java_uuid(app_uuid_msb, app_uuid_lsb);
1469 sGattIf->server->register_server(uuid);
1470 }
1471
gattServerUnregisterAppNative(JNIEnv * env,jobject object,jint serverIf)1472 static void gattServerUnregisterAppNative(JNIEnv* env, jobject object,
1473 jint serverIf) {
1474 if (!sGattIf) return;
1475 sGattIf->server->unregister_server(serverIf);
1476 }
1477
gattServerConnectNative(JNIEnv * env,jobject object,jint server_if,jstring address,jboolean is_direct,jint transport)1478 static void gattServerConnectNative(JNIEnv* env, jobject object, jint server_if,
1479 jstring address, jboolean is_direct,
1480 jint transport) {
1481 if (!sGattIf) return;
1482
1483 RawAddress bd_addr = str2addr(env, address);
1484 sGattIf->server->connect(server_if, bd_addr, is_direct, transport);
1485 }
1486
gattServerDisconnectNative(JNIEnv * env,jobject object,jint serverIf,jstring address,jint conn_id)1487 static void gattServerDisconnectNative(JNIEnv* env, jobject object,
1488 jint serverIf, jstring address,
1489 jint conn_id) {
1490 if (!sGattIf) return;
1491 sGattIf->server->disconnect(serverIf, str2addr(env, address), conn_id);
1492 }
1493
gattServerSetPreferredPhyNative(JNIEnv * env,jobject object,jint serverIf,jstring address,jint tx_phy,jint rx_phy,jint phy_options)1494 static void gattServerSetPreferredPhyNative(JNIEnv* env, jobject object,
1495 jint serverIf, jstring address,
1496 jint tx_phy, jint rx_phy,
1497 jint phy_options) {
1498 if (!sGattIf) return;
1499 RawAddress bda = str2addr(env, address);
1500 sGattIf->server->set_preferred_phy(bda, tx_phy, rx_phy, phy_options);
1501 }
1502
readServerPhyCb(uint8_t serverIf,RawAddress bda,uint8_t tx_phy,uint8_t rx_phy,uint8_t status)1503 static void readServerPhyCb(uint8_t serverIf, RawAddress bda, uint8_t tx_phy,
1504 uint8_t rx_phy, uint8_t status) {
1505 CallbackEnv sCallbackEnv(__func__);
1506 if (!sCallbackEnv.valid()) return;
1507
1508 ScopedLocalRef<jstring> address(sCallbackEnv.get(),
1509 bdaddr2newjstr(sCallbackEnv.get(), &bda));
1510
1511 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerPhyRead, serverIf,
1512 address.get(), tx_phy, rx_phy, status);
1513 }
1514
gattServerReadPhyNative(JNIEnv * env,jobject object,jint serverIf,jstring address)1515 static void gattServerReadPhyNative(JNIEnv* env, jobject object, jint serverIf,
1516 jstring address) {
1517 if (!sGattIf) return;
1518
1519 RawAddress bda = str2addr(env, address);
1520 sGattIf->server->read_phy(bda, base::Bind(&readServerPhyCb, serverIf, bda));
1521 }
1522
gattServerAddServiceNative(JNIEnv * env,jobject object,jint server_if,jobject gatt_db_elements)1523 static void gattServerAddServiceNative(JNIEnv* env, jobject object,
1524 jint server_if,
1525 jobject gatt_db_elements) {
1526 if (!sGattIf) return;
1527
1528 jclass arrayListclazz = env->FindClass("java/util/List");
1529 jmethodID arrayGet =
1530 env->GetMethodID(arrayListclazz, "get", "(I)Ljava/lang/Object;");
1531 jmethodID arraySize = env->GetMethodID(arrayListclazz, "size", "()I");
1532
1533 int count = env->CallIntMethod(gatt_db_elements, arraySize);
1534 std::vector<btgatt_db_element_t> db;
1535
1536 jclass uuidClazz = env->FindClass("java/util/UUID");
1537 jmethodID uuidGetMsb =
1538 env->GetMethodID(uuidClazz, "getMostSignificantBits", "()J");
1539 jmethodID uuidGetLsb =
1540 env->GetMethodID(uuidClazz, "getLeastSignificantBits", "()J");
1541
1542 jobject objectForClass =
1543 env->CallObjectMethod(mCallbacksObj, method_getSampleGattDbElement);
1544 jclass gattDbElementClazz = env->GetObjectClass(objectForClass);
1545
1546 for (int i = 0; i < count; i++) {
1547 btgatt_db_element_t curr;
1548
1549 jint index = i;
1550 ScopedLocalRef<jobject> element(
1551 env, env->CallObjectMethod(gatt_db_elements, arrayGet, index));
1552
1553 jfieldID fid;
1554
1555 fid = env->GetFieldID(gattDbElementClazz, "id", "I");
1556 curr.id = env->GetIntField(element.get(), fid);
1557
1558 fid = env->GetFieldID(gattDbElementClazz, "uuid", "Ljava/util/UUID;");
1559 ScopedLocalRef<jobject> uuid(env, env->GetObjectField(element.get(), fid));
1560 if (uuid.get() != NULL) {
1561 jlong uuid_msb = env->CallLongMethod(uuid.get(), uuidGetMsb);
1562 jlong uuid_lsb = env->CallLongMethod(uuid.get(), uuidGetLsb);
1563 curr.uuid = from_java_uuid(uuid_msb, uuid_lsb);
1564 }
1565
1566 fid = env->GetFieldID(gattDbElementClazz, "type", "I");
1567 curr.type =
1568 (bt_gatt_db_attribute_type_t)env->GetIntField(element.get(), fid);
1569
1570 fid = env->GetFieldID(gattDbElementClazz, "attributeHandle", "I");
1571 curr.attribute_handle = env->GetIntField(element.get(), fid);
1572
1573 fid = env->GetFieldID(gattDbElementClazz, "startHandle", "I");
1574 curr.start_handle = env->GetIntField(element.get(), fid);
1575
1576 fid = env->GetFieldID(gattDbElementClazz, "endHandle", "I");
1577 curr.end_handle = env->GetIntField(element.get(), fid);
1578
1579 fid = env->GetFieldID(gattDbElementClazz, "properties", "I");
1580 curr.properties = env->GetIntField(element.get(), fid);
1581
1582 fid = env->GetFieldID(gattDbElementClazz, "permissions", "I");
1583 curr.permissions = env->GetIntField(element.get(), fid);
1584
1585 db.push_back(curr);
1586 }
1587
1588 sGattIf->server->add_service(server_if, std::move(db));
1589 }
1590
gattServerStopServiceNative(JNIEnv * env,jobject object,jint server_if,jint svc_handle)1591 static void gattServerStopServiceNative(JNIEnv* env, jobject object,
1592 jint server_if, jint svc_handle) {
1593 if (!sGattIf) return;
1594 sGattIf->server->stop_service(server_if, svc_handle);
1595 }
1596
gattServerDeleteServiceNative(JNIEnv * env,jobject object,jint server_if,jint svc_handle)1597 static void gattServerDeleteServiceNative(JNIEnv* env, jobject object,
1598 jint server_if, jint svc_handle) {
1599 if (!sGattIf) return;
1600 sGattIf->server->delete_service(server_if, svc_handle);
1601 }
1602
gattServerSendIndicationNative(JNIEnv * env,jobject object,jint server_if,jint attr_handle,jint conn_id,jbyteArray val)1603 static void gattServerSendIndicationNative(JNIEnv* env, jobject object,
1604 jint server_if, jint attr_handle,
1605 jint conn_id, jbyteArray val) {
1606 if (!sGattIf) return;
1607
1608 jbyte* array = env->GetByteArrayElements(val, 0);
1609 int val_len = env->GetArrayLength(val);
1610
1611 std::vector<uint8_t> vect_val((uint8_t*)array, (uint8_t*)array + val_len);
1612 env->ReleaseByteArrayElements(val, array, JNI_ABORT);
1613
1614 sGattIf->server->send_indication(server_if, attr_handle, conn_id,
1615 /*confirm*/ 1, std::move(vect_val));
1616 }
1617
gattServerSendNotificationNative(JNIEnv * env,jobject object,jint server_if,jint attr_handle,jint conn_id,jbyteArray val)1618 static void gattServerSendNotificationNative(JNIEnv* env, jobject object,
1619 jint server_if, jint attr_handle,
1620 jint conn_id, jbyteArray val) {
1621 if (!sGattIf) return;
1622
1623 jbyte* array = env->GetByteArrayElements(val, 0);
1624 int val_len = env->GetArrayLength(val);
1625
1626 std::vector<uint8_t> vect_val((uint8_t*)array, (uint8_t*)array + val_len);
1627 env->ReleaseByteArrayElements(val, array, JNI_ABORT);
1628
1629 sGattIf->server->send_indication(server_if, attr_handle, conn_id,
1630 /*confirm*/ 0, std::move(vect_val));
1631 }
1632
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)1633 static void gattServerSendResponseNative(JNIEnv* env, jobject object,
1634 jint server_if, jint conn_id,
1635 jint trans_id, jint status,
1636 jint handle, jint offset,
1637 jbyteArray val, jint auth_req) {
1638 if (!sGattIf) return;
1639
1640 btgatt_response_t response;
1641
1642 response.attr_value.handle = handle;
1643 response.attr_value.auth_req = auth_req;
1644 response.attr_value.offset = offset;
1645 response.attr_value.len = 0;
1646
1647 if (val != NULL) {
1648 if (env->GetArrayLength(val) < BTGATT_MAX_ATTR_LEN) {
1649 response.attr_value.len = (uint16_t)env->GetArrayLength(val);
1650 } else {
1651 android_errorWriteLog(0x534e4554, "78787521");
1652 response.attr_value.len = BTGATT_MAX_ATTR_LEN;
1653 }
1654
1655 jbyte* array = env->GetByteArrayElements(val, 0);
1656
1657 for (int i = 0; i != response.attr_value.len; ++i)
1658 response.attr_value.value[i] = (uint8_t)array[i];
1659 env->ReleaseByteArrayElements(val, array, JNI_ABORT);
1660 }
1661
1662 sGattIf->server->send_response(conn_id, trans_id, status, response);
1663 }
1664
advertiseClassInitNative(JNIEnv * env,jclass clazz)1665 static void advertiseClassInitNative(JNIEnv* env, jclass clazz) {
1666 method_onAdvertisingSetStarted =
1667 env->GetMethodID(clazz, "onAdvertisingSetStarted", "(IIII)V");
1668 method_onOwnAddressRead =
1669 env->GetMethodID(clazz, "onOwnAddressRead", "(IILjava/lang/String;)V");
1670 method_onAdvertisingEnabled =
1671 env->GetMethodID(clazz, "onAdvertisingEnabled", "(IZI)V");
1672 method_onAdvertisingDataSet =
1673 env->GetMethodID(clazz, "onAdvertisingDataSet", "(II)V");
1674 method_onScanResponseDataSet =
1675 env->GetMethodID(clazz, "onScanResponseDataSet", "(II)V");
1676 method_onAdvertisingParametersUpdated =
1677 env->GetMethodID(clazz, "onAdvertisingParametersUpdated", "(III)V");
1678 method_onPeriodicAdvertisingParametersUpdated = env->GetMethodID(
1679 clazz, "onPeriodicAdvertisingParametersUpdated", "(II)V");
1680 method_onPeriodicAdvertisingDataSet =
1681 env->GetMethodID(clazz, "onPeriodicAdvertisingDataSet", "(II)V");
1682 method_onPeriodicAdvertisingEnabled =
1683 env->GetMethodID(clazz, "onPeriodicAdvertisingEnabled", "(IZI)V");
1684 }
1685
advertiseInitializeNative(JNIEnv * env,jobject object)1686 static void advertiseInitializeNative(JNIEnv* env, jobject object) {
1687 if (mAdvertiseCallbacksObj != NULL) {
1688 ALOGW("Cleaning up Advertise callback object");
1689 env->DeleteGlobalRef(mAdvertiseCallbacksObj);
1690 mAdvertiseCallbacksObj = NULL;
1691 }
1692
1693 mAdvertiseCallbacksObj = env->NewGlobalRef(object);
1694 }
1695
advertiseCleanupNative(JNIEnv * env,jobject object)1696 static void advertiseCleanupNative(JNIEnv* env, jobject object) {
1697 if (mAdvertiseCallbacksObj != NULL) {
1698 env->DeleteGlobalRef(mAdvertiseCallbacksObj);
1699 mAdvertiseCallbacksObj = NULL;
1700 }
1701 }
1702
1703 static uint32_t INTERVAL_MAX = 0xFFFFFF;
1704 // Always give controller 31.25ms difference between min and max
1705 static uint32_t INTERVAL_DELTA = 50;
1706
parseParams(JNIEnv * env,jobject i)1707 static AdvertiseParameters parseParams(JNIEnv* env, jobject i) {
1708 AdvertiseParameters p;
1709
1710 jclass clazz = env->GetObjectClass(i);
1711 jmethodID methodId;
1712
1713 methodId = env->GetMethodID(clazz, "isConnectable", "()Z");
1714 jboolean isConnectable = env->CallBooleanMethod(i, methodId);
1715 methodId = env->GetMethodID(clazz, "isScannable", "()Z");
1716 jboolean isScannable = env->CallBooleanMethod(i, methodId);
1717 methodId = env->GetMethodID(clazz, "isLegacy", "()Z");
1718 jboolean isLegacy = env->CallBooleanMethod(i, methodId);
1719 methodId = env->GetMethodID(clazz, "isAnonymous", "()Z");
1720 jboolean isAnonymous = env->CallBooleanMethod(i, methodId);
1721 methodId = env->GetMethodID(clazz, "includeTxPower", "()Z");
1722 jboolean includeTxPower = env->CallBooleanMethod(i, methodId);
1723 methodId = env->GetMethodID(clazz, "getPrimaryPhy", "()I");
1724 uint8_t primaryPhy = env->CallIntMethod(i, methodId);
1725 methodId = env->GetMethodID(clazz, "getSecondaryPhy", "()I");
1726 uint8_t secondaryPhy = env->CallIntMethod(i, methodId);
1727 methodId = env->GetMethodID(clazz, "getInterval", "()I");
1728 uint32_t interval = env->CallIntMethod(i, methodId);
1729 methodId = env->GetMethodID(clazz, "getTxPowerLevel", "()I");
1730 int8_t txPowerLevel = env->CallIntMethod(i, methodId);
1731
1732 uint16_t props = 0;
1733 if (isConnectable) props |= 0x01;
1734 if (isScannable) props |= 0x02;
1735 if (isLegacy) props |= 0x10;
1736 if (isAnonymous) props |= 0x20;
1737 if (includeTxPower) props |= 0x40;
1738
1739 if (interval > INTERVAL_MAX - INTERVAL_DELTA) {
1740 interval = INTERVAL_MAX - INTERVAL_DELTA;
1741 }
1742
1743 p.advertising_event_properties = props;
1744 p.min_interval = interval;
1745 p.max_interval = interval + INTERVAL_DELTA;
1746 p.channel_map = 0x07; /* all channels */
1747 p.tx_power = txPowerLevel;
1748 p.primary_advertising_phy = primaryPhy;
1749 p.secondary_advertising_phy = secondaryPhy;
1750 p.scan_request_notification_enable = false;
1751 return p;
1752 }
1753
parsePeriodicParams(JNIEnv * env,jobject i)1754 static PeriodicAdvertisingParameters parsePeriodicParams(JNIEnv* env,
1755 jobject i) {
1756 PeriodicAdvertisingParameters p;
1757
1758 if (i == NULL) {
1759 p.enable = false;
1760 return p;
1761 }
1762
1763 jclass clazz = env->GetObjectClass(i);
1764 jmethodID methodId;
1765
1766 methodId = env->GetMethodID(clazz, "getIncludeTxPower", "()Z");
1767 jboolean includeTxPower = env->CallBooleanMethod(i, methodId);
1768 methodId = env->GetMethodID(clazz, "getInterval", "()I");
1769 uint16_t interval = env->CallIntMethod(i, methodId);
1770
1771 p.enable = true;
1772 p.min_interval = interval;
1773 p.max_interval = interval + 16; /* 20ms difference betwen min and max */
1774 uint16_t props = 0;
1775 if (includeTxPower) props |= 0x40;
1776 p.periodic_advertising_properties = props;
1777 return p;
1778 }
1779
ble_advertising_set_started_cb(int reg_id,uint8_t advertiser_id,int8_t tx_power,uint8_t status)1780 static void ble_advertising_set_started_cb(int reg_id, uint8_t advertiser_id,
1781 int8_t tx_power, uint8_t status) {
1782 CallbackEnv sCallbackEnv(__func__);
1783 if (!sCallbackEnv.valid()) return;
1784 sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj,
1785 method_onAdvertisingSetStarted, reg_id,
1786 advertiser_id, tx_power, status);
1787 }
1788
ble_advertising_set_timeout_cb(uint8_t advertiser_id,uint8_t status)1789 static void ble_advertising_set_timeout_cb(uint8_t advertiser_id,
1790 uint8_t status) {
1791 CallbackEnv sCallbackEnv(__func__);
1792 if (!sCallbackEnv.valid()) return;
1793 sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj,
1794 method_onAdvertisingEnabled, advertiser_id,
1795 false, status);
1796 }
1797
startAdvertisingSetNative(JNIEnv * env,jobject object,jobject parameters,jbyteArray adv_data,jbyteArray scan_resp,jobject periodic_parameters,jbyteArray periodic_data,jint duration,jint maxExtAdvEvents,jint reg_id)1798 static void startAdvertisingSetNative(JNIEnv* env, jobject object,
1799 jobject parameters, jbyteArray adv_data,
1800 jbyteArray scan_resp,
1801 jobject periodic_parameters,
1802 jbyteArray periodic_data, jint duration,
1803 jint maxExtAdvEvents, jint reg_id) {
1804 if (!sGattIf) return;
1805
1806 jbyte* scan_resp_data = env->GetByteArrayElements(scan_resp, NULL);
1807 uint16_t scan_resp_len = (uint16_t)env->GetArrayLength(scan_resp);
1808 std::vector<uint8_t> scan_resp_vec(scan_resp_data,
1809 scan_resp_data + scan_resp_len);
1810 env->ReleaseByteArrayElements(scan_resp, scan_resp_data, JNI_ABORT);
1811
1812 AdvertiseParameters params = parseParams(env, parameters);
1813 PeriodicAdvertisingParameters periodicParams =
1814 parsePeriodicParams(env, periodic_parameters);
1815
1816 jbyte* adv_data_data = env->GetByteArrayElements(adv_data, NULL);
1817 uint16_t adv_data_len = (uint16_t)env->GetArrayLength(adv_data);
1818 std::vector<uint8_t> data_vec(adv_data_data, adv_data_data + adv_data_len);
1819 env->ReleaseByteArrayElements(adv_data, adv_data_data, JNI_ABORT);
1820
1821 jbyte* periodic_data_data = env->GetByteArrayElements(periodic_data, NULL);
1822 uint16_t periodic_data_len = (uint16_t)env->GetArrayLength(periodic_data);
1823 std::vector<uint8_t> periodic_data_vec(
1824 periodic_data_data, periodic_data_data + periodic_data_len);
1825 env->ReleaseByteArrayElements(periodic_data, periodic_data_data, JNI_ABORT);
1826
1827 sGattIf->advertiser->StartAdvertisingSet(
1828 base::Bind(&ble_advertising_set_started_cb, reg_id), params, data_vec,
1829 scan_resp_vec, periodicParams, periodic_data_vec, duration,
1830 maxExtAdvEvents, base::Bind(ble_advertising_set_timeout_cb));
1831 }
1832
stopAdvertisingSetNative(JNIEnv * env,jobject object,jint advertiser_id)1833 static void stopAdvertisingSetNative(JNIEnv* env, jobject object,
1834 jint advertiser_id) {
1835 if (!sGattIf) return;
1836
1837 sGattIf->advertiser->Unregister(advertiser_id);
1838 }
1839
getOwnAddressCb(uint8_t advertiser_id,uint8_t address_type,RawAddress address)1840 static void getOwnAddressCb(uint8_t advertiser_id, uint8_t address_type,
1841 RawAddress address) {
1842 CallbackEnv sCallbackEnv(__func__);
1843 if (!sCallbackEnv.valid()) return;
1844
1845 ScopedLocalRef<jstring> addr(sCallbackEnv.get(),
1846 bdaddr2newjstr(sCallbackEnv.get(), &address));
1847 sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj, method_onOwnAddressRead,
1848 advertiser_id, address_type, addr.get());
1849 }
1850
getOwnAddressNative(JNIEnv * env,jobject object,jint advertiser_id)1851 static void getOwnAddressNative(JNIEnv* env, jobject object,
1852 jint advertiser_id) {
1853 if (!sGattIf) return;
1854 sGattIf->advertiser->GetOwnAddress(
1855 advertiser_id, base::Bind(&getOwnAddressCb, advertiser_id));
1856 }
1857
callJniCallback(jmethodID method,uint8_t advertiser_id,uint8_t status)1858 static void callJniCallback(jmethodID method, uint8_t advertiser_id,
1859 uint8_t status) {
1860 CallbackEnv sCallbackEnv(__func__);
1861 if (!sCallbackEnv.valid()) return;
1862 sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj, method, advertiser_id,
1863 status);
1864 }
1865
enableSetCb(uint8_t advertiser_id,bool enable,uint8_t status)1866 static void enableSetCb(uint8_t advertiser_id, bool enable, uint8_t status) {
1867 CallbackEnv sCallbackEnv(__func__);
1868 if (!sCallbackEnv.valid()) return;
1869 sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj,
1870 method_onAdvertisingEnabled, advertiser_id,
1871 enable, status);
1872 }
1873
enableAdvertisingSetNative(JNIEnv * env,jobject object,jint advertiser_id,jboolean enable,jint duration,jint maxExtAdvEvents)1874 static void enableAdvertisingSetNative(JNIEnv* env, jobject object,
1875 jint advertiser_id, jboolean enable,
1876 jint duration, jint maxExtAdvEvents) {
1877 if (!sGattIf) return;
1878
1879 sGattIf->advertiser->Enable(advertiser_id, enable,
1880 base::Bind(&enableSetCb, advertiser_id, enable),
1881 duration, maxExtAdvEvents,
1882 base::Bind(&enableSetCb, advertiser_id, false));
1883 }
1884
setAdvertisingDataNative(JNIEnv * env,jobject object,jint advertiser_id,jbyteArray data)1885 static void setAdvertisingDataNative(JNIEnv* env, jobject object,
1886 jint advertiser_id, jbyteArray data) {
1887 if (!sGattIf) return;
1888
1889 sGattIf->advertiser->SetData(
1890 advertiser_id, false, toVector(env, data),
1891 base::Bind(&callJniCallback, method_onAdvertisingDataSet, advertiser_id));
1892 }
1893
setScanResponseDataNative(JNIEnv * env,jobject object,jint advertiser_id,jbyteArray data)1894 static void setScanResponseDataNative(JNIEnv* env, jobject object,
1895 jint advertiser_id, jbyteArray data) {
1896 if (!sGattIf) return;
1897
1898 sGattIf->advertiser->SetData(
1899 advertiser_id, true, toVector(env, data),
1900 base::Bind(&callJniCallback, method_onScanResponseDataSet,
1901 advertiser_id));
1902 }
1903
setAdvertisingParametersNativeCb(uint8_t advertiser_id,uint8_t status,int8_t tx_power)1904 static void setAdvertisingParametersNativeCb(uint8_t advertiser_id,
1905 uint8_t status, int8_t tx_power) {
1906 CallbackEnv sCallbackEnv(__func__);
1907 if (!sCallbackEnv.valid()) return;
1908 sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj,
1909 method_onAdvertisingParametersUpdated,
1910 advertiser_id, tx_power, status);
1911 }
1912
setAdvertisingParametersNative(JNIEnv * env,jobject object,jint advertiser_id,jobject parameters)1913 static void setAdvertisingParametersNative(JNIEnv* env, jobject object,
1914 jint advertiser_id,
1915 jobject parameters) {
1916 if (!sGattIf) return;
1917
1918 AdvertiseParameters params = parseParams(env, parameters);
1919 sGattIf->advertiser->SetParameters(
1920 advertiser_id, params,
1921 base::Bind(&setAdvertisingParametersNativeCb, advertiser_id));
1922 }
1923
setPeriodicAdvertisingParametersNative(JNIEnv * env,jobject object,jint advertiser_id,jobject periodic_parameters)1924 static void setPeriodicAdvertisingParametersNative(
1925 JNIEnv* env, jobject object, jint advertiser_id,
1926 jobject periodic_parameters) {
1927 if (!sGattIf) return;
1928
1929 PeriodicAdvertisingParameters periodicParams =
1930 parsePeriodicParams(env, periodic_parameters);
1931 sGattIf->advertiser->SetPeriodicAdvertisingParameters(
1932 advertiser_id, periodicParams,
1933 base::Bind(&callJniCallback,
1934 method_onPeriodicAdvertisingParametersUpdated, advertiser_id));
1935 }
1936
setPeriodicAdvertisingDataNative(JNIEnv * env,jobject object,jint advertiser_id,jbyteArray data)1937 static void setPeriodicAdvertisingDataNative(JNIEnv* env, jobject object,
1938 jint advertiser_id,
1939 jbyteArray data) {
1940 if (!sGattIf) return;
1941
1942 sGattIf->advertiser->SetPeriodicAdvertisingData(
1943 advertiser_id, toVector(env, data),
1944 base::Bind(&callJniCallback, method_onPeriodicAdvertisingDataSet,
1945 advertiser_id));
1946 }
1947
enablePeriodicSetCb(uint8_t advertiser_id,bool enable,uint8_t status)1948 static void enablePeriodicSetCb(uint8_t advertiser_id, bool enable,
1949 uint8_t status) {
1950 CallbackEnv sCallbackEnv(__func__);
1951 if (!sCallbackEnv.valid()) return;
1952 sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj,
1953 method_onPeriodicAdvertisingEnabled,
1954 advertiser_id, enable, status);
1955 }
1956
setPeriodicAdvertisingEnableNative(JNIEnv * env,jobject object,jint advertiser_id,jboolean enable)1957 static void setPeriodicAdvertisingEnableNative(JNIEnv* env, jobject object,
1958 jint advertiser_id,
1959 jboolean enable) {
1960 if (!sGattIf) return;
1961
1962 sGattIf->advertiser->SetPeriodicAdvertisingEnable(
1963 advertiser_id, enable,
1964 base::Bind(&enablePeriodicSetCb, advertiser_id, enable));
1965 }
1966
periodicScanClassInitNative(JNIEnv * env,jclass clazz)1967 static void periodicScanClassInitNative(JNIEnv* env, jclass clazz) {
1968 method_onSyncStarted =
1969 env->GetMethodID(clazz, "onSyncStarted", "(IIIILjava/lang/String;III)V");
1970 method_onSyncReport = env->GetMethodID(clazz, "onSyncReport", "(IIII[B)V");
1971 method_onSyncLost = env->GetMethodID(clazz, "onSyncLost", "(I)V");
1972 }
1973
periodicScanInitializeNative(JNIEnv * env,jobject object)1974 static void periodicScanInitializeNative(JNIEnv* env, jobject object) {
1975 if (mPeriodicScanCallbacksObj != NULL) {
1976 ALOGW("Cleaning up periodic scan callback object");
1977 env->DeleteGlobalRef(mPeriodicScanCallbacksObj);
1978 mPeriodicScanCallbacksObj = NULL;
1979 }
1980
1981 mPeriodicScanCallbacksObj = env->NewGlobalRef(object);
1982 }
1983
periodicScanCleanupNative(JNIEnv * env,jobject object)1984 static void periodicScanCleanupNative(JNIEnv* env, jobject object) {
1985 if (mPeriodicScanCallbacksObj != NULL) {
1986 env->DeleteGlobalRef(mPeriodicScanCallbacksObj);
1987 mPeriodicScanCallbacksObj = NULL;
1988 }
1989 }
1990
onSyncStarted(int reg_id,uint8_t status,uint16_t sync_handle,uint8_t sid,uint8_t address_type,RawAddress address,uint8_t phy,uint16_t interval)1991 static void onSyncStarted(int reg_id, uint8_t status, uint16_t sync_handle,
1992 uint8_t sid, uint8_t address_type, RawAddress address,
1993 uint8_t phy, uint16_t interval) {
1994 CallbackEnv sCallbackEnv(__func__);
1995 if (!sCallbackEnv.valid()) return;
1996
1997 sCallbackEnv->CallVoidMethod(mPeriodicScanCallbacksObj, method_onSyncStarted,
1998 reg_id, sync_handle, sid, address_type, address,
1999 phy, interval, status);
2000 }
2001
onSyncReport(uint16_t sync_handle,int8_t tx_power,int8_t rssi,uint8_t data_status,std::vector<uint8_t> data)2002 static void onSyncReport(uint16_t sync_handle, int8_t tx_power, int8_t rssi,
2003 uint8_t data_status, std::vector<uint8_t> data) {
2004 CallbackEnv sCallbackEnv(__func__);
2005 if (!sCallbackEnv.valid()) return;
2006
2007 ScopedLocalRef<jbyteArray> jb(sCallbackEnv.get(),
2008 sCallbackEnv->NewByteArray(data.size()));
2009 sCallbackEnv->SetByteArrayRegion(jb.get(), 0, data.size(),
2010 (jbyte*)data.data());
2011
2012 sCallbackEnv->CallVoidMethod(mPeriodicScanCallbacksObj, method_onSyncReport,
2013 sync_handle, tx_power, rssi, data_status,
2014 jb.get());
2015 }
2016
onSyncLost(uint16_t sync_handle)2017 static void onSyncLost(uint16_t sync_handle) {
2018 CallbackEnv sCallbackEnv(__func__);
2019 if (!sCallbackEnv.valid()) return;
2020
2021 sCallbackEnv->CallVoidMethod(mPeriodicScanCallbacksObj, method_onSyncLost,
2022 sync_handle);
2023 }
2024
startSyncNative(JNIEnv * env,jobject object,jint sid,jstring address,jint skip,jint timeout,jint reg_id)2025 static void startSyncNative(JNIEnv* env, jobject object, jint sid,
2026 jstring address, jint skip, jint timeout,
2027 jint reg_id) {
2028 if (!sGattIf) return;
2029
2030 sGattIf->scanner->StartSync(sid, str2addr(env, address), skip, timeout,
2031 base::Bind(&onSyncStarted, reg_id),
2032 base::Bind(&onSyncReport),
2033 base::Bind(&onSyncLost));
2034 }
2035
stopSyncNative(int sync_handle)2036 static void stopSyncNative(int sync_handle) {
2037 if (!sGattIf) return;
2038
2039 sGattIf->scanner->StopSync(sync_handle);
2040 }
2041
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)2042 static void gattTestNative(JNIEnv* env, jobject object, jint command,
2043 jlong uuid1_lsb, jlong uuid1_msb, jstring bda1,
2044 jint p1, jint p2, jint p3, jint p4, jint p5) {
2045 if (!sGattIf) return;
2046
2047 RawAddress bt_bda1 = str2addr(env, bda1);
2048
2049 Uuid uuid1 = from_java_uuid(uuid1_msb, uuid1_lsb);
2050
2051 btgatt_test_params_t params;
2052 params.bda1 = &bt_bda1;
2053 params.uuid1 = &uuid1;
2054 params.u1 = p1;
2055 params.u2 = p2;
2056 params.u3 = p3;
2057 params.u4 = p4;
2058 params.u5 = p5;
2059 sGattIf->client->test_command(command, params);
2060 }
2061
2062 /**
2063 * JNI function definitinos
2064 */
2065
2066 // JNI functions defined in AdvertiseManager class.
2067 static JNINativeMethod sAdvertiseMethods[] = {
2068 {"classInitNative", "()V", (void*)advertiseClassInitNative},
2069 {"initializeNative", "()V", (void*)advertiseInitializeNative},
2070 {"cleanupNative", "()V", (void*)advertiseCleanupNative},
2071 {"startAdvertisingSetNative",
2072 "(Landroid/bluetooth/le/AdvertisingSetParameters;[B[BLandroid/bluetooth/"
2073 "le/PeriodicAdvertisingParameters;[BIII)V",
2074 (void*)startAdvertisingSetNative},
2075 {"getOwnAddressNative", "(I)V", (void*)getOwnAddressNative},
2076 {"stopAdvertisingSetNative", "(I)V", (void*)stopAdvertisingSetNative},
2077 {"enableAdvertisingSetNative", "(IZII)V",
2078 (void*)enableAdvertisingSetNative},
2079 {"setAdvertisingDataNative", "(I[B)V", (void*)setAdvertisingDataNative},
2080 {"setScanResponseDataNative", "(I[B)V", (void*)setScanResponseDataNative},
2081 {"setAdvertisingParametersNative",
2082 "(ILandroid/bluetooth/le/AdvertisingSetParameters;)V",
2083 (void*)setAdvertisingParametersNative},
2084 {"setPeriodicAdvertisingParametersNative",
2085 "(ILandroid/bluetooth/le/PeriodicAdvertisingParameters;)V",
2086 (void*)setPeriodicAdvertisingParametersNative},
2087 {"setPeriodicAdvertisingDataNative", "(I[B)V",
2088 (void*)setPeriodicAdvertisingDataNative},
2089 {"setPeriodicAdvertisingEnableNative", "(IZ)V",
2090 (void*)setPeriodicAdvertisingEnableNative},
2091 };
2092
2093 // JNI functions defined in PeriodicScanManager class.
2094 static JNINativeMethod sPeriodicScanMethods[] = {
2095 {"classInitNative", "()V", (void*)periodicScanClassInitNative},
2096 {"initializeNative", "()V", (void*)periodicScanInitializeNative},
2097 {"cleanupNative", "()V", (void*)periodicScanCleanupNative},
2098 {"startSyncNative", "(ILjava/lang/String;III)V", (void*)startSyncNative},
2099 {"stopSyncNative", "(I)V", (void*)stopSyncNative},
2100 };
2101
2102 // JNI functions defined in ScanManager class.
2103 static JNINativeMethod sScanMethods[] = {
2104 {"registerScannerNative", "(JJ)V", (void*)registerScannerNative},
2105 {"unregisterScannerNative", "(I)V", (void*)unregisterScannerNative},
2106 {"gattClientScanNative", "(Z)V", (void*)gattClientScanNative},
2107 // Batch scan JNI functions.
2108 {"gattClientConfigBatchScanStorageNative", "(IIII)V",
2109 (void*)gattClientConfigBatchScanStorageNative},
2110 {"gattClientStartBatchScanNative", "(IIIIII)V",
2111 (void*)gattClientStartBatchScanNative},
2112 {"gattClientStopBatchScanNative", "(I)V",
2113 (void*)gattClientStopBatchScanNative},
2114 {"gattClientReadScanReportsNative", "(II)V",
2115 (void*)gattClientReadScanReportsNative},
2116 // Scan filter JNI functions.
2117 {"gattClientScanFilterParamAddNative",
2118 "(Lcom/android/bluetooth/gatt/FilterParams;)V",
2119 (void*)gattClientScanFilterParamAddNative},
2120 {"gattClientScanFilterParamDeleteNative", "(II)V",
2121 (void*)gattClientScanFilterParamDeleteNative},
2122 {"gattClientScanFilterParamClearAllNative", "(I)V",
2123 (void*)gattClientScanFilterParamClearAllNative},
2124 {"gattClientScanFilterAddNative",
2125 "(I[Lcom/android/bluetooth/gatt/ScanFilterQueue$Entry;I)V",
2126 (void*)gattClientScanFilterAddNative},
2127 {"gattClientScanFilterClearNative", "(II)V",
2128 (void*)gattClientScanFilterClearNative},
2129 {"gattClientScanFilterEnableNative", "(IZ)V",
2130 (void*)gattClientScanFilterEnableNative},
2131 {"gattSetScanParametersNative", "(III)V",
2132 (void*)gattSetScanParametersNative},
2133 };
2134
2135 // JNI functions defined in GattService class.
2136 static JNINativeMethod sMethods[] = {
2137 {"classInitNative", "()V", (void*)classInitNative},
2138 {"initializeNative", "()V", (void*)initializeNative},
2139 {"cleanupNative", "()V", (void*)cleanupNative},
2140 {"gattClientGetDeviceTypeNative", "(Ljava/lang/String;)I",
2141 (void*)gattClientGetDeviceTypeNative},
2142 {"gattClientRegisterAppNative", "(JJ)V",
2143 (void*)gattClientRegisterAppNative},
2144 {"gattClientUnregisterAppNative", "(I)V",
2145 (void*)gattClientUnregisterAppNative},
2146 {"gattClientConnectNative", "(ILjava/lang/String;ZIZI)V",
2147 (void*)gattClientConnectNative},
2148 {"gattClientDisconnectNative", "(ILjava/lang/String;I)V",
2149 (void*)gattClientDisconnectNative},
2150 {"gattClientSetPreferredPhyNative", "(ILjava/lang/String;III)V",
2151 (void*)gattClientSetPreferredPhyNative},
2152 {"gattClientReadPhyNative", "(ILjava/lang/String;)V",
2153 (void*)gattClientReadPhyNative},
2154 {"gattClientRefreshNative", "(ILjava/lang/String;)V",
2155 (void*)gattClientRefreshNative},
2156 {"gattClientSearchServiceNative", "(IZJJ)V",
2157 (void*)gattClientSearchServiceNative},
2158 {"gattClientDiscoverServiceByUuidNative", "(IJJ)V",
2159 (void*)gattClientDiscoverServiceByUuidNative},
2160 {"gattClientGetGattDbNative", "(I)V", (void*)gattClientGetGattDbNative},
2161 {"gattClientReadCharacteristicNative", "(III)V",
2162 (void*)gattClientReadCharacteristicNative},
2163 {"gattClientReadUsingCharacteristicUuidNative", "(IJJIII)V",
2164 (void*)gattClientReadUsingCharacteristicUuidNative},
2165 {"gattClientReadDescriptorNative", "(III)V",
2166 (void*)gattClientReadDescriptorNative},
2167 {"gattClientWriteCharacteristicNative", "(IIII[B)V",
2168 (void*)gattClientWriteCharacteristicNative},
2169 {"gattClientWriteDescriptorNative", "(III[B)V",
2170 (void*)gattClientWriteDescriptorNative},
2171 {"gattClientExecuteWriteNative", "(IZ)V",
2172 (void*)gattClientExecuteWriteNative},
2173 {"gattClientRegisterForNotificationsNative", "(ILjava/lang/String;IZ)V",
2174 (void*)gattClientRegisterForNotificationsNative},
2175 {"gattClientReadRemoteRssiNative", "(ILjava/lang/String;)V",
2176 (void*)gattClientReadRemoteRssiNative},
2177 {"gattClientConfigureMTUNative", "(II)V",
2178 (void*)gattClientConfigureMTUNative},
2179 {"gattConnectionParameterUpdateNative", "(ILjava/lang/String;IIIIII)V",
2180 (void*)gattConnectionParameterUpdateNative},
2181 {"gattServerRegisterAppNative", "(JJ)V",
2182 (void*)gattServerRegisterAppNative},
2183 {"gattServerUnregisterAppNative", "(I)V",
2184 (void*)gattServerUnregisterAppNative},
2185 {"gattServerConnectNative", "(ILjava/lang/String;ZI)V",
2186 (void*)gattServerConnectNative},
2187 {"gattServerDisconnectNative", "(ILjava/lang/String;I)V",
2188 (void*)gattServerDisconnectNative},
2189 {"gattServerSetPreferredPhyNative", "(ILjava/lang/String;III)V",
2190 (void*)gattServerSetPreferredPhyNative},
2191 {"gattServerReadPhyNative", "(ILjava/lang/String;)V",
2192 (void*)gattServerReadPhyNative},
2193 {"gattServerAddServiceNative", "(ILjava/util/List;)V",
2194 (void*)gattServerAddServiceNative},
2195 {"gattServerStopServiceNative", "(II)V",
2196 (void*)gattServerStopServiceNative},
2197 {"gattServerDeleteServiceNative", "(II)V",
2198 (void*)gattServerDeleteServiceNative},
2199 {"gattServerSendIndicationNative", "(III[B)V",
2200 (void*)gattServerSendIndicationNative},
2201 {"gattServerSendNotificationNative", "(III[B)V",
2202 (void*)gattServerSendNotificationNative},
2203 {"gattServerSendResponseNative", "(IIIIII[BI)V",
2204 (void*)gattServerSendResponseNative},
2205
2206 {"gattTestNative", "(IJJLjava/lang/String;IIIII)V", (void*)gattTestNative},
2207 };
2208
register_com_android_bluetooth_gatt(JNIEnv * env)2209 int register_com_android_bluetooth_gatt(JNIEnv* env) {
2210 int register_success = jniRegisterNativeMethods(
2211 env, "com/android/bluetooth/gatt/ScanManager$ScanNative", sScanMethods,
2212 NELEM(sScanMethods));
2213 register_success &= jniRegisterNativeMethods(
2214 env, "com/android/bluetooth/gatt/AdvertiseManager", sAdvertiseMethods,
2215 NELEM(sAdvertiseMethods));
2216 register_success &= jniRegisterNativeMethods(
2217 env, "com/android/bluetooth/gatt/PeriodicScanManager",
2218 sPeriodicScanMethods, NELEM(sPeriodicScanMethods));
2219 return register_success &
2220 jniRegisterNativeMethods(env, "com/android/bluetooth/gatt/GattService",
2221 sMethods, NELEM(sMethods));
2222 }
2223 } // namespace android
2224