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