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