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