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 18#define LOG_TAG "BtGatt.JNI" 19 20#define LOG_NDEBUG 0 21 22#define CHECK_CALLBACK_ENV \ 23 if (!checkCallbackThread()) { \ 24 error("Callback: '%s' is not called on the correct thread", __FUNCTION__);\ 25 return; \ 26 } 27 28#include "com_android_bluetooth.h" 29#include "hardware/bt_gatt.h" 30#include "utils/Log.h" 31#include "android_runtime/AndroidRuntime.h" 32 33#include <string.h> 34 35#include <cutils/log.h> 36#define info(fmt, ...) ALOGI ("%s(L%d): " fmt,__FUNCTION__, __LINE__, ## __VA_ARGS__) 37#define debug(fmt, ...) ALOGD ("%s(L%d): " fmt,__FUNCTION__, __LINE__, ## __VA_ARGS__) 38#define warn(fmt, ...) ALOGW ("WARNING: %s(L%d): " fmt "##",__FUNCTION__, __LINE__, ## __VA_ARGS__) 39#define error(fmt, ...) ALOGE ("ERROR: %s(L%d): " fmt "##",__FUNCTION__, __LINE__, ## __VA_ARGS__) 40#define asrt(s) if(!(s)) ALOGE ("%s(L%d): ASSERT %s failed! ##",__FUNCTION__, __LINE__, #s) 41 42#define BD_ADDR_LEN 6 43 44#define UUID_PARAMS(uuid_ptr) \ 45 uuid_lsb(uuid_ptr), uuid_msb(uuid_ptr) 46 47#define GATT_ID_PARAMS(attr_ptr) \ 48 attr_ptr->inst_id, \ 49 UUID_PARAMS((&attr_ptr->uuid)) 50 51#define SRVC_ID_PARAMS(srvc_ptr) \ 52 (srvc_ptr->is_primary ? \ 53 BTGATT_SERVICE_TYPE_PRIMARY : BTGATT_SERVICE_TYPE_SECONDARY), \ 54 GATT_ID_PARAMS((&srvc_ptr->id)) 55 56 57static void set_uuid(uint8_t* uuid, jlong uuid_msb, jlong uuid_lsb) 58{ 59 for (int i = 0; i != 8; ++i) 60 { 61 uuid[i] = (uuid_lsb >> (8 * i)) & 0xFF; 62 uuid[i + 8] = (uuid_msb >> (8 * i)) & 0xFF; 63 } 64} 65 66static uint64_t uuid_lsb(const bt_uuid_t* uuid) 67{ 68 uint64_t lsb = 0; 69 int i; 70 71 for (i = 7; i >= 0; i--) 72 { 73 lsb <<= 8; 74 lsb |= uuid->uu[i]; 75 } 76 77 return lsb; 78} 79 80static uint64_t uuid_msb(const bt_uuid_t* uuid) 81{ 82 uint64_t msb = 0; 83 int i; 84 85 for (i = 15; i >= 8; i--) 86 { 87 msb <<= 8; 88 msb |= uuid->uu[i]; 89 } 90 91 return msb; 92} 93 94static void bd_addr_str_to_addr(const char* str, uint8_t *bd_addr) 95{ 96 int i; 97 char c; 98 99 c = *str++; 100 for (i = 0; i < BD_ADDR_LEN; i++) 101 { 102 if (c >= '0' && c <= '9') 103 bd_addr[i] = c - '0'; 104 else if (c >= 'a' && c <= 'z') 105 bd_addr[i] = c - 'a' + 10; 106 else // (c >= 'A' && c <= 'Z') 107 bd_addr[i] = c - 'A' + 10; 108 109 c = *str++; 110 if (c != ':') 111 { 112 bd_addr[i] <<= 4; 113 if (c >= '0' && c <= '9') 114 bd_addr[i] |= c - '0'; 115 else if (c >= 'a' && c <= 'z') 116 bd_addr[i] |= c - 'a' + 10; 117 else // (c >= 'A' && c <= 'Z') 118 bd_addr[i] |= c - 'A' + 10; 119 120 c = *str++; 121 } 122 123 c = *str++; 124 } 125} 126 127static void jstr2bdaddr(JNIEnv* env, bt_bdaddr_t *bda, jstring address) 128{ 129 const char* c_bda = env->GetStringUTFChars(address, NULL); 130 if (c_bda != NULL && bda != NULL && strlen(c_bda) == 17) 131 { 132 bd_addr_str_to_addr(c_bda, bda->address); 133 env->ReleaseStringUTFChars(address, c_bda); 134 } 135} 136 137namespace android { 138 139/** 140 * Client callback methods 141 */ 142 143static jmethodID method_onClientRegistered; 144static jmethodID method_onScanResult; 145static jmethodID method_onConnected; 146static jmethodID method_onDisconnected; 147static jmethodID method_onReadCharacteristic; 148static jmethodID method_onWriteCharacteristic; 149static jmethodID method_onExecuteCompleted; 150static jmethodID method_onSearchCompleted; 151static jmethodID method_onReadDescriptor; 152static jmethodID method_onWriteDescriptor; 153static jmethodID method_onNotify; 154static jmethodID method_onRegisterForNotifications; 155static jmethodID method_onReadRemoteRssi; 156static jmethodID method_onAdvertiseCallback; 157static jmethodID method_onConfigureMTU; 158static jmethodID method_onScanFilterConfig; 159static jmethodID method_onScanFilterParamsConfigured; 160static jmethodID method_onScanFilterEnableDisabled; 161static jmethodID method_onMultiAdvEnable; 162static jmethodID method_onMultiAdvUpdate; 163static jmethodID method_onMultiAdvSetAdvData; 164static jmethodID method_onMultiAdvDisable; 165static jmethodID method_onClientCongestion; 166static jmethodID method_onBatchScanStorageConfigured; 167static jmethodID method_onBatchScanStartStopped; 168static jmethodID method_onBatchScanReports; 169static jmethodID method_onBatchScanThresholdCrossed; 170 171static jmethodID method_CreateonTrackAdvFoundLostObject; 172static jmethodID method_onTrackAdvFoundLost; 173static jmethodID method_onScanParamSetupCompleted; 174static jmethodID method_getSampleGattDbElement; 175static jmethodID method_onGetGattDb; 176 177/** 178 * Server callback methods 179 */ 180static jmethodID method_onServerRegistered; 181static jmethodID method_onClientConnected; 182static jmethodID method_onServiceAdded; 183static jmethodID method_onIncludedServiceAdded; 184static jmethodID method_onCharacteristicAdded; 185static jmethodID method_onDescriptorAdded; 186static jmethodID method_onServiceStarted; 187static jmethodID method_onServiceStopped; 188static jmethodID method_onServiceDeleted; 189static jmethodID method_onResponseSendCompleted; 190static jmethodID method_onAttributeRead; 191static jmethodID method_onAttributeWrite; 192static jmethodID method_onExecuteWrite; 193static jmethodID method_onNotificationSent; 194static jmethodID method_onServerCongestion; 195static jmethodID method_onServerMtuChanged; 196 197/** 198 * Static variables 199 */ 200 201static const btgatt_interface_t *sGattIf = NULL; 202static jobject mCallbacksObj = NULL; 203static JNIEnv *sCallbackEnv = NULL; 204 205static bool checkCallbackThread() { 206 sCallbackEnv = getCallbackEnv(); 207 208 JNIEnv* env = AndroidRuntime::getJNIEnv(); 209 if (sCallbackEnv != env || sCallbackEnv == NULL) return false; 210 return true; 211} 212 213/** 214 * BTA client callbacks 215 */ 216 217void btgattc_register_app_cb(int status, int clientIf, bt_uuid_t *app_uuid) 218{ 219 CHECK_CALLBACK_ENV 220 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientRegistered, status, 221 clientIf, UUID_PARAMS(app_uuid)); 222 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 223} 224 225void btgattc_scan_result_cb(bt_bdaddr_t* bda, int rssi, uint8_t* adv_data) 226{ 227 CHECK_CALLBACK_ENV 228 229 char c_address[32]; 230 snprintf(c_address, sizeof(c_address),"%02X:%02X:%02X:%02X:%02X:%02X", 231 bda->address[0], bda->address[1], bda->address[2], 232 bda->address[3], bda->address[4], bda->address[5]); 233 234 jstring address = sCallbackEnv->NewStringUTF(c_address); 235 jbyteArray jb = sCallbackEnv->NewByteArray(62); 236 sCallbackEnv->SetByteArrayRegion(jb, 0, 62, (jbyte *) adv_data); 237 238 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScanResult 239 , address, rssi, jb); 240 241 sCallbackEnv->DeleteLocalRef(address); 242 sCallbackEnv->DeleteLocalRef(jb); 243 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 244} 245 246void btgattc_open_cb(int conn_id, int status, int clientIf, bt_bdaddr_t* bda) 247{ 248 CHECK_CALLBACK_ENV 249 250 char c_address[32]; 251 snprintf(c_address, sizeof(c_address),"%02X:%02X:%02X:%02X:%02X:%02X", 252 bda->address[0], bda->address[1], bda->address[2], 253 bda->address[3], bda->address[4], bda->address[5]); 254 255 jstring address = sCallbackEnv->NewStringUTF(c_address); 256 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnected, 257 clientIf, conn_id, status, address); 258 sCallbackEnv->DeleteLocalRef(address); 259 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 260} 261 262void btgattc_close_cb(int conn_id, int status, int clientIf, bt_bdaddr_t* bda) 263{ 264 CHECK_CALLBACK_ENV 265 char c_address[32]; 266 snprintf(c_address, sizeof(c_address),"%02X:%02X:%02X:%02X:%02X:%02X", 267 bda->address[0], bda->address[1], bda->address[2], 268 bda->address[3], bda->address[4], bda->address[5]); 269 270 jstring address = sCallbackEnv->NewStringUTF(c_address); 271 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onDisconnected, 272 clientIf, conn_id, status, address); 273 sCallbackEnv->DeleteLocalRef(address); 274 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 275} 276 277void btgattc_search_complete_cb(int conn_id, int status) 278{ 279 CHECK_CALLBACK_ENV 280 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onSearchCompleted, 281 conn_id, status); 282 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 283} 284 285void btgattc_register_for_notification_cb(int conn_id, int registered, int status, uint16_t handle) 286{ 287 CHECK_CALLBACK_ENV 288 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onRegisterForNotifications, 289 conn_id, status, registered, handle); 290 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 291} 292 293void btgattc_notify_cb(int conn_id, btgatt_notify_params_t *p_data) 294{ 295 CHECK_CALLBACK_ENV 296 297 char c_address[32]; 298 snprintf(c_address, sizeof(c_address), "%02X:%02X:%02X:%02X:%02X:%02X", 299 p_data->bda.address[0], p_data->bda.address[1], p_data->bda.address[2], 300 p_data->bda.address[3], p_data->bda.address[4], p_data->bda.address[5]); 301 302 jstring address = sCallbackEnv->NewStringUTF(c_address); 303 jbyteArray jb = sCallbackEnv->NewByteArray(p_data->len); 304 sCallbackEnv->SetByteArrayRegion(jb, 0, p_data->len, (jbyte *) p_data->value); 305 306 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNotify 307 , conn_id, address, p_data->handle, p_data->is_notify, jb); 308 309 sCallbackEnv->DeleteLocalRef(address); 310 sCallbackEnv->DeleteLocalRef(jb); 311 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 312} 313 314void btgattc_read_characteristic_cb(int conn_id, int status, btgatt_read_params_t *p_data) 315{ 316 CHECK_CALLBACK_ENV 317 318 jbyteArray jb; 319 if ( status == 0 ) //successful 320 { 321 jb = sCallbackEnv->NewByteArray(p_data->value.len); 322 sCallbackEnv->SetByteArrayRegion(jb, 0, p_data->value.len, 323 (jbyte *) p_data->value.value); 324 } else { 325 uint8_t value = 0; 326 jb = sCallbackEnv->NewByteArray(1); 327 sCallbackEnv->SetByteArrayRegion(jb, 0, 1, (jbyte *) &value); 328 } 329 330 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onReadCharacteristic, 331 conn_id, status, p_data->handle, jb); 332 sCallbackEnv->DeleteLocalRef(jb); 333 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 334} 335 336void btgattc_write_characteristic_cb(int conn_id, int status, uint16_t handle) 337{ 338 CHECK_CALLBACK_ENV 339 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onWriteCharacteristic 340 , conn_id, status, handle); 341 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 342} 343 344void btgattc_execute_write_cb(int conn_id, int status) 345{ 346 CHECK_CALLBACK_ENV 347 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onExecuteCompleted 348 , conn_id, status); 349 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 350} 351 352void btgattc_read_descriptor_cb(int conn_id, int status, btgatt_read_params_t *p_data) 353{ 354 CHECK_CALLBACK_ENV 355 356 jbyteArray jb; 357 if ( p_data->value.len != 0 ) 358 { 359 jb = sCallbackEnv->NewByteArray(p_data->value.len); 360 sCallbackEnv->SetByteArrayRegion(jb, 0, p_data->value.len, 361 (jbyte *) p_data->value.value); 362 } else { 363 jb = sCallbackEnv->NewByteArray(1); 364 } 365 366 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onReadDescriptor, 367 conn_id, status, p_data->handle, jb); 368 369 sCallbackEnv->DeleteLocalRef(jb); 370 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 371} 372 373void btgattc_write_descriptor_cb(int conn_id, int status, uint16_t handle) 374{ 375 CHECK_CALLBACK_ENV 376 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onWriteDescriptor 377 , conn_id, status, handle); 378 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 379} 380 381void btgattc_remote_rssi_cb(int client_if,bt_bdaddr_t* bda, int rssi, int status) 382{ 383 CHECK_CALLBACK_ENV 384 385 char c_address[32]; 386 snprintf(c_address, sizeof(c_address),"%02X:%02X:%02X:%02X:%02X:%02X", 387 bda->address[0], bda->address[1], bda->address[2], 388 bda->address[3], bda->address[4], bda->address[5]); 389 jstring address = sCallbackEnv->NewStringUTF(c_address); 390 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onReadRemoteRssi, 391 client_if, address, rssi, status); 392 sCallbackEnv->DeleteLocalRef(address); 393 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 394} 395 396void btgattc_advertise_cb(int status, int client_if) 397{ 398 CHECK_CALLBACK_ENV 399 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAdvertiseCallback, status, client_if); 400 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 401} 402 403void btgattc_configure_mtu_cb(int conn_id, int status, int mtu) 404{ 405 CHECK_CALLBACK_ENV 406 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConfigureMTU, 407 conn_id, status, mtu); 408 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 409} 410 411void btgattc_scan_filter_cfg_cb(int action, int client_if, int status, int filt_type, 412 int avbl_space) 413{ 414 CHECK_CALLBACK_ENV 415 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScanFilterConfig, 416 action, status, client_if, filt_type, avbl_space); 417 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 418} 419 420void btgattc_scan_filter_param_cb(int action, int client_if, int status, int avbl_space) 421{ 422 CHECK_CALLBACK_ENV 423 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScanFilterParamsConfigured, 424 action, status, client_if, avbl_space); 425 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 426} 427 428void btgattc_scan_filter_status_cb(int action, int client_if, int status) 429{ 430 CHECK_CALLBACK_ENV 431 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScanFilterEnableDisabled, 432 action, status, client_if); 433 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 434} 435 436void btgattc_multiadv_enable_cb(int client_if, int status) 437{ 438 CHECK_CALLBACK_ENV 439 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onMultiAdvEnable, status,client_if); 440 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 441} 442 443void btgattc_multiadv_update_cb(int client_if, int status) 444{ 445 CHECK_CALLBACK_ENV 446 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onMultiAdvUpdate, status, client_if); 447 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 448} 449 450void btgattc_multiadv_setadv_data_cb(int client_if, int status) 451{ 452 CHECK_CALLBACK_ENV 453 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onMultiAdvSetAdvData, status, client_if); 454 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 455} 456 457void btgattc_multiadv_disable_cb(int client_if, int status) 458{ 459 CHECK_CALLBACK_ENV 460 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onMultiAdvDisable, status, client_if); 461 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 462} 463 464void btgattc_congestion_cb(int conn_id, bool congested) 465{ 466 CHECK_CALLBACK_ENV 467 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientCongestion, conn_id, congested); 468 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 469} 470 471void btgattc_batchscan_cfg_storage_cb(int client_if, int status) 472{ 473 CHECK_CALLBACK_ENV 474 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onBatchScanStorageConfigured, status, client_if); 475 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 476} 477 478void btgattc_batchscan_startstop_cb(int startstop_action, int client_if, int status) 479{ 480 CHECK_CALLBACK_ENV 481 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onBatchScanStartStopped, startstop_action, 482 status, client_if); 483 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 484} 485 486void btgattc_batchscan_reports_cb(int client_if, int status, int report_format, 487 int num_records, int data_len, uint8_t *p_rep_data) 488{ 489 CHECK_CALLBACK_ENV 490 jbyteArray jb = sCallbackEnv->NewByteArray(data_len); 491 sCallbackEnv->SetByteArrayRegion(jb, 0, data_len, (jbyte *) p_rep_data); 492 493 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onBatchScanReports, status, client_if, 494 report_format, num_records, jb); 495 sCallbackEnv->DeleteLocalRef(jb); 496 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 497} 498 499void btgattc_batchscan_threshold_cb(int client_if) 500{ 501 CHECK_CALLBACK_ENV 502 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onBatchScanThresholdCrossed, client_if); 503 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 504} 505 506void btgattc_track_adv_event_cb(btgatt_track_adv_info_t *p_adv_track_info) 507{ 508 CHECK_CALLBACK_ENV 509 char c_address[32]; 510 jobject trackadv_obj = NULL; 511 512 snprintf(c_address, sizeof(c_address),"%02X:%02X:%02X:%02X:%02X:%02X", 513 p_adv_track_info->bd_addr.address[0], p_adv_track_info->bd_addr.address[1], 514 p_adv_track_info->bd_addr.address[2], p_adv_track_info->bd_addr.address[3], 515 p_adv_track_info->bd_addr.address[4], p_adv_track_info->bd_addr.address[5]); 516 517 jstring address = sCallbackEnv->NewStringUTF(c_address); 518 519 jbyteArray jb_adv_pkt = sCallbackEnv->NewByteArray(p_adv_track_info->adv_pkt_len); 520 jbyteArray jb_scan_rsp = sCallbackEnv->NewByteArray(p_adv_track_info->scan_rsp_len); 521 522 sCallbackEnv->SetByteArrayRegion(jb_adv_pkt, 0, p_adv_track_info->adv_pkt_len, 523 (jbyte *) p_adv_track_info->p_adv_pkt_data); 524 525 sCallbackEnv->SetByteArrayRegion(jb_scan_rsp, 0, p_adv_track_info->scan_rsp_len, 526 (jbyte *) p_adv_track_info->p_scan_rsp_data); 527 528 trackadv_obj = sCallbackEnv->CallObjectMethod(mCallbacksObj, method_CreateonTrackAdvFoundLostObject, 529 p_adv_track_info->client_if, p_adv_track_info->adv_pkt_len, jb_adv_pkt, 530 p_adv_track_info->scan_rsp_len, jb_scan_rsp, p_adv_track_info->filt_index, 531 p_adv_track_info->advertiser_state, p_adv_track_info->advertiser_info_present, 532 address, p_adv_track_info->addr_type, p_adv_track_info->tx_power, 533 p_adv_track_info->rssi_value, p_adv_track_info->time_stamp); 534 535 if (NULL != trackadv_obj) { 536 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onTrackAdvFoundLost, trackadv_obj); 537 sCallbackEnv->DeleteLocalRef(trackadv_obj); 538 } 539 sCallbackEnv->DeleteLocalRef(address); 540 sCallbackEnv->DeleteLocalRef(jb_adv_pkt); 541 sCallbackEnv->DeleteLocalRef(jb_scan_rsp); 542 543 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 544} 545 546void btgattc_scan_parameter_setup_completed_cb(int client_if, btgattc_error_t status) 547{ 548 CHECK_CALLBACK_ENV 549 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScanParamSetupCompleted, status, client_if); 550 checkAndClearExceptionFromCallback(sCallbackEnv, __func__); 551} 552 553void btgattc_get_gatt_db_cb(int conn_id, btgatt_db_element_t *db, int count) 554{ 555 CHECK_CALLBACK_ENV 556 557 // Because JNI uses a different class loader in the callback context, we cannot simply get the class. 558 // As a workaround, we have to make sure we obtain an object of the class first, as this will cause 559 // class loader to load it. 560 jobject objectForClass = sCallbackEnv->CallObjectMethod(mCallbacksObj, method_getSampleGattDbElement); 561 jclass gattDbElementClazz = sCallbackEnv->GetObjectClass(objectForClass); 562 sCallbackEnv->DeleteLocalRef(objectForClass); 563 564 jmethodID gattDbElementConstructor = sCallbackEnv->GetMethodID(gattDbElementClazz, "<init>", "()V"); 565 566 jclass arrayListclazz = sCallbackEnv->FindClass("java/util/ArrayList"); 567 jobject array = sCallbackEnv->NewObject(arrayListclazz, sCallbackEnv->GetMethodID(arrayListclazz, "<init>", "()V")); 568 jmethodID arrayAdd = sCallbackEnv->GetMethodID(arrayListclazz, "add", "(Ljava/lang/Object;)Z"); 569 sCallbackEnv->DeleteLocalRef(arrayListclazz); 570 571 jclass uuidClazz = sCallbackEnv->FindClass("java/util/UUID"); 572 jmethodID uuidConstructor = sCallbackEnv->GetMethodID(uuidClazz, "<init>", "(JJ)V"); 573 574 for (int i = 0; i < count; i++) { 575 const btgatt_db_element_t &curr = db[i]; 576 577 jobject element = sCallbackEnv->NewObject(gattDbElementClazz, gattDbElementConstructor); 578 579 jfieldID fid = sCallbackEnv->GetFieldID(gattDbElementClazz, "id", "I"); 580 sCallbackEnv->SetIntField(element, fid, curr.id); 581 582 jobject uuid = sCallbackEnv->NewObject(uuidClazz, uuidConstructor, uuid_msb(&curr.uuid), uuid_lsb(&curr.uuid)); 583 fid = sCallbackEnv->GetFieldID(gattDbElementClazz, "uuid", "java/util/UUID"); 584 sCallbackEnv->SetObjectField(element, fid, uuid); 585 sCallbackEnv->DeleteLocalRef(uuid); 586 587 fid = sCallbackEnv->GetFieldID(gattDbElementClazz, "type", "I"); 588 sCallbackEnv->SetIntField(element, fid, curr.type); 589 590 fid = sCallbackEnv->GetFieldID(gattDbElementClazz, "attributeHandle", "I"); 591 sCallbackEnv->SetIntField(element, fid, curr.attribute_handle); 592 593 fid = sCallbackEnv->GetFieldID(gattDbElementClazz, "startHandle", "I"); 594 sCallbackEnv->SetIntField(element, fid, curr.start_handle); 595 596 fid = sCallbackEnv->GetFieldID(gattDbElementClazz, "endHandle", "I"); 597 sCallbackEnv->SetIntField(element, fid, curr.end_handle); 598 599 fid = sCallbackEnv->GetFieldID(gattDbElementClazz, "properties", "I"); 600 sCallbackEnv->SetIntField(element, fid, curr.properties); 601 602 sCallbackEnv->CallBooleanMethod(array, arrayAdd, element); 603 sCallbackEnv->DeleteLocalRef(element); 604 } 605 606 sCallbackEnv->DeleteLocalRef(gattDbElementClazz); 607 sCallbackEnv->DeleteLocalRef(uuidClazz); 608 609 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onGetGattDb, conn_id, array); 610 sCallbackEnv->DeleteLocalRef(array); 611 612 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 613} 614 615static const btgatt_client_callbacks_t sGattClientCallbacks = { 616 btgattc_register_app_cb, 617 btgattc_scan_result_cb, 618 btgattc_open_cb, 619 btgattc_close_cb, 620 btgattc_search_complete_cb, 621 btgattc_register_for_notification_cb, 622 btgattc_notify_cb, 623 btgattc_read_characteristic_cb, 624 btgattc_write_characteristic_cb, 625 btgattc_read_descriptor_cb, 626 btgattc_write_descriptor_cb, 627 btgattc_execute_write_cb, 628 btgattc_remote_rssi_cb, 629 btgattc_advertise_cb, 630 btgattc_configure_mtu_cb, 631 btgattc_scan_filter_cfg_cb, 632 btgattc_scan_filter_param_cb, 633 btgattc_scan_filter_status_cb, 634 btgattc_multiadv_enable_cb, 635 btgattc_multiadv_update_cb, 636 btgattc_multiadv_setadv_data_cb, 637 btgattc_multiadv_disable_cb, 638 btgattc_congestion_cb, 639 btgattc_batchscan_cfg_storage_cb, 640 btgattc_batchscan_startstop_cb, 641 btgattc_batchscan_reports_cb, 642 btgattc_batchscan_threshold_cb, 643 btgattc_track_adv_event_cb, 644 btgattc_scan_parameter_setup_completed_cb, 645 btgattc_get_gatt_db_cb, 646 NULL, /* services_removed_cb */ 647 NULL /* services_added_cb */ 648}; 649 650 651/** 652 * BTA server callbacks 653 */ 654 655void btgatts_register_app_cb(int status, int server_if, bt_uuid_t *uuid) 656{ 657 CHECK_CALLBACK_ENV 658 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerRegistered 659 , status, server_if, UUID_PARAMS(uuid)); 660 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 661} 662 663void btgatts_connection_cb(int conn_id, int server_if, int connected, bt_bdaddr_t *bda) 664{ 665 CHECK_CALLBACK_ENV 666 667 char c_address[32]; 668 sprintf(c_address, "%02X:%02X:%02X:%02X:%02X:%02X", 669 bda->address[0], bda->address[1], bda->address[2], 670 bda->address[3], bda->address[4], bda->address[5]); 671 672 jstring address = sCallbackEnv->NewStringUTF(c_address); 673 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientConnected, 674 address, connected, conn_id, server_if); 675 sCallbackEnv->DeleteLocalRef(address); 676 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 677} 678 679void btgatts_service_added_cb(int status, int server_if, 680 btgatt_srvc_id_t *srvc_id, int srvc_handle) 681{ 682 CHECK_CALLBACK_ENV 683 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceAdded, status, 684 server_if, SRVC_ID_PARAMS(srvc_id), 685 srvc_handle); 686 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 687} 688 689void btgatts_included_service_added_cb(int status, int server_if, 690 int srvc_handle, 691 int incl_srvc_handle) 692{ 693 CHECK_CALLBACK_ENV 694 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onIncludedServiceAdded, 695 status, server_if, srvc_handle, incl_srvc_handle); 696 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 697} 698 699void btgatts_characteristic_added_cb(int status, int server_if, bt_uuid_t *char_id, 700 int srvc_handle, int char_handle) 701{ 702 CHECK_CALLBACK_ENV 703 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onCharacteristicAdded, 704 status, server_if, UUID_PARAMS(char_id), 705 srvc_handle, char_handle); 706 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 707} 708 709void btgatts_descriptor_added_cb(int status, int server_if, 710 bt_uuid_t *descr_id, int srvc_handle, 711 int descr_handle) 712{ 713 CHECK_CALLBACK_ENV 714 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onDescriptorAdded, 715 status, server_if, UUID_PARAMS(descr_id), 716 srvc_handle, descr_handle); 717 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 718} 719 720void btgatts_service_started_cb(int status, int server_if, int srvc_handle) 721{ 722 CHECK_CALLBACK_ENV 723 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceStarted, status, 724 server_if, srvc_handle); 725 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 726} 727 728void btgatts_service_stopped_cb(int status, int server_if, int srvc_handle) 729{ 730 CHECK_CALLBACK_ENV 731 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceStopped, status, 732 server_if, srvc_handle); 733 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 734} 735 736void btgatts_service_deleted_cb(int status, int server_if, int srvc_handle) 737{ 738 CHECK_CALLBACK_ENV 739 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceDeleted, status, 740 server_if, srvc_handle); 741 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 742} 743 744void btgatts_request_read_cb(int conn_id, int trans_id, bt_bdaddr_t *bda, 745 int attr_handle, int offset, bool is_long) 746{ 747 CHECK_CALLBACK_ENV 748 749 char c_address[32]; 750 sprintf(c_address, "%02X:%02X:%02X:%02X:%02X:%02X", 751 bda->address[0], bda->address[1], bda->address[2], 752 bda->address[3], bda->address[4], bda->address[5]); 753 754 jstring address = sCallbackEnv->NewStringUTF(c_address); 755 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAttributeRead, 756 address, conn_id, trans_id, attr_handle, 757 offset, is_long); 758 sCallbackEnv->DeleteLocalRef(address); 759 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 760} 761 762void btgatts_request_write_cb(int conn_id, int trans_id, 763 bt_bdaddr_t *bda, int attr_handle, 764 int offset, int length, 765 bool need_rsp, bool is_prep, uint8_t* value) 766{ 767 CHECK_CALLBACK_ENV 768 769 char c_address[32]; 770 sprintf(c_address, "%02X:%02X:%02X:%02X:%02X:%02X", 771 bda->address[0], bda->address[1], bda->address[2], 772 bda->address[3], bda->address[4], bda->address[5]); 773 774 jstring address = sCallbackEnv->NewStringUTF(c_address); 775 776 jbyteArray val = sCallbackEnv->NewByteArray(length); 777 if (val) sCallbackEnv->SetByteArrayRegion(val, 0, length, (jbyte*)value); 778 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAttributeWrite, 779 address, conn_id, trans_id, attr_handle, 780 offset, length, need_rsp, is_prep, val); 781 sCallbackEnv->DeleteLocalRef(address); 782 sCallbackEnv->DeleteLocalRef(val); 783 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 784} 785 786void btgatts_request_exec_write_cb(int conn_id, int trans_id, 787 bt_bdaddr_t *bda, int exec_write) 788{ 789 CHECK_CALLBACK_ENV 790 791 char c_address[32]; 792 sprintf(c_address, "%02X:%02X:%02X:%02X:%02X:%02X", 793 bda->address[0], bda->address[1], bda->address[2], 794 bda->address[3], bda->address[4], bda->address[5]); 795 796 jstring address = sCallbackEnv->NewStringUTF(c_address); 797 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onExecuteWrite, 798 address, conn_id, trans_id, exec_write); 799 sCallbackEnv->DeleteLocalRef(address); 800 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 801} 802 803void btgatts_response_confirmation_cb(int status, int handle) 804{ 805 CHECK_CALLBACK_ENV 806 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onResponseSendCompleted, 807 status, handle); 808 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 809} 810 811void btgatts_indication_sent_cb(int conn_id, int status) 812{ 813 CHECK_CALLBACK_ENV 814 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNotificationSent, 815 conn_id, status); 816 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 817} 818 819void btgatts_congestion_cb(int conn_id, bool congested) 820{ 821 CHECK_CALLBACK_ENV 822 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerCongestion, conn_id, congested); 823 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 824} 825 826void btgatts_mtu_changed_cb(int conn_id, int mtu) 827{ 828 CHECK_CALLBACK_ENV 829 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerMtuChanged, conn_id, mtu); 830 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 831} 832 833static const btgatt_server_callbacks_t sGattServerCallbacks = { 834 btgatts_register_app_cb, 835 btgatts_connection_cb, 836 btgatts_service_added_cb, 837 btgatts_included_service_added_cb, 838 btgatts_characteristic_added_cb, 839 btgatts_descriptor_added_cb, 840 btgatts_service_started_cb, 841 btgatts_service_stopped_cb, 842 btgatts_service_deleted_cb, 843 btgatts_request_read_cb, 844 btgatts_request_write_cb, 845 btgatts_request_exec_write_cb, 846 btgatts_response_confirmation_cb, 847 btgatts_indication_sent_cb, 848 btgatts_congestion_cb, 849 btgatts_mtu_changed_cb 850}; 851 852/** 853 * GATT callbacks 854 */ 855 856static const btgatt_callbacks_t sGattCallbacks = { 857 sizeof(btgatt_callbacks_t), 858 &sGattClientCallbacks, 859 &sGattServerCallbacks 860}; 861 862/** 863 * Native function definitions 864 */ 865static void classInitNative(JNIEnv* env, jclass clazz) { 866 867 // Client callbacks 868 869 method_onClientRegistered = env->GetMethodID(clazz, "onClientRegistered", "(IIJJ)V"); 870 method_onScanResult = env->GetMethodID(clazz, "onScanResult", "(Ljava/lang/String;I[B)V"); 871 method_onConnected = env->GetMethodID(clazz, "onConnected", "(IIILjava/lang/String;)V"); 872 method_onDisconnected = env->GetMethodID(clazz, "onDisconnected", "(IIILjava/lang/String;)V"); 873 method_onReadCharacteristic = env->GetMethodID(clazz, "onReadCharacteristic", "(III[B)V"); 874 method_onWriteCharacteristic = env->GetMethodID(clazz, "onWriteCharacteristic", "(III)V"); 875 method_onExecuteCompleted = env->GetMethodID(clazz, "onExecuteCompleted", "(II)V"); 876 method_onSearchCompleted = env->GetMethodID(clazz, "onSearchCompleted", "(II)V"); 877 method_onReadDescriptor = env->GetMethodID(clazz, "onReadDescriptor", "(III[B)V"); 878 method_onWriteDescriptor = env->GetMethodID(clazz, "onWriteDescriptor", "(III)V"); 879 method_onNotify = env->GetMethodID(clazz, "onNotify", "(ILjava/lang/String;IZ[B)V"); 880 method_onRegisterForNotifications = env->GetMethodID(clazz, "onRegisterForNotifications", "(IIII)V"); 881 method_onReadRemoteRssi = env->GetMethodID(clazz, "onReadRemoteRssi", "(ILjava/lang/String;II)V"); 882 method_onConfigureMTU = env->GetMethodID(clazz, "onConfigureMTU", "(III)V"); 883 method_onAdvertiseCallback = env->GetMethodID(clazz, "onAdvertiseCallback", "(II)V"); 884 method_onScanFilterConfig = env->GetMethodID(clazz, "onScanFilterConfig", "(IIIII)V"); 885 method_onScanFilterParamsConfigured = env->GetMethodID(clazz, "onScanFilterParamsConfigured", "(IIII)V"); 886 method_onScanFilterEnableDisabled = env->GetMethodID(clazz, "onScanFilterEnableDisabled", "(III)V"); 887 method_onMultiAdvEnable = env->GetMethodID(clazz, "onAdvertiseInstanceEnabled", "(II)V"); 888 method_onMultiAdvUpdate = env->GetMethodID(clazz, "onAdvertiseDataUpdated", "(II)V"); 889 method_onMultiAdvSetAdvData = env->GetMethodID(clazz, "onAdvertiseDataSet", "(II)V"); 890 method_onMultiAdvDisable = env->GetMethodID(clazz, "onAdvertiseInstanceDisabled", "(II)V"); 891 method_onClientCongestion = env->GetMethodID(clazz, "onClientCongestion", "(IZ)V"); 892 method_onBatchScanStorageConfigured = env->GetMethodID(clazz, "onBatchScanStorageConfigured", "(II)V"); 893 method_onBatchScanStartStopped = env->GetMethodID(clazz, "onBatchScanStartStopped", "(III)V"); 894 method_onBatchScanReports = env->GetMethodID(clazz, "onBatchScanReports", "(IIII[B)V"); 895 method_onBatchScanThresholdCrossed = env->GetMethodID(clazz, "onBatchScanThresholdCrossed", "(I)V"); 896 method_CreateonTrackAdvFoundLostObject = env->GetMethodID(clazz, "CreateonTrackAdvFoundLostObject", "(II[BI[BIIILjava/lang/String;IIII)Lcom/android/bluetooth/gatt/AdvtFilterOnFoundOnLostInfo;"); 897 method_onTrackAdvFoundLost = env->GetMethodID(clazz, "onTrackAdvFoundLost", 898 "(Lcom/android/bluetooth/gatt/AdvtFilterOnFoundOnLostInfo;)V"); 899 method_onScanParamSetupCompleted = env->GetMethodID(clazz, "onScanParamSetupCompleted", "(II)V"); 900 method_getSampleGattDbElement = env->GetMethodID(clazz, "GetSampleGattDbElement", "()Lcom/android/bluetooth/gatt/GattDbElement;"); 901 method_onGetGattDb = env->GetMethodID(clazz, "onGetGattDb", "(ILjava/util/ArrayList;)V"); 902 903 // Server callbacks 904 905 method_onServerRegistered = env->GetMethodID(clazz, "onServerRegistered", "(IIJJ)V"); 906 method_onClientConnected = env->GetMethodID(clazz, "onClientConnected", "(Ljava/lang/String;ZII)V"); 907 method_onServiceAdded = env->GetMethodID(clazz, "onServiceAdded", "(IIIIJJI)V"); 908 method_onIncludedServiceAdded = env->GetMethodID(clazz, "onIncludedServiceAdded", "(IIII)V"); 909 method_onCharacteristicAdded = env->GetMethodID(clazz, "onCharacteristicAdded", "(IIJJII)V"); 910 method_onDescriptorAdded = env->GetMethodID(clazz, "onDescriptorAdded", "(IIJJII)V"); 911 method_onServiceStarted = env->GetMethodID(clazz, "onServiceStarted", "(III)V"); 912 method_onServiceStopped = env->GetMethodID(clazz, "onServiceStopped", "(III)V"); 913 method_onServiceDeleted = env->GetMethodID(clazz, "onServiceDeleted", "(III)V"); 914 method_onResponseSendCompleted = env->GetMethodID(clazz, "onResponseSendCompleted", "(II)V"); 915 method_onAttributeRead= env->GetMethodID(clazz, "onAttributeRead", "(Ljava/lang/String;IIIIZ)V"); 916 method_onAttributeWrite= env->GetMethodID(clazz, "onAttributeWrite", "(Ljava/lang/String;IIIIIZZ[B)V"); 917 method_onExecuteWrite= env->GetMethodID(clazz, "onExecuteWrite", "(Ljava/lang/String;III)V"); 918 method_onNotificationSent = env->GetMethodID(clazz, "onNotificationSent", "(II)V"); 919 method_onServerCongestion = env->GetMethodID(clazz, "onServerCongestion", "(IZ)V"); 920 method_onServerMtuChanged = env->GetMethodID(clazz, "onMtuChanged", "(II)V"); 921 922 info("classInitNative: Success!"); 923} 924 925static const bt_interface_t* btIf; 926 927static void initializeNative(JNIEnv *env, jobject object) { 928 if(btIf) 929 return; 930 931 if ( (btIf = getBluetoothInterface()) == NULL) { 932 error("Bluetooth module is not loaded"); 933 return; 934 } 935 936 if (sGattIf != NULL) { 937 ALOGW("Cleaning up Bluetooth GATT Interface before initializing..."); 938 sGattIf->cleanup(); 939 sGattIf = NULL; 940 } 941 942 if (mCallbacksObj != NULL) { 943 ALOGW("Cleaning up Bluetooth GATT callback object"); 944 env->DeleteGlobalRef(mCallbacksObj); 945 mCallbacksObj = NULL; 946 } 947 948 if ( (sGattIf = (btgatt_interface_t *) 949 btIf->get_profile_interface(BT_PROFILE_GATT_ID)) == NULL) { 950 error("Failed to get Bluetooth GATT Interface"); 951 return; 952 } 953 954 bt_status_t status; 955 if ( (status = sGattIf->init(&sGattCallbacks)) != BT_STATUS_SUCCESS) { 956 error("Failed to initialize Bluetooth GATT, status: %d", status); 957 sGattIf = NULL; 958 return; 959 } 960 961 mCallbacksObj = env->NewGlobalRef(object); 962} 963 964static void cleanupNative(JNIEnv *env, jobject object) { 965 if (!btIf) return; 966 967 if (sGattIf != NULL) { 968 sGattIf->cleanup(); 969 sGattIf = NULL; 970 } 971 972 if (mCallbacksObj != NULL) { 973 env->DeleteGlobalRef(mCallbacksObj); 974 mCallbacksObj = NULL; 975 } 976 btIf = NULL; 977} 978 979/** 980 * Native Client functions 981 */ 982 983static int gattClientGetDeviceTypeNative(JNIEnv* env, jobject object, jstring address) 984{ 985 if (!sGattIf) return 0; 986 bt_bdaddr_t bda; 987 jstr2bdaddr(env, &bda, address); 988 return sGattIf->client->get_device_type(&bda); 989} 990 991static void gattClientRegisterAppNative(JNIEnv* env, jobject object, 992 jlong app_uuid_lsb, jlong app_uuid_msb ) 993{ 994 bt_uuid_t uuid; 995 996 if (!sGattIf) return; 997 set_uuid(uuid.uu, app_uuid_msb, app_uuid_lsb); 998 sGattIf->client->register_client(&uuid); 999} 1000 1001static void gattClientUnregisterAppNative(JNIEnv* env, jobject object, jint clientIf) 1002{ 1003 if (!sGattIf) return; 1004 sGattIf->client->unregister_client(clientIf); 1005} 1006 1007static void gattClientScanNative(JNIEnv* env, jobject object, jboolean start) 1008{ 1009 if (!sGattIf) return; 1010 sGattIf->client->scan(start); 1011} 1012 1013static void gattClientConnectNative(JNIEnv* env, jobject object, jint clientif, 1014 jstring address, jboolean isDirect, jint transport) 1015{ 1016 if (!sGattIf) return; 1017 1018 bt_bdaddr_t bda; 1019 jstr2bdaddr(env, &bda, address); 1020 sGattIf->client->connect(clientif, &bda, isDirect, transport); 1021} 1022 1023static void gattClientDisconnectNative(JNIEnv* env, jobject object, jint clientIf, 1024 jstring address, jint conn_id) 1025{ 1026 if (!sGattIf) return; 1027 bt_bdaddr_t bda; 1028 jstr2bdaddr(env, &bda, address); 1029 sGattIf->client->disconnect(clientIf, &bda, conn_id); 1030} 1031 1032static void gattClientRefreshNative(JNIEnv* env, jobject object, jint clientIf, 1033 jstring address) 1034{ 1035 if (!sGattIf) return; 1036 1037 bt_bdaddr_t bda; 1038 jstr2bdaddr(env, &bda, address); 1039 sGattIf->client->refresh(clientIf, &bda); 1040} 1041 1042static void gattClientSearchServiceNative(JNIEnv* env, jobject object, jint conn_id, 1043 jboolean search_all, jlong service_uuid_lsb, jlong service_uuid_msb) 1044{ 1045 if (!sGattIf) return; 1046 1047 bt_uuid_t uuid; 1048 set_uuid(uuid.uu, service_uuid_msb, service_uuid_lsb); 1049 sGattIf->client->search_service(conn_id, search_all ? 0 : &uuid); 1050} 1051 1052static void gattClientGetGattDbNative(JNIEnv* env, jobject object, 1053 jint conn_id) 1054{ 1055 if (!sGattIf) return; 1056 1057 sGattIf->client->get_gatt_db(conn_id); 1058} 1059 1060static void gattClientReadCharacteristicNative(JNIEnv* env, jobject object, 1061 jint conn_id, jint handle, jint authReq) 1062{ 1063 if (!sGattIf) return; 1064 1065 sGattIf->client->read_characteristic(conn_id, handle, authReq); 1066} 1067 1068static void gattClientReadDescriptorNative(JNIEnv* env, jobject object, 1069 jint conn_id, jint handle, jint authReq) 1070{ 1071 if (!sGattIf) return; 1072 1073 sGattIf->client->read_descriptor(conn_id, handle, authReq); 1074} 1075 1076static void gattClientWriteCharacteristicNative(JNIEnv* env, jobject object, 1077 jint conn_id, jint handle, jint write_type, jint auth_req, jbyteArray value) 1078{ 1079 if (!sGattIf) return; 1080 1081 if (value == NULL) { 1082 warn("gattClientWriteCharacteristicNative() ignoring NULL array"); 1083 return; 1084 } 1085 1086 uint16_t len = (uint16_t) env->GetArrayLength(value); 1087 jbyte *p_value = env->GetByteArrayElements(value, NULL); 1088 if (p_value == NULL) return; 1089 1090 sGattIf->client->write_characteristic(conn_id, handle, write_type, len, auth_req, (char*)p_value); 1091 env->ReleaseByteArrayElements(value, p_value, 0); 1092} 1093 1094static void gattClientExecuteWriteNative(JNIEnv* env, jobject object, 1095 jint conn_id, jboolean execute) 1096{ 1097 if (!sGattIf) return; 1098 sGattIf->client->execute_write(conn_id, execute ? 1 : 0); 1099} 1100 1101static void gattClientWriteDescriptorNative(JNIEnv* env, jobject object, 1102 jint conn_id, jint handle, jint write_type, jint auth_req, jbyteArray value) 1103{ 1104 if (!sGattIf) return; 1105 1106 if (value == NULL) { 1107 warn("gattClientWriteDescriptorNative() ignoring NULL array"); 1108 return; 1109 } 1110 1111 uint16_t len = (uint16_t) env->GetArrayLength(value); 1112 jbyte *p_value = env->GetByteArrayElements(value, NULL); 1113 if (p_value == NULL) return; 1114 1115 sGattIf->client->write_descriptor(conn_id, handle, write_type, len, auth_req, (char*)p_value); 1116 env->ReleaseByteArrayElements(value, p_value, 0); 1117} 1118 1119static void gattClientRegisterForNotificationsNative(JNIEnv* env, jobject object, 1120 jint clientIf, jstring address, jint handle, jboolean enable) 1121{ 1122 if (!sGattIf) return; 1123 1124 bt_bdaddr_t bd_addr; 1125 const char *c_address = env->GetStringUTFChars(address, NULL); 1126 bd_addr_str_to_addr(c_address, bd_addr.address); 1127 1128 if (enable) 1129 sGattIf->client->register_for_notification(clientIf, &bd_addr, handle); 1130 else 1131 sGattIf->client->deregister_for_notification(clientIf, &bd_addr, handle); 1132} 1133 1134static void gattClientReadRemoteRssiNative(JNIEnv* env, jobject object, jint clientif, 1135 jstring address) 1136{ 1137 if (!sGattIf) return; 1138 1139 bt_bdaddr_t bda; 1140 jstr2bdaddr(env, &bda, address); 1141 1142 sGattIf->client->read_remote_rssi(clientif, &bda); 1143} 1144 1145static void gattAdvertiseNative(JNIEnv *env, jobject object, 1146 jint client_if, jboolean start) 1147{ 1148 if (!sGattIf) return; 1149 sGattIf->client->listen(client_if, start); 1150} 1151 1152static void gattSetAdvDataNative(JNIEnv *env, jobject object, jint client_if, 1153 jboolean setScanRsp, jboolean inclName, jboolean inclTxPower, jint minInterval, 1154 jint maxInterval, jint appearance, jbyteArray manufacturerData, jbyteArray serviceData, 1155 jbyteArray serviceUuid) 1156{ 1157 if (!sGattIf) return; 1158 jbyte* arr_data = env->GetByteArrayElements(manufacturerData, NULL); 1159 uint16_t arr_len = (uint16_t) env->GetArrayLength(manufacturerData); 1160 1161 jbyte* service_data = env->GetByteArrayElements(serviceData, NULL); 1162 uint16_t service_data_len = (uint16_t) env->GetArrayLength(serviceData); 1163 1164 jbyte* service_uuid = env->GetByteArrayElements(serviceUuid, NULL); 1165 uint16_t service_uuid_len = (uint16_t) env->GetArrayLength(serviceUuid); 1166 1167 sGattIf->client->set_adv_data(client_if, setScanRsp, inclName, inclTxPower, 1168 minInterval, maxInterval, appearance, arr_len, (char*)arr_data, 1169 service_data_len, (char*)service_data, service_uuid_len, 1170 (char*)service_uuid); 1171 1172 env->ReleaseByteArrayElements(manufacturerData, arr_data, JNI_ABORT); 1173 env->ReleaseByteArrayElements(serviceData, service_data, JNI_ABORT); 1174 env->ReleaseByteArrayElements(serviceUuid, service_uuid, JNI_ABORT); 1175} 1176 1177static void gattSetScanParametersNative(JNIEnv* env, jobject object, 1178 jint client_if, jint scan_interval_unit, 1179 jint scan_window_unit) 1180{ 1181 if (!sGattIf) return; 1182 sGattIf->client->set_scan_parameters(client_if, scan_interval_unit, scan_window_unit); 1183} 1184 1185static void gattClientScanFilterParamAddNative(JNIEnv* env, jobject object, jobject params) 1186{ 1187 if (!sGattIf) return; 1188 const int add_scan_filter_params_action = 0; 1189 btgatt_filt_param_setup_t filt_params; 1190 1191 jmethodID methodId = 0; 1192 jclass filtparam = env->GetObjectClass(params); 1193 1194 methodId = env->GetMethodID(filtparam, "getClientIf", "()I"); 1195 filt_params.client_if = env->CallIntMethod(params, methodId);; 1196 1197 filt_params.action = add_scan_filter_params_action; 1198 1199 methodId = env->GetMethodID(filtparam, "getFiltIndex", "()I"); 1200 filt_params.filt_index = env->CallIntMethod(params, methodId);; 1201 1202 methodId = env->GetMethodID(filtparam, "getFeatSeln", "()I"); 1203 filt_params.feat_seln = env->CallIntMethod(params, methodId);; 1204 1205 methodId = env->GetMethodID(filtparam, "getListLogicType", "()I"); 1206 filt_params.list_logic_type = env->CallIntMethod(params, methodId); 1207 1208 methodId = env->GetMethodID(filtparam, "getFiltLogicType", "()I"); 1209 filt_params.filt_logic_type = env->CallIntMethod(params, methodId); 1210 1211 methodId = env->GetMethodID(filtparam, "getDelyMode", "()I"); 1212 filt_params.dely_mode = env->CallIntMethod(params, methodId); 1213 1214 methodId = env->GetMethodID(filtparam, "getFoundTimeout", "()I"); 1215 filt_params.found_timeout = env->CallIntMethod(params, methodId); 1216 1217 methodId = env->GetMethodID(filtparam, "getLostTimeout", "()I"); 1218 filt_params.lost_timeout = env->CallIntMethod(params, methodId); 1219 1220 methodId = env->GetMethodID(filtparam, "getFoundTimeOutCnt", "()I"); 1221 filt_params.found_timeout_cnt = env->CallIntMethod(params, methodId); 1222 1223 methodId = env->GetMethodID(filtparam, "getNumOfTrackEntries", "()I"); 1224 filt_params.num_of_tracking_entries = env->CallIntMethod(params, methodId); 1225 1226 methodId = env->GetMethodID(filtparam, "getRSSIHighValue", "()I"); 1227 filt_params.rssi_high_thres = env->CallIntMethod(params, methodId); 1228 1229 methodId = env->GetMethodID(filtparam, "getRSSILowValue", "()I"); 1230 filt_params.rssi_low_thres = env->CallIntMethod(params, methodId); 1231 1232 env->DeleteLocalRef(filtparam); 1233 sGattIf->client->scan_filter_param_setup(filt_params); 1234} 1235 1236static void gattClientScanFilterParamDeleteNative(JNIEnv* env, jobject object, 1237 jint client_if, jint filt_index) 1238{ 1239 if (!sGattIf) return; 1240 const int delete_scan_filter_params_action = 1; 1241 btgatt_filt_param_setup_t filt_params; 1242 memset(&filt_params, 0, sizeof(btgatt_filt_param_setup_t)); 1243 filt_params.client_if = client_if; 1244 filt_params.action = delete_scan_filter_params_action; 1245 filt_params.filt_index = filt_index; 1246 sGattIf->client->scan_filter_param_setup(filt_params); 1247} 1248 1249static void gattClientScanFilterParamClearAllNative(JNIEnv* env, jobject object, jint client_if) 1250{ 1251 if (!sGattIf) return; 1252 const int clear_scan_filter_params_action = 2; 1253 btgatt_filt_param_setup_t filt_params; 1254 memset(&filt_params, 0, sizeof(btgatt_filt_param_setup_t)); 1255 filt_params.client_if = client_if; 1256 filt_params.action = clear_scan_filter_params_action; 1257 sGattIf->client->scan_filter_param_setup(filt_params); 1258} 1259 1260static void gattClientScanFilterAddRemoveNative(JNIEnv* env, jobject object, 1261 jint client_if, jint action, jint filt_type, jint filt_index, jint company_id, 1262 jint company_id_mask, jlong uuid_lsb, jlong uuid_msb, jlong uuid_mask_lsb, 1263 jlong uuid_mask_msb, jstring name, jstring address, jbyte addr_type, 1264 jbyteArray data, jbyteArray mask) 1265{ 1266 switch(filt_type) 1267 { 1268 case 0: // BTM_BLE_PF_ADDR_FILTER 1269 { 1270 bt_bdaddr_t bda; 1271 jstr2bdaddr(env, &bda, address); 1272 sGattIf->client->scan_filter_add_remove(client_if, action, filt_type, filt_index, 0, 1273 0, NULL, NULL, &bda, addr_type,0, NULL,0, NULL); 1274 break; 1275 } 1276 1277 case 1: // BTM_BLE_PF_SRVC_DATA 1278 { 1279 jbyte* data_array = env->GetByteArrayElements(data, 0); 1280 int data_len = env->GetArrayLength(data); 1281 jbyte* mask_array = env->GetByteArrayElements(mask, NULL); 1282 uint16_t mask_len = (uint16_t) env->GetArrayLength(mask); 1283 sGattIf->client->scan_filter_add_remove(client_if, action, filt_type, filt_index, 1284 0, 0, NULL, NULL, NULL, 0, data_len, (char*)data_array, mask_len,(char*) mask_array); 1285 env->ReleaseByteArrayElements(data, data_array, JNI_ABORT); 1286 env->ReleaseByteArrayElements(mask, mask_array, JNI_ABORT); 1287 break; 1288 } 1289 1290 case 2: // BTM_BLE_PF_SRVC_UUID 1291 case 3: // BTM_BLE_PF_SRVC_SOL_UUID 1292 { 1293 bt_uuid_t uuid, uuid_mask; 1294 set_uuid(uuid.uu, uuid_msb, uuid_lsb); 1295 set_uuid(uuid_mask.uu, uuid_mask_msb, uuid_mask_lsb); 1296 if (uuid_mask_lsb != 0 && uuid_mask_msb != 0) 1297 sGattIf->client->scan_filter_add_remove(client_if, action, filt_type, filt_index, 1298 0, 0, &uuid, &uuid_mask, NULL,0,0, NULL,0, NULL); 1299 else 1300 sGattIf->client->scan_filter_add_remove(client_if, action, filt_type, filt_index, 1301 0, 0, &uuid, NULL, NULL, 0,0, NULL,0, NULL); 1302 break; 1303 } 1304 1305 case 4: // BTM_BLE_PF_LOCAL_NAME 1306 { 1307 const char* c_name = env->GetStringUTFChars(name, NULL); 1308 if (c_name != NULL && strlen(c_name) != 0) 1309 { 1310 sGattIf->client->scan_filter_add_remove(client_if, action, filt_type, 1311 filt_index, 0, 0, NULL, NULL, NULL, 0, strlen(c_name), 1312 (char*)c_name, 0, NULL); 1313 env->ReleaseStringUTFChars(name, c_name); 1314 } 1315 break; 1316 } 1317 1318 case 5: // BTM_BLE_PF_MANU_DATA 1319 case 6: // BTM_BLE_PF_SRVC_DATA_PATTERN 1320 { 1321 jbyte* data_array = env->GetByteArrayElements(data, 0); 1322 int data_len = env->GetArrayLength(data); // Array contains mask 1323 jbyte* mask_array = env->GetByteArrayElements(mask, NULL); 1324 uint16_t mask_len = (uint16_t) env->GetArrayLength(mask); 1325 sGattIf->client->scan_filter_add_remove(client_if, action, filt_type, filt_index, 1326 company_id, company_id_mask, NULL, NULL, NULL, 0, data_len, (char*)data_array, 1327 mask_len, (char*) mask_array); 1328 env->ReleaseByteArrayElements(data, data_array, JNI_ABORT); 1329 env->ReleaseByteArrayElements(mask, mask_array, JNI_ABORT); 1330 break; 1331 } 1332 1333 default: 1334 break; 1335 } 1336} 1337 1338static void gattClientScanFilterAddNative(JNIEnv* env, jobject object, jint client_if, 1339 jint filt_type, jint filt_index, jint company_id, jint company_id_mask, 1340 jlong uuid_lsb, jlong uuid_msb, jlong uuid_mask_lsb, jlong uuid_mask_msb, 1341 jstring name, jstring address, jbyte addr_type, jbyteArray data, jbyteArray mask) 1342{ 1343 if (!sGattIf) return; 1344 int action = 0; 1345 gattClientScanFilterAddRemoveNative(env, object, client_if, action, filt_type, filt_index, 1346 company_id, company_id_mask, uuid_lsb, uuid_msb, uuid_mask_lsb, uuid_mask_msb, 1347 name, address, addr_type, data, mask); 1348 1349} 1350 1351static void gattClientScanFilterDeleteNative(JNIEnv* env, jobject object, jint client_if, 1352 jint filt_type, jint filt_index, jint company_id, jint company_id_mask, 1353 jlong uuid_lsb, jlong uuid_msb, jlong uuid_mask_lsb, jlong uuid_mask_msb, 1354 jstring name, jstring address, jbyte addr_type, jbyteArray data, jbyteArray mask) 1355{ 1356 if (!sGattIf) return; 1357 int action = 1; 1358 gattClientScanFilterAddRemoveNative(env, object, client_if, action, filt_type, filt_index, 1359 company_id, company_id_mask, uuid_lsb, uuid_msb, uuid_mask_lsb, uuid_mask_msb, 1360 name, address, addr_type, data, mask); 1361} 1362 1363static void gattClientScanFilterClearNative(JNIEnv* env, jobject object, jint client_if, 1364 jint filt_index) 1365{ 1366 if (!sGattIf) return; 1367 sGattIf->client->scan_filter_clear(client_if, filt_index); 1368} 1369 1370static void gattClientScanFilterEnableNative (JNIEnv* env, jobject object, jint client_if, 1371 jboolean enable) 1372{ 1373 if (!sGattIf) return; 1374 sGattIf->client->scan_filter_enable(client_if, enable); 1375} 1376 1377static void gattClientConfigureMTUNative(JNIEnv *env, jobject object, 1378 jint conn_id, jint mtu) 1379{ 1380 if (!sGattIf) return; 1381 sGattIf->client->configure_mtu(conn_id, mtu); 1382} 1383 1384static void gattConnectionParameterUpdateNative(JNIEnv *env, jobject object, jint client_if, 1385 jstring address, jint min_interval, jint max_interval, jint latency, jint timeout) 1386{ 1387 if (!sGattIf) return; 1388 bt_bdaddr_t bda; 1389 jstr2bdaddr(env, &bda, address); 1390 sGattIf->client->conn_parameter_update(&bda, min_interval, max_interval, latency, timeout); 1391} 1392 1393static void gattClientEnableAdvNative(JNIEnv* env, jobject object, jint client_if, 1394 jint min_interval, jint max_interval, jint adv_type, jint chnl_map, jint tx_power, 1395 jint timeout_s) 1396{ 1397 if (!sGattIf) return; 1398 1399 sGattIf->client->multi_adv_enable(client_if, min_interval, max_interval, adv_type, chnl_map, 1400 tx_power, timeout_s); 1401} 1402 1403static void gattClientUpdateAdvNative(JNIEnv* env, jobject object, jint client_if, 1404 jint min_interval, jint max_interval, jint adv_type, jint chnl_map, jint tx_power, 1405 jint timeout_s) 1406{ 1407 if (!sGattIf) return; 1408 1409 sGattIf->client->multi_adv_update(client_if, min_interval, max_interval, adv_type, chnl_map, 1410 tx_power, timeout_s); 1411} 1412 1413static void gattClientSetAdvDataNative(JNIEnv* env, jobject object , jint client_if, 1414 jboolean set_scan_rsp, jboolean incl_name, jboolean incl_txpower, jint appearance, 1415 jbyteArray manufacturer_data,jbyteArray service_data, jbyteArray service_uuid) 1416{ 1417 if (!sGattIf) return; 1418 jbyte* manu_data = env->GetByteArrayElements(manufacturer_data, NULL); 1419 uint16_t manu_len = (uint16_t) env->GetArrayLength(manufacturer_data); 1420 1421 jbyte* serv_data = env->GetByteArrayElements(service_data, NULL); 1422 uint16_t serv_data_len = (uint16_t) env->GetArrayLength(service_data); 1423 1424 jbyte* serv_uuid = env->GetByteArrayElements(service_uuid, NULL); 1425 uint16_t serv_uuid_len = (uint16_t) env->GetArrayLength(service_uuid); 1426 1427 sGattIf->client->multi_adv_set_inst_data(client_if, set_scan_rsp, incl_name,incl_txpower, 1428 appearance, manu_len, (char*)manu_data, 1429 serv_data_len, (char*)serv_data, serv_uuid_len, 1430 (char*)serv_uuid); 1431 1432 env->ReleaseByteArrayElements(manufacturer_data, manu_data, JNI_ABORT); 1433 env->ReleaseByteArrayElements(service_data, serv_data, JNI_ABORT); 1434 env->ReleaseByteArrayElements(service_uuid, serv_uuid, JNI_ABORT); 1435} 1436 1437static void gattClientDisableAdvNative(JNIEnv* env, jobject object, jint client_if) 1438{ 1439 if (!sGattIf) return; 1440 sGattIf->client->multi_adv_disable(client_if); 1441} 1442 1443static void gattClientConfigBatchScanStorageNative(JNIEnv* env, jobject object, jint client_if, 1444 jint max_full_reports_percent, jint max_trunc_reports_percent, 1445 jint notify_threshold_level_percent) 1446{ 1447 if (!sGattIf) return; 1448 sGattIf->client->batchscan_cfg_storage(client_if, max_full_reports_percent, 1449 max_trunc_reports_percent, notify_threshold_level_percent); 1450} 1451 1452static void gattClientStartBatchScanNative(JNIEnv* env, jobject object, jint client_if, 1453 jint scan_mode, jint scan_interval_unit, jint scan_window_unit, jint addr_type, 1454 jint discard_rule) 1455{ 1456 if (!sGattIf) return; 1457 sGattIf->client->batchscan_enb_batch_scan(client_if, scan_mode, scan_interval_unit, 1458 scan_window_unit, addr_type, discard_rule); 1459} 1460 1461static void gattClientStopBatchScanNative(JNIEnv* env, jobject object, jint client_if) 1462{ 1463 if (!sGattIf) return; 1464 sGattIf->client->batchscan_dis_batch_scan(client_if); 1465} 1466 1467static void gattClientReadScanReportsNative(JNIEnv* env, jobject object, jint client_if, 1468 jint scan_type) 1469{ 1470 if (!sGattIf) return; 1471 sGattIf->client->batchscan_read_reports(client_if, scan_type); 1472} 1473 1474/** 1475 * Native server functions 1476 */ 1477static void gattServerRegisterAppNative(JNIEnv* env, jobject object, 1478 jlong app_uuid_lsb, jlong app_uuid_msb ) 1479{ 1480 bt_uuid_t uuid; 1481 if (!sGattIf) return; 1482 set_uuid(uuid.uu, app_uuid_msb, app_uuid_lsb); 1483 sGattIf->server->register_server(&uuid); 1484} 1485 1486static void gattServerUnregisterAppNative(JNIEnv* env, jobject object, jint serverIf) 1487{ 1488 if (!sGattIf) return; 1489 sGattIf->server->unregister_server(serverIf); 1490} 1491 1492static void gattServerConnectNative(JNIEnv *env, jobject object, 1493 jint server_if, jstring address, jboolean is_direct, jint transport) 1494{ 1495 if (!sGattIf) return; 1496 1497 bt_bdaddr_t bd_addr; 1498 const char *c_address = env->GetStringUTFChars(address, NULL); 1499 bd_addr_str_to_addr(c_address, bd_addr.address); 1500 1501 sGattIf->server->connect(server_if, &bd_addr, is_direct, transport); 1502} 1503 1504static void gattServerDisconnectNative(JNIEnv* env, jobject object, jint serverIf, 1505 jstring address, jint conn_id) 1506{ 1507 if (!sGattIf) return; 1508 bt_bdaddr_t bda; 1509 jstr2bdaddr(env, &bda, address); 1510 sGattIf->server->disconnect(serverIf, &bda, conn_id); 1511} 1512 1513static void gattServerAddServiceNative (JNIEnv *env, jobject object, 1514 jint server_if, jint service_type, jint service_id_inst_id, 1515 jlong service_id_uuid_lsb, jlong service_id_uuid_msb, 1516 jint num_handles) 1517{ 1518 if (!sGattIf) return; 1519 1520 btgatt_srvc_id_t srvc_id; 1521 srvc_id.id.inst_id = (uint8_t) service_id_inst_id; 1522 srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0); 1523 set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb); 1524 1525 sGattIf->server->add_service(server_if, &srvc_id, num_handles); 1526} 1527 1528static void gattServerAddIncludedServiceNative (JNIEnv *env, jobject object, 1529 jint server_if, jint svc_handle, jint included_svc_handle) 1530{ 1531 if (!sGattIf) return; 1532 sGattIf->server->add_included_service(server_if, svc_handle, 1533 included_svc_handle); 1534} 1535 1536static void gattServerAddCharacteristicNative (JNIEnv *env, jobject object, 1537 jint server_if, jint svc_handle, 1538 jlong char_uuid_lsb, jlong char_uuid_msb, 1539 jint properties, jint permissions) 1540{ 1541 if (!sGattIf) return; 1542 1543 bt_uuid_t uuid; 1544 set_uuid(uuid.uu, char_uuid_msb, char_uuid_lsb); 1545 1546 sGattIf->server->add_characteristic(server_if, svc_handle, 1547 &uuid, properties, permissions); 1548} 1549 1550static void gattServerAddDescriptorNative (JNIEnv *env, jobject object, 1551 jint server_if, jint svc_handle, 1552 jlong desc_uuid_lsb, jlong desc_uuid_msb, 1553 jint permissions) 1554{ 1555 if (!sGattIf) return; 1556 1557 bt_uuid_t uuid; 1558 set_uuid(uuid.uu, desc_uuid_msb, desc_uuid_lsb); 1559 1560 sGattIf->server->add_descriptor(server_if, svc_handle, &uuid, permissions); 1561} 1562 1563static void gattServerStartServiceNative (JNIEnv *env, jobject object, 1564 jint server_if, jint svc_handle, jint transport ) 1565{ 1566 if (!sGattIf) return; 1567 sGattIf->server->start_service(server_if, svc_handle, transport); 1568} 1569 1570static void gattServerStopServiceNative (JNIEnv *env, jobject object, 1571 jint server_if, jint svc_handle) 1572{ 1573 if (!sGattIf) return; 1574 sGattIf->server->stop_service(server_if, svc_handle); 1575} 1576 1577static void gattServerDeleteServiceNative (JNIEnv *env, jobject object, 1578 jint server_if, jint svc_handle) 1579{ 1580 if (!sGattIf) return; 1581 sGattIf->server->delete_service(server_if, svc_handle); 1582} 1583 1584static void gattServerSendIndicationNative (JNIEnv *env, jobject object, 1585 jint server_if, jint attr_handle, jint conn_id, jbyteArray val) 1586{ 1587 if (!sGattIf) return; 1588 1589 jbyte* array = env->GetByteArrayElements(val, 0); 1590 int val_len = env->GetArrayLength(val); 1591 1592 sGattIf->server->send_indication(server_if, attr_handle, conn_id, val_len, 1593 /*confirm*/ 1, (char*)array); 1594 env->ReleaseByteArrayElements(val, array, JNI_ABORT); 1595} 1596 1597static void gattServerSendNotificationNative (JNIEnv *env, jobject object, 1598 jint server_if, jint attr_handle, jint conn_id, jbyteArray val) 1599{ 1600 if (!sGattIf) return; 1601 1602 jbyte* array = env->GetByteArrayElements(val, 0); 1603 int val_len = env->GetArrayLength(val); 1604 1605 sGattIf->server->send_indication(server_if, attr_handle, conn_id, val_len, 1606 /*confirm*/ 0, (char*)array); 1607 env->ReleaseByteArrayElements(val, array, JNI_ABORT); 1608} 1609 1610static void gattServerSendResponseNative (JNIEnv *env, jobject object, 1611 jint server_if, jint conn_id, jint trans_id, jint status, 1612 jint handle, jint offset, jbyteArray val, jint auth_req) 1613{ 1614 if (!sGattIf) return; 1615 1616 btgatt_response_t response; 1617 1618 response.attr_value.handle = handle; 1619 response.attr_value.auth_req = auth_req; 1620 response.attr_value.offset = offset; 1621 response.attr_value.len = 0; 1622 1623 if (val != NULL) 1624 { 1625 response.attr_value.len = (uint16_t) env->GetArrayLength(val); 1626 jbyte* array = env->GetByteArrayElements(val, 0); 1627 1628 for (int i = 0; i != response.attr_value.len; ++i) 1629 response.attr_value.value[i] = (uint8_t) array[i]; 1630 env->ReleaseByteArrayElements(val, array, JNI_ABORT); 1631 } 1632 1633 sGattIf->server->send_response(conn_id, trans_id, status, &response); 1634} 1635 1636static void gattTestNative(JNIEnv *env, jobject object, jint command, 1637 jlong uuid1_lsb, jlong uuid1_msb, jstring bda1, 1638 jint p1, jint p2, jint p3, jint p4, jint p5 ) 1639{ 1640 if (!sGattIf) return; 1641 1642 bt_bdaddr_t bt_bda1; 1643 jstr2bdaddr(env, &bt_bda1, bda1); 1644 1645 bt_uuid_t uuid1; 1646 set_uuid(uuid1.uu, uuid1_msb, uuid1_lsb); 1647 1648 btgatt_test_params_t params; 1649 params.bda1 = &bt_bda1; 1650 params.uuid1 = &uuid1; 1651 params.u1 = p1; 1652 params.u2 = p2; 1653 params.u3 = p3; 1654 params.u4 = p4; 1655 params.u5 = p5; 1656 sGattIf->client->test_command(command, ¶ms); 1657} 1658 1659/** 1660 * JNI function definitinos 1661 */ 1662 1663// JNI functions defined in AdvertiseManager class. 1664static JNINativeMethod sAdvertiseMethods[] = { 1665 {"gattClientEnableAdvNative", "(IIIIIII)V", (void *) gattClientEnableAdvNative}, 1666 {"gattClientUpdateAdvNative", "(IIIIIII)V", (void *) gattClientUpdateAdvNative}, 1667 {"gattClientSetAdvDataNative", "(IZZZI[B[B[B)V", (void *) gattClientSetAdvDataNative}, 1668 {"gattClientDisableAdvNative", "(I)V", (void *) gattClientDisableAdvNative}, 1669 {"gattSetAdvDataNative", "(IZZZIII[B[B[B)V", (void *) gattSetAdvDataNative}, 1670 {"gattAdvertiseNative", "(IZ)V", (void *) gattAdvertiseNative}, 1671}; 1672 1673// JNI functions defined in ScanManager class. 1674static JNINativeMethod sScanMethods[] = { 1675 {"gattClientScanNative", "(Z)V", (void *) gattClientScanNative}, 1676 // Batch scan JNI functions. 1677 {"gattClientConfigBatchScanStorageNative", "(IIII)V",(void *) gattClientConfigBatchScanStorageNative}, 1678 {"gattClientStartBatchScanNative", "(IIIIII)V", (void *) gattClientStartBatchScanNative}, 1679 {"gattClientStopBatchScanNative", "(I)V", (void *) gattClientStopBatchScanNative}, 1680 {"gattClientReadScanReportsNative", "(II)V", (void *) gattClientReadScanReportsNative}, 1681 // Scan filter JNI functions. 1682 {"gattClientScanFilterParamAddNative", "(Lcom/android/bluetooth/gatt/FilterParams;)V", (void *) gattClientScanFilterParamAddNative}, 1683 {"gattClientScanFilterParamDeleteNative", "(II)V", (void *) gattClientScanFilterParamDeleteNative}, 1684 {"gattClientScanFilterParamClearAllNative", "(I)V", (void *) gattClientScanFilterParamClearAllNative}, 1685 {"gattClientScanFilterAddNative", "(IIIIIJJJJLjava/lang/String;Ljava/lang/String;B[B[B)V", (void *) gattClientScanFilterAddNative}, 1686 {"gattClientScanFilterDeleteNative", "(IIIIIJJJJLjava/lang/String;Ljava/lang/String;B[B[B)V", (void *) gattClientScanFilterDeleteNative}, 1687 {"gattClientScanFilterClearNative", "(II)V", (void *) gattClientScanFilterClearNative}, 1688 {"gattClientScanFilterEnableNative", "(IZ)V", (void *) gattClientScanFilterEnableNative}, 1689 {"gattSetScanParametersNative", "(III)V", (void *) gattSetScanParametersNative}, 1690}; 1691 1692// JNI functions defined in GattService class. 1693static JNINativeMethod sMethods[] = { 1694 {"classInitNative", "()V", (void *) classInitNative}, 1695 {"initializeNative", "()V", (void *) initializeNative}, 1696 {"cleanupNative", "()V", (void *) cleanupNative}, 1697 {"gattClientGetDeviceTypeNative", "(Ljava/lang/String;)I", (void *) gattClientGetDeviceTypeNative}, 1698 {"gattClientRegisterAppNative", "(JJ)V", (void *) gattClientRegisterAppNative}, 1699 {"gattClientUnregisterAppNative", "(I)V", (void *) gattClientUnregisterAppNative}, 1700 {"gattClientConnectNative", "(ILjava/lang/String;ZI)V", (void *) gattClientConnectNative}, 1701 {"gattClientDisconnectNative", "(ILjava/lang/String;I)V", (void *) gattClientDisconnectNative}, 1702 {"gattClientRefreshNative", "(ILjava/lang/String;)V", (void *) gattClientRefreshNative}, 1703 {"gattClientSearchServiceNative", "(IZJJ)V", (void *) gattClientSearchServiceNative}, 1704 {"gattClientGetGattDbNative", "(I)V", (void *) gattClientGetGattDbNative}, 1705 {"gattClientReadCharacteristicNative", "(III)V", (void *) gattClientReadCharacteristicNative}, 1706 {"gattClientReadDescriptorNative", "(III)V", (void *) gattClientReadDescriptorNative}, 1707 {"gattClientWriteCharacteristicNative", "(IIII[B)V", (void *) gattClientWriteCharacteristicNative}, 1708 {"gattClientWriteDescriptorNative", "(IIII[B)V", (void *) gattClientWriteDescriptorNative}, 1709 {"gattClientExecuteWriteNative", "(IZ)V", (void *) gattClientExecuteWriteNative}, 1710 {"gattClientRegisterForNotificationsNative", "(ILjava/lang/String;IZ)V", (void *) gattClientRegisterForNotificationsNative}, 1711 {"gattClientReadRemoteRssiNative", "(ILjava/lang/String;)V", (void *) gattClientReadRemoteRssiNative}, 1712 {"gattClientConfigureMTUNative", "(II)V", (void *) gattClientConfigureMTUNative}, 1713 {"gattConnectionParameterUpdateNative", "(ILjava/lang/String;IIII)V", (void *) gattConnectionParameterUpdateNative}, 1714 {"gattServerRegisterAppNative", "(JJ)V", (void *) gattServerRegisterAppNative}, 1715 {"gattServerUnregisterAppNative", "(I)V", (void *) gattServerUnregisterAppNative}, 1716 {"gattServerConnectNative", "(ILjava/lang/String;ZI)V", (void *) gattServerConnectNative}, 1717 {"gattServerDisconnectNative", "(ILjava/lang/String;I)V", (void *) gattServerDisconnectNative}, 1718 {"gattServerAddServiceNative", "(IIIJJI)V", (void *) gattServerAddServiceNative}, 1719 {"gattServerAddIncludedServiceNative", "(III)V", (void *) gattServerAddIncludedServiceNative}, 1720 {"gattServerAddCharacteristicNative", "(IIJJII)V", (void *) gattServerAddCharacteristicNative}, 1721 {"gattServerAddDescriptorNative", "(IIJJI)V", (void *) gattServerAddDescriptorNative}, 1722 {"gattServerStartServiceNative", "(III)V", (void *) gattServerStartServiceNative}, 1723 {"gattServerStopServiceNative", "(II)V", (void *) gattServerStopServiceNative}, 1724 {"gattServerDeleteServiceNative", "(II)V", (void *) gattServerDeleteServiceNative}, 1725 {"gattServerSendIndicationNative", "(III[B)V", (void *) gattServerSendIndicationNative}, 1726 {"gattServerSendNotificationNative", "(III[B)V", (void *) gattServerSendNotificationNative}, 1727 {"gattServerSendResponseNative", "(IIIIII[BI)V", (void *) gattServerSendResponseNative}, 1728 1729 {"gattTestNative", "(IJJLjava/lang/String;IIIII)V", (void *) gattTestNative}, 1730}; 1731 1732int register_com_android_bluetooth_gatt(JNIEnv* env) 1733{ 1734 int register_success = 1735 jniRegisterNativeMethods(env, "com/android/bluetooth/gatt/ScanManager$ScanNative", 1736 sScanMethods, NELEM(sScanMethods)); 1737 register_success &= 1738 jniRegisterNativeMethods(env, "com/android/bluetooth/gatt/AdvertiseManager$AdvertiseNative", 1739 sAdvertiseMethods, NELEM(sAdvertiseMethods)); 1740 return register_success & 1741 jniRegisterNativeMethods(env, "com/android/bluetooth/gatt/GattService", 1742 sMethods, NELEM(sMethods)); 1743} 1744} 1745