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