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