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