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