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