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 #include <base/functional/bind.h>
20 #include <base/functional/callback.h>
21 #include <bluetooth/log.h>
22 #include <jni.h>
23 #include <nativehelper/JNIHelp.h>
24 #include <nativehelper/scoped_local_ref.h>
25
26 #include <array>
27 #include <cerrno>
28 #include <cstdint>
29 #include <cstdio>
30 #include <cstring>
31 #include <functional>
32 #include <memory>
33 #include <mutex>
34 #include <shared_mutex>
35 #include <string>
36 #include <utility>
37 #include <vector>
38
39 #include "com_android_bluetooth.h"
40 #include "com_android_bluetooth_flags.h"
41 #include "hardware/ble_advertiser.h"
42 #include "hardware/ble_scanner.h"
43 #include "hardware/bluetooth.h"
44 #include "hardware/bt_common_types.h"
45 #include "hardware/bt_gatt.h"
46 #include "hardware/bt_gatt_client.h"
47 #include "hardware/bt_gatt_server.h"
48 #include "hardware/bt_gatt_types.h"
49 #include "hardware/distance_measurement_interface.h"
50 #include "main/shim/le_scanning_manager.h"
51 #include "rust/cxx.h"
52 #include "src/gatt/ffi.rs.h"
53 #include "types/bluetooth/uuid.h"
54 #include "types/raw_address.h"
55
56 // TODO(b/369381361) Enfore -Wmissing-prototypes
57 #pragma GCC diagnostic ignored "-Wmissing-prototypes"
58
59 using bluetooth::Uuid;
60
61 #define UUID_PARAMS(uuid) uuid_lsb(uuid), uuid_msb(uuid)
62
from_java_uuid(jlong uuid_msb,jlong uuid_lsb)63 static Uuid from_java_uuid(jlong uuid_msb, jlong uuid_lsb) {
64 std::array<uint8_t, Uuid::kNumBytes128> uu;
65 for (int i = 0; i < 8; i++) {
66 uu[7 - i] = (uuid_msb >> (8 * i)) & 0xFF;
67 uu[15 - i] = (uuid_lsb >> (8 * i)) & 0xFF;
68 }
69 return Uuid::From128BitBE(uu);
70 }
71
uuid_lsb(const Uuid & uuid)72 static uint64_t uuid_lsb(const Uuid& uuid) {
73 uint64_t lsb = 0;
74
75 auto uu = uuid.To128BitBE();
76 for (int i = 8; i <= 15; i++) {
77 lsb <<= 8;
78 lsb |= uu[i];
79 }
80
81 return lsb;
82 }
83
uuid_msb(const Uuid & uuid)84 static uint64_t uuid_msb(const Uuid& uuid) {
85 uint64_t msb = 0;
86
87 auto uu = uuid.To128BitBE();
88 for (int i = 0; i <= 7; i++) {
89 msb <<= 8;
90 msb |= uu[i];
91 }
92
93 return msb;
94 }
95
str2addr(JNIEnv * env,jstring address)96 static RawAddress str2addr(JNIEnv* env, jstring address) {
97 RawAddress bd_addr;
98 const char* c_address = env->GetStringUTFChars(address, NULL);
99 if (!c_address) {
100 return bd_addr;
101 }
102
103 RawAddress::FromString(std::string(c_address), bd_addr);
104 env->ReleaseStringUTFChars(address, c_address);
105
106 return bd_addr;
107 }
108
bdaddr2newjstr(JNIEnv * env,const RawAddress * bda)109 static jstring bdaddr2newjstr(JNIEnv* env, const RawAddress* bda) {
110 char c_address[32];
111 snprintf(c_address, sizeof(c_address), "%02X:%02X:%02X:%02X:%02X:%02X", bda->address[0],
112 bda->address[1], bda->address[2], bda->address[3], bda->address[4], bda->address[5]);
113
114 return env->NewStringUTF(c_address);
115 }
116
toVector(JNIEnv * env,jbyteArray ba)117 static std::vector<uint8_t> toVector(JNIEnv* env, jbyteArray ba) {
118 jbyte* data_data = env->GetByteArrayElements(ba, NULL);
119 uint16_t data_len = (uint16_t)env->GetArrayLength(ba);
120 std::vector<uint8_t> data_vec(data_data, data_data + data_len);
121 env->ReleaseByteArrayElements(ba, data_data, JNI_ABORT);
122 return data_vec;
123 }
124
125 namespace android {
126
127 /**
128 * Client callback methods
129 */
130 static jmethodID method_onClientRegistered;
131 static jmethodID method_onConnected;
132 static jmethodID method_onDisconnected;
133 static jmethodID method_onReadCharacteristic;
134 static jmethodID method_onWriteCharacteristic;
135 static jmethodID method_onExecuteCompleted;
136 static jmethodID method_onSearchCompleted;
137 static jmethodID method_onReadDescriptor;
138 static jmethodID method_onWriteDescriptor;
139 static jmethodID method_onNotify;
140 static jmethodID method_onRegisterForNotifications;
141 static jmethodID method_onReadRemoteRssi;
142 static jmethodID method_onConfigureMTU;
143 static jmethodID method_onClientCongestion;
144
145 static jmethodID method_getSampleGattDbElement;
146 static jmethodID method_onGetGattDb;
147 static jmethodID method_onClientPhyUpdate;
148 static jmethodID method_onClientPhyRead;
149 static jmethodID method_onClientConnUpdate;
150 static jmethodID method_onServiceChanged;
151 static jmethodID method_onClientSubrateChange;
152
153 /**
154 * Server callback methods
155 */
156 static jmethodID method_onServerRegistered;
157 static jmethodID method_onClientConnected;
158 static jmethodID method_onServiceAdded;
159 static jmethodID method_onServiceStopped;
160 static jmethodID method_onServiceDeleted;
161 static jmethodID method_onResponseSendCompleted;
162 static jmethodID method_onServerReadCharacteristic;
163 static jmethodID method_onServerReadDescriptor;
164 static jmethodID method_onServerWriteCharacteristic;
165 static jmethodID method_onServerWriteDescriptor;
166 static jmethodID method_onExecuteWrite;
167 static jmethodID method_onNotificationSent;
168 static jmethodID method_onServerCongestion;
169 static jmethodID method_onServerMtuChanged;
170 static jmethodID method_onServerPhyUpdate;
171 static jmethodID method_onServerPhyRead;
172 static jmethodID method_onServerConnUpdate;
173 static jmethodID method_onServerSubrateChange;
174
175 /**
176 * Advertiser callback methods
177 */
178 static jmethodID method_onAdvertisingSetStarted;
179 static jmethodID method_onOwnAddressRead;
180 static jmethodID method_onAdvertisingEnabled;
181 static jmethodID method_onAdvertisingDataSet;
182 static jmethodID method_onScanResponseDataSet;
183 static jmethodID method_onAdvertisingParametersUpdated;
184 static jmethodID method_onPeriodicAdvertisingParametersUpdated;
185 static jmethodID method_onPeriodicAdvertisingDataSet;
186 static jmethodID method_onPeriodicAdvertisingEnabled;
187
188 /**
189 * Scanner callback methods
190 */
191 static jmethodID method_onScannerRegistered;
192 static jmethodID method_onScanResult;
193 static jmethodID method_onScanFilterConfig;
194 static jmethodID method_onScanFilterParamsConfigured;
195 static jmethodID method_onScanFilterEnableDisabled;
196 static jmethodID method_onBatchScanStorageConfigured;
197 static jmethodID method_onBatchScanStartStopped;
198 static jmethodID method_onBatchScanReports;
199 static jmethodID method_onBatchScanThresholdCrossed;
200 static jmethodID method_createOnTrackAdvFoundLostObject;
201 static jmethodID method_onTrackAdvFoundLost;
202 static jmethodID method_onScanParamSetupCompleted;
203 static jmethodID method_onMsftAdvMonitorAdd;
204 static jmethodID method_onMsftAdvMonitorRemove;
205 static jmethodID method_onMsftAdvMonitorEnable;
206
207 /**
208 * Periodic scanner callback methods
209 */
210 static jmethodID method_onSyncLost;
211 static jmethodID method_onSyncReport;
212 static jmethodID method_onSyncStarted;
213 static jmethodID method_onSyncTransferredCallback;
214 static jmethodID method_onBigInfoReport;
215
216 /**
217 * Distance Measurement callback methods
218 */
219 static jmethodID method_onDistanceMeasurementStarted;
220 static jmethodID method_onDistanceMeasurementStopped;
221 static jmethodID method_onDistanceMeasurementResult;
222
223 /**
224 * Static variables
225 */
226 static const btgatt_interface_t* sGattIf = NULL;
227 /** Pointer to the LE scanner interface methods.*/
228 static BleScannerInterface* sScanner = NULL;
229 static jobject mCallbacksObj = NULL;
230 static jobject mScanCallbacksObj = NULL;
231 static jobject mAdvertiseCallbacksObj = NULL;
232 static jobject mPeriodicScanCallbacksObj = NULL;
233 static jobject mDistanceMeasurementCallbacksObj = NULL;
234 static std::shared_mutex callbacks_mutex;
235
236 /**
237 * BTA client callbacks
238 */
239
btgattc_register_app_cb(int status,int clientIf,const Uuid & app_uuid)240 void btgattc_register_app_cb(int status, int clientIf, const Uuid& app_uuid) {
241 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
242 CallbackEnv sCallbackEnv(__func__);
243 if (!sCallbackEnv.valid() || !mCallbacksObj) {
244 return;
245 }
246 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientRegistered, status, clientIf,
247 UUID_PARAMS(app_uuid));
248 }
249
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,RawAddress * original_bda)250 void btgattc_scan_result_cb(uint16_t event_type, uint8_t addr_type, RawAddress* bda,
251 uint8_t primary_phy, uint8_t secondary_phy, uint8_t advertising_sid,
252 int8_t tx_power, int8_t rssi, uint16_t periodic_adv_int,
253 std::vector<uint8_t> adv_data, RawAddress* original_bda) {
254 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
255 CallbackEnv sCallbackEnv(__func__);
256 if (!sCallbackEnv.valid() || !mScanCallbacksObj) {
257 return;
258 }
259
260 ScopedLocalRef<jstring> address(sCallbackEnv.get(), bdaddr2newjstr(sCallbackEnv.get(), bda));
261 ScopedLocalRef<jbyteArray> jb(sCallbackEnv.get(), sCallbackEnv->NewByteArray(adv_data.size()));
262 sCallbackEnv->SetByteArrayRegion(jb.get(), 0, adv_data.size(), (jbyte*)adv_data.data());
263
264 ScopedLocalRef<jstring> original_address(sCallbackEnv.get(),
265 bdaddr2newjstr(sCallbackEnv.get(), original_bda));
266
267 sCallbackEnv->CallVoidMethod(mScanCallbacksObj, method_onScanResult, event_type, addr_type,
268 address.get(), primary_phy, secondary_phy, advertising_sid, tx_power,
269 rssi, periodic_adv_int, jb.get(), original_address.get());
270 }
271
btgattc_open_cb(int conn_id,int status,int clientIf,const RawAddress & bda)272 void btgattc_open_cb(int conn_id, int status, int clientIf, const RawAddress& bda) {
273 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
274 CallbackEnv sCallbackEnv(__func__);
275 if (!sCallbackEnv.valid() || !mCallbacksObj) {
276 return;
277 }
278
279 ScopedLocalRef<jstring> address(sCallbackEnv.get(), bdaddr2newjstr(sCallbackEnv.get(), &bda));
280 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnected, clientIf, conn_id, status,
281 address.get());
282 }
283
btgattc_close_cb(int conn_id,int status,int clientIf,const RawAddress & bda)284 void btgattc_close_cb(int conn_id, int status, int clientIf, const RawAddress& bda) {
285 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
286 CallbackEnv sCallbackEnv(__func__);
287 if (!sCallbackEnv.valid() || !mCallbacksObj) {
288 return;
289 }
290
291 ScopedLocalRef<jstring> address(sCallbackEnv.get(), bdaddr2newjstr(sCallbackEnv.get(), &bda));
292 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onDisconnected, clientIf, conn_id, status,
293 address.get());
294 }
295
btgattc_search_complete_cb(int conn_id,int status)296 void btgattc_search_complete_cb(int conn_id, int status) {
297 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
298 CallbackEnv sCallbackEnv(__func__);
299 if (!sCallbackEnv.valid() || !mCallbacksObj) {
300 return;
301 }
302
303 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onSearchCompleted, conn_id, status);
304 }
305
btgattc_register_for_notification_cb(int conn_id,int registered,int status,uint16_t handle)306 void btgattc_register_for_notification_cb(int conn_id, int registered, int status,
307 uint16_t handle) {
308 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
309 CallbackEnv sCallbackEnv(__func__);
310 if (!sCallbackEnv.valid() || !mCallbacksObj) {
311 return;
312 }
313
314 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onRegisterForNotifications, conn_id, status,
315 registered, handle);
316 }
317
btgattc_notify_cb(int conn_id,const btgatt_notify_params_t & p_data)318 void btgattc_notify_cb(int conn_id, const btgatt_notify_params_t& p_data) {
319 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
320 CallbackEnv sCallbackEnv(__func__);
321 if (!sCallbackEnv.valid() || !mCallbacksObj) {
322 return;
323 }
324
325 ScopedLocalRef<jstring> address(sCallbackEnv.get(),
326 bdaddr2newjstr(sCallbackEnv.get(), &p_data.bda));
327 ScopedLocalRef<jbyteArray> jb(sCallbackEnv.get(), sCallbackEnv->NewByteArray(p_data.len));
328 sCallbackEnv->SetByteArrayRegion(jb.get(), 0, p_data.len, (jbyte*)p_data.value);
329
330 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNotify, conn_id, address.get(),
331 p_data.handle, p_data.is_notify, jb.get());
332 }
333
btgattc_read_characteristic_cb(int conn_id,int status,const btgatt_read_params_t & p_data)334 void btgattc_read_characteristic_cb(int conn_id, int status, const btgatt_read_params_t& p_data) {
335 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
336 CallbackEnv sCallbackEnv(__func__);
337 if (!sCallbackEnv.valid() || !mCallbacksObj) {
338 return;
339 }
340
341 ScopedLocalRef<jbyteArray> jb(sCallbackEnv.get(), NULL);
342 if (status == 0) { // Success
343 jb.reset(sCallbackEnv->NewByteArray(p_data.value.len));
344 sCallbackEnv->SetByteArrayRegion(jb.get(), 0, p_data.value.len, (jbyte*)p_data.value.value);
345 } else {
346 uint8_t value = 0;
347 jb.reset(sCallbackEnv->NewByteArray(1));
348 sCallbackEnv->SetByteArrayRegion(jb.get(), 0, 1, (jbyte*)&value);
349 }
350
351 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onReadCharacteristic, conn_id, status,
352 p_data.handle, jb.get());
353 }
354
btgattc_write_characteristic_cb(int conn_id,int status,uint16_t handle,uint16_t len,const uint8_t * value)355 void btgattc_write_characteristic_cb(int conn_id, int status, uint16_t handle, uint16_t len,
356 const uint8_t* value) {
357 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
358 CallbackEnv sCallbackEnv(__func__);
359 if (!sCallbackEnv.valid() || !mCallbacksObj) {
360 return;
361 }
362
363 ScopedLocalRef<jbyteArray> jb(sCallbackEnv.get(), NULL);
364 jb.reset(sCallbackEnv->NewByteArray(len));
365 sCallbackEnv->SetByteArrayRegion(jb.get(), 0, len, (jbyte*)value);
366 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onWriteCharacteristic, conn_id, status, handle,
367 jb.get());
368 }
369
btgattc_execute_write_cb(int conn_id,int status)370 void btgattc_execute_write_cb(int conn_id, int status) {
371 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
372 CallbackEnv sCallbackEnv(__func__);
373 if (!sCallbackEnv.valid() || !mCallbacksObj) {
374 return;
375 }
376
377 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onExecuteCompleted, conn_id, status);
378 }
379
btgattc_read_descriptor_cb(int conn_id,int status,const btgatt_read_params_t & p_data)380 void btgattc_read_descriptor_cb(int conn_id, int status, const btgatt_read_params_t& p_data) {
381 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
382 CallbackEnv sCallbackEnv(__func__);
383 if (!sCallbackEnv.valid() || !mCallbacksObj) {
384 return;
385 }
386
387 ScopedLocalRef<jbyteArray> jb(sCallbackEnv.get(), NULL);
388 if (p_data.value.len != 0) {
389 jb.reset(sCallbackEnv->NewByteArray(p_data.value.len));
390 sCallbackEnv->SetByteArrayRegion(jb.get(), 0, p_data.value.len, (jbyte*)p_data.value.value);
391 } else {
392 jb.reset(sCallbackEnv->NewByteArray(1));
393 }
394
395 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onReadDescriptor, conn_id, status,
396 p_data.handle, jb.get());
397 }
398
btgattc_write_descriptor_cb(int conn_id,int status,uint16_t handle,uint16_t len,const uint8_t * value)399 void btgattc_write_descriptor_cb(int conn_id, int status, uint16_t handle, uint16_t len,
400 const uint8_t* value) {
401 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
402 CallbackEnv sCallbackEnv(__func__);
403 if (!sCallbackEnv.valid() || !mCallbacksObj) {
404 return;
405 }
406
407 ScopedLocalRef<jbyteArray> jb(sCallbackEnv.get(), NULL);
408 jb.reset(sCallbackEnv->NewByteArray(len));
409 sCallbackEnv->SetByteArrayRegion(jb.get(), 0, len, (jbyte*)value);
410 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onWriteDescriptor, conn_id, status, handle,
411 jb.get());
412 }
413
btgattc_remote_rssi_cb(int client_if,const RawAddress & bda,int rssi,int status)414 void btgattc_remote_rssi_cb(int client_if, const RawAddress& bda, int rssi, int status) {
415 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
416 CallbackEnv sCallbackEnv(__func__);
417 if (!sCallbackEnv.valid() || !mCallbacksObj) {
418 return;
419 }
420
421 ScopedLocalRef<jstring> address(sCallbackEnv.get(), bdaddr2newjstr(sCallbackEnv.get(), &bda));
422
423 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onReadRemoteRssi, client_if, address.get(),
424 rssi, status);
425 }
426
btgattc_configure_mtu_cb(int conn_id,int status,int mtu)427 void btgattc_configure_mtu_cb(int conn_id, int status, int mtu) {
428 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
429 CallbackEnv sCallbackEnv(__func__);
430 if (!sCallbackEnv.valid() || !mCallbacksObj) {
431 return;
432 }
433 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConfigureMTU, conn_id, status, mtu);
434 }
435
btgattc_congestion_cb(int conn_id,bool congested)436 void btgattc_congestion_cb(int conn_id, bool congested) {
437 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
438 CallbackEnv sCallbackEnv(__func__);
439 if (!sCallbackEnv.valid() || !mCallbacksObj) {
440 return;
441 }
442 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientCongestion, conn_id, congested);
443 }
444
btgattc_batchscan_reports_cb(int client_if,int status,int report_format,int num_records,std::vector<uint8_t> data)445 void btgattc_batchscan_reports_cb(int client_if, int status, int report_format, int num_records,
446 std::vector<uint8_t> data) {
447 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
448 CallbackEnv sCallbackEnv(__func__);
449 if (!sCallbackEnv.valid() || !mScanCallbacksObj) {
450 return;
451 }
452 ScopedLocalRef<jbyteArray> jb(sCallbackEnv.get(), sCallbackEnv->NewByteArray(data.size()));
453 sCallbackEnv->SetByteArrayRegion(jb.get(), 0, data.size(), (jbyte*)data.data());
454
455 sCallbackEnv->CallVoidMethod(mScanCallbacksObj, method_onBatchScanReports, status, client_if,
456 report_format, num_records, jb.get());
457 }
458
btgattc_batchscan_threshold_cb(int client_if)459 void btgattc_batchscan_threshold_cb(int client_if) {
460 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
461 CallbackEnv sCallbackEnv(__func__);
462 if (!sCallbackEnv.valid() || !mScanCallbacksObj) {
463 return;
464 }
465 sCallbackEnv->CallVoidMethod(mScanCallbacksObj, method_onBatchScanThresholdCrossed, client_if);
466 }
467
btgattc_track_adv_event_cb(btgatt_track_adv_info_t * p_adv_track_info)468 void btgattc_track_adv_event_cb(btgatt_track_adv_info_t* p_adv_track_info) {
469 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
470 CallbackEnv sCallbackEnv(__func__);
471 if (!sCallbackEnv.valid() || !mScanCallbacksObj) {
472 return;
473 }
474
475 ScopedLocalRef<jstring> address(sCallbackEnv.get(),
476 bdaddr2newjstr(sCallbackEnv.get(), &p_adv_track_info->bd_addr));
477
478 ScopedLocalRef<jbyteArray> jb_adv_pkt(sCallbackEnv.get(),
479 sCallbackEnv->NewByteArray(p_adv_track_info->adv_pkt_len));
480 ScopedLocalRef<jbyteArray> jb_scan_rsp(
481 sCallbackEnv.get(), sCallbackEnv->NewByteArray(p_adv_track_info->scan_rsp_len));
482
483 sCallbackEnv->SetByteArrayRegion(jb_adv_pkt.get(), 0, p_adv_track_info->adv_pkt_len,
484 (jbyte*)p_adv_track_info->p_adv_pkt_data);
485
486 sCallbackEnv->SetByteArrayRegion(jb_scan_rsp.get(), 0, p_adv_track_info->scan_rsp_len,
487 (jbyte*)p_adv_track_info->p_scan_rsp_data);
488
489 ScopedLocalRef<jobject> trackadv_obj(
490 sCallbackEnv.get(),
491 sCallbackEnv->CallObjectMethod(
492 mScanCallbacksObj, method_createOnTrackAdvFoundLostObject,
493 p_adv_track_info->client_if, p_adv_track_info->adv_pkt_len, jb_adv_pkt.get(),
494 p_adv_track_info->scan_rsp_len, jb_scan_rsp.get(), p_adv_track_info->filt_index,
495 p_adv_track_info->advertiser_state, p_adv_track_info->advertiser_info_present,
496 address.get(), p_adv_track_info->addr_type, p_adv_track_info->tx_power,
497 p_adv_track_info->rssi_value, p_adv_track_info->time_stamp));
498
499 if (NULL != trackadv_obj.get()) {
500 sCallbackEnv->CallVoidMethod(mScanCallbacksObj, method_onTrackAdvFoundLost, trackadv_obj.get());
501 }
502 }
503
fillGattDbElementArray(JNIEnv * env,jobject * array,const btgatt_db_element_t * db,int count)504 void fillGattDbElementArray(JNIEnv* env, jobject* array, const btgatt_db_element_t* db, int count) {
505 // Because JNI uses a different class loader in the callback context, we
506 // cannot simply get the class.
507 // As a workaround, we have to make sure we obtain an object of the class
508 // first, as this will cause
509 // class loader to load it.
510 ScopedLocalRef<jobject> objectForClass(
511 env, env->CallObjectMethod(mCallbacksObj, method_getSampleGattDbElement));
512 ScopedLocalRef<jclass> gattDbElementClazz(env, env->GetObjectClass(objectForClass.get()));
513
514 jmethodID gattDbElementConstructor = env->GetMethodID(gattDbElementClazz.get(), "<init>", "()V");
515
516 jmethodID arrayAdd;
517
518 const JNIJavaMethod javaMethods[] = {
519 {"add", "(Ljava/lang/Object;)Z", &arrayAdd},
520 };
521 GET_JAVA_METHODS(env, "java/util/ArrayList", javaMethods);
522
523 jmethodID uuidConstructor;
524
525 const JNIJavaMethod javaUuidMethods[] = {
526 {"<init>", "(JJ)V", &uuidConstructor},
527 };
528 GET_JAVA_METHODS(env, "java/util/UUID", javaUuidMethods);
529
530 for (int i = 0; i < count; i++) {
531 const btgatt_db_element_t& curr = db[i];
532
533 ScopedLocalRef<jobject> element(
534 env, env->NewObject(gattDbElementClazz.get(), gattDbElementConstructor));
535
536 jfieldID fid = env->GetFieldID(gattDbElementClazz.get(), "id", "I");
537 env->SetIntField(element.get(), fid, curr.id);
538
539 fid = env->GetFieldID(gattDbElementClazz.get(), "attributeHandle", "I");
540 env->SetIntField(element.get(), fid, curr.attribute_handle);
541
542 ScopedLocalRef<jclass> uuidClazz(env, env->FindClass("java/util/UUID"));
543 ScopedLocalRef<jobject> uuid(env, env->NewObject(uuidClazz.get(), uuidConstructor,
544 uuid_msb(curr.uuid), uuid_lsb(curr.uuid)));
545 fid = env->GetFieldID(gattDbElementClazz.get(), "uuid", "Ljava/util/UUID;");
546 env->SetObjectField(element.get(), fid, uuid.get());
547
548 fid = env->GetFieldID(gattDbElementClazz.get(), "type", "I");
549 env->SetIntField(element.get(), fid, curr.type);
550
551 fid = env->GetFieldID(gattDbElementClazz.get(), "attributeHandle", "I");
552 env->SetIntField(element.get(), fid, curr.attribute_handle);
553
554 fid = env->GetFieldID(gattDbElementClazz.get(), "startHandle", "I");
555 env->SetIntField(element.get(), fid, curr.start_handle);
556
557 fid = env->GetFieldID(gattDbElementClazz.get(), "endHandle", "I");
558 env->SetIntField(element.get(), fid, curr.end_handle);
559
560 fid = env->GetFieldID(gattDbElementClazz.get(), "properties", "I");
561 env->SetIntField(element.get(), fid, curr.properties);
562
563 env->CallBooleanMethod(*array, arrayAdd, element.get());
564 }
565 }
566
btgattc_get_gatt_db_cb(int conn_id,const btgatt_db_element_t * db,int count)567 void btgattc_get_gatt_db_cb(int conn_id, const btgatt_db_element_t* db, int count) {
568 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
569 CallbackEnv sCallbackEnv(__func__);
570 if (!sCallbackEnv.valid() || !mCallbacksObj) {
571 return;
572 }
573
574 jclass arrayListclazz = sCallbackEnv->FindClass("java/util/ArrayList");
575 ScopedLocalRef<jobject> array(
576 sCallbackEnv.get(),
577 sCallbackEnv->NewObject(arrayListclazz,
578 sCallbackEnv->GetMethodID(arrayListclazz, "<init>", "()V")));
579
580 jobject arrayPtr = array.get();
581 fillGattDbElementArray(sCallbackEnv.get(), &arrayPtr, db, count);
582
583 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onGetGattDb, conn_id, array.get());
584 }
585
btgattc_phy_updated_cb(int conn_id,uint8_t tx_phy,uint8_t rx_phy,uint8_t status)586 void btgattc_phy_updated_cb(int conn_id, uint8_t tx_phy, uint8_t rx_phy, uint8_t status) {
587 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
588 CallbackEnv sCallbackEnv(__func__);
589 if (!sCallbackEnv.valid() || !mCallbacksObj) {
590 return;
591 }
592
593 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientPhyUpdate, conn_id, tx_phy, rx_phy,
594 status);
595 }
596
btgattc_conn_updated_cb(int conn_id,uint16_t interval,uint16_t latency,uint16_t timeout,uint8_t status)597 void btgattc_conn_updated_cb(int conn_id, uint16_t interval, uint16_t latency, uint16_t timeout,
598 uint8_t status) {
599 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
600 CallbackEnv sCallbackEnv(__func__);
601 if (!sCallbackEnv.valid() || !mCallbacksObj) {
602 return;
603 }
604
605 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientConnUpdate, conn_id, interval, latency,
606 timeout, status);
607 }
608
btgattc_service_changed_cb(int conn_id)609 void btgattc_service_changed_cb(int conn_id) {
610 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
611 CallbackEnv sCallbackEnv(__func__);
612 if (!sCallbackEnv.valid() || !mCallbacksObj) {
613 return;
614 }
615
616 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceChanged, conn_id);
617 }
618
btgattc_subrate_change_cb(int conn_id,uint16_t subrate_factor,uint16_t latency,uint16_t cont_num,uint16_t timeout,uint8_t status)619 void btgattc_subrate_change_cb(int conn_id, uint16_t subrate_factor, uint16_t latency,
620 uint16_t cont_num, uint16_t timeout, uint8_t status) {
621 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
622 CallbackEnv sCallbackEnv(__func__);
623 if (!sCallbackEnv.valid() || !mCallbacksObj) {
624 return;
625 }
626
627 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientSubrateChange, conn_id, subrate_factor,
628 latency, cont_num, timeout, status);
629 }
630
631 static const btgatt_scanner_callbacks_t sGattScannerCallbacks = {
632 btgattc_scan_result_cb,
633 btgattc_batchscan_reports_cb,
634 btgattc_batchscan_threshold_cb,
635 btgattc_track_adv_event_cb,
636 };
637
638 static const btgatt_client_callbacks_t sGattClientCallbacks = {
639 btgattc_register_app_cb,
640 btgattc_open_cb,
641 btgattc_close_cb,
642 btgattc_search_complete_cb,
643 btgattc_register_for_notification_cb,
644 btgattc_notify_cb,
645 btgattc_read_characteristic_cb,
646 btgattc_write_characteristic_cb,
647 btgattc_read_descriptor_cb,
648 btgattc_write_descriptor_cb,
649 btgattc_execute_write_cb,
650 btgattc_remote_rssi_cb,
651 btgattc_configure_mtu_cb,
652 btgattc_congestion_cb,
653 btgattc_get_gatt_db_cb,
654 NULL, /* services_removed_cb */
655 NULL, /* services_added_cb */
656 btgattc_phy_updated_cb,
657 btgattc_conn_updated_cb,
658 btgattc_service_changed_cb,
659 btgattc_subrate_change_cb,
660 };
661
662 /**
663 * BTA server callbacks
664 */
665
btgatts_register_app_cb(int status,int server_if,const Uuid & uuid)666 void btgatts_register_app_cb(int status, int server_if, const Uuid& uuid) {
667 bluetooth::gatt::open_server(server_if);
668 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
669 CallbackEnv sCallbackEnv(__func__);
670 if (!sCallbackEnv.valid() || !mCallbacksObj) {
671 return;
672 }
673 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerRegistered, status, server_if,
674 UUID_PARAMS(uuid));
675 }
676
btgatts_connection_cb(int conn_id,int server_if,int connected,const RawAddress & bda)677 void btgatts_connection_cb(int conn_id, int server_if, int connected, const RawAddress& bda) {
678 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
679 CallbackEnv sCallbackEnv(__func__);
680 if (!sCallbackEnv.valid() || !mCallbacksObj) {
681 return;
682 }
683
684 ScopedLocalRef<jstring> address(sCallbackEnv.get(), bdaddr2newjstr(sCallbackEnv.get(), &bda));
685 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientConnected, address.get(), connected,
686 conn_id, server_if);
687 }
688
btgatts_service_added_cb(int status,int server_if,const btgatt_db_element_t * service,size_t service_count)689 void btgatts_service_added_cb(int status, int server_if, const btgatt_db_element_t* service,
690 size_t service_count) {
691 // mirror the database in rust, now that it's created.
692 if (status == 0x00 /* SUCCESS */) {
693 auto service_records = rust::Vec<bluetooth::gatt::GattRecord>();
694 for (size_t i = 0; i != service_count; ++i) {
695 auto& curr_service = service[i];
696 service_records.push_back(bluetooth::gatt::GattRecord{
697 curr_service.uuid, (bluetooth::gatt::GattRecordType)curr_service.type,
698 curr_service.attribute_handle, curr_service.properties,
699 curr_service.extended_properties, curr_service.permissions});
700 }
701 bluetooth::gatt::add_service(server_if, std::move(service_records));
702 }
703
704 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
705 CallbackEnv sCallbackEnv(__func__);
706 if (!sCallbackEnv.valid() || !mCallbacksObj) {
707 return;
708 }
709
710 jclass arrayListclazz = sCallbackEnv->FindClass("java/util/ArrayList");
711 ScopedLocalRef<jobject> array(
712 sCallbackEnv.get(),
713 sCallbackEnv->NewObject(arrayListclazz,
714 sCallbackEnv->GetMethodID(arrayListclazz, "<init>", "()V")));
715 jobject arrayPtr = array.get();
716 fillGattDbElementArray(sCallbackEnv.get(), &arrayPtr, service, service_count);
717
718 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceAdded, status, server_if,
719 array.get());
720 }
721
btgatts_service_stopped_cb(int status,int server_if,int srvc_handle)722 void btgatts_service_stopped_cb(int status, int server_if, int srvc_handle) {
723 bluetooth::gatt::remove_service(server_if, srvc_handle);
724
725 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
726 CallbackEnv sCallbackEnv(__func__);
727 if (!sCallbackEnv.valid() || !mCallbacksObj) {
728 return;
729 }
730 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceStopped, status, server_if,
731 srvc_handle);
732 }
733
btgatts_service_deleted_cb(int status,int server_if,int srvc_handle)734 void btgatts_service_deleted_cb(int status, int server_if, int srvc_handle) {
735 bluetooth::gatt::remove_service(server_if, srvc_handle);
736
737 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
738 CallbackEnv sCallbackEnv(__func__);
739 if (!sCallbackEnv.valid() || !mCallbacksObj) {
740 return;
741 }
742 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceDeleted, status, server_if,
743 srvc_handle);
744 }
745
btgatts_request_read_characteristic_cb(int conn_id,int trans_id,const RawAddress & bda,int attr_handle,int offset,bool is_long)746 void btgatts_request_read_characteristic_cb(int conn_id, int trans_id, const RawAddress& bda,
747 int attr_handle, int offset, bool is_long) {
748 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
749 CallbackEnv sCallbackEnv(__func__);
750 if (!sCallbackEnv.valid() || !mCallbacksObj) {
751 return;
752 }
753
754 ScopedLocalRef<jstring> address(sCallbackEnv.get(), bdaddr2newjstr(sCallbackEnv.get(), &bda));
755 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerReadCharacteristic, address.get(),
756 conn_id, trans_id, attr_handle, offset, is_long);
757 }
758
btgatts_request_read_descriptor_cb(int conn_id,int trans_id,const RawAddress & bda,int attr_handle,int offset,bool is_long)759 void btgatts_request_read_descriptor_cb(int conn_id, int trans_id, const RawAddress& bda,
760 int attr_handle, int offset, bool is_long) {
761 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
762 CallbackEnv sCallbackEnv(__func__);
763 if (!sCallbackEnv.valid() || !mCallbacksObj) {
764 return;
765 }
766
767 ScopedLocalRef<jstring> address(sCallbackEnv.get(), bdaddr2newjstr(sCallbackEnv.get(), &bda));
768 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerReadDescriptor, address.get(), conn_id,
769 trans_id, attr_handle, offset, is_long);
770 }
771
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,const uint8_t * value,size_t length)772 void btgatts_request_write_characteristic_cb(int conn_id, int trans_id, const RawAddress& bda,
773 int attr_handle, int offset, bool need_rsp,
774 bool is_prep, const uint8_t* value, size_t length) {
775 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
776 CallbackEnv sCallbackEnv(__func__);
777 if (!sCallbackEnv.valid() || !mCallbacksObj) {
778 return;
779 }
780
781 ScopedLocalRef<jstring> address(sCallbackEnv.get(), bdaddr2newjstr(sCallbackEnv.get(), &bda));
782 ScopedLocalRef<jbyteArray> val(sCallbackEnv.get(), sCallbackEnv->NewByteArray(length));
783 if (val.get()) {
784 sCallbackEnv->SetByteArrayRegion(val.get(), 0, length, (jbyte*)value);
785 }
786 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerWriteCharacteristic, address.get(),
787 conn_id, trans_id, attr_handle, offset, length, need_rsp, is_prep,
788 val.get());
789 }
790
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,const uint8_t * value,size_t length)791 void btgatts_request_write_descriptor_cb(int conn_id, int trans_id, const RawAddress& bda,
792 int attr_handle, int offset, bool need_rsp, bool is_prep,
793 const uint8_t* value, size_t length) {
794 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
795 CallbackEnv sCallbackEnv(__func__);
796 if (!sCallbackEnv.valid() || !mCallbacksObj) {
797 return;
798 }
799
800 ScopedLocalRef<jstring> address(sCallbackEnv.get(), bdaddr2newjstr(sCallbackEnv.get(), &bda));
801 ScopedLocalRef<jbyteArray> val(sCallbackEnv.get(), sCallbackEnv->NewByteArray(length));
802 if (val.get()) {
803 sCallbackEnv->SetByteArrayRegion(val.get(), 0, length, (jbyte*)value);
804 }
805 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerWriteDescriptor, address.get(),
806 conn_id, trans_id, attr_handle, offset, length, need_rsp, is_prep,
807 val.get());
808 }
809
btgatts_request_exec_write_cb(int conn_id,int trans_id,const RawAddress & bda,int exec_write)810 void btgatts_request_exec_write_cb(int conn_id, int trans_id, const RawAddress& bda,
811 int exec_write) {
812 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
813 CallbackEnv sCallbackEnv(__func__);
814 if (!sCallbackEnv.valid() || !mCallbacksObj) {
815 return;
816 }
817
818 ScopedLocalRef<jstring> address(sCallbackEnv.get(), bdaddr2newjstr(sCallbackEnv.get(), &bda));
819 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onExecuteWrite, address.get(), conn_id,
820 trans_id, exec_write);
821 }
822
btgatts_response_confirmation_cb(int status,int handle)823 void btgatts_response_confirmation_cb(int status, int handle) {
824 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
825 CallbackEnv sCallbackEnv(__func__);
826 if (!sCallbackEnv.valid() || !mCallbacksObj) {
827 return;
828 }
829 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onResponseSendCompleted, status, handle);
830 }
831
btgatts_indication_sent_cb(int conn_id,int status)832 void btgatts_indication_sent_cb(int conn_id, int status) {
833 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
834 CallbackEnv sCallbackEnv(__func__);
835 if (!sCallbackEnv.valid() || !mCallbacksObj) {
836 return;
837 }
838 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNotificationSent, conn_id, status);
839 }
840
btgatts_congestion_cb(int conn_id,bool congested)841 void btgatts_congestion_cb(int conn_id, bool congested) {
842 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
843 CallbackEnv sCallbackEnv(__func__);
844 if (!sCallbackEnv.valid() || !mCallbacksObj) {
845 return;
846 }
847 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerCongestion, conn_id, congested);
848 }
849
btgatts_mtu_changed_cb(int conn_id,int mtu)850 void btgatts_mtu_changed_cb(int conn_id, int mtu) {
851 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
852 CallbackEnv sCallbackEnv(__func__);
853 if (!sCallbackEnv.valid() || !mCallbacksObj) {
854 return;
855 }
856 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerMtuChanged, conn_id, mtu);
857 }
858
btgatts_phy_updated_cb(int conn_id,uint8_t tx_phy,uint8_t rx_phy,uint8_t status)859 void btgatts_phy_updated_cb(int conn_id, uint8_t tx_phy, uint8_t rx_phy, uint8_t status) {
860 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
861 CallbackEnv sCallbackEnv(__func__);
862 if (!sCallbackEnv.valid() || !mCallbacksObj) {
863 return;
864 }
865
866 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerPhyUpdate, conn_id, tx_phy, rx_phy,
867 status);
868 }
869
btgatts_conn_updated_cb(int conn_id,uint16_t interval,uint16_t latency,uint16_t timeout,uint8_t status)870 void btgatts_conn_updated_cb(int conn_id, uint16_t interval, uint16_t latency, uint16_t timeout,
871 uint8_t status) {
872 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
873 CallbackEnv sCallbackEnv(__func__);
874 if (!sCallbackEnv.valid() || !mCallbacksObj) {
875 return;
876 }
877
878 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerConnUpdate, conn_id, interval, latency,
879 timeout, status);
880 }
881
btgatts_subrate_change_cb(int conn_id,uint16_t subrate_factor,uint16_t latency,uint16_t cont_num,uint16_t timeout,uint8_t status)882 void btgatts_subrate_change_cb(int conn_id, uint16_t subrate_factor, uint16_t latency,
883 uint16_t cont_num, uint16_t timeout, uint8_t status) {
884 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
885 CallbackEnv sCallbackEnv(__func__);
886 if (!sCallbackEnv.valid() || !mCallbacksObj) {
887 return;
888 }
889
890 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerSubrateChange, conn_id, subrate_factor,
891 latency, cont_num, timeout, status);
892 }
893
894 static const btgatt_server_callbacks_t sGattServerCallbacks = {
895 btgatts_register_app_cb,
896 btgatts_connection_cb,
897 btgatts_service_added_cb,
898 btgatts_service_stopped_cb,
899 btgatts_service_deleted_cb,
900 btgatts_request_read_characteristic_cb,
901 btgatts_request_read_descriptor_cb,
902 btgatts_request_write_characteristic_cb,
903 btgatts_request_write_descriptor_cb,
904 btgatts_request_exec_write_cb,
905 btgatts_response_confirmation_cb,
906 btgatts_indication_sent_cb,
907 btgatts_congestion_cb,
908 btgatts_mtu_changed_cb,
909 btgatts_phy_updated_cb,
910 btgatts_conn_updated_cb,
911 btgatts_subrate_change_cb,
912 };
913
914 /**
915 * GATT callbacks
916 */
917
918 static const btgatt_callbacks_t sGattCallbacks = {
919 sizeof(btgatt_callbacks_t),
920 &sGattClientCallbacks,
921 &sGattServerCallbacks,
922 &sGattScannerCallbacks,
923 };
924
925 class JniAdvertisingCallbacks : AdvertisingCallbacks {
926 public:
GetInstance()927 static AdvertisingCallbacks* GetInstance() {
928 static AdvertisingCallbacks* instance = new JniAdvertisingCallbacks();
929 return instance;
930 }
931
OnAdvertisingSetStarted(int reg_id,uint8_t advertiser_id,int8_t tx_power,uint8_t status)932 void OnAdvertisingSetStarted(int reg_id, uint8_t advertiser_id, int8_t tx_power, uint8_t status) {
933 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
934 CallbackEnv sCallbackEnv(__func__);
935 if (!sCallbackEnv.valid() || mAdvertiseCallbacksObj == NULL) {
936 return;
937 }
938 sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj, method_onAdvertisingSetStarted, reg_id,
939 advertiser_id, tx_power, status);
940 }
941
OnAdvertisingEnabled(uint8_t advertiser_id,bool enable,uint8_t status)942 void OnAdvertisingEnabled(uint8_t advertiser_id, bool enable, uint8_t status) {
943 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
944 CallbackEnv sCallbackEnv(__func__);
945 if (!sCallbackEnv.valid() || mAdvertiseCallbacksObj == NULL) {
946 return;
947 }
948 sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj, method_onAdvertisingEnabled, advertiser_id,
949 enable, status);
950 }
951
OnAdvertisingDataSet(uint8_t advertiser_id,uint8_t status)952 void OnAdvertisingDataSet(uint8_t advertiser_id, uint8_t status) {
953 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
954 CallbackEnv sCallbackEnv(__func__);
955 if (!sCallbackEnv.valid() || mAdvertiseCallbacksObj == NULL) {
956 return;
957 }
958 sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj, method_onAdvertisingDataSet, advertiser_id,
959 status);
960 }
961
OnScanResponseDataSet(uint8_t advertiser_id,uint8_t status)962 void OnScanResponseDataSet(uint8_t advertiser_id, uint8_t status) {
963 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
964 CallbackEnv sCallbackEnv(__func__);
965 if (!sCallbackEnv.valid() || mAdvertiseCallbacksObj == NULL) {
966 return;
967 }
968 sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj, method_onScanResponseDataSet,
969 advertiser_id, status);
970 }
971
OnAdvertisingParametersUpdated(uint8_t advertiser_id,int8_t tx_power,uint8_t status)972 void OnAdvertisingParametersUpdated(uint8_t advertiser_id, int8_t tx_power, uint8_t status) {
973 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
974 CallbackEnv sCallbackEnv(__func__);
975 if (!sCallbackEnv.valid() || mAdvertiseCallbacksObj == NULL) {
976 return;
977 }
978 sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj, method_onAdvertisingParametersUpdated,
979 advertiser_id, tx_power, status);
980 }
981
OnPeriodicAdvertisingParametersUpdated(uint8_t advertiser_id,uint8_t status)982 void OnPeriodicAdvertisingParametersUpdated(uint8_t advertiser_id, uint8_t status) {
983 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
984 CallbackEnv sCallbackEnv(__func__);
985 if (!sCallbackEnv.valid() || mAdvertiseCallbacksObj == NULL) {
986 return;
987 }
988 sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj,
989 method_onPeriodicAdvertisingParametersUpdated, advertiser_id,
990 status);
991 }
992
OnPeriodicAdvertisingDataSet(uint8_t advertiser_id,uint8_t status)993 void OnPeriodicAdvertisingDataSet(uint8_t advertiser_id, uint8_t status) {
994 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
995 CallbackEnv sCallbackEnv(__func__);
996 if (!sCallbackEnv.valid() || mAdvertiseCallbacksObj == NULL) {
997 return;
998 }
999 sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj, method_onPeriodicAdvertisingDataSet,
1000 advertiser_id, status);
1001 }
1002
OnPeriodicAdvertisingEnabled(uint8_t advertiser_id,bool enable,uint8_t status)1003 void OnPeriodicAdvertisingEnabled(uint8_t advertiser_id, bool enable, uint8_t status) {
1004 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
1005 CallbackEnv sCallbackEnv(__func__);
1006 if (!sCallbackEnv.valid() || mAdvertiseCallbacksObj == NULL) {
1007 return;
1008 }
1009 sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj, method_onPeriodicAdvertisingEnabled,
1010 advertiser_id, enable, status);
1011 }
1012
OnOwnAddressRead(uint8_t advertiser_id,uint8_t address_type,RawAddress address)1013 void OnOwnAddressRead(uint8_t advertiser_id, uint8_t address_type, RawAddress address) {
1014 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
1015 CallbackEnv sCallbackEnv(__func__);
1016 if (!sCallbackEnv.valid() || mAdvertiseCallbacksObj == NULL) {
1017 return;
1018 }
1019
1020 ScopedLocalRef<jstring> addr(sCallbackEnv.get(), bdaddr2newjstr(sCallbackEnv.get(), &address));
1021 sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj, method_onOwnAddressRead, advertiser_id,
1022 address_type, addr.get());
1023 }
1024 };
1025
1026 class JniScanningCallbacks : ScanningCallbacks {
1027 public:
GetInstance()1028 static ScanningCallbacks* GetInstance() {
1029 static ScanningCallbacks* instance = new JniScanningCallbacks();
1030 return instance;
1031 }
1032
OnScannerRegistered(const Uuid app_uuid,uint8_t scannerId,uint8_t status)1033 void OnScannerRegistered(const Uuid app_uuid, uint8_t scannerId, uint8_t status) {
1034 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
1035 CallbackEnv sCallbackEnv(__func__);
1036 if (!sCallbackEnv.valid() || !mScanCallbacksObj) {
1037 return;
1038 }
1039 sCallbackEnv->CallVoidMethod(mScanCallbacksObj, method_onScannerRegistered, status, scannerId,
1040 UUID_PARAMS(app_uuid));
1041 }
1042
OnSetScannerParameterComplete(uint8_t scannerId,uint8_t status)1043 void OnSetScannerParameterComplete(uint8_t scannerId, uint8_t status) {
1044 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
1045 CallbackEnv sCallbackEnv(__func__);
1046 if (!sCallbackEnv.valid() || !mScanCallbacksObj) {
1047 return;
1048 }
1049 sCallbackEnv->CallVoidMethod(mScanCallbacksObj, method_onScanParamSetupCompleted, status,
1050 scannerId);
1051 }
1052
OnScanResult(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)1053 void OnScanResult(uint16_t event_type, uint8_t addr_type, RawAddress bda, uint8_t primary_phy,
1054 uint8_t secondary_phy, uint8_t advertising_sid, int8_t tx_power, int8_t rssi,
1055 uint16_t periodic_adv_int, std::vector<uint8_t> adv_data) {
1056 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
1057 CallbackEnv sCallbackEnv(__func__);
1058 if (!sCallbackEnv.valid() || !mScanCallbacksObj) {
1059 return;
1060 }
1061
1062 ScopedLocalRef<jstring> address(sCallbackEnv.get(), bdaddr2newjstr(sCallbackEnv.get(), &bda));
1063 ScopedLocalRef<jbyteArray> jb(sCallbackEnv.get(), sCallbackEnv->NewByteArray(adv_data.size()));
1064 sCallbackEnv->SetByteArrayRegion(jb.get(), 0, adv_data.size(), (jbyte*)adv_data.data());
1065
1066 // TODO(optedoblivion): Figure out original address for here, use empty
1067 // for now
1068
1069 // length of data + '\0'
1070 char empty_address[18] = "00:00:00:00:00:00";
1071 ScopedLocalRef<jstring> fake_address(sCallbackEnv.get(),
1072 sCallbackEnv->NewStringUTF(empty_address));
1073
1074 sCallbackEnv->CallVoidMethod(mScanCallbacksObj, method_onScanResult, event_type, addr_type,
1075 address.get(), primary_phy, secondary_phy, advertising_sid,
1076 tx_power, rssi, periodic_adv_int, jb.get(), fake_address.get());
1077 }
1078
OnTrackAdvFoundLost(AdvertisingTrackInfo track_info)1079 void OnTrackAdvFoundLost(AdvertisingTrackInfo track_info) {
1080 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
1081 CallbackEnv sCallbackEnv(__func__);
1082 if (!sCallbackEnv.valid() || !mScanCallbacksObj) {
1083 log::error("sCallbackEnv not valid or no mScanCallbacksObj.");
1084 return;
1085 }
1086
1087 ScopedLocalRef<jstring> address(
1088 sCallbackEnv.get(), bdaddr2newjstr(sCallbackEnv.get(), &track_info.advertiser_address));
1089
1090 ScopedLocalRef<jbyteArray> jb_adv_pkt(sCallbackEnv.get(),
1091 sCallbackEnv->NewByteArray(track_info.adv_packet_len));
1092 ScopedLocalRef<jbyteArray> jb_scan_rsp(
1093 sCallbackEnv.get(), sCallbackEnv->NewByteArray(track_info.scan_response_len));
1094
1095 sCallbackEnv->SetByteArrayRegion(jb_adv_pkt.get(), 0, track_info.adv_packet_len,
1096 (jbyte*)track_info.adv_packet.data());
1097
1098 sCallbackEnv->SetByteArrayRegion(jb_scan_rsp.get(), 0, track_info.scan_response_len,
1099 (jbyte*)track_info.scan_response.data());
1100
1101 ScopedLocalRef<jobject> trackadv_obj(
1102 sCallbackEnv.get(),
1103 sCallbackEnv->CallObjectMethod(
1104 mScanCallbacksObj, method_createOnTrackAdvFoundLostObject,
1105 track_info.scanner_id, track_info.adv_packet_len, jb_adv_pkt.get(),
1106 track_info.scan_response_len, jb_scan_rsp.get(), track_info.filter_index,
1107 track_info.advertiser_state, track_info.advertiser_info_present, address.get(),
1108 track_info.advertiser_address_type, track_info.tx_power, track_info.rssi,
1109 track_info.time_stamp));
1110
1111 if (NULL != trackadv_obj.get()) {
1112 sCallbackEnv->CallVoidMethod(mScanCallbacksObj, method_onTrackAdvFoundLost,
1113 trackadv_obj.get());
1114 }
1115 }
1116
OnBatchScanReports(int client_if,int status,int report_format,int num_records,std::vector<uint8_t> data)1117 void OnBatchScanReports(int client_if, int status, int report_format, int num_records,
1118 std::vector<uint8_t> data) {
1119 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
1120 CallbackEnv sCallbackEnv(__func__);
1121 if (!sCallbackEnv.valid() || !mScanCallbacksObj) {
1122 return;
1123 }
1124 ScopedLocalRef<jbyteArray> jb(sCallbackEnv.get(), sCallbackEnv->NewByteArray(data.size()));
1125 sCallbackEnv->SetByteArrayRegion(jb.get(), 0, data.size(), (jbyte*)data.data());
1126
1127 sCallbackEnv->CallVoidMethod(mScanCallbacksObj, method_onBatchScanReports, status, client_if,
1128 report_format, num_records, jb.get());
1129 }
1130
OnBatchScanThresholdCrossed(int client_if)1131 void OnBatchScanThresholdCrossed(int client_if) {
1132 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
1133 CallbackEnv sCallbackEnv(__func__);
1134 if (!sCallbackEnv.valid() || !mScanCallbacksObj) {
1135 return;
1136 }
1137 sCallbackEnv->CallVoidMethod(mScanCallbacksObj, method_onBatchScanThresholdCrossed, client_if);
1138 }
1139
OnPeriodicSyncStarted(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)1140 void OnPeriodicSyncStarted(int reg_id, uint8_t status, uint16_t sync_handle, uint8_t sid,
1141 uint8_t address_type, RawAddress address, uint8_t phy,
1142 uint16_t interval) override {
1143 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
1144 CallbackEnv sCallbackEnv(__func__);
1145 if (!sCallbackEnv.valid()) {
1146 return;
1147 }
1148 if (!mPeriodicScanCallbacksObj) {
1149 log::error("mPeriodicScanCallbacksObj is NULL. Return.");
1150 return;
1151 }
1152 ScopedLocalRef<jstring> addr(sCallbackEnv.get(), bdaddr2newjstr(sCallbackEnv.get(), &address));
1153
1154 sCallbackEnv->CallVoidMethod(mPeriodicScanCallbacksObj, method_onSyncStarted, reg_id,
1155 sync_handle, sid, address_type, addr.get(), phy, interval, status);
1156 }
1157
OnPeriodicSyncReport(uint16_t sync_handle,int8_t tx_power,int8_t rssi,uint8_t data_status,std::vector<uint8_t> data)1158 void OnPeriodicSyncReport(uint16_t sync_handle, int8_t tx_power, int8_t rssi, uint8_t data_status,
1159 std::vector<uint8_t> data) override {
1160 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
1161 CallbackEnv sCallbackEnv(__func__);
1162 if (!sCallbackEnv.valid() || !mPeriodicScanCallbacksObj) {
1163 return;
1164 }
1165
1166 ScopedLocalRef<jbyteArray> jb(sCallbackEnv.get(), sCallbackEnv->NewByteArray(data.size()));
1167 sCallbackEnv->SetByteArrayRegion(jb.get(), 0, data.size(), (jbyte*)data.data());
1168
1169 sCallbackEnv->CallVoidMethod(mPeriodicScanCallbacksObj, method_onSyncReport, sync_handle,
1170 tx_power, rssi, data_status, jb.get());
1171 }
1172
OnPeriodicSyncLost(uint16_t sync_handle)1173 void OnPeriodicSyncLost(uint16_t sync_handle) override {
1174 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
1175 CallbackEnv sCallbackEnv(__func__);
1176 if (!sCallbackEnv.valid() || !mPeriodicScanCallbacksObj) {
1177 return;
1178 }
1179
1180 sCallbackEnv->CallVoidMethod(mPeriodicScanCallbacksObj, method_onSyncLost, sync_handle);
1181 }
1182
OnPeriodicSyncTransferred(int pa_source,uint8_t status,RawAddress address)1183 void OnPeriodicSyncTransferred(int pa_source, uint8_t status, RawAddress address) override {
1184 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
1185 CallbackEnv sCallbackEnv(__func__);
1186 if (!sCallbackEnv.valid()) {
1187 return;
1188 }
1189 if (!mPeriodicScanCallbacksObj) {
1190 log::error("mPeriodicScanCallbacksObj is NULL. Return.");
1191 return;
1192 }
1193 ScopedLocalRef<jstring> addr(sCallbackEnv.get(), bdaddr2newjstr(sCallbackEnv.get(), &address));
1194
1195 sCallbackEnv->CallVoidMethod(mPeriodicScanCallbacksObj, method_onSyncTransferredCallback,
1196 pa_source, status, addr.get());
1197 }
1198
OnBigInfoReport(uint16_t sync_handle,bool encrypted)1199 void OnBigInfoReport(uint16_t sync_handle, bool encrypted) {
1200 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
1201 CallbackEnv sCallbackEnv(__func__);
1202 if (!sCallbackEnv.valid()) {
1203 return;
1204 }
1205
1206 if (!mPeriodicScanCallbacksObj) {
1207 log::error("mPeriodicScanCallbacksObj is NULL. Return.");
1208 return;
1209 }
1210 sCallbackEnv->CallVoidMethod(mPeriodicScanCallbacksObj, method_onBigInfoReport, sync_handle,
1211 encrypted);
1212 }
1213 };
1214
1215 class JniDistanceMeasurementCallbacks : DistanceMeasurementCallbacks {
1216 public:
GetInstance()1217 static DistanceMeasurementCallbacks* GetInstance() {
1218 static DistanceMeasurementCallbacks* instance = new JniDistanceMeasurementCallbacks();
1219 return instance;
1220 }
1221
OnDistanceMeasurementStarted(RawAddress address,uint8_t method)1222 void OnDistanceMeasurementStarted(RawAddress address, uint8_t method) {
1223 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
1224 CallbackEnv sCallbackEnv(__func__);
1225 if (!sCallbackEnv.valid() || !mDistanceMeasurementCallbacksObj) {
1226 return;
1227 }
1228 ScopedLocalRef<jstring> addr(sCallbackEnv.get(), bdaddr2newjstr(sCallbackEnv.get(), &address));
1229 sCallbackEnv->CallVoidMethod(mDistanceMeasurementCallbacksObj,
1230 method_onDistanceMeasurementStarted, addr.get(), method);
1231 }
1232
OnDistanceMeasurementStopped(RawAddress address,uint8_t reason,uint8_t method)1233 void OnDistanceMeasurementStopped(RawAddress address, uint8_t reason, uint8_t method) {
1234 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
1235 CallbackEnv sCallbackEnv(__func__);
1236 if (!sCallbackEnv.valid() || !mDistanceMeasurementCallbacksObj) {
1237 return;
1238 }
1239 ScopedLocalRef<jstring> addr(sCallbackEnv.get(), bdaddr2newjstr(sCallbackEnv.get(), &address));
1240 sCallbackEnv->CallVoidMethod(mDistanceMeasurementCallbacksObj,
1241 method_onDistanceMeasurementStopped, addr.get(), reason, method);
1242 }
1243
OnDistanceMeasurementResult(RawAddress address,uint32_t centimeter,uint32_t error_centimeter,int azimuth_angle,int error_azimuth_angle,int altitude_angle,int error_altitude_angle,uint64_t elapsedRealtimeNanos,int8_t confidence_level,uint8_t method)1244 void OnDistanceMeasurementResult(RawAddress address, uint32_t centimeter,
1245 uint32_t error_centimeter, int azimuth_angle,
1246 int error_azimuth_angle, int altitude_angle,
1247 int error_altitude_angle, uint64_t elapsedRealtimeNanos,
1248 int8_t confidence_level, uint8_t method) {
1249 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
1250 CallbackEnv sCallbackEnv(__func__);
1251 if (!sCallbackEnv.valid() || !mDistanceMeasurementCallbacksObj) {
1252 return;
1253 }
1254 ScopedLocalRef<jstring> addr(sCallbackEnv.get(), bdaddr2newjstr(sCallbackEnv.get(), &address));
1255 sCallbackEnv->CallVoidMethod(
1256 mDistanceMeasurementCallbacksObj, method_onDistanceMeasurementResult, addr.get(),
1257 centimeter, error_centimeter, azimuth_angle, error_azimuth_angle, altitude_angle,
1258 error_altitude_angle, elapsedRealtimeNanos, confidence_level, method);
1259 }
1260 };
1261
1262 /**
1263 * Native function definitions
1264 */
1265 static const bt_interface_t* btIf;
1266
initializeNative(JNIEnv * env,jobject object)1267 static void initializeNative(JNIEnv* env, jobject object) {
1268 std::unique_lock<std::shared_mutex> lock(callbacks_mutex);
1269 if (btIf) {
1270 return;
1271 }
1272
1273 btIf = getBluetoothInterface();
1274 if (btIf == NULL) {
1275 log::error("Bluetooth module is not loaded");
1276 return;
1277 }
1278
1279 if (sGattIf != NULL) {
1280 log::warn("Cleaning up Bluetooth GATT Interface before initializing...");
1281 sGattIf->cleanup();
1282 sGattIf = NULL;
1283 }
1284
1285 if (mCallbacksObj != NULL) {
1286 log::warn("Cleaning up Bluetooth GATT callback object");
1287 env->DeleteGlobalRef(mCallbacksObj);
1288 mCallbacksObj = NULL;
1289 }
1290
1291 sGattIf = (btgatt_interface_t*)btIf->get_profile_interface(BT_PROFILE_GATT_ID);
1292 if (sGattIf == NULL) {
1293 log::error("Failed to get Bluetooth GATT Interface");
1294 return;
1295 }
1296
1297 bt_status_t status = sGattIf->init(&sGattCallbacks);
1298 if (status != BT_STATUS_SUCCESS) {
1299 log::error("Failed to initialize Bluetooth GATT, status: {}", bt_status_text(status));
1300 sGattIf = NULL;
1301 return;
1302 }
1303
1304 if (com::android::bluetooth::flags::scan_manager_refactor()) {
1305 log::info("Starting rust module");
1306 btIf->start_rust_module();
1307 }
1308
1309 sGattIf->advertiser->RegisterCallbacks(JniAdvertisingCallbacks::GetInstance());
1310 sGattIf->distance_measurement_manager->RegisterDistanceMeasurementCallbacks(
1311 JniDistanceMeasurementCallbacks::GetInstance());
1312
1313 mCallbacksObj = env->NewGlobalRef(object);
1314 }
1315
cleanupNative(JNIEnv * env,jobject)1316 static void cleanupNative(JNIEnv* env, jobject /* object */) {
1317 std::unique_lock<std::shared_mutex> lock(callbacks_mutex);
1318
1319 if (!btIf) {
1320 return;
1321 }
1322
1323 if (com::android::bluetooth::flags::scan_manager_refactor()) {
1324 log::info("Stopping rust module");
1325 btIf->stop_rust_module();
1326 }
1327
1328 if (sGattIf != NULL) {
1329 sGattIf->cleanup();
1330 sGattIf = NULL;
1331 }
1332
1333 if (mCallbacksObj != NULL) {
1334 env->DeleteGlobalRef(mCallbacksObj);
1335 mCallbacksObj = NULL;
1336 }
1337 btIf = NULL;
1338 }
1339
1340 /**
1341 * Native Client functions
1342 */
1343
gattClientGetDeviceTypeNative(JNIEnv * env,jobject,jstring address)1344 static int gattClientGetDeviceTypeNative(JNIEnv* env, jobject /* object */, jstring address) {
1345 if (!sGattIf) {
1346 return 0;
1347 }
1348 return sGattIf->client->get_device_type(str2addr(env, address));
1349 }
1350
gattClientRegisterAppNative(JNIEnv *,jobject,jlong app_uuid_lsb,jlong app_uuid_msb,jboolean eatt_support)1351 static void gattClientRegisterAppNative(JNIEnv* /* env */, jobject /* object */, jlong app_uuid_lsb,
1352 jlong app_uuid_msb, jboolean eatt_support) {
1353 if (!sGattIf) {
1354 return;
1355 }
1356 Uuid uuid = from_java_uuid(app_uuid_msb, app_uuid_lsb);
1357 sGattIf->client->register_client(uuid, eatt_support);
1358 }
1359
gattClientUnregisterAppNative(JNIEnv *,jobject,jint clientIf)1360 static void gattClientUnregisterAppNative(JNIEnv* /* env */, jobject /* object */, jint clientIf) {
1361 if (!sGattIf) {
1362 return;
1363 }
1364 sGattIf->client->unregister_client(clientIf);
1365 }
1366
btgattc_register_scanner_cb(const Uuid & app_uuid,uint8_t scannerId,uint8_t status)1367 void btgattc_register_scanner_cb(const Uuid& app_uuid, uint8_t scannerId, uint8_t status) {
1368 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
1369 CallbackEnv sCallbackEnv(__func__);
1370 if (!sCallbackEnv.valid() || !mScanCallbacksObj) {
1371 return;
1372 }
1373 sCallbackEnv->CallVoidMethod(mScanCallbacksObj, method_onScannerRegistered, status, scannerId,
1374 UUID_PARAMS(app_uuid));
1375 }
1376
registerScannerNative(JNIEnv *,jobject,jlong app_uuid_lsb,jlong app_uuid_msb)1377 static void registerScannerNative(JNIEnv* /* env */, jobject /* object */, jlong app_uuid_lsb,
1378 jlong app_uuid_msb) {
1379 if (!sScanner) {
1380 return;
1381 }
1382
1383 Uuid uuid = from_java_uuid(app_uuid_msb, app_uuid_lsb);
1384 sScanner->RegisterScanner(uuid, base::Bind(&btgattc_register_scanner_cb, uuid));
1385 }
1386
unregisterScannerNative(JNIEnv *,jobject,jint scanner_id)1387 static void unregisterScannerNative(JNIEnv* /* env */, jobject /* object */, jint scanner_id) {
1388 if (!sScanner) {
1389 return;
1390 }
1391
1392 sScanner->Unregister(scanner_id);
1393 }
1394
gattClientScanNative(JNIEnv *,jobject,jboolean start)1395 static void gattClientScanNative(JNIEnv* /* env */, jobject /* object */, jboolean start) {
1396 if (!sScanner) {
1397 return;
1398 }
1399 sScanner->Scan(start);
1400 }
1401
gattClientConnectNative(JNIEnv * env,jobject,jint clientif,jstring address,jint addressType,jboolean isDirect,jint transport,jboolean opportunistic,jint initiating_phys,jint preferred_mtu)1402 static void gattClientConnectNative(JNIEnv* env, jobject /* object */, jint clientif,
1403 jstring address, jint addressType, jboolean isDirect,
1404 jint transport, jboolean opportunistic, jint initiating_phys,
1405 jint preferred_mtu) {
1406 if (!sGattIf) {
1407 return;
1408 }
1409
1410 sGattIf->client->connect(clientif, str2addr(env, address), addressType, isDirect, transport,
1411 opportunistic, initiating_phys, preferred_mtu);
1412 }
1413
gattClientDisconnectNative(JNIEnv * env,jobject,jint clientIf,jstring address,jint conn_id)1414 static void gattClientDisconnectNative(JNIEnv* env, jobject /* object */, jint clientIf,
1415 jstring address, jint conn_id) {
1416 if (!sGattIf) {
1417 return;
1418 }
1419 sGattIf->client->disconnect(clientIf, str2addr(env, address), conn_id);
1420 }
1421
gattClientSetPreferredPhyNative(JNIEnv * env,jobject,jint,jstring address,jint tx_phy,jint rx_phy,jint phy_options)1422 static void gattClientSetPreferredPhyNative(JNIEnv* env, jobject /* object */, jint /* clientIf */,
1423 jstring address, jint tx_phy, jint rx_phy,
1424 jint phy_options) {
1425 if (!sGattIf) {
1426 return;
1427 }
1428 sGattIf->client->set_preferred_phy(str2addr(env, address), tx_phy, rx_phy, phy_options);
1429 }
1430
readClientPhyCb(uint8_t clientIf,RawAddress bda,uint8_t tx_phy,uint8_t rx_phy,uint8_t status)1431 static void readClientPhyCb(uint8_t clientIf, RawAddress bda, uint8_t tx_phy, uint8_t rx_phy,
1432 uint8_t status) {
1433 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
1434 CallbackEnv sCallbackEnv(__func__);
1435 if (!sCallbackEnv.valid() || !mCallbacksObj) {
1436 return;
1437 }
1438
1439 ScopedLocalRef<jstring> address(sCallbackEnv.get(), bdaddr2newjstr(sCallbackEnv.get(), &bda));
1440
1441 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientPhyRead, clientIf, address.get(),
1442 tx_phy, rx_phy, status);
1443 }
1444
gattClientReadPhyNative(JNIEnv * env,jobject,jint clientIf,jstring address)1445 static void gattClientReadPhyNative(JNIEnv* env, jobject /* object */, jint clientIf,
1446 jstring address) {
1447 if (!sGattIf) {
1448 return;
1449 }
1450
1451 RawAddress bda = str2addr(env, address);
1452 sGattIf->client->read_phy(bda, base::Bind(&readClientPhyCb, clientIf, bda));
1453 }
1454
gattClientRefreshNative(JNIEnv * env,jobject,jint clientIf,jstring address)1455 static void gattClientRefreshNative(JNIEnv* env, jobject /* object */, jint clientIf,
1456 jstring address) {
1457 if (!sGattIf) {
1458 return;
1459 }
1460
1461 sGattIf->client->refresh(clientIf, str2addr(env, address));
1462 }
1463
gattClientSearchServiceNative(JNIEnv *,jobject,jint conn_id,jboolean search_all,jlong service_uuid_lsb,jlong service_uuid_msb)1464 static void gattClientSearchServiceNative(JNIEnv* /* env */, jobject /* object */, jint conn_id,
1465 jboolean search_all, jlong service_uuid_lsb,
1466 jlong service_uuid_msb) {
1467 if (!sGattIf) {
1468 return;
1469 }
1470
1471 Uuid uuid = from_java_uuid(service_uuid_msb, service_uuid_lsb);
1472 sGattIf->client->search_service(conn_id, search_all ? 0 : &uuid);
1473 }
1474
gattClientDiscoverServiceByUuidNative(JNIEnv *,jobject,jint conn_id,jlong service_uuid_lsb,jlong service_uuid_msb)1475 static void gattClientDiscoverServiceByUuidNative(JNIEnv* /* env */, jobject /* object */,
1476 jint conn_id, jlong service_uuid_lsb,
1477 jlong service_uuid_msb) {
1478 if (!sGattIf) {
1479 return;
1480 }
1481
1482 Uuid uuid = from_java_uuid(service_uuid_msb, service_uuid_lsb);
1483 sGattIf->client->btif_gattc_discover_service_by_uuid(conn_id, uuid);
1484 }
1485
gattClientGetGattDbNative(JNIEnv *,jobject,jint conn_id)1486 static void gattClientGetGattDbNative(JNIEnv* /* env */, jobject /* object */, jint conn_id) {
1487 if (!sGattIf) {
1488 return;
1489 }
1490
1491 sGattIf->client->get_gatt_db(conn_id);
1492 }
1493
gattClientReadCharacteristicNative(JNIEnv *,jobject,jint conn_id,jint handle,jint authReq)1494 static void gattClientReadCharacteristicNative(JNIEnv* /* env */, jobject /* object */,
1495 jint conn_id, jint handle, jint authReq) {
1496 if (!sGattIf) {
1497 return;
1498 }
1499
1500 sGattIf->client->read_characteristic(conn_id, handle, authReq);
1501 }
1502
gattClientReadUsingCharacteristicUuidNative(JNIEnv *,jobject,jint conn_id,jlong uuid_lsb,jlong uuid_msb,jint s_handle,jint e_handle,jint authReq)1503 static void gattClientReadUsingCharacteristicUuidNative(JNIEnv* /* env */, jobject /* object */,
1504 jint conn_id, jlong uuid_lsb,
1505 jlong uuid_msb, jint s_handle,
1506 jint e_handle, jint authReq) {
1507 if (!sGattIf) {
1508 return;
1509 }
1510
1511 Uuid uuid = from_java_uuid(uuid_msb, uuid_lsb);
1512 sGattIf->client->read_using_characteristic_uuid(conn_id, uuid, s_handle, e_handle, authReq);
1513 }
1514
gattClientReadDescriptorNative(JNIEnv *,jobject,jint conn_id,jint handle,jint authReq)1515 static void gattClientReadDescriptorNative(JNIEnv* /* env */, jobject /* object */, jint conn_id,
1516 jint handle, jint authReq) {
1517 if (!sGattIf) {
1518 return;
1519 }
1520
1521 sGattIf->client->read_descriptor(conn_id, handle, authReq);
1522 }
1523
gattClientWriteCharacteristicNative(JNIEnv * env,jobject,jint conn_id,jint handle,jint write_type,jint auth_req,jbyteArray value)1524 static void gattClientWriteCharacteristicNative(JNIEnv* env, jobject /* object */, jint conn_id,
1525 jint handle, jint write_type, jint auth_req,
1526 jbyteArray value) {
1527 if (!sGattIf) {
1528 return;
1529 }
1530
1531 if (value == NULL) {
1532 log::warn("gattClientWriteCharacteristicNative() ignoring NULL array");
1533 return;
1534 }
1535
1536 uint16_t len = (uint16_t)env->GetArrayLength(value);
1537 jbyte* p_value = env->GetByteArrayElements(value, NULL);
1538 if (p_value == NULL) {
1539 return;
1540 }
1541
1542 sGattIf->client->write_characteristic(conn_id, handle, write_type, auth_req,
1543 reinterpret_cast<uint8_t*>(p_value), len);
1544
1545 env->ReleaseByteArrayElements(value, p_value, 0);
1546 }
1547
gattClientExecuteWriteNative(JNIEnv *,jobject,jint conn_id,jboolean execute)1548 static void gattClientExecuteWriteNative(JNIEnv* /* env */, jobject /* object */, jint conn_id,
1549 jboolean execute) {
1550 if (!sGattIf) {
1551 return;
1552 }
1553 sGattIf->client->execute_write(conn_id, execute ? 1 : 0);
1554 }
1555
gattClientWriteDescriptorNative(JNIEnv * env,jobject,jint conn_id,jint handle,jint auth_req,jbyteArray value)1556 static void gattClientWriteDescriptorNative(JNIEnv* env, jobject /* object */, jint conn_id,
1557 jint handle, jint auth_req, jbyteArray value) {
1558 if (!sGattIf) {
1559 return;
1560 }
1561
1562 if (value == NULL) {
1563 log::warn("gattClientWriteDescriptorNative() ignoring NULL array");
1564 return;
1565 }
1566
1567 uint16_t len = (uint16_t)env->GetArrayLength(value);
1568 jbyte* p_value = env->GetByteArrayElements(value, NULL);
1569 if (p_value == NULL) {
1570 return;
1571 }
1572
1573 sGattIf->client->write_descriptor(conn_id, handle, auth_req, reinterpret_cast<uint8_t*>(p_value),
1574 len);
1575
1576 env->ReleaseByteArrayElements(value, p_value, 0);
1577 }
1578
gattClientRegisterForNotificationsNative(JNIEnv * env,jobject,jint clientIf,jstring address,jint handle,jboolean enable)1579 static void gattClientRegisterForNotificationsNative(JNIEnv* env, jobject /* object */,
1580 jint clientIf, jstring address, jint handle,
1581 jboolean enable) {
1582 if (!sGattIf) {
1583 return;
1584 }
1585
1586 RawAddress bd_addr = str2addr(env, address);
1587 if (enable) {
1588 sGattIf->client->register_for_notification(clientIf, bd_addr, handle);
1589 } else {
1590 sGattIf->client->deregister_for_notification(clientIf, bd_addr, handle);
1591 }
1592 }
1593
gattClientReadRemoteRssiNative(JNIEnv * env,jobject,jint clientif,jstring address)1594 static void gattClientReadRemoteRssiNative(JNIEnv* env, jobject /* object */, jint clientif,
1595 jstring address) {
1596 if (!sGattIf) {
1597 return;
1598 }
1599
1600 sGattIf->client->read_remote_rssi(clientif, str2addr(env, address));
1601 }
1602
set_scan_params_cmpl_cb(int client_if,uint8_t status)1603 void set_scan_params_cmpl_cb(int client_if, uint8_t status) {
1604 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
1605 CallbackEnv sCallbackEnv(__func__);
1606 if (!sCallbackEnv.valid() || !mScanCallbacksObj) {
1607 return;
1608 }
1609 sCallbackEnv->CallVoidMethod(mScanCallbacksObj, method_onScanParamSetupCompleted, status,
1610 client_if);
1611 }
1612
gattSetScanParametersNative(JNIEnv *,jobject,jint client_if,jint scan_interval_unit,jint scan_window_unit,jint scan_phy)1613 static void gattSetScanParametersNative(JNIEnv* /* env */, jobject /* object */, jint client_if,
1614 jint scan_interval_unit, jint scan_window_unit,
1615 jint scan_phy) {
1616 if (!sScanner) {
1617 return;
1618 }
1619 sScanner->SetScanParameters(client_if, /* use active scan */ 0x01, scan_interval_unit,
1620 scan_window_unit, scan_phy,
1621 base::Bind(&set_scan_params_cmpl_cb, client_if));
1622 }
1623
scan_filter_param_cb(uint8_t client_if,uint8_t avbl_space,uint8_t action,uint8_t status)1624 void scan_filter_param_cb(uint8_t client_if, uint8_t avbl_space, uint8_t action, uint8_t status) {
1625 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
1626 CallbackEnv sCallbackEnv(__func__);
1627 if (!sCallbackEnv.valid() || !mScanCallbacksObj) {
1628 return;
1629 }
1630 sCallbackEnv->CallVoidMethod(mScanCallbacksObj, method_onScanFilterParamsConfigured, action,
1631 status, client_if, avbl_space);
1632 }
1633
gattClientScanFilterParamAddNative(JNIEnv * env,jobject,jobject params)1634 static void gattClientScanFilterParamAddNative(JNIEnv* env, jobject /* object */, jobject params) {
1635 if (!sScanner) {
1636 return;
1637 }
1638 const int add_scan_filter_params_action = 0;
1639 auto filt_params = std::make_unique<btgatt_filt_param_setup_t>();
1640
1641 jmethodID methodId = 0;
1642 ScopedLocalRef<jclass> filtparam(env, env->GetObjectClass(params));
1643
1644 methodId = env->GetMethodID(filtparam.get(), "getClientIf", "()I");
1645 uint8_t client_if = env->CallIntMethod(params, methodId);
1646
1647 methodId = env->GetMethodID(filtparam.get(), "getFiltIndex", "()I");
1648 uint8_t filt_index = env->CallIntMethod(params, methodId);
1649
1650 methodId = env->GetMethodID(filtparam.get(), "getFeatSeln", "()I");
1651 filt_params->feat_seln = env->CallIntMethod(params, methodId);
1652
1653 methodId = env->GetMethodID(filtparam.get(), "getListLogicType", "()I");
1654 filt_params->list_logic_type = env->CallIntMethod(params, methodId);
1655
1656 methodId = env->GetMethodID(filtparam.get(), "getFiltLogicType", "()I");
1657 filt_params->filt_logic_type = env->CallIntMethod(params, methodId);
1658
1659 methodId = env->GetMethodID(filtparam.get(), "getDelyMode", "()I");
1660 filt_params->dely_mode = env->CallIntMethod(params, methodId);
1661
1662 methodId = env->GetMethodID(filtparam.get(), "getFoundTimeout", "()I");
1663 filt_params->found_timeout = env->CallIntMethod(params, methodId);
1664
1665 methodId = env->GetMethodID(filtparam.get(), "getLostTimeout", "()I");
1666 filt_params->lost_timeout = env->CallIntMethod(params, methodId);
1667
1668 methodId = env->GetMethodID(filtparam.get(), "getFoundTimeOutCnt", "()I");
1669 filt_params->found_timeout_cnt = env->CallIntMethod(params, methodId);
1670
1671 methodId = env->GetMethodID(filtparam.get(), "getNumOfTrackEntries", "()I");
1672 filt_params->num_of_tracking_entries = env->CallIntMethod(params, methodId);
1673
1674 methodId = env->GetMethodID(filtparam.get(), "getRSSIHighValue", "()I");
1675 filt_params->rssi_high_thres = env->CallIntMethod(params, methodId);
1676
1677 methodId = env->GetMethodID(filtparam.get(), "getRSSILowValue", "()I");
1678 filt_params->rssi_low_thres = env->CallIntMethod(params, methodId);
1679
1680 sScanner->ScanFilterParamSetup(client_if, add_scan_filter_params_action, filt_index,
1681 std::move(filt_params),
1682 base::Bind(&scan_filter_param_cb, client_if));
1683 }
1684
gattClientScanFilterParamDeleteNative(JNIEnv *,jobject,jint client_if,jint filt_index)1685 static void gattClientScanFilterParamDeleteNative(JNIEnv* /* env */, jobject /* object */,
1686 jint client_if, jint filt_index) {
1687 if (!sScanner) {
1688 return;
1689 }
1690 const int delete_scan_filter_params_action = 1;
1691 sScanner->ScanFilterParamSetup(client_if, delete_scan_filter_params_action, filt_index, nullptr,
1692 base::Bind(&scan_filter_param_cb, client_if));
1693 }
1694
gattClientScanFilterParamClearAllNative(JNIEnv *,jobject,jint client_if)1695 static void gattClientScanFilterParamClearAllNative(JNIEnv* /* env */, jobject /* object */,
1696 jint client_if) {
1697 if (!sScanner) {
1698 return;
1699 }
1700 const int clear_scan_filter_params_action = 2;
1701 sScanner->ScanFilterParamSetup(client_if, clear_scan_filter_params_action, 0 /* index, unused */,
1702 nullptr, base::Bind(&scan_filter_param_cb, client_if));
1703 }
1704
scan_filter_cfg_cb(uint8_t client_if,uint8_t filt_type,uint8_t avbl_space,uint8_t action,uint8_t status)1705 static void scan_filter_cfg_cb(uint8_t client_if, uint8_t filt_type, uint8_t avbl_space,
1706 uint8_t action, uint8_t status) {
1707 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
1708 CallbackEnv sCallbackEnv(__func__);
1709 if (!sCallbackEnv.valid() || !mScanCallbacksObj) {
1710 return;
1711 }
1712 sCallbackEnv->CallVoidMethod(mScanCallbacksObj, method_onScanFilterConfig, action, status,
1713 client_if, filt_type, avbl_space);
1714 }
1715
gattClientScanFilterAddNative(JNIEnv * env,jobject,jint client_if,jobjectArray filters,jint filter_index)1716 static void gattClientScanFilterAddNative(JNIEnv* env, jobject /* object */, jint client_if,
1717 jobjectArray filters, jint filter_index) {
1718 if (!sScanner) {
1719 return;
1720 }
1721
1722 jmethodID uuidGetMsb;
1723 jmethodID uuidGetLsb;
1724
1725 const JNIJavaMethod javaMethods[] = {
1726 {"getMostSignificantBits", "()J", &uuidGetMsb},
1727 {"getLeastSignificantBits", "()J", &uuidGetLsb},
1728 };
1729 GET_JAVA_METHODS(env, "java/util/UUID", javaMethods);
1730
1731 std::vector<ApcfCommand> native_filters;
1732
1733 int numFilters = env->GetArrayLength(filters);
1734 if (numFilters == 0) {
1735 sScanner->ScanFilterAdd(filter_index, std::move(native_filters),
1736 base::Bind(&scan_filter_cfg_cb, client_if));
1737 return;
1738 }
1739
1740 jclass entryClazz = env->GetObjectClass(env->GetObjectArrayElement(filters, 0));
1741
1742 jfieldID typeFid = env->GetFieldID(entryClazz, "type", "B");
1743 jfieldID addressFid = env->GetFieldID(entryClazz, "address", "Ljava/lang/String;");
1744 jfieldID addrTypeFid = env->GetFieldID(entryClazz, "addr_type", "B");
1745 jfieldID irkTypeFid = env->GetFieldID(entryClazz, "irk", "[B");
1746 jfieldID uuidFid = env->GetFieldID(entryClazz, "uuid", "Ljava/util/UUID;");
1747 jfieldID uuidMaskFid = env->GetFieldID(entryClazz, "uuid_mask", "Ljava/util/UUID;");
1748 jfieldID nameFid = env->GetFieldID(entryClazz, "name", "Ljava/lang/String;");
1749 jfieldID companyFid = env->GetFieldID(entryClazz, "company", "I");
1750 jfieldID companyMaskFid = env->GetFieldID(entryClazz, "company_mask", "I");
1751 jfieldID adTypeFid = env->GetFieldID(entryClazz, "ad_type", "I");
1752 jfieldID dataFid = env->GetFieldID(entryClazz, "data", "[B");
1753 jfieldID dataMaskFid = env->GetFieldID(entryClazz, "data_mask", "[B");
1754 jfieldID orgFid = env->GetFieldID(entryClazz, "org_id", "I");
1755 jfieldID TDSFlagsFid = env->GetFieldID(entryClazz, "tds_flags", "I");
1756 jfieldID TDSFlagsMaskFid = env->GetFieldID(entryClazz, "tds_flags_mask", "I");
1757 jfieldID metaDataTypeFid = env->GetFieldID(entryClazz, "meta_data_type", "I");
1758 jfieldID metaDataFid = env->GetFieldID(entryClazz, "meta_data", "[B");
1759
1760 for (int i = 0; i < numFilters; ++i) {
1761 ApcfCommand curr{};
1762
1763 ScopedLocalRef<jobject> current(env, env->GetObjectArrayElement(filters, i));
1764
1765 curr.type = env->GetByteField(current.get(), typeFid);
1766
1767 ScopedLocalRef<jstring> address(env, (jstring)env->GetObjectField(current.get(), addressFid));
1768 if (address.get() != NULL) {
1769 curr.address = str2addr(env, address.get());
1770 }
1771
1772 curr.addr_type = env->GetByteField(current.get(), addrTypeFid);
1773
1774 ScopedLocalRef<jbyteArray> irkByteArray(
1775 env, (jbyteArray)env->GetObjectField(current.get(), irkTypeFid));
1776
1777 if (irkByteArray.get() != nullptr) {
1778 int len = env->GetArrayLength(irkByteArray.get());
1779 // IRK is 128 bits or 16 octets, set the bytes or zero it out
1780 if (len != 16) {
1781 log::error("Invalid IRK length '{}'; expected 16", len);
1782 jniThrowIOException(env, EINVAL);
1783 return;
1784 }
1785 jbyte* irkBytes = env->GetByteArrayElements(irkByteArray.get(), NULL);
1786 if (irkBytes == NULL) {
1787 jniThrowIOException(env, EINVAL);
1788 return;
1789 }
1790 for (int j = 0; j < len; j++) {
1791 curr.irk[j] = irkBytes[j];
1792 }
1793 }
1794
1795 ScopedLocalRef<jobject> uuid(env, env->GetObjectField(current.get(), uuidFid));
1796 if (uuid.get() != NULL) {
1797 jlong uuid_msb = env->CallLongMethod(uuid.get(), uuidGetMsb);
1798 jlong uuid_lsb = env->CallLongMethod(uuid.get(), uuidGetLsb);
1799 curr.uuid = from_java_uuid(uuid_msb, uuid_lsb);
1800 }
1801
1802 ScopedLocalRef<jobject> uuid_mask(env, env->GetObjectField(current.get(), uuidMaskFid));
1803 if (uuid.get() != NULL) {
1804 jlong uuid_msb = env->CallLongMethod(uuid_mask.get(), uuidGetMsb);
1805 jlong uuid_lsb = env->CallLongMethod(uuid_mask.get(), uuidGetLsb);
1806 curr.uuid_mask = from_java_uuid(uuid_msb, uuid_lsb);
1807 }
1808
1809 ScopedLocalRef<jstring> name(env, (jstring)env->GetObjectField(current.get(), nameFid));
1810 if (name.get() != NULL) {
1811 const char* c_name = env->GetStringUTFChars(name.get(), NULL);
1812 if (c_name != NULL && strlen(c_name) != 0) {
1813 curr.name = std::vector<uint8_t>(c_name, c_name + strlen(c_name));
1814 env->ReleaseStringUTFChars(name.get(), c_name);
1815 }
1816 }
1817
1818 curr.company = env->GetIntField(current.get(), companyFid);
1819
1820 curr.company_mask = env->GetIntField(current.get(), companyMaskFid);
1821
1822 curr.ad_type = env->GetIntField(current.get(), adTypeFid);
1823
1824 ScopedLocalRef<jbyteArray> data(env, (jbyteArray)env->GetObjectField(current.get(), dataFid));
1825 if (data.get() != NULL) {
1826 jbyte* data_array = env->GetByteArrayElements(data.get(), 0);
1827 int data_len = env->GetArrayLength(data.get());
1828 if (data_array && data_len) {
1829 curr.data = std::vector<uint8_t>(data_array, data_array + data_len);
1830 env->ReleaseByteArrayElements(data.get(), data_array, JNI_ABORT);
1831 }
1832 }
1833
1834 ScopedLocalRef<jbyteArray> data_mask(
1835 env, (jbyteArray)env->GetObjectField(current.get(), dataMaskFid));
1836 if (data_mask.get() != NULL) {
1837 jbyte* data_array = env->GetByteArrayElements(data_mask.get(), 0);
1838 int data_len = env->GetArrayLength(data_mask.get());
1839 if (data_array && data_len) {
1840 curr.data_mask = std::vector<uint8_t>(data_array, data_array + data_len);
1841 env->ReleaseByteArrayElements(data_mask.get(), data_array, JNI_ABORT);
1842 }
1843 }
1844 curr.org_id = env->GetIntField(current.get(), orgFid);
1845 curr.tds_flags = env->GetIntField(current.get(), TDSFlagsFid);
1846 curr.tds_flags_mask = env->GetIntField(current.get(), TDSFlagsMaskFid);
1847 curr.meta_data_type = env->GetIntField(current.get(), metaDataTypeFid);
1848
1849 ScopedLocalRef<jbyteArray> meta_data(
1850 env, (jbyteArray)env->GetObjectField(current.get(), metaDataFid));
1851 if (meta_data.get() != NULL) {
1852 jbyte* data_array = env->GetByteArrayElements(meta_data.get(), 0);
1853 int data_len = env->GetArrayLength(meta_data.get());
1854 if (data_array && data_len) {
1855 curr.meta_data = std::vector<uint8_t>(data_array, data_array + data_len);
1856 env->ReleaseByteArrayElements(meta_data.get(), data_array, JNI_ABORT);
1857 }
1858 }
1859
1860 native_filters.push_back(curr);
1861 }
1862
1863 sScanner->ScanFilterAdd(filter_index, std::move(native_filters),
1864 base::Bind(&scan_filter_cfg_cb, client_if));
1865 }
1866
gattClientScanFilterClearNative(JNIEnv *,jobject,jint client_if,jint filt_index)1867 static void gattClientScanFilterClearNative(JNIEnv* /* env */, jobject /* object */, jint client_if,
1868 jint filt_index) {
1869 if (!sScanner) {
1870 return;
1871 }
1872 sScanner->ScanFilterClear(filt_index, base::Bind(&scan_filter_cfg_cb, client_if));
1873 }
1874
scan_enable_cb(uint8_t client_if,uint8_t action,uint8_t status)1875 void scan_enable_cb(uint8_t client_if, uint8_t action, uint8_t status) {
1876 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
1877 CallbackEnv sCallbackEnv(__func__);
1878 if (!sCallbackEnv.valid() || !mScanCallbacksObj) {
1879 return;
1880 }
1881 sCallbackEnv->CallVoidMethod(mScanCallbacksObj, method_onScanFilterEnableDisabled, action, status,
1882 client_if);
1883 }
1884
gattClientScanFilterEnableNative(JNIEnv *,jobject,jint client_if,jboolean enable)1885 static void gattClientScanFilterEnableNative(JNIEnv* /* env */, jobject /* object */,
1886 jint client_if, jboolean enable) {
1887 if (!sScanner) {
1888 return;
1889 }
1890 sScanner->ScanFilterEnable(enable, base::Bind(&scan_enable_cb, client_if));
1891 }
1892
msft_monitor_add_cb(int filter_index,uint8_t monitor_handle,uint8_t status)1893 void msft_monitor_add_cb(int filter_index, uint8_t monitor_handle, uint8_t status) {
1894 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
1895 CallbackEnv sCallbackEnv(__func__);
1896 if (!sCallbackEnv.valid() || !mScanCallbacksObj) {
1897 return;
1898 }
1899 sCallbackEnv->CallVoidMethod(mScanCallbacksObj, method_onMsftAdvMonitorAdd, filter_index,
1900 monitor_handle, status);
1901 }
1902
msft_monitor_remove_cb(int filter_index,uint8_t status)1903 void msft_monitor_remove_cb(int filter_index, uint8_t status) {
1904 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
1905 CallbackEnv sCallbackEnv(__func__);
1906 if (!sCallbackEnv.valid() || !mScanCallbacksObj) {
1907 return;
1908 }
1909 sCallbackEnv->CallVoidMethod(mScanCallbacksObj, method_onMsftAdvMonitorRemove, filter_index,
1910 status);
1911 }
1912
msft_monitor_enable_cb(uint8_t status)1913 void msft_monitor_enable_cb(uint8_t status) {
1914 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
1915 CallbackEnv sCallbackEnv(__func__);
1916 if (!sCallbackEnv.valid() || !mScanCallbacksObj) {
1917 return;
1918 }
1919 sCallbackEnv->CallVoidMethod(mScanCallbacksObj, method_onMsftAdvMonitorEnable, status);
1920 }
1921
gattClientIsMsftSupportedNative(JNIEnv *,jobject)1922 static bool gattClientIsMsftSupportedNative(JNIEnv* /* env */, jobject /* object */) {
1923 return sScanner && sScanner->IsMsftSupported();
1924 }
1925
gattClientMsftAdvMonitorAddNative(JNIEnv * env,jobject,jobject msft_adv_monitor,jobjectArray msft_adv_monitor_patterns,jobject msft_adv_monitor_address,jint filter_index)1926 static void gattClientMsftAdvMonitorAddNative(JNIEnv* env, jobject /* object*/,
1927 jobject msft_adv_monitor,
1928 jobjectArray msft_adv_monitor_patterns,
1929 jobject msft_adv_monitor_address, jint filter_index) {
1930 if (!sScanner) {
1931 return;
1932 }
1933
1934 jclass msftAdvMonitorClazz = env->GetObjectClass(msft_adv_monitor);
1935 jfieldID rssiThresholdHighFid = env->GetFieldID(msftAdvMonitorClazz, "rssi_threshold_high", "B");
1936 jfieldID rssiThresholdLowFid = env->GetFieldID(msftAdvMonitorClazz, "rssi_threshold_low", "B");
1937 jfieldID rssiThresholdLowTimeIntervalFid =
1938 env->GetFieldID(msftAdvMonitorClazz, "rssi_threshold_low_time_interval", "B");
1939 jfieldID rssiSamplingPeriodFid =
1940 env->GetFieldID(msftAdvMonitorClazz, "rssi_sampling_period", "B");
1941 jfieldID conditionTypeFid = env->GetFieldID(msftAdvMonitorClazz, "condition_type", "B");
1942
1943 jclass msftAdvMonitorAddressClazz = env->GetObjectClass(msft_adv_monitor_address);
1944 jfieldID addrTypeFid = env->GetFieldID(msftAdvMonitorAddressClazz, "addr_type", "B");
1945 jfieldID bdAddrFid = env->GetFieldID(msftAdvMonitorAddressClazz, "bd_addr", "Ljava/lang/String;");
1946
1947 MsftAdvMonitor native_msft_adv_monitor{};
1948 ScopedLocalRef<jobject> msft_adv_monitor_object(env, msft_adv_monitor);
1949 native_msft_adv_monitor.rssi_threshold_high =
1950 env->GetByteField(msft_adv_monitor_object.get(), rssiThresholdHighFid);
1951 native_msft_adv_monitor.rssi_threshold_low =
1952 env->GetByteField(msft_adv_monitor_object.get(), rssiThresholdLowFid);
1953 native_msft_adv_monitor.rssi_threshold_low_time_interval =
1954 env->GetByteField(msft_adv_monitor_object.get(), rssiThresholdLowTimeIntervalFid);
1955 native_msft_adv_monitor.rssi_sampling_period =
1956 env->GetByteField(msft_adv_monitor_object.get(), rssiSamplingPeriodFid);
1957 native_msft_adv_monitor.condition_type =
1958 env->GetByteField(msft_adv_monitor_object.get(), conditionTypeFid);
1959
1960 MsftAdvMonitorAddress native_msft_adv_monitor_address{};
1961 ScopedLocalRef<jobject> msft_adv_monitor_address_object(env, msftAdvMonitorAddressClazz);
1962 native_msft_adv_monitor_address.addr_type =
1963 env->GetByteField(msft_adv_monitor_address_object.get(), addrTypeFid);
1964 native_msft_adv_monitor_address.bd_addr = str2addr(
1965 env, (jstring)env->GetObjectField(msft_adv_monitor_address_object.get(), bdAddrFid));
1966 native_msft_adv_monitor.addr_info = native_msft_adv_monitor_address;
1967
1968 int numPatterns = env->GetArrayLength(msft_adv_monitor_patterns);
1969 if (numPatterns == 0) {
1970 sScanner->MsftAdvMonitorAdd(std::move(native_msft_adv_monitor),
1971 base::Bind(&msft_monitor_add_cb, filter_index));
1972 return;
1973 }
1974
1975 jclass msftAdvMonitorPatternClazz =
1976 env->GetObjectClass(env->GetObjectArrayElement(msft_adv_monitor_patterns, 0));
1977 jfieldID adTypeFid = env->GetFieldID(msftAdvMonitorPatternClazz, "ad_type", "B");
1978 jfieldID startByteFid = env->GetFieldID(msftAdvMonitorPatternClazz, "start_byte", "B");
1979 jfieldID patternFid = env->GetFieldID(msftAdvMonitorPatternClazz, "pattern", "[B");
1980
1981 std::vector<MsftAdvMonitorPattern> patterns;
1982 for (int i = 0; i < numPatterns; i++) {
1983 MsftAdvMonitorPattern native_msft_adv_monitor_pattern{};
1984 ScopedLocalRef<jobject> msft_adv_monitor_pattern_object(
1985 env, env->GetObjectArrayElement(msft_adv_monitor_patterns, i));
1986 native_msft_adv_monitor_pattern.ad_type =
1987 env->GetByteField(msft_adv_monitor_pattern_object.get(), adTypeFid);
1988 native_msft_adv_monitor_pattern.start_byte =
1989 env->GetByteField(msft_adv_monitor_pattern_object.get(), startByteFid);
1990
1991 ScopedLocalRef<jbyteArray> patternByteArray(
1992 env,
1993 (jbyteArray)env->GetObjectField(msft_adv_monitor_pattern_object.get(), patternFid));
1994 if (patternByteArray.get() != nullptr) {
1995 jbyte* patternBytes = env->GetByteArrayElements(patternByteArray.get(), NULL);
1996 if (patternBytes == NULL) {
1997 jniThrowIOException(env, EINVAL);
1998 return;
1999 }
2000 for (int j = 0; j < env->GetArrayLength(patternByteArray.get()); j++) {
2001 native_msft_adv_monitor_pattern.pattern.push_back(patternBytes[j]);
2002 }
2003 }
2004
2005 patterns.push_back(native_msft_adv_monitor_pattern);
2006 }
2007 native_msft_adv_monitor.patterns = patterns;
2008
2009 sScanner->MsftAdvMonitorAdd(std::move(native_msft_adv_monitor),
2010 base::Bind(&msft_monitor_add_cb, filter_index));
2011 }
2012
gattClientMsftAdvMonitorRemoveNative(JNIEnv *,jobject,int filter_index,int monitor_handle)2013 static void gattClientMsftAdvMonitorRemoveNative(JNIEnv* /* env */, jobject /* object */,
2014 int filter_index, int monitor_handle) {
2015 if (!sScanner) {
2016 return;
2017 }
2018 sScanner->MsftAdvMonitorRemove(monitor_handle, base::Bind(&msft_monitor_remove_cb, filter_index));
2019 }
2020
gattClientMsftAdvMonitorEnableNative(JNIEnv *,jobject,jboolean enable)2021 static void gattClientMsftAdvMonitorEnableNative(JNIEnv* /* env */, jobject /* object */,
2022 jboolean enable) {
2023 if (!sScanner) {
2024 return;
2025 }
2026 sScanner->MsftAdvMonitorEnable(enable, base::Bind(&msft_monitor_enable_cb));
2027 }
2028
gattClientConfigureMTUNative(JNIEnv *,jobject,jint conn_id,jint mtu)2029 static void gattClientConfigureMTUNative(JNIEnv* /* env */, jobject /* object */, jint conn_id,
2030 jint mtu) {
2031 if (!sGattIf) {
2032 return;
2033 }
2034 sGattIf->client->configure_mtu(conn_id, mtu);
2035 }
2036
gattConnectionParameterUpdateNative(JNIEnv * env,jobject,jint,jstring address,jint min_interval,jint max_interval,jint latency,jint timeout,jint min_ce_len,jint max_ce_len)2037 static void gattConnectionParameterUpdateNative(JNIEnv* env, jobject /* object */,
2038 jint /* client_if */, jstring address,
2039 jint min_interval, jint max_interval, jint latency,
2040 jint timeout, jint min_ce_len, jint max_ce_len) {
2041 if (!sGattIf) {
2042 return;
2043 }
2044 sGattIf->client->conn_parameter_update(str2addr(env, address), min_interval, max_interval,
2045 latency, timeout, (uint16_t)min_ce_len,
2046 (uint16_t)max_ce_len);
2047 }
2048
gattSubrateRequestNative(JNIEnv * env,jobject,jint,jstring address,jint subrate_min,jint subrate_max,jint max_latency,jint cont_num,jint sup_timeout)2049 static void gattSubrateRequestNative(JNIEnv* env, jobject /* object */, jint /* client_if */,
2050 jstring address, jint subrate_min, jint subrate_max,
2051 jint max_latency, jint cont_num, jint sup_timeout) {
2052 if (!sGattIf) {
2053 return;
2054 }
2055 sGattIf->client->subrate_request(str2addr(env, address), subrate_min, subrate_max, max_latency,
2056 cont_num, sup_timeout);
2057 }
2058
batchscan_cfg_storage_cb(uint8_t client_if,uint8_t status)2059 void batchscan_cfg_storage_cb(uint8_t client_if, uint8_t status) {
2060 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
2061 CallbackEnv sCallbackEnv(__func__);
2062 if (!sCallbackEnv.valid() || !mScanCallbacksObj) {
2063 return;
2064 }
2065 sCallbackEnv->CallVoidMethod(mScanCallbacksObj, method_onBatchScanStorageConfigured, status,
2066 client_if);
2067 }
2068
gattClientConfigBatchScanStorageNative(JNIEnv *,jobject,jint client_if,jint max_full_reports_percent,jint max_trunc_reports_percent,jint notify_threshold_level_percent)2069 static void gattClientConfigBatchScanStorageNative(JNIEnv* /* env */, jobject /* object */,
2070 jint client_if, jint max_full_reports_percent,
2071 jint max_trunc_reports_percent,
2072 jint notify_threshold_level_percent) {
2073 if (!sScanner) {
2074 return;
2075 }
2076 sScanner->BatchscanConfigStorage(client_if, max_full_reports_percent, max_trunc_reports_percent,
2077 notify_threshold_level_percent,
2078 base::Bind(&batchscan_cfg_storage_cb, client_if));
2079 }
2080
batchscan_enable_cb(uint8_t client_if,uint8_t status)2081 void batchscan_enable_cb(uint8_t client_if, uint8_t status) {
2082 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
2083 CallbackEnv sCallbackEnv(__func__);
2084 if (!sCallbackEnv.valid() || !mScanCallbacksObj) {
2085 return;
2086 }
2087 sCallbackEnv->CallVoidMethod(mScanCallbacksObj, method_onBatchScanStartStopped, 0 /* unused */,
2088 status, client_if);
2089 }
2090
gattClientStartBatchScanNative(JNIEnv *,jobject,jint client_if,jint scan_mode,jint scan_interval_unit,jint scan_window_unit,jint addr_type,jint discard_rule)2091 static void gattClientStartBatchScanNative(JNIEnv* /* env */, jobject /* object */, jint client_if,
2092 jint scan_mode, jint scan_interval_unit,
2093 jint scan_window_unit, jint addr_type,
2094 jint discard_rule) {
2095 if (!sScanner) {
2096 return;
2097 }
2098 sScanner->BatchscanEnable(scan_mode, scan_interval_unit, scan_window_unit, addr_type,
2099 discard_rule, base::Bind(&batchscan_enable_cb, client_if));
2100 }
2101
gattClientStopBatchScanNative(JNIEnv *,jobject,jint client_if)2102 static void gattClientStopBatchScanNative(JNIEnv* /* env */, jobject /* object */, jint client_if) {
2103 if (!sScanner) {
2104 return;
2105 }
2106 sScanner->BatchscanDisable(base::Bind(&batchscan_enable_cb, client_if));
2107 }
2108
gattClientReadScanReportsNative(JNIEnv *,jobject,jint client_if,jint scan_type)2109 static void gattClientReadScanReportsNative(JNIEnv* /* env */, jobject /* object */, jint client_if,
2110 jint scan_type) {
2111 if (!sScanner) {
2112 return;
2113 }
2114 sScanner->BatchscanReadReports(client_if, scan_type);
2115 }
2116
2117 /**
2118 * Native server functions
2119 */
2120
gattServerRegisterAppNative(JNIEnv *,jobject,jlong app_uuid_lsb,jlong app_uuid_msb,jboolean eatt_support)2121 static void gattServerRegisterAppNative(JNIEnv* /* env */, jobject /* object */, jlong app_uuid_lsb,
2122 jlong app_uuid_msb, jboolean eatt_support) {
2123 if (!sGattIf) {
2124 return;
2125 }
2126 Uuid uuid = from_java_uuid(app_uuid_msb, app_uuid_lsb);
2127 sGattIf->server->register_server(uuid, eatt_support);
2128 }
2129
gattServerUnregisterAppNative(JNIEnv *,jobject,jint serverIf)2130 static void gattServerUnregisterAppNative(JNIEnv* /* env */, jobject /* object */, jint serverIf) {
2131 if (!sGattIf) {
2132 return;
2133 }
2134 bluetooth::gatt::close_server(serverIf);
2135 sGattIf->server->unregister_server(serverIf);
2136 }
2137
gattServerConnectNative(JNIEnv * env,jobject,jint server_if,jstring address,jint addr_type,jboolean is_direct,jint transport)2138 static void gattServerConnectNative(JNIEnv* env, jobject /* object */, jint server_if,
2139 jstring address, jint addr_type, jboolean is_direct,
2140 jint transport) {
2141 if (!sGattIf) {
2142 return;
2143 }
2144
2145 RawAddress bd_addr = str2addr(env, address);
2146 sGattIf->server->connect(server_if, bd_addr, addr_type, is_direct, transport);
2147 }
2148
gattServerDisconnectNative(JNIEnv * env,jobject,jint serverIf,jstring address,jint conn_id)2149 static void gattServerDisconnectNative(JNIEnv* env, jobject /* object */, jint serverIf,
2150 jstring address, jint conn_id) {
2151 if (!sGattIf) {
2152 return;
2153 }
2154 sGattIf->server->disconnect(serverIf, str2addr(env, address), conn_id);
2155 }
2156
gattServerSetPreferredPhyNative(JNIEnv * env,jobject,jint,jstring address,jint tx_phy,jint rx_phy,jint phy_options)2157 static void gattServerSetPreferredPhyNative(JNIEnv* env, jobject /* object */, jint /* serverIf */,
2158 jstring address, jint tx_phy, jint rx_phy,
2159 jint phy_options) {
2160 if (!sGattIf) {
2161 return;
2162 }
2163 RawAddress bda = str2addr(env, address);
2164 sGattIf->server->set_preferred_phy(bda, tx_phy, rx_phy, phy_options);
2165 }
2166
readServerPhyCb(uint8_t serverIf,RawAddress bda,uint8_t tx_phy,uint8_t rx_phy,uint8_t status)2167 static void readServerPhyCb(uint8_t serverIf, RawAddress bda, uint8_t tx_phy, uint8_t rx_phy,
2168 uint8_t status) {
2169 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
2170 CallbackEnv sCallbackEnv(__func__);
2171 if (!sCallbackEnv.valid() || !mCallbacksObj) {
2172 return;
2173 }
2174
2175 ScopedLocalRef<jstring> address(sCallbackEnv.get(), bdaddr2newjstr(sCallbackEnv.get(), &bda));
2176
2177 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerPhyRead, serverIf, address.get(),
2178 tx_phy, rx_phy, status);
2179 }
2180
gattServerReadPhyNative(JNIEnv * env,jobject,jint serverIf,jstring address)2181 static void gattServerReadPhyNative(JNIEnv* env, jobject /* object */, jint serverIf,
2182 jstring address) {
2183 if (!sGattIf) {
2184 return;
2185 }
2186
2187 RawAddress bda = str2addr(env, address);
2188 sGattIf->server->read_phy(bda, base::Bind(&readServerPhyCb, serverIf, bda));
2189 }
2190
gattServerAddServiceNative(JNIEnv * env,jobject,jint server_if,jobject gatt_db_elements)2191 static void gattServerAddServiceNative(JNIEnv* env, jobject /* object */, jint server_if,
2192 jobject gatt_db_elements) {
2193 if (!sGattIf) {
2194 return;
2195 }
2196
2197 jmethodID arrayGet;
2198 jmethodID arraySize;
2199
2200 const JNIJavaMethod javaListMethods[] = {
2201 {"get", "(I)Ljava/lang/Object;", &arrayGet},
2202 {"size", "()I", &arraySize},
2203 };
2204 GET_JAVA_METHODS(env, "java/util/List", javaListMethods);
2205
2206 int count = env->CallIntMethod(gatt_db_elements, arraySize);
2207 std::vector<btgatt_db_element_t> db;
2208
2209 jmethodID uuidGetMsb;
2210 jmethodID uuidGetLsb;
2211
2212 const JNIJavaMethod javaUuidMethods[] = {
2213 {"getMostSignificantBits", "()J", &uuidGetMsb},
2214 {"getLeastSignificantBits", "()J", &uuidGetLsb},
2215 };
2216 GET_JAVA_METHODS(env, "java/util/UUID", javaUuidMethods);
2217
2218 jobject objectForClass = env->CallObjectMethod(mCallbacksObj, method_getSampleGattDbElement);
2219 jclass gattDbElementClazz = env->GetObjectClass(objectForClass);
2220
2221 for (int i = 0; i < count; i++) {
2222 btgatt_db_element_t curr;
2223
2224 jint index = i;
2225 ScopedLocalRef<jobject> element(env, env->CallObjectMethod(gatt_db_elements, arrayGet, index));
2226
2227 jfieldID fid;
2228
2229 fid = env->GetFieldID(gattDbElementClazz, "id", "I");
2230 curr.id = env->GetIntField(element.get(), fid);
2231
2232 fid = env->GetFieldID(gattDbElementClazz, "uuid", "Ljava/util/UUID;");
2233 ScopedLocalRef<jobject> uuid(env, env->GetObjectField(element.get(), fid));
2234 if (uuid.get() != NULL) {
2235 jlong uuid_msb = env->CallLongMethod(uuid.get(), uuidGetMsb);
2236 jlong uuid_lsb = env->CallLongMethod(uuid.get(), uuidGetLsb);
2237 curr.uuid = from_java_uuid(uuid_msb, uuid_lsb);
2238 }
2239
2240 fid = env->GetFieldID(gattDbElementClazz, "type", "I");
2241 curr.type = (bt_gatt_db_attribute_type_t)env->GetIntField(element.get(), fid);
2242
2243 fid = env->GetFieldID(gattDbElementClazz, "attributeHandle", "I");
2244 curr.attribute_handle = env->GetIntField(element.get(), fid);
2245
2246 fid = env->GetFieldID(gattDbElementClazz, "startHandle", "I");
2247 curr.start_handle = env->GetIntField(element.get(), fid);
2248
2249 fid = env->GetFieldID(gattDbElementClazz, "endHandle", "I");
2250 curr.end_handle = env->GetIntField(element.get(), fid);
2251
2252 fid = env->GetFieldID(gattDbElementClazz, "properties", "I");
2253 curr.properties = env->GetIntField(element.get(), fid);
2254
2255 fid = env->GetFieldID(gattDbElementClazz, "permissions", "I");
2256 curr.permissions = env->GetIntField(element.get(), fid);
2257
2258 db.push_back(curr);
2259 }
2260
2261 sGattIf->server->add_service(server_if, db.data(), db.size());
2262 }
2263
gattServerStopServiceNative(JNIEnv *,jobject,jint server_if,jint svc_handle)2264 static void gattServerStopServiceNative(JNIEnv* /* env */, jobject /* object */, jint server_if,
2265 jint svc_handle) {
2266 if (!sGattIf) {
2267 return;
2268 }
2269 sGattIf->server->stop_service(server_if, svc_handle);
2270 }
2271
gattServerDeleteServiceNative(JNIEnv *,jobject,jint server_if,jint svc_handle)2272 static void gattServerDeleteServiceNative(JNIEnv* /* env */, jobject /* object */, jint server_if,
2273 jint svc_handle) {
2274 if (!sGattIf) {
2275 return;
2276 }
2277 sGattIf->server->delete_service(server_if, svc_handle);
2278 }
2279
gattServerSendIndicationNative(JNIEnv * env,jobject,jint server_if,jint attr_handle,jint conn_id,jbyteArray val)2280 static void gattServerSendIndicationNative(JNIEnv* env, jobject /* object */, jint server_if,
2281 jint attr_handle, jint conn_id, jbyteArray val) {
2282 if (!sGattIf) {
2283 return;
2284 }
2285
2286 jbyte* array = env->GetByteArrayElements(val, 0);
2287 int val_len = env->GetArrayLength(val);
2288
2289 if (bluetooth::gatt::is_connection_isolated(conn_id)) {
2290 auto data = ::rust::Slice<const uint8_t>((uint8_t*)array, val_len);
2291 bluetooth::gatt::send_indication(server_if, attr_handle, conn_id, data);
2292 } else {
2293 sGattIf->server->send_indication(server_if, attr_handle, conn_id,
2294 /*confirm*/ 1, (uint8_t*)array, val_len);
2295 }
2296
2297 env->ReleaseByteArrayElements(val, array, JNI_ABORT);
2298 }
2299
gattServerSendNotificationNative(JNIEnv * env,jobject,jint server_if,jint attr_handle,jint conn_id,jbyteArray val)2300 static void gattServerSendNotificationNative(JNIEnv* env, jobject /* object */, jint server_if,
2301 jint attr_handle, jint conn_id, jbyteArray val) {
2302 if (!sGattIf) {
2303 return;
2304 }
2305
2306 jbyte* array = env->GetByteArrayElements(val, 0);
2307 int val_len = env->GetArrayLength(val);
2308
2309 sGattIf->server->send_indication(server_if, attr_handle, conn_id,
2310 /*confirm*/ 0, (uint8_t*)array, val_len);
2311
2312 env->ReleaseByteArrayElements(val, array, JNI_ABORT);
2313 }
2314
gattServerSendResponseNative(JNIEnv * env,jobject,jint server_if,jint conn_id,jint trans_id,jint status,jint handle,jint offset,jbyteArray val,jint auth_req)2315 static void gattServerSendResponseNative(JNIEnv* env, jobject /* object */, jint server_if,
2316 jint conn_id, jint trans_id, jint status, jint handle,
2317 jint offset, jbyteArray val, jint auth_req) {
2318 if (!sGattIf) {
2319 return;
2320 }
2321
2322 btgatt_response_t response;
2323
2324 response.attr_value.handle = handle;
2325 response.attr_value.auth_req = auth_req;
2326 response.attr_value.offset = offset;
2327 response.attr_value.len = 0;
2328
2329 if (val != NULL) {
2330 if (env->GetArrayLength(val) < GATT_MAX_ATTR_LEN) {
2331 response.attr_value.len = (uint16_t)env->GetArrayLength(val);
2332 } else {
2333 response.attr_value.len = GATT_MAX_ATTR_LEN;
2334 }
2335
2336 jbyte* array = env->GetByteArrayElements(val, 0);
2337
2338 for (int i = 0; i != response.attr_value.len; ++i) {
2339 response.attr_value.value[i] = (uint8_t)array[i];
2340 }
2341 env->ReleaseByteArrayElements(val, array, JNI_ABORT);
2342 }
2343
2344 if (bluetooth::gatt::is_connection_isolated(conn_id)) {
2345 auto data = ::rust::Slice<const uint8_t>(response.attr_value.value, response.attr_value.len);
2346 bluetooth::gatt::send_response(server_if, conn_id, trans_id, status, data);
2347 } else {
2348 sGattIf->server->send_response(conn_id, trans_id, status, response);
2349 }
2350 }
2351
advertiseInitializeNative(JNIEnv * env,jobject object)2352 static void advertiseInitializeNative(JNIEnv* env, jobject object) {
2353 std::unique_lock<std::shared_mutex> lock(callbacks_mutex);
2354 if (mAdvertiseCallbacksObj != NULL) {
2355 log::warn("Cleaning up Advertise callback object");
2356 env->DeleteGlobalRef(mAdvertiseCallbacksObj);
2357 mAdvertiseCallbacksObj = NULL;
2358 }
2359
2360 mAdvertiseCallbacksObj = env->NewGlobalRef(object);
2361 }
2362
advertiseCleanupNative(JNIEnv * env,jobject)2363 static void advertiseCleanupNative(JNIEnv* env, jobject /* object */) {
2364 std::unique_lock<std::shared_mutex> lock(callbacks_mutex);
2365 if (mAdvertiseCallbacksObj != NULL) {
2366 env->DeleteGlobalRef(mAdvertiseCallbacksObj);
2367 mAdvertiseCallbacksObj = NULL;
2368 }
2369 }
2370
2371 static uint32_t INTERVAL_MAX = 0xFFFFFF;
2372 // Always give controller 31.25ms difference between min and max
2373 static uint32_t INTERVAL_DELTA = 50;
2374
parseParams(JNIEnv * env,jobject i)2375 static AdvertiseParameters parseParams(JNIEnv* env, jobject i) {
2376 AdvertiseParameters p;
2377
2378 jclass clazz = env->GetObjectClass(i);
2379 jmethodID methodId;
2380
2381 methodId = env->GetMethodID(clazz, "isConnectable", "()Z");
2382 jboolean isConnectable = env->CallBooleanMethod(i, methodId);
2383 methodId = env->GetMethodID(clazz, "isDiscoverable", "()Z");
2384 jboolean isDiscoverable = env->CallBooleanMethod(i, methodId);
2385 methodId = env->GetMethodID(clazz, "isScannable", "()Z");
2386 jboolean isScannable = env->CallBooleanMethod(i, methodId);
2387 methodId = env->GetMethodID(clazz, "isLegacy", "()Z");
2388 jboolean isLegacy = env->CallBooleanMethod(i, methodId);
2389 methodId = env->GetMethodID(clazz, "isAnonymous", "()Z");
2390 jboolean isAnonymous = env->CallBooleanMethod(i, methodId);
2391 methodId = env->GetMethodID(clazz, "includeTxPower", "()Z");
2392 jboolean includeTxPower = env->CallBooleanMethod(i, methodId);
2393 methodId = env->GetMethodID(clazz, "getPrimaryPhy", "()I");
2394 uint8_t primaryPhy = env->CallIntMethod(i, methodId);
2395 methodId = env->GetMethodID(clazz, "getSecondaryPhy", "()I");
2396 uint8_t secondaryPhy = env->CallIntMethod(i, methodId);
2397 methodId = env->GetMethodID(clazz, "getInterval", "()I");
2398 uint32_t interval = env->CallIntMethod(i, methodId);
2399 methodId = env->GetMethodID(clazz, "getTxPowerLevel", "()I");
2400 int8_t txPowerLevel = env->CallIntMethod(i, methodId);
2401 methodId = env->GetMethodID(clazz, "getOwnAddressType", "()I");
2402 int8_t ownAddressType = env->CallIntMethod(i, methodId);
2403 methodId = env->GetMethodID(clazz, "isDirected", "()Z");
2404 jboolean isDirected = env->CallBooleanMethod(i, methodId);
2405 methodId = env->GetMethodID(clazz, "isHighDutyCycle", "()Z");
2406 jboolean isHighDutyCycle = env->CallBooleanMethod(i, methodId);
2407 methodId = env->GetMethodID(clazz, "getPeerAddress", "()Ljava/lang/String;");
2408 jstring peerAddress = (jstring)env->CallObjectMethod(i, methodId);
2409 methodId = env->GetMethodID(clazz, "getPeerAddressType", "()I");
2410 int8_t peerAddressType = env->CallIntMethod(i, methodId);
2411
2412 uint16_t props = 0;
2413 if (isConnectable) {
2414 props |= 0x01;
2415 }
2416 if (isScannable) {
2417 props |= 0x02;
2418 }
2419 if (isDirected) {
2420 props |= 0x04;
2421 }
2422 if (isHighDutyCycle) {
2423 props |= 0x08;
2424 }
2425 if (isLegacy) {
2426 props |= 0x10;
2427 }
2428 if (isAnonymous) {
2429 props |= 0x20;
2430 }
2431 if (includeTxPower) {
2432 props |= 0x40;
2433 }
2434
2435 if (interval > INTERVAL_MAX - INTERVAL_DELTA) {
2436 interval = INTERVAL_MAX - INTERVAL_DELTA;
2437 }
2438
2439 p.advertising_event_properties = props;
2440 p.min_interval = interval;
2441 p.max_interval = interval + INTERVAL_DELTA;
2442 p.channel_map = 0x07; /* all channels */
2443 p.tx_power = txPowerLevel;
2444 p.primary_advertising_phy = primaryPhy;
2445 p.secondary_advertising_phy = secondaryPhy;
2446 p.scan_request_notification_enable = false;
2447 p.own_address_type = ownAddressType;
2448 p.peer_address = str2addr(env, peerAddress);
2449 p.peer_address_type = peerAddressType;
2450 p.discoverable = isDiscoverable;
2451 return p;
2452 }
2453
parsePeriodicParams(JNIEnv * env,jobject i)2454 static PeriodicAdvertisingParameters parsePeriodicParams(JNIEnv* env, jobject i) {
2455 PeriodicAdvertisingParameters p;
2456
2457 if (i == NULL) {
2458 p.enable = false;
2459 return p;
2460 }
2461
2462 jclass clazz = env->GetObjectClass(i);
2463 jmethodID methodId;
2464
2465 methodId = env->GetMethodID(clazz, "getIncludeTxPower", "()Z");
2466 jboolean includeTxPower = env->CallBooleanMethod(i, methodId);
2467 methodId = env->GetMethodID(clazz, "getInterval", "()I");
2468 uint16_t interval = env->CallIntMethod(i, methodId);
2469
2470 p.enable = true;
2471 p.include_adi = true;
2472 p.min_interval = interval;
2473 p.max_interval = interval + 16; /* 20ms difference betwen min and max */
2474 uint16_t props = 0;
2475 if (includeTxPower) {
2476 props |= 0x40;
2477 }
2478 p.periodic_advertising_properties = props;
2479 return p;
2480 }
2481
ble_advertising_set_started_cb(int reg_id,int server_if,uint8_t advertiser_id,int8_t tx_power,uint8_t status)2482 static void ble_advertising_set_started_cb(int reg_id, int server_if, uint8_t advertiser_id,
2483 int8_t tx_power, uint8_t status) {
2484 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
2485 CallbackEnv sCallbackEnv(__func__);
2486 if (!sCallbackEnv.valid() || !mAdvertiseCallbacksObj) {
2487 return;
2488 }
2489
2490 // tie advertiser ID to server_if, once the advertisement has started
2491 if (status == 0 /* AdvertisingCallback::AdvertisingStatus::SUCCESS */ && server_if != 0) {
2492 bluetooth::gatt::associate_server_with_advertiser(server_if, advertiser_id);
2493 }
2494
2495 sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj, method_onAdvertisingSetStarted, reg_id,
2496 advertiser_id, tx_power, status);
2497 }
2498
ble_advertising_set_timeout_cb(uint8_t advertiser_id,uint8_t status)2499 static void ble_advertising_set_timeout_cb(uint8_t advertiser_id, uint8_t status) {
2500 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
2501 CallbackEnv sCallbackEnv(__func__);
2502 if (!sCallbackEnv.valid() || !mAdvertiseCallbacksObj) {
2503 return;
2504 }
2505 sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj, method_onAdvertisingEnabled, advertiser_id,
2506 false, status);
2507 }
2508
startAdvertisingSetNative(JNIEnv * env,jobject,jobject parameters,jbyteArray adv_data,jbyteArray scan_resp,jobject periodic_parameters,jbyteArray periodic_data,jint duration,jint maxExtAdvEvents,jint reg_id,jint server_if)2509 static void startAdvertisingSetNative(JNIEnv* env, jobject /* object */, jobject parameters,
2510 jbyteArray adv_data, jbyteArray scan_resp,
2511 jobject periodic_parameters, jbyteArray periodic_data,
2512 jint duration, jint maxExtAdvEvents, jint reg_id,
2513 jint server_if) {
2514 if (!sGattIf) {
2515 return;
2516 }
2517
2518 jbyte* scan_resp_data = env->GetByteArrayElements(scan_resp, NULL);
2519 uint16_t scan_resp_len = (uint16_t)env->GetArrayLength(scan_resp);
2520 std::vector<uint8_t> scan_resp_vec(scan_resp_data, scan_resp_data + scan_resp_len);
2521 env->ReleaseByteArrayElements(scan_resp, scan_resp_data, JNI_ABORT);
2522
2523 AdvertiseParameters params = parseParams(env, parameters);
2524 PeriodicAdvertisingParameters periodicParams = parsePeriodicParams(env, periodic_parameters);
2525
2526 jbyte* adv_data_data = env->GetByteArrayElements(adv_data, NULL);
2527 uint16_t adv_data_len = (uint16_t)env->GetArrayLength(adv_data);
2528 std::vector<uint8_t> data_vec(adv_data_data, adv_data_data + adv_data_len);
2529 env->ReleaseByteArrayElements(adv_data, adv_data_data, JNI_ABORT);
2530
2531 jbyte* periodic_data_data = env->GetByteArrayElements(periodic_data, NULL);
2532 uint16_t periodic_data_len = (uint16_t)env->GetArrayLength(periodic_data);
2533 std::vector<uint8_t> periodic_data_vec(periodic_data_data,
2534 periodic_data_data + periodic_data_len);
2535 env->ReleaseByteArrayElements(periodic_data, periodic_data_data, JNI_ABORT);
2536
2537 sGattIf->advertiser->StartAdvertisingSet(
2538 kAdvertiserClientIdJni, reg_id,
2539 base::Bind(&ble_advertising_set_started_cb, reg_id, server_if), params, data_vec,
2540 scan_resp_vec, periodicParams, periodic_data_vec, duration, maxExtAdvEvents,
2541 base::Bind(ble_advertising_set_timeout_cb));
2542 }
2543
stopAdvertisingSetNative(JNIEnv *,jobject,jint advertiser_id)2544 static void stopAdvertisingSetNative(JNIEnv* /* env */, jobject /* object */, jint advertiser_id) {
2545 if (!sGattIf) {
2546 return;
2547 }
2548
2549 bluetooth::gatt::clear_advertiser(advertiser_id);
2550
2551 sGattIf->advertiser->Unregister(advertiser_id);
2552 }
2553
getOwnAddressCb(uint8_t advertiser_id,uint8_t address_type,RawAddress address)2554 static void getOwnAddressCb(uint8_t advertiser_id, uint8_t address_type, RawAddress address) {
2555 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
2556 CallbackEnv sCallbackEnv(__func__);
2557 if (!sCallbackEnv.valid() || !mAdvertiseCallbacksObj) {
2558 return;
2559 }
2560
2561 ScopedLocalRef<jstring> addr(sCallbackEnv.get(), bdaddr2newjstr(sCallbackEnv.get(), &address));
2562 sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj, method_onOwnAddressRead, advertiser_id,
2563 address_type, addr.get());
2564 }
2565
getOwnAddressNative(JNIEnv *,jobject,jint advertiser_id)2566 static void getOwnAddressNative(JNIEnv* /* env */, jobject /* object */, jint advertiser_id) {
2567 if (!sGattIf) {
2568 return;
2569 }
2570 sGattIf->advertiser->GetOwnAddress(advertiser_id, base::Bind(&getOwnAddressCb, advertiser_id));
2571 }
2572
callJniCallback(jmethodID method,uint8_t advertiser_id,uint8_t status)2573 static void callJniCallback(jmethodID method, uint8_t advertiser_id, uint8_t status) {
2574 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
2575 CallbackEnv sCallbackEnv(__func__);
2576 if (!sCallbackEnv.valid() || !mAdvertiseCallbacksObj) {
2577 return;
2578 }
2579 sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj, method, advertiser_id, status);
2580 }
2581
enableSetCb(uint8_t advertiser_id,bool enable,uint8_t status)2582 static void enableSetCb(uint8_t advertiser_id, bool enable, uint8_t status) {
2583 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
2584 CallbackEnv sCallbackEnv(__func__);
2585 if (!sCallbackEnv.valid() || !mAdvertiseCallbacksObj) {
2586 return;
2587 }
2588 sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj, method_onAdvertisingEnabled, advertiser_id,
2589 enable, status);
2590 }
2591
enableAdvertisingSetNative(JNIEnv *,jobject,jint advertiser_id,jboolean enable,jint duration,jint maxExtAdvEvents)2592 static void enableAdvertisingSetNative(JNIEnv* /* env */, jobject /* object */, jint advertiser_id,
2593 jboolean enable, jint duration, jint maxExtAdvEvents) {
2594 if (!sGattIf) {
2595 return;
2596 }
2597
2598 sGattIf->advertiser->Enable(advertiser_id, enable,
2599 base::Bind(&enableSetCb, advertiser_id, enable), duration,
2600 maxExtAdvEvents, base::Bind(&enableSetCb, advertiser_id, false));
2601 }
2602
setAdvertisingDataNative(JNIEnv * env,jobject,jint advertiser_id,jbyteArray data)2603 static void setAdvertisingDataNative(JNIEnv* env, jobject /* object */, jint advertiser_id,
2604 jbyteArray data) {
2605 if (!sGattIf) {
2606 return;
2607 }
2608
2609 sGattIf->advertiser->SetData(
2610 advertiser_id, false, toVector(env, data),
2611 base::Bind(&callJniCallback, method_onAdvertisingDataSet, advertiser_id));
2612 }
2613
setScanResponseDataNative(JNIEnv * env,jobject,jint advertiser_id,jbyteArray data)2614 static void setScanResponseDataNative(JNIEnv* env, jobject /* object */, jint advertiser_id,
2615 jbyteArray data) {
2616 if (!sGattIf) {
2617 return;
2618 }
2619
2620 sGattIf->advertiser->SetData(
2621 advertiser_id, true, toVector(env, data),
2622 base::Bind(&callJniCallback, method_onScanResponseDataSet, advertiser_id));
2623 }
2624
setAdvertisingParametersNativeCb(uint8_t advertiser_id,uint8_t status,int8_t tx_power)2625 static void setAdvertisingParametersNativeCb(uint8_t advertiser_id, uint8_t status,
2626 int8_t tx_power) {
2627 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
2628 CallbackEnv sCallbackEnv(__func__);
2629 if (!sCallbackEnv.valid() || !mAdvertiseCallbacksObj) {
2630 return;
2631 }
2632 sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj, method_onAdvertisingParametersUpdated,
2633 advertiser_id, tx_power, status);
2634 }
2635
setAdvertisingParametersNative(JNIEnv * env,jobject,jint advertiser_id,jobject parameters)2636 static void setAdvertisingParametersNative(JNIEnv* env, jobject /* object */, jint advertiser_id,
2637 jobject parameters) {
2638 if (!sGattIf) {
2639 return;
2640 }
2641
2642 AdvertiseParameters params = parseParams(env, parameters);
2643 sGattIf->advertiser->SetParameters(advertiser_id, params,
2644 base::Bind(&setAdvertisingParametersNativeCb, advertiser_id));
2645 }
2646
setPeriodicAdvertisingParametersNative(JNIEnv * env,jobject,jint advertiser_id,jobject periodic_parameters)2647 static void setPeriodicAdvertisingParametersNative(JNIEnv* env, jobject /* object */,
2648 jint advertiser_id,
2649 jobject periodic_parameters) {
2650 if (!sGattIf) {
2651 return;
2652 }
2653
2654 PeriodicAdvertisingParameters periodicParams = parsePeriodicParams(env, periodic_parameters);
2655 sGattIf->advertiser->SetPeriodicAdvertisingParameters(
2656 advertiser_id, periodicParams,
2657 base::Bind(&callJniCallback, method_onPeriodicAdvertisingParametersUpdated,
2658 advertiser_id));
2659 }
2660
setPeriodicAdvertisingDataNative(JNIEnv * env,jobject,jint advertiser_id,jbyteArray data)2661 static void setPeriodicAdvertisingDataNative(JNIEnv* env, jobject /* object */, jint advertiser_id,
2662 jbyteArray data) {
2663 if (!sGattIf) {
2664 return;
2665 }
2666
2667 sGattIf->advertiser->SetPeriodicAdvertisingData(
2668 advertiser_id, toVector(env, data),
2669 base::Bind(&callJniCallback, method_onPeriodicAdvertisingDataSet, advertiser_id));
2670 }
2671
enablePeriodicSetCb(uint8_t advertiser_id,bool enable,uint8_t status)2672 static void enablePeriodicSetCb(uint8_t advertiser_id, bool enable, uint8_t status) {
2673 std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
2674 CallbackEnv sCallbackEnv(__func__);
2675 if (!sCallbackEnv.valid() || !mAdvertiseCallbacksObj) {
2676 return;
2677 }
2678 sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj, method_onPeriodicAdvertisingEnabled,
2679 advertiser_id, enable, status);
2680 }
2681
setPeriodicAdvertisingEnableNative(JNIEnv *,jobject,jint advertiser_id,jboolean enable)2682 static void setPeriodicAdvertisingEnableNative(JNIEnv* /* env */, jobject /* object */,
2683 jint advertiser_id, jboolean enable) {
2684 if (!sGattIf) {
2685 return;
2686 }
2687
2688 sGattIf->advertiser->SetPeriodicAdvertisingEnable(
2689 advertiser_id, enable, true /*include_adi*/,
2690 base::Bind(&enablePeriodicSetCb, advertiser_id, enable));
2691 }
2692
periodicScanInitializeNative(JNIEnv * env,jobject object)2693 static void periodicScanInitializeNative(JNIEnv* env, jobject object) {
2694 std::unique_lock<std::shared_mutex> lock(callbacks_mutex);
2695 if (mPeriodicScanCallbacksObj != NULL) {
2696 log::warn("Cleaning up periodic scan callback object");
2697 env->DeleteGlobalRef(mPeriodicScanCallbacksObj);
2698 mPeriodicScanCallbacksObj = NULL;
2699 }
2700
2701 mPeriodicScanCallbacksObj = env->NewGlobalRef(object);
2702 }
2703
periodicScanCleanupNative(JNIEnv * env,jobject)2704 static void periodicScanCleanupNative(JNIEnv* env, jobject /* object */) {
2705 std::unique_lock<std::shared_mutex> lock(callbacks_mutex);
2706 if (mPeriodicScanCallbacksObj != NULL) {
2707 env->DeleteGlobalRef(mPeriodicScanCallbacksObj);
2708 mPeriodicScanCallbacksObj = NULL;
2709 }
2710 }
2711
scanInitializeNative(JNIEnv * env,jobject object)2712 static void scanInitializeNative(JNIEnv* env, jobject object) {
2713 std::unique_lock<std::shared_mutex> lock(callbacks_mutex);
2714
2715 sScanner = bluetooth::shim::get_ble_scanner_instance();
2716 sScanner->RegisterCallbacks(JniScanningCallbacks::GetInstance());
2717
2718 if (mScanCallbacksObj != NULL) {
2719 log::warn("Cleaning up scan callback object");
2720 env->DeleteGlobalRef(mScanCallbacksObj);
2721 mScanCallbacksObj = NULL;
2722 }
2723
2724 mScanCallbacksObj = env->NewGlobalRef(object);
2725 }
2726
scanCleanupNative(JNIEnv * env,jobject)2727 static void scanCleanupNative(JNIEnv* env, jobject /* object */) {
2728 std::unique_lock<std::shared_mutex> lock(callbacks_mutex);
2729 if (mScanCallbacksObj != NULL) {
2730 env->DeleteGlobalRef(mScanCallbacksObj);
2731 mScanCallbacksObj = NULL;
2732 }
2733 if (sScanner != NULL) {
2734 sScanner = NULL;
2735 }
2736 }
2737
startSyncNative(JNIEnv * env,jobject,jint sid,jstring address,jint skip,jint timeout,jint reg_id)2738 static void startSyncNative(JNIEnv* env, jobject /* object */, jint sid, jstring address, jint skip,
2739 jint timeout, jint reg_id) {
2740 if (!sScanner) {
2741 return;
2742 }
2743 sScanner->StartSync(sid, str2addr(env, address), skip, timeout, reg_id);
2744 }
2745
stopSyncNative(JNIEnv *,jobject,jint sync_handle)2746 static void stopSyncNative(JNIEnv* /* env */, jobject /* object */, jint sync_handle) {
2747 if (!sScanner) {
2748 return;
2749 }
2750 sScanner->StopSync(sync_handle);
2751 }
2752
cancelSyncNative(JNIEnv * env,jobject,jint sid,jstring address)2753 static void cancelSyncNative(JNIEnv* env, jobject /* object */, jint sid, jstring address) {
2754 if (!sScanner) {
2755 return;
2756 }
2757 sScanner->CancelCreateSync(sid, str2addr(env, address));
2758 }
2759
syncTransferNative(JNIEnv * env,jobject,jint pa_source,jstring addr,jint service_data,jint sync_handle)2760 static void syncTransferNative(JNIEnv* env, jobject /* object */, jint pa_source, jstring addr,
2761 jint service_data, jint sync_handle) {
2762 if (!sScanner) {
2763 return;
2764 }
2765 sScanner->TransferSync(str2addr(env, addr), service_data, sync_handle, pa_source);
2766 }
2767
transferSetInfoNative(JNIEnv * env,jobject,jint pa_source,jstring addr,jint service_data,jint adv_handle)2768 static void transferSetInfoNative(JNIEnv* env, jobject /* object */, jint pa_source, jstring addr,
2769 jint service_data, jint adv_handle) {
2770 if (!sScanner) {
2771 return;
2772 }
2773 sScanner->TransferSetInfo(str2addr(env, addr), service_data, adv_handle, pa_source);
2774 }
2775
gattTestNative(JNIEnv * env,jobject,jint command,jlong uuid1_lsb,jlong uuid1_msb,jstring bda1,jint p1,jint p2,jint p3,jint p4,jint p5)2776 static void gattTestNative(JNIEnv* env, jobject /* object */, jint command, jlong uuid1_lsb,
2777 jlong uuid1_msb, jstring bda1, jint p1, jint p2, jint p3, jint p4,
2778 jint p5) {
2779 if (!sGattIf) {
2780 return;
2781 }
2782
2783 RawAddress bt_bda1 = str2addr(env, bda1);
2784
2785 Uuid uuid1 = from_java_uuid(uuid1_msb, uuid1_lsb);
2786
2787 btgatt_test_params_t params;
2788 params.bda1 = &bt_bda1;
2789 params.uuid1 = &uuid1;
2790 params.u1 = p1;
2791 params.u2 = p2;
2792 params.u3 = p3;
2793 params.u4 = p4;
2794 params.u5 = p5;
2795 sGattIf->client->test_command(command, params);
2796 }
2797
distanceMeasurementInitializeNative(JNIEnv * env,jobject object)2798 static void distanceMeasurementInitializeNative(JNIEnv* env, jobject object) {
2799 std::unique_lock<std::shared_mutex> lock(callbacks_mutex);
2800 if (mDistanceMeasurementCallbacksObj != NULL) {
2801 log::warn("Cleaning up Advertise callback object");
2802 env->DeleteGlobalRef(mDistanceMeasurementCallbacksObj);
2803 mDistanceMeasurementCallbacksObj = NULL;
2804 }
2805
2806 mDistanceMeasurementCallbacksObj = env->NewGlobalRef(object);
2807 }
2808
distanceMeasurementCleanupNative(JNIEnv * env,jobject)2809 static void distanceMeasurementCleanupNative(JNIEnv* env, jobject /* object */) {
2810 std::unique_lock<std::shared_mutex> lock(callbacks_mutex);
2811 if (mDistanceMeasurementCallbacksObj != NULL) {
2812 env->DeleteGlobalRef(mDistanceMeasurementCallbacksObj);
2813 mDistanceMeasurementCallbacksObj = NULL;
2814 }
2815 }
2816
startDistanceMeasurementNative(JNIEnv * env,jobject,jstring address,jint interval,jint method)2817 static void startDistanceMeasurementNative(JNIEnv* env, jobject /* object */, jstring address,
2818 jint interval, jint method) {
2819 if (!sGattIf) {
2820 return;
2821 }
2822 sGattIf->distance_measurement_manager->StartDistanceMeasurement(str2addr(env, address), interval,
2823 method);
2824 }
2825
stopDistanceMeasurementNative(JNIEnv * env,jobject,jstring address,jint method)2826 static void stopDistanceMeasurementNative(JNIEnv* env, jobject /* object */, jstring address,
2827 jint method) {
2828 if (!sGattIf) {
2829 return;
2830 }
2831 sGattIf->distance_measurement_manager->StopDistanceMeasurement(str2addr(env, address), method);
2832 }
2833
2834 /**
2835 * JNI function definitions
2836 */
2837
2838 // JNI functions defined in ScanNativeInterface class.
register_com_android_bluetooth_gatt_scan(JNIEnv * env)2839 static int register_com_android_bluetooth_gatt_scan(JNIEnv* env) {
2840 const JNINativeMethod methods[] = {
2841 {"initializeNative", "()V", (void*)scanInitializeNative},
2842 {"cleanupNative", "()V", (void*)scanCleanupNative},
2843 {"registerScannerNative", "(JJ)V", (void*)registerScannerNative},
2844 {"unregisterScannerNative", "(I)V", (void*)unregisterScannerNative},
2845 {"gattClientScanNative", "(Z)V", (void*)gattClientScanNative},
2846 // Batch scan JNI functions.
2847 {"gattClientConfigBatchScanStorageNative", "(IIII)V",
2848 (void*)gattClientConfigBatchScanStorageNative},
2849 {"gattClientStartBatchScanNative", "(IIIIII)V", (void*)gattClientStartBatchScanNative},
2850 {"gattClientStopBatchScanNative", "(I)V", (void*)gattClientStopBatchScanNative},
2851 {"gattClientReadScanReportsNative", "(II)V", (void*)gattClientReadScanReportsNative},
2852 // Scan filter JNI functions.
2853 {"gattClientScanFilterParamAddNative", "(Lcom/android/bluetooth/gatt/FilterParams;)V",
2854 (void*)gattClientScanFilterParamAddNative},
2855 {"gattClientScanFilterParamDeleteNative", "(II)V",
2856 (void*)gattClientScanFilterParamDeleteNative},
2857 {"gattClientScanFilterParamClearAllNative", "(I)V",
2858 (void*)gattClientScanFilterParamClearAllNative},
2859 {"gattClientScanFilterAddNative",
2860 "(I[Lcom/android/bluetooth/le_scan/ScanFilterQueue$Entry;I)V",
2861 (void*)gattClientScanFilterAddNative},
2862 {"gattClientScanFilterClearNative", "(II)V", (void*)gattClientScanFilterClearNative},
2863 {"gattClientScanFilterEnableNative", "(IZ)V", (void*)gattClientScanFilterEnableNative},
2864 {"gattSetScanParametersNative", "(IIII)V", (void*)gattSetScanParametersNative},
2865 // MSFT HCI Extension functions.
2866 {"gattClientIsMsftSupportedNative", "()Z", (bool*)gattClientIsMsftSupportedNative},
2867 {"gattClientMsftAdvMonitorAddNative",
2868 "(Lcom/android/bluetooth/le_scan/MsftAdvMonitor$Monitor;[Lcom/android/bluetooth/le_scan/"
2869 "MsftAdvMonitor$Pattern;Lcom/android/bluetooth/le_scan/MsftAdvMonitor$Address;I)V",
2870 (void*)gattClientMsftAdvMonitorAddNative},
2871 {"gattClientMsftAdvMonitorRemoveNative", "(II)V",
2872 (void*)gattClientMsftAdvMonitorRemoveNative},
2873 {"gattClientMsftAdvMonitorEnableNative", "(Z)V",
2874 (void*)gattClientMsftAdvMonitorEnableNative},
2875 };
2876 const int result = REGISTER_NATIVE_METHODS(
2877 env, "com/android/bluetooth/le_scan/ScanNativeInterface", methods);
2878 if (result != 0) {
2879 return result;
2880 }
2881
2882 const JNIJavaMethod javaMethods[] = {
2883 // Client callbacks
2884 {"onScannerRegistered", "(IIJJ)V", &method_onScannerRegistered},
2885 {"onScanResult", "(IILjava/lang/String;IIIIII[BLjava/lang/String;)V",
2886 &method_onScanResult},
2887 {"onScanFilterConfig", "(IIIII)V", &method_onScanFilterConfig},
2888 {"onScanFilterParamsConfigured", "(IIII)V", &method_onScanFilterParamsConfigured},
2889 {"onScanFilterEnableDisabled", "(III)V", &method_onScanFilterEnableDisabled},
2890 {"onBatchScanStorageConfigured", "(II)V", &method_onBatchScanStorageConfigured},
2891 {"onBatchScanStartStopped", "(III)V", &method_onBatchScanStartStopped},
2892 {"onBatchScanReports", "(IIII[B)V", &method_onBatchScanReports},
2893 {"onBatchScanThresholdCrossed", "(I)V", &method_onBatchScanThresholdCrossed},
2894 {"createOnTrackAdvFoundLostObject",
2895 "(II[BI[BIIILjava/lang/String;IIII)"
2896 "Lcom/android/bluetooth/le_scan/AdvtFilterOnFoundOnLostInfo;",
2897 &method_createOnTrackAdvFoundLostObject},
2898 {"onTrackAdvFoundLost", "(Lcom/android/bluetooth/le_scan/AdvtFilterOnFoundOnLostInfo;)V",
2899 &method_onTrackAdvFoundLost},
2900 {"onScanParamSetupCompleted", "(II)V", &method_onScanParamSetupCompleted},
2901 {"onMsftAdvMonitorAdd", "(III)V", &method_onMsftAdvMonitorAdd},
2902 {"onMsftAdvMonitorRemove", "(II)V", &method_onMsftAdvMonitorRemove},
2903 {"onMsftAdvMonitorEnable", "(I)V", &method_onMsftAdvMonitorEnable},
2904 };
2905 GET_JAVA_METHODS(env, "com/android/bluetooth/le_scan/ScanNativeInterface", javaMethods);
2906 return 0;
2907 }
2908
2909 // JNI functions defined in AdvertiseManagerNativeInterface class.
register_com_android_bluetooth_gatt_advertise_manager(JNIEnv * env)2910 static int register_com_android_bluetooth_gatt_advertise_manager(JNIEnv* env) {
2911 const JNINativeMethod methods[] = {
2912 {"initializeNative", "()V", (void*)advertiseInitializeNative},
2913 {"cleanupNative", "()V", (void*)advertiseCleanupNative},
2914 {"startAdvertisingSetNative",
2915 "(Landroid/bluetooth/le/AdvertisingSetParameters;"
2916 "[B[BLandroid/bluetooth/le/PeriodicAdvertisingParameters;[BIIII)V",
2917 (void*)startAdvertisingSetNative},
2918 {"stopAdvertisingSetNative", "(I)V", (void*)stopAdvertisingSetNative},
2919 {"getOwnAddressNative", "(I)V", (void*)getOwnAddressNative},
2920 {"enableAdvertisingSetNative", "(IZII)V", (void*)enableAdvertisingSetNative},
2921 {"setAdvertisingDataNative", "(I[B)V", (void*)setAdvertisingDataNative},
2922 {"setScanResponseDataNative", "(I[B)V", (void*)setScanResponseDataNative},
2923 {"setAdvertisingParametersNative", "(ILandroid/bluetooth/le/AdvertisingSetParameters;)V",
2924 (void*)setAdvertisingParametersNative},
2925 {"setPeriodicAdvertisingParametersNative",
2926 "(ILandroid/bluetooth/le/PeriodicAdvertisingParameters;)V",
2927 (void*)setPeriodicAdvertisingParametersNative},
2928 {"setPeriodicAdvertisingDataNative", "(I[B)V", (void*)setPeriodicAdvertisingDataNative},
2929 {"setPeriodicAdvertisingEnableNative", "(IZ)V",
2930 (void*)setPeriodicAdvertisingEnableNative},
2931 };
2932 const int result = REGISTER_NATIVE_METHODS(
2933 env, "com/android/bluetooth/gatt/AdvertiseManagerNativeInterface", methods);
2934 if (result != 0) {
2935 return result;
2936 }
2937
2938 const JNIJavaMethod javaMethods[] = {
2939 {"onAdvertisingSetStarted", "(IIII)V", &method_onAdvertisingSetStarted},
2940 {"onOwnAddressRead", "(IILjava/lang/String;)V", &method_onOwnAddressRead},
2941 {"onAdvertisingEnabled", "(IZI)V", &method_onAdvertisingEnabled},
2942 {"onAdvertisingDataSet", "(II)V", &method_onAdvertisingDataSet},
2943 {"onScanResponseDataSet", "(II)V", &method_onScanResponseDataSet},
2944 {"onAdvertisingParametersUpdated", "(III)V", &method_onAdvertisingParametersUpdated},
2945 {"onPeriodicAdvertisingParametersUpdated", "(II)V",
2946 &method_onPeriodicAdvertisingParametersUpdated},
2947 {"onPeriodicAdvertisingDataSet", "(II)V", &method_onPeriodicAdvertisingDataSet},
2948 {"onPeriodicAdvertisingEnabled", "(IZI)V", &method_onPeriodicAdvertisingEnabled},
2949 };
2950 GET_JAVA_METHODS(env, "com/android/bluetooth/gatt/AdvertiseManagerNativeInterface", javaMethods);
2951 return 0;
2952 }
2953
2954 // JNI functions defined in PeriodicScanNativeInterface class.
register_com_android_bluetooth_gatt_periodic_scan(JNIEnv * env)2955 static int register_com_android_bluetooth_gatt_periodic_scan(JNIEnv* env) {
2956 const JNINativeMethod methods[] = {
2957 {"initializeNative", "()V", (void*)periodicScanInitializeNative},
2958 {"cleanupNative", "()V", (void*)periodicScanCleanupNative},
2959 {"startSyncNative", "(ILjava/lang/String;III)V", (void*)startSyncNative},
2960 {"stopSyncNative", "(I)V", (void*)stopSyncNative},
2961 {"cancelSyncNative", "(ILjava/lang/String;)V", (void*)cancelSyncNative},
2962 {"syncTransferNative", "(ILjava/lang/String;II)V", (void*)syncTransferNative},
2963 {"transferSetInfoNative", "(ILjava/lang/String;II)V", (void*)transferSetInfoNative},
2964 };
2965 const int result = REGISTER_NATIVE_METHODS(
2966 env, "com/android/bluetooth/le_scan/PeriodicScanNativeInterface", methods);
2967 if (result != 0) {
2968 return result;
2969 }
2970
2971 const JNIJavaMethod javaMethods[] = {
2972 {"onSyncStarted", "(IIIILjava/lang/String;III)V", &method_onSyncStarted},
2973 {"onSyncReport", "(IIII[B)V", &method_onSyncReport},
2974 {"onSyncLost", "(I)V", &method_onSyncLost},
2975 {"onSyncTransferredCallback", "(IILjava/lang/String;)V",
2976 &method_onSyncTransferredCallback},
2977 {"onBigInfoReport", "(IZ)V", &method_onBigInfoReport},
2978 };
2979 GET_JAVA_METHODS(env, "com/android/bluetooth/le_scan/PeriodicScanNativeInterface", javaMethods);
2980 return 0;
2981 }
2982
2983 // JNI functions defined in DistanceMeasurementNativeInterface class.
register_com_android_bluetooth_gatt_distance_measurement(JNIEnv * env)2984 static int register_com_android_bluetooth_gatt_distance_measurement(JNIEnv* env) {
2985 const JNINativeMethod methods[] = {
2986 {"initializeNative", "()V", (void*)distanceMeasurementInitializeNative},
2987 {"cleanupNative", "()V", (void*)distanceMeasurementCleanupNative},
2988 {"startDistanceMeasurementNative", "(Ljava/lang/String;II)V",
2989 (void*)startDistanceMeasurementNative},
2990 {"stopDistanceMeasurementNative", "(Ljava/lang/String;I)V",
2991 (void*)stopDistanceMeasurementNative},
2992 };
2993 const int result = REGISTER_NATIVE_METHODS(
2994 env, "com/android/bluetooth/gatt/DistanceMeasurementNativeInterface", methods);
2995 if (result != 0) {
2996 return result;
2997 }
2998
2999 const JNIJavaMethod javaMethods[] = {
3000 {"onDistanceMeasurementStarted", "(Ljava/lang/String;I)V",
3001 &method_onDistanceMeasurementStarted},
3002 {"onDistanceMeasurementStopped", "(Ljava/lang/String;II)V",
3003 &method_onDistanceMeasurementStopped},
3004 {"onDistanceMeasurementResult", "(Ljava/lang/String;IIIIIIJII)V",
3005 &method_onDistanceMeasurementResult},
3006 };
3007 GET_JAVA_METHODS(env, "com/android/bluetooth/gatt/DistanceMeasurementNativeInterface",
3008 javaMethods);
3009 return 0;
3010 }
3011
3012 // JNI functions defined in GattNativeInterface class.
register_com_android_bluetooth_gatt_(JNIEnv * env)3013 static int register_com_android_bluetooth_gatt_(JNIEnv* env) {
3014 const JNINativeMethod methods[] = {
3015 {"initializeNative", "()V", (void*)initializeNative},
3016 {"cleanupNative", "()V", (void*)cleanupNative},
3017 {"gattClientGetDeviceTypeNative", "(Ljava/lang/String;)I",
3018 (void*)gattClientGetDeviceTypeNative},
3019 {"gattClientRegisterAppNative", "(JJZ)V", (void*)gattClientRegisterAppNative},
3020 {"gattClientUnregisterAppNative", "(I)V", (void*)gattClientUnregisterAppNative},
3021 {"gattClientConnectNative", "(ILjava/lang/String;IZIZII)V",
3022 (void*)gattClientConnectNative},
3023 {"gattClientDisconnectNative", "(ILjava/lang/String;I)V",
3024 (void*)gattClientDisconnectNative},
3025 {"gattClientSetPreferredPhyNative", "(ILjava/lang/String;III)V",
3026 (void*)gattClientSetPreferredPhyNative},
3027 {"gattClientReadPhyNative", "(ILjava/lang/String;)V", (void*)gattClientReadPhyNative},
3028 {"gattClientRefreshNative", "(ILjava/lang/String;)V", (void*)gattClientRefreshNative},
3029 {"gattClientSearchServiceNative", "(IZJJ)V", (void*)gattClientSearchServiceNative},
3030 {"gattClientDiscoverServiceByUuidNative", "(IJJ)V",
3031 (void*)gattClientDiscoverServiceByUuidNative},
3032 {"gattClientGetGattDbNative", "(I)V", (void*)gattClientGetGattDbNative},
3033 {"gattClientReadCharacteristicNative", "(III)V",
3034 (void*)gattClientReadCharacteristicNative},
3035 {"gattClientReadUsingCharacteristicUuidNative", "(IJJIII)V",
3036 (void*)gattClientReadUsingCharacteristicUuidNative},
3037 {"gattClientReadDescriptorNative", "(III)V", (void*)gattClientReadDescriptorNative},
3038 {"gattClientWriteCharacteristicNative", "(IIII[B)V",
3039 (void*)gattClientWriteCharacteristicNative},
3040 {"gattClientWriteDescriptorNative", "(III[B)V", (void*)gattClientWriteDescriptorNative},
3041 {"gattClientExecuteWriteNative", "(IZ)V", (void*)gattClientExecuteWriteNative},
3042 {"gattClientRegisterForNotificationsNative", "(ILjava/lang/String;IZ)V",
3043 (void*)gattClientRegisterForNotificationsNative},
3044 {"gattClientReadRemoteRssiNative", "(ILjava/lang/String;)V",
3045 (void*)gattClientReadRemoteRssiNative},
3046 {"gattClientConfigureMTUNative", "(II)V", (void*)gattClientConfigureMTUNative},
3047 {"gattConnectionParameterUpdateNative", "(ILjava/lang/String;IIIIII)V",
3048 (void*)gattConnectionParameterUpdateNative},
3049 {"gattServerRegisterAppNative", "(JJZ)V", (void*)gattServerRegisterAppNative},
3050 {"gattServerUnregisterAppNative", "(I)V", (void*)gattServerUnregisterAppNative},
3051 {"gattServerConnectNative", "(ILjava/lang/String;IZI)V", (void*)gattServerConnectNative},
3052 {"gattServerDisconnectNative", "(ILjava/lang/String;I)V",
3053 (void*)gattServerDisconnectNative},
3054 {"gattServerSetPreferredPhyNative", "(ILjava/lang/String;III)V",
3055 (void*)gattServerSetPreferredPhyNative},
3056 {"gattServerReadPhyNative", "(ILjava/lang/String;)V", (void*)gattServerReadPhyNative},
3057 {"gattServerAddServiceNative", "(ILjava/util/List;)V", (void*)gattServerAddServiceNative},
3058 {"gattServerStopServiceNative", "(II)V", (void*)gattServerStopServiceNative},
3059 {"gattServerDeleteServiceNative", "(II)V", (void*)gattServerDeleteServiceNative},
3060 {"gattServerSendIndicationNative", "(III[B)V", (void*)gattServerSendIndicationNative},
3061 {"gattServerSendNotificationNative", "(III[B)V", (void*)gattServerSendNotificationNative},
3062 {"gattServerSendResponseNative", "(IIIIII[BI)V", (void*)gattServerSendResponseNative},
3063 {"gattSubrateRequestNative", "(ILjava/lang/String;IIIII)V",
3064 (void*)gattSubrateRequestNative},
3065
3066 {"gattTestNative", "(IJJLjava/lang/String;IIIII)V", (void*)gattTestNative},
3067 };
3068 const int result =
3069 REGISTER_NATIVE_METHODS(env, "com/android/bluetooth/gatt/GattNativeInterface", methods);
3070 if (result != 0) {
3071 return result;
3072 }
3073
3074 const JNIJavaMethod javaMethods[] = {
3075 // Client callbacks
3076 {"onClientRegistered", "(IIJJ)V", &method_onClientRegistered},
3077 {"onConnected", "(IIILjava/lang/String;)V", &method_onConnected},
3078 {"onDisconnected", "(IIILjava/lang/String;)V", &method_onDisconnected},
3079 {"onReadCharacteristic", "(III[B)V", &method_onReadCharacteristic},
3080 {"onWriteCharacteristic", "(III[B)V", &method_onWriteCharacteristic},
3081 {"onExecuteCompleted", "(II)V", &method_onExecuteCompleted},
3082 {"onSearchCompleted", "(II)V", &method_onSearchCompleted},
3083 {"onReadDescriptor", "(III[B)V", &method_onReadDescriptor},
3084 {"onWriteDescriptor", "(III[B)V", &method_onWriteDescriptor},
3085 {"onNotify", "(ILjava/lang/String;IZ[B)V", &method_onNotify},
3086 {"onRegisterForNotifications", "(IIII)V", &method_onRegisterForNotifications},
3087 {"onReadRemoteRssi", "(ILjava/lang/String;II)V", &method_onReadRemoteRssi},
3088 {"onConfigureMTU", "(III)V", &method_onConfigureMTU},
3089 {"onClientCongestion", "(IZ)V", &method_onClientCongestion},
3090 {"getSampleGattDbElement", "()Lcom/android/bluetooth/gatt/GattDbElement;",
3091 &method_getSampleGattDbElement},
3092 {"onGetGattDb", "(ILjava/util/List;)V", &method_onGetGattDb},
3093 {"onClientPhyRead", "(ILjava/lang/String;III)V", &method_onClientPhyRead},
3094 {"onClientPhyUpdate", "(IIII)V", &method_onClientPhyUpdate},
3095 {"onClientConnUpdate", "(IIIII)V", &method_onClientConnUpdate},
3096 {"onServiceChanged", "(I)V", &method_onServiceChanged},
3097 {"onClientSubrateChange", "(IIIIII)V", &method_onClientSubrateChange},
3098
3099 // Server callbacks
3100 {"onServerRegistered", "(IIJJ)V", &method_onServerRegistered},
3101 {"onClientConnected", "(Ljava/lang/String;ZII)V", &method_onClientConnected},
3102 {"onServiceAdded", "(IILjava/util/List;)V", &method_onServiceAdded},
3103 {"onServiceStopped", "(III)V", &method_onServiceStopped},
3104 {"onServiceDeleted", "(III)V", &method_onServiceDeleted},
3105 {"onResponseSendCompleted", "(II)V", &method_onResponseSendCompleted},
3106 {"onServerReadCharacteristic", "(Ljava/lang/String;IIIIZ)V",
3107 &method_onServerReadCharacteristic},
3108 {"onServerReadDescriptor", "(Ljava/lang/String;IIIIZ)V", &method_onServerReadDescriptor},
3109 {"onServerWriteCharacteristic", "(Ljava/lang/String;IIIIIZZ[B)V",
3110 &method_onServerWriteCharacteristic},
3111 {"onServerWriteDescriptor", "(Ljava/lang/String;IIIIIZZ[B)V",
3112 &method_onServerWriteDescriptor},
3113 {"onExecuteWrite", "(Ljava/lang/String;III)V", &method_onExecuteWrite},
3114 {"onNotificationSent", "(II)V", &method_onNotificationSent},
3115 {"onServerCongestion", "(IZ)V", &method_onServerCongestion},
3116 {"onMtuChanged", "(II)V", &method_onServerMtuChanged},
3117 {"onServerPhyRead", "(ILjava/lang/String;III)V", &method_onServerPhyRead},
3118 {"onServerPhyUpdate", "(IIII)V", &method_onServerPhyUpdate},
3119 {"onServerConnUpdate", "(IIIII)V", &method_onServerConnUpdate},
3120 {"onServerSubrateChange", "(IIIIII)V", &method_onServerSubrateChange},
3121 };
3122 GET_JAVA_METHODS(env, "com/android/bluetooth/gatt/GattNativeInterface", javaMethods);
3123 return 0;
3124 }
3125
register_com_android_bluetooth_gatt(JNIEnv * env)3126 int register_com_android_bluetooth_gatt(JNIEnv* env) {
3127 const std::array<std::function<int(JNIEnv*)>, 5> register_fns = {
3128 register_com_android_bluetooth_gatt_scan,
3129 register_com_android_bluetooth_gatt_advertise_manager,
3130 register_com_android_bluetooth_gatt_periodic_scan,
3131 register_com_android_bluetooth_gatt_distance_measurement,
3132 register_com_android_bluetooth_gatt_,
3133 };
3134
3135 for (const auto& fn : register_fns) {
3136 const int result = fn(env);
3137 if (result != 0) {
3138 return result;
3139 }
3140 }
3141 return 0;
3142 }
3143 } // namespace android
3144