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