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