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_onReadDescrExtProp; 153 static jmethodID method_onReadDescriptor; 154 static jmethodID method_onWriteDescriptor; 155 static jmethodID method_onNotify; 156 static jmethodID method_onGetCharacteristic; 157 static jmethodID method_onGetDescriptor; 158 static jmethodID method_onGetIncludedService; 159 static jmethodID method_onRegisterForNotifications; 160 static jmethodID method_onReadRemoteRssi; 161 static jmethodID method_onAdvertiseCallback; 162 163 /** 164 * Server callback methods 165 */ 166 static jmethodID method_onServerRegistered; 167 static jmethodID method_onClientConnected; 168 static jmethodID method_onServiceAdded; 169 static jmethodID method_onIncludedServiceAdded; 170 static jmethodID method_onCharacteristicAdded; 171 static jmethodID method_onDescriptorAdded; 172 static jmethodID method_onServiceStarted; 173 static jmethodID method_onServiceStopped; 174 static jmethodID method_onServiceDeleted; 175 static jmethodID method_onResponseSendCompleted; 176 static jmethodID method_onAttributeRead; 177 static jmethodID method_onAttributeWrite; 178 static jmethodID method_onExecuteWrite; 179 180 /** 181 * Static variables 182 */ 183 184 static const btgatt_interface_t *sGattIf = NULL; 185 static jobject mCallbacksObj = NULL; 186 static JNIEnv *sCallbackEnv = NULL; 187 188 static bool checkCallbackThread() { 189 sCallbackEnv = getCallbackEnv(); 190 191 JNIEnv* env = AndroidRuntime::getJNIEnv(); 192 if (sCallbackEnv != env || sCallbackEnv == NULL) return false; 193 return true; 194 } 195 196 /** 197 * BTA client callbacks 198 */ 199 200 void btgattc_register_app_cb(int status, int clientIf, bt_uuid_t *app_uuid) 201 { 202 CHECK_CALLBACK_ENV 203 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientRegistered, status, 204 clientIf, UUID_PARAMS(app_uuid)); 205 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 206 } 207 208 void btgattc_scan_result_cb(bt_bdaddr_t* bda, int rssi, uint8_t* adv_data) 209 { 210 CHECK_CALLBACK_ENV 211 212 char c_address[32]; 213 snprintf(c_address, sizeof(c_address),"%02X:%02X:%02X:%02X:%02X:%02X", 214 bda->address[0], bda->address[1], bda->address[2], 215 bda->address[3], bda->address[4], bda->address[5]); 216 217 jstring address = sCallbackEnv->NewStringUTF(c_address); 218 jbyteArray jb = sCallbackEnv->NewByteArray(62); 219 sCallbackEnv->SetByteArrayRegion(jb, 0, 62, (jbyte *) adv_data); 220 221 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScanResult 222 , address, rssi, jb); 223 224 sCallbackEnv->DeleteLocalRef(address); 225 sCallbackEnv->DeleteLocalRef(jb); 226 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 227 } 228 229 void btgattc_open_cb(int conn_id, int status, int clientIf, bt_bdaddr_t* bda) 230 { 231 CHECK_CALLBACK_ENV 232 233 char c_address[32]; 234 snprintf(c_address, sizeof(c_address),"%02X:%02X:%02X:%02X:%02X:%02X", 235 bda->address[0], bda->address[1], bda->address[2], 236 bda->address[3], bda->address[4], bda->address[5]); 237 238 jstring address = sCallbackEnv->NewStringUTF(c_address); 239 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnected, 240 clientIf, conn_id, status, address); 241 sCallbackEnv->DeleteLocalRef(address); 242 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 243 } 244 245 void btgattc_close_cb(int conn_id, int status, int clientIf, bt_bdaddr_t* bda) 246 { 247 CHECK_CALLBACK_ENV 248 char c_address[32]; 249 snprintf(c_address, sizeof(c_address),"%02X:%02X:%02X:%02X:%02X:%02X", 250 bda->address[0], bda->address[1], bda->address[2], 251 bda->address[3], bda->address[4], bda->address[5]); 252 253 jstring address = sCallbackEnv->NewStringUTF(c_address); 254 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onDisconnected, 255 clientIf, conn_id, status, address); 256 sCallbackEnv->DeleteLocalRef(address); 257 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 258 } 259 260 void btgattc_search_complete_cb(int conn_id, int status) 261 { 262 CHECK_CALLBACK_ENV 263 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onSearchCompleted, 264 conn_id, status); 265 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 266 } 267 268 void btgattc_search_result_cb(int conn_id, btgatt_srvc_id_t *srvc_id) 269 { 270 CHECK_CALLBACK_ENV 271 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onSearchResult, conn_id, 272 SRVC_ID_PARAMS(srvc_id)); 273 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 274 } 275 276 void btgattc_get_characteristic_cb(int conn_id, int status, 277 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id, 278 int char_prop) 279 { 280 CHECK_CALLBACK_ENV 281 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onGetCharacteristic 282 , conn_id, status, SRVC_ID_PARAMS(srvc_id), GATT_ID_PARAMS(char_id) 283 , char_prop); 284 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 285 } 286 287 void btgattc_get_descriptor_cb(int conn_id, int status, 288 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id, 289 btgatt_gatt_id_t *descr_id) 290 { 291 CHECK_CALLBACK_ENV 292 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onGetDescriptor 293 , conn_id, status, SRVC_ID_PARAMS(srvc_id), GATT_ID_PARAMS(char_id) 294 , GATT_ID_PARAMS(descr_id)); 295 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 296 } 297 298 void btgattc_get_included_service_cb(int conn_id, int status, 299 btgatt_srvc_id_t *srvc_id, btgatt_srvc_id_t *incl_srvc_id) 300 { 301 CHECK_CALLBACK_ENV 302 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onGetIncludedService 303 , conn_id, status, SRVC_ID_PARAMS(srvc_id), SRVC_ID_PARAMS(incl_srvc_id)); 304 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 305 } 306 307 void btgattc_register_for_notification_cb(int conn_id, int registered, int status, 308 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id) 309 { 310 CHECK_CALLBACK_ENV 311 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onRegisterForNotifications 312 , conn_id, status, registered, SRVC_ID_PARAMS(srvc_id), GATT_ID_PARAMS(char_id)); 313 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 314 } 315 316 void btgattc_notify_cb(int conn_id, btgatt_notify_params_t *p_data) 317 { 318 CHECK_CALLBACK_ENV 319 320 char c_address[32]; 321 snprintf(c_address, sizeof(c_address), "%02X:%02X:%02X:%02X:%02X:%02X", 322 p_data->bda.address[0], p_data->bda.address[1], p_data->bda.address[2], 323 p_data->bda.address[3], p_data->bda.address[4], p_data->bda.address[5]); 324 325 jstring address = sCallbackEnv->NewStringUTF(c_address); 326 jbyteArray jb = sCallbackEnv->NewByteArray(p_data->len); 327 sCallbackEnv->SetByteArrayRegion(jb, 0, p_data->len, (jbyte *) p_data->value); 328 329 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNotify 330 , conn_id, address, SRVC_ID_PARAMS((&p_data->srvc_id)) 331 , GATT_ID_PARAMS((&p_data->char_id)), p_data->is_notify, jb); 332 333 sCallbackEnv->DeleteLocalRef(address); 334 sCallbackEnv->DeleteLocalRef(jb); 335 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 336 } 337 338 void btgattc_read_characteristic_cb(int conn_id, int status, btgatt_read_params_t *p_data) 339 { 340 CHECK_CALLBACK_ENV 341 342 jbyteArray jb; 343 if ( status == 0 ) //successful 344 { 345 jb = sCallbackEnv->NewByteArray(p_data->value.len); 346 sCallbackEnv->SetByteArrayRegion(jb, 0, p_data->value.len, 347 (jbyte *) p_data->value.value); 348 } else { 349 uint8_t value = 0; 350 jb = sCallbackEnv->NewByteArray(1); 351 sCallbackEnv->SetByteArrayRegion(jb, 0, 1, (jbyte *) &value); 352 } 353 354 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onReadCharacteristic 355 , conn_id, status, SRVC_ID_PARAMS((&p_data->srvc_id)) 356 , GATT_ID_PARAMS((&p_data->char_id)), p_data->value_type, jb); 357 sCallbackEnv->DeleteLocalRef(jb); 358 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 359 } 360 361 void btgattc_write_characteristic_cb(int conn_id, int status, btgatt_write_params_t *p_data) 362 { 363 CHECK_CALLBACK_ENV 364 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onWriteCharacteristic 365 , conn_id, status, SRVC_ID_PARAMS((&p_data->srvc_id)) 366 , GATT_ID_PARAMS((&p_data->char_id))); 367 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 368 } 369 370 void btgattc_execute_write_cb(int conn_id, int status) 371 { 372 CHECK_CALLBACK_ENV 373 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onExecuteCompleted 374 , conn_id, status); 375 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 376 } 377 378 void btgattc_read_descriptor_cb(int conn_id, int status, btgatt_read_params_t *p_data) 379 { 380 CHECK_CALLBACK_ENV 381 382 jbyteArray jb; 383 if ( p_data->value.len != 0 ) 384 { 385 jb = sCallbackEnv->NewByteArray(p_data->value.len); 386 sCallbackEnv->SetByteArrayRegion(jb, 0, p_data->value.len, 387 (jbyte *) p_data->value.value); 388 } else { 389 jb = sCallbackEnv->NewByteArray(1); 390 } 391 392 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onReadDescriptor 393 , conn_id, status, SRVC_ID_PARAMS((&p_data->srvc_id)) 394 , GATT_ID_PARAMS((&p_data->char_id)), GATT_ID_PARAMS((&p_data->descr_id)) 395 , p_data->value_type, jb); 396 397 sCallbackEnv->DeleteLocalRef(jb); 398 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 399 } 400 401 void btgattc_write_descriptor_cb(int conn_id, int status, btgatt_write_params_t *p_data) 402 { 403 CHECK_CALLBACK_ENV 404 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onWriteDescriptor 405 , conn_id, status, SRVC_ID_PARAMS((&p_data->srvc_id)) 406 , GATT_ID_PARAMS((&p_data->char_id)) 407 , GATT_ID_PARAMS((&p_data->descr_id))); 408 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 409 } 410 411 void btgattc_remote_rssi_cb(int client_if,bt_bdaddr_t* bda, int rssi, int status) 412 { 413 CHECK_CALLBACK_ENV 414 415 char c_address[32]; 416 snprintf(c_address, sizeof(c_address),"%02X:%02X:%02X:%02X:%02X:%02X", 417 bda->address[0], bda->address[1], bda->address[2], 418 bda->address[3], bda->address[4], bda->address[5]); 419 jstring address = sCallbackEnv->NewStringUTF(c_address); 420 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onReadRemoteRssi, 421 client_if, address, rssi, status); 422 sCallbackEnv->DeleteLocalRef(address); 423 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 424 } 425 426 void btgattc_advertise_cb(int status, int client_if) 427 { 428 CHECK_CALLBACK_ENV 429 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAdvertiseCallback, status, client_if); 430 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 431 } 432 433 static const btgatt_client_callbacks_t sGattClientCallbacks = { 434 btgattc_register_app_cb, 435 btgattc_scan_result_cb, 436 btgattc_open_cb, 437 btgattc_close_cb, 438 btgattc_search_complete_cb, 439 btgattc_search_result_cb, 440 btgattc_get_characteristic_cb, 441 btgattc_get_descriptor_cb, 442 btgattc_get_included_service_cb, 443 btgattc_register_for_notification_cb, 444 btgattc_notify_cb, 445 btgattc_read_characteristic_cb, 446 btgattc_write_characteristic_cb, 447 btgattc_read_descriptor_cb, 448 btgattc_write_descriptor_cb, 449 btgattc_execute_write_cb, 450 btgattc_remote_rssi_cb, 451 btgattc_advertise_cb 452 }; 453 454 455 /** 456 * BTA server callbacks 457 */ 458 459 void btgatts_register_app_cb(int status, int server_if, bt_uuid_t *uuid) 460 { 461 CHECK_CALLBACK_ENV 462 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerRegistered 463 , status, server_if, UUID_PARAMS(uuid)); 464 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 465 } 466 467 void btgatts_connection_cb(int conn_id, int server_if, int connected, bt_bdaddr_t *bda) 468 { 469 CHECK_CALLBACK_ENV 470 471 char c_address[32]; 472 sprintf(c_address, "%02X:%02X:%02X:%02X:%02X:%02X", 473 bda->address[0], bda->address[1], bda->address[2], 474 bda->address[3], bda->address[4], bda->address[5]); 475 476 jstring address = sCallbackEnv->NewStringUTF(c_address); 477 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientConnected, 478 address, connected, conn_id, server_if); 479 sCallbackEnv->DeleteLocalRef(address); 480 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 481 } 482 483 void btgatts_service_added_cb(int status, int server_if, 484 btgatt_srvc_id_t *srvc_id, int srvc_handle) 485 { 486 CHECK_CALLBACK_ENV 487 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceAdded, status, 488 server_if, SRVC_ID_PARAMS(srvc_id), 489 srvc_handle); 490 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 491 } 492 493 void btgatts_included_service_added_cb(int status, int server_if, 494 int srvc_handle, 495 int incl_srvc_handle) 496 { 497 CHECK_CALLBACK_ENV 498 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onIncludedServiceAdded, 499 status, server_if, srvc_handle, incl_srvc_handle); 500 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 501 } 502 503 void btgatts_characteristic_added_cb(int status, int server_if, bt_uuid_t *char_id, 504 int srvc_handle, int char_handle) 505 { 506 CHECK_CALLBACK_ENV 507 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onCharacteristicAdded, 508 status, server_if, UUID_PARAMS(char_id), 509 srvc_handle, char_handle); 510 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 511 } 512 513 void btgatts_descriptor_added_cb(int status, int server_if, 514 bt_uuid_t *descr_id, int srvc_handle, 515 int descr_handle) 516 { 517 CHECK_CALLBACK_ENV 518 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onDescriptorAdded, 519 status, server_if, UUID_PARAMS(descr_id), 520 srvc_handle, descr_handle); 521 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 522 } 523 524 void btgatts_service_started_cb(int status, int server_if, int srvc_handle) 525 { 526 CHECK_CALLBACK_ENV 527 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceStarted, status, 528 server_if, srvc_handle); 529 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 530 } 531 532 void btgatts_service_stopped_cb(int status, int server_if, int srvc_handle) 533 { 534 CHECK_CALLBACK_ENV 535 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceStopped, status, 536 server_if, srvc_handle); 537 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 538 } 539 540 void btgatts_service_deleted_cb(int status, int server_if, int srvc_handle) 541 { 542 CHECK_CALLBACK_ENV 543 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceDeleted, status, 544 server_if, srvc_handle); 545 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 546 } 547 548 void btgatts_request_read_cb(int conn_id, int trans_id, bt_bdaddr_t *bda, 549 int attr_handle, int offset, bool is_long) 550 { 551 CHECK_CALLBACK_ENV 552 553 char c_address[32]; 554 sprintf(c_address, "%02X:%02X:%02X:%02X:%02X:%02X", 555 bda->address[0], bda->address[1], bda->address[2], 556 bda->address[3], bda->address[4], bda->address[5]); 557 558 jstring address = sCallbackEnv->NewStringUTF(c_address); 559 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAttributeRead, 560 address, conn_id, trans_id, attr_handle, 561 offset, is_long); 562 sCallbackEnv->DeleteLocalRef(address); 563 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 564 } 565 566 void btgatts_request_write_cb(int conn_id, int trans_id, 567 bt_bdaddr_t *bda, int attr_handle, 568 int offset, int length, 569 bool need_rsp, bool is_prep, uint8_t* value) 570 { 571 CHECK_CALLBACK_ENV 572 573 char c_address[32]; 574 sprintf(c_address, "%02X:%02X:%02X:%02X:%02X:%02X", 575 bda->address[0], bda->address[1], bda->address[2], 576 bda->address[3], bda->address[4], bda->address[5]); 577 578 jstring address = sCallbackEnv->NewStringUTF(c_address); 579 580 jbyteArray val = sCallbackEnv->NewByteArray(length); 581 if (val) sCallbackEnv->SetByteArrayRegion(val, 0, length, (jbyte*)value); 582 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAttributeWrite, 583 address, conn_id, trans_id, attr_handle, 584 offset, length, need_rsp, is_prep, val); 585 sCallbackEnv->DeleteLocalRef(address); 586 sCallbackEnv->DeleteLocalRef(val); 587 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 588 } 589 590 void btgatts_request_exec_write_cb(int conn_id, int trans_id, 591 bt_bdaddr_t *bda, int exec_write) 592 { 593 CHECK_CALLBACK_ENV 594 595 char c_address[32]; 596 sprintf(c_address, "%02X:%02X:%02X:%02X:%02X:%02X", 597 bda->address[0], bda->address[1], bda->address[2], 598 bda->address[3], bda->address[4], bda->address[5]); 599 600 jstring address = sCallbackEnv->NewStringUTF(c_address); 601 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onExecuteWrite, 602 address, conn_id, trans_id, exec_write); 603 sCallbackEnv->DeleteLocalRef(address); 604 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 605 } 606 607 void btgatts_response_confirmation_cb(int status, int handle) 608 { 609 CHECK_CALLBACK_ENV 610 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onResponseSendCompleted, 611 status, handle); 612 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 613 } 614 615 static const btgatt_server_callbacks_t sGattServerCallbacks = { 616 btgatts_register_app_cb, 617 btgatts_connection_cb, 618 btgatts_service_added_cb, 619 btgatts_included_service_added_cb, 620 btgatts_characteristic_added_cb, 621 btgatts_descriptor_added_cb, 622 btgatts_service_started_cb, 623 btgatts_service_stopped_cb, 624 btgatts_service_deleted_cb, 625 btgatts_request_read_cb, 626 btgatts_request_write_cb, 627 btgatts_request_exec_write_cb, 628 btgatts_response_confirmation_cb 629 }; 630 631 /** 632 * GATT callbacks 633 */ 634 635 static const btgatt_callbacks_t sGattCallbacks = { 636 sizeof(btgatt_callbacks_t), 637 &sGattClientCallbacks, 638 &sGattServerCallbacks 639 }; 640 641 /** 642 * Native function definitions 643 */ 644 645 static void classInitNative(JNIEnv* env, jclass clazz) { 646 647 // Client callbacks 648 649 method_onClientRegistered = env->GetMethodID(clazz, "onClientRegistered", "(IIJJ)V"); 650 method_onScanResult = env->GetMethodID(clazz, "onScanResult", "(Ljava/lang/String;I[B)V"); 651 method_onConnected = env->GetMethodID(clazz, "onConnected", "(IIILjava/lang/String;)V"); 652 method_onDisconnected = env->GetMethodID(clazz, "onDisconnected", "(IIILjava/lang/String;)V"); 653 method_onReadCharacteristic = env->GetMethodID(clazz, "onReadCharacteristic", "(IIIIJJIJJI[B)V"); 654 method_onWriteCharacteristic = env->GetMethodID(clazz, "onWriteCharacteristic", "(IIIIJJIJJ)V"); 655 method_onExecuteCompleted = env->GetMethodID(clazz, "onExecuteCompleted", "(II)V"); 656 method_onSearchCompleted = env->GetMethodID(clazz, "onSearchCompleted", "(II)V"); 657 method_onSearchResult = env->GetMethodID(clazz, "onSearchResult", "(IIIJJ)V"); 658 method_onReadDescriptor = env->GetMethodID(clazz, "onReadDescriptor", "(IIIIJJIJJIJJI[B)V"); 659 method_onWriteDescriptor = env->GetMethodID(clazz, "onWriteDescriptor", "(IIIIJJIJJIJJ)V"); 660 method_onNotify = env->GetMethodID(clazz, "onNotify", "(ILjava/lang/String;IIJJIJJZ[B)V"); 661 method_onGetCharacteristic = env->GetMethodID(clazz, "onGetCharacteristic", "(IIIIJJIJJI)V"); 662 method_onGetDescriptor = env->GetMethodID(clazz, "onGetDescriptor", "(IIIIJJIJJIJJ)V"); 663 method_onGetIncludedService = env->GetMethodID(clazz, "onGetIncludedService", "(IIIIJJIIJJ)V"); 664 method_onRegisterForNotifications = env->GetMethodID(clazz, "onRegisterForNotifications", "(IIIIIJJIJJ)V"); 665 method_onReadRemoteRssi = env->GetMethodID(clazz, "onReadRemoteRssi", "(ILjava/lang/String;II)V"); 666 667 // Server callbacks 668 669 method_onServerRegistered = env->GetMethodID(clazz, "onServerRegistered", "(IIJJ)V"); 670 method_onClientConnected = env->GetMethodID(clazz, "onClientConnected", "(Ljava/lang/String;ZII)V"); 671 method_onServiceAdded = env->GetMethodID(clazz, "onServiceAdded", "(IIIIJJI)V"); 672 method_onIncludedServiceAdded = env->GetMethodID(clazz, "onIncludedServiceAdded", "(IIII)V"); 673 method_onCharacteristicAdded = env->GetMethodID(clazz, "onCharacteristicAdded", "(IIJJII)V"); 674 method_onDescriptorAdded = env->GetMethodID(clazz, "onDescriptorAdded", "(IIJJII)V"); 675 method_onServiceStarted = env->GetMethodID(clazz, "onServiceStarted", "(III)V"); 676 method_onServiceStopped = env->GetMethodID(clazz, "onServiceStopped", "(III)V"); 677 method_onServiceDeleted = env->GetMethodID(clazz, "onServiceDeleted", "(III)V"); 678 method_onResponseSendCompleted = env->GetMethodID(clazz, "onResponseSendCompleted", "(II)V"); 679 method_onAttributeRead= env->GetMethodID(clazz, "onAttributeRead", "(Ljava/lang/String;IIIIZ)V"); 680 method_onAttributeWrite= env->GetMethodID(clazz, "onAttributeWrite", "(Ljava/lang/String;IIIIIZZ[B)V"); 681 method_onExecuteWrite= env->GetMethodID(clazz, "onExecuteWrite", "(Ljava/lang/String;III)V"); 682 method_onAdvertiseCallback = env->GetMethodID(clazz, "onAdvertiseCallback", "(II)V"); 683 684 info("classInitNative: Success!"); 685 } 686 687 static const bt_interface_t* btIf; 688 689 static void initializeNative(JNIEnv *env, jobject object) { 690 if(btIf) 691 return; 692 693 if ( (btIf = getBluetoothInterface()) == NULL) { 694 error("Bluetooth module is not loaded"); 695 return; 696 } 697 698 if (sGattIf != NULL) { 699 ALOGW("Cleaning up Bluetooth GATT Interface before initializing..."); 700 sGattIf->cleanup(); 701 sGattIf = NULL; 702 } 703 704 if (mCallbacksObj != NULL) { 705 ALOGW("Cleaning up Bluetooth GATT callback object"); 706 env->DeleteGlobalRef(mCallbacksObj); 707 mCallbacksObj = NULL; 708 } 709 710 if ( (sGattIf = (btgatt_interface_t *) 711 btIf->get_profile_interface(BT_PROFILE_GATT_ID)) == NULL) { 712 error("Failed to get Bluetooth GATT Interface"); 713 return; 714 } 715 716 bt_status_t status; 717 if ( (status = sGattIf->init(&sGattCallbacks)) != BT_STATUS_SUCCESS) { 718 error("Failed to initialize Bluetooth GATT, status: %d", status); 719 sGattIf = NULL; 720 return; 721 } 722 723 mCallbacksObj = env->NewGlobalRef(object); 724 } 725 726 static void cleanupNative(JNIEnv *env, jobject object) { 727 bt_status_t status; 728 if (!btIf) return; 729 730 if (sGattIf != NULL) { 731 sGattIf->cleanup(); 732 sGattIf = NULL; 733 } 734 735 if (mCallbacksObj != NULL) { 736 env->DeleteGlobalRef(mCallbacksObj); 737 mCallbacksObj = NULL; 738 } 739 btIf = NULL; 740 } 741 742 /** 743 * Native Client functions 744 */ 745 746 static int gattClientGetDeviceTypeNative(JNIEnv* env, jobject object, jstring address) 747 { 748 if (!sGattIf) return 0; 749 bt_bdaddr_t bda; 750 jstr2bdaddr(env, &bda, address); 751 return sGattIf->client->get_device_type(&bda); 752 } 753 754 static void gattClientRegisterAppNative(JNIEnv* env, jobject object, 755 jlong app_uuid_lsb, jlong app_uuid_msb ) 756 { 757 bt_uuid_t uuid; 758 759 if (!sGattIf) return; 760 set_uuid(uuid.uu, app_uuid_msb, app_uuid_lsb); 761 sGattIf->client->register_client(&uuid); 762 } 763 764 static void gattClientUnregisterAppNative(JNIEnv* env, jobject object, jint clientIf) 765 { 766 if (!sGattIf) return; 767 sGattIf->client->unregister_client(clientIf); 768 } 769 770 static void gattClientScanNative(JNIEnv* env, jobject object, jint clientIf, jboolean start) 771 { 772 if (!sGattIf) return; 773 sGattIf->client->scan(clientIf, start); 774 } 775 776 static void gattClientConnectNative(JNIEnv* env, jobject object, jint clientif, 777 jstring address, jboolean isDirect) 778 { 779 if (!sGattIf) return; 780 781 bt_bdaddr_t bda; 782 jstr2bdaddr(env, &bda, address); 783 sGattIf->client->connect(clientif, &bda, isDirect); 784 } 785 786 static void gattClientDisconnectNative(JNIEnv* env, jobject object, jint clientIf, 787 jstring address, jint conn_id) 788 { 789 if (!sGattIf) return; 790 bt_bdaddr_t bda; 791 jstr2bdaddr(env, &bda, address); 792 sGattIf->client->disconnect(clientIf, &bda, conn_id); 793 } 794 795 static void gattClientRefreshNative(JNIEnv* env, jobject object, jint clientIf, 796 jstring address) 797 { 798 if (!sGattIf) return; 799 800 bt_bdaddr_t bda; 801 jstr2bdaddr(env, &bda, address); 802 sGattIf->client->refresh(clientIf, &bda); 803 } 804 805 static void gattClientSearchServiceNative(JNIEnv* env, jobject object, jint conn_id, 806 jboolean search_all, jlong service_uuid_lsb, jlong service_uuid_msb) 807 { 808 if (!sGattIf) return; 809 810 bt_uuid_t uuid; 811 set_uuid(uuid.uu, service_uuid_msb, service_uuid_lsb); 812 sGattIf->client->search_service(conn_id, search_all ? 0 : &uuid); 813 } 814 815 static void gattClientGetCharacteristicNative(JNIEnv* env, jobject object, 816 jint conn_id, 817 jint service_type, jint service_id_inst_id, 818 jlong service_id_uuid_lsb, jlong service_id_uuid_msb, 819 jint char_id_inst_id, 820 jlong char_id_uuid_lsb, jlong char_id_uuid_msb) 821 { 822 if (!sGattIf) return; 823 824 btgatt_srvc_id_t srvc_id; 825 srvc_id.id.inst_id = (uint8_t) service_id_inst_id; 826 srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0); 827 828 set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb); 829 830 btgatt_gatt_id_t char_id; 831 char_id.inst_id = (uint8_t) char_id_inst_id; 832 set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb); 833 834 if (char_id_uuid_lsb == 0) 835 { 836 sGattIf->client->get_characteristic(conn_id, &srvc_id, 0); 837 } else { 838 sGattIf->client->get_characteristic(conn_id, &srvc_id, &char_id); 839 } 840 } 841 842 static void gattClientGetDescriptorNative(JNIEnv* env, jobject object, 843 jint conn_id, 844 jint service_type, jint service_id_inst_id, 845 jlong service_id_uuid_lsb, jlong service_id_uuid_msb, 846 jint char_id_inst_id, 847 jlong char_id_uuid_lsb, jlong char_id_uuid_msb, 848 jint descr_id_inst_id, 849 jlong descr_id_uuid_lsb, jlong descr_id_uuid_msb) 850 { 851 if (!sGattIf) return; 852 853 btgatt_srvc_id_t srvc_id; 854 srvc_id.id.inst_id = (uint8_t) service_id_inst_id; 855 srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0); 856 set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb); 857 858 btgatt_gatt_id_t char_id; 859 char_id.inst_id = (uint8_t) char_id_inst_id; 860 set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb); 861 862 btgatt_gatt_id_t descr_id; 863 descr_id.inst_id = (uint8_t) descr_id_inst_id; 864 set_uuid(descr_id.uuid.uu, descr_id_uuid_msb, descr_id_uuid_lsb); 865 866 if (descr_id_uuid_lsb == 0) 867 { 868 sGattIf->client->get_descriptor(conn_id, &srvc_id, &char_id, 0); 869 } else { 870 sGattIf->client->get_descriptor(conn_id, &srvc_id, &char_id, &descr_id); 871 } 872 } 873 874 static void gattClientGetIncludedServiceNative(JNIEnv* env, jobject object, 875 jint conn_id, jint service_type, jint service_id_inst_id, 876 jlong service_id_uuid_lsb, jlong service_id_uuid_msb, 877 jint incl_service_id_inst_id, jint incl_service_type, 878 jlong incl_service_id_uuid_lsb, jlong incl_service_id_uuid_msb) 879 { 880 if (!sGattIf) return; 881 882 btgatt_srvc_id_t srvc_id; 883 srvc_id.id.inst_id = (uint8_t) service_id_inst_id; 884 srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0); 885 set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb); 886 887 btgatt_srvc_id_t incl_srvc_id; 888 incl_srvc_id.id.inst_id = (uint8_t) incl_service_id_inst_id; 889 incl_srvc_id.is_primary = (incl_service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0); 890 set_uuid(incl_srvc_id.id.uuid.uu, incl_service_id_uuid_msb, incl_service_id_uuid_lsb); 891 892 if (incl_service_id_uuid_lsb == 0) 893 { 894 sGattIf->client->get_included_service(conn_id, &srvc_id, 0); 895 } else { 896 sGattIf->client->get_included_service(conn_id, &srvc_id, &incl_srvc_id); 897 } 898 } 899 900 static void gattClientReadCharacteristicNative(JNIEnv* env, jobject object, 901 jint conn_id, jint service_type, jint service_id_inst_id, 902 jlong service_id_uuid_lsb, jlong service_id_uuid_msb, 903 jint char_id_inst_id, 904 jlong char_id_uuid_lsb, jlong char_id_uuid_msb, 905 jint authReq) 906 { 907 if (!sGattIf) return; 908 909 btgatt_srvc_id_t srvc_id; 910 srvc_id.id.inst_id = (uint8_t) service_id_inst_id; 911 srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0); 912 set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb); 913 914 btgatt_gatt_id_t char_id; 915 char_id.inst_id = (uint8_t) char_id_inst_id; 916 set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb); 917 918 sGattIf->client->read_characteristic(conn_id, &srvc_id, &char_id, authReq); 919 } 920 921 static void gattClientReadDescriptorNative(JNIEnv* env, jobject object, 922 jint conn_id, jint service_type, jint service_id_inst_id, 923 jlong service_id_uuid_lsb, jlong service_id_uuid_msb, 924 jint char_id_inst_id, 925 jlong char_id_uuid_lsb, jlong char_id_uuid_msb, 926 jint descr_id_inst_id, 927 jlong descr_id_uuid_lsb, jlong descr_id_uuid_msb, 928 jint authReq) 929 { 930 if (!sGattIf) return; 931 932 btgatt_srvc_id_t srvc_id; 933 srvc_id.id.inst_id = (uint8_t) service_id_inst_id; 934 srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0); 935 set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb); 936 937 btgatt_gatt_id_t char_id; 938 char_id.inst_id = (uint8_t) char_id_inst_id; 939 set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb); 940 941 btgatt_gatt_id_t descr_id; 942 descr_id.inst_id = (uint8_t) descr_id_inst_id; 943 set_uuid(descr_id.uuid.uu, descr_id_uuid_msb, descr_id_uuid_lsb); 944 945 sGattIf->client->read_descriptor(conn_id, &srvc_id, &char_id, &descr_id, authReq); 946 } 947 948 static void gattClientWriteCharacteristicNative(JNIEnv* env, jobject object, 949 jint conn_id, jint service_type, jint service_id_inst_id, 950 jlong service_id_uuid_lsb, jlong service_id_uuid_msb, 951 jint char_id_inst_id, 952 jlong char_id_uuid_lsb, jlong char_id_uuid_msb, 953 jint write_type, jint auth_req, jbyteArray value) 954 { 955 if (!sGattIf) return; 956 957 btgatt_srvc_id_t srvc_id; 958 srvc_id.id.inst_id = (uint8_t) service_id_inst_id; 959 srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0); 960 set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb); 961 962 btgatt_gatt_id_t char_id; 963 char_id.inst_id = (uint8_t) char_id_inst_id; 964 set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb); 965 966 uint16_t len = (uint16_t) env->GetArrayLength(value); 967 jbyte *p_value = env->GetByteArrayElements(value, NULL); 968 if (p_value == NULL) return; 969 970 sGattIf->client->write_characteristic(conn_id, &srvc_id, &char_id, 971 write_type, len, auth_req, (char*)p_value); 972 env->ReleaseByteArrayElements(value, p_value, 0); 973 } 974 975 static void gattClientExecuteWriteNative(JNIEnv* env, jobject object, 976 jint conn_id, jboolean execute) 977 { 978 if (!sGattIf) return; 979 sGattIf->client->execute_write(conn_id, execute ? 1 : 0); 980 } 981 982 static void gattClientWriteDescriptorNative(JNIEnv* env, jobject object, 983 jint conn_id, jint service_type, jint service_id_inst_id, 984 jlong service_id_uuid_lsb, jlong service_id_uuid_msb, 985 jint char_id_inst_id, 986 jlong char_id_uuid_lsb, jlong char_id_uuid_msb, 987 jint descr_id_inst_id, 988 jlong descr_id_uuid_lsb, jlong descr_id_uuid_msb, 989 jint write_type, jint auth_req, jbyteArray value) 990 { 991 if (!sGattIf) return; 992 993 if (value == NULL) { 994 warn("gattClientWriteDescriptorNative() ignoring NULL array"); 995 return; 996 } 997 998 btgatt_srvc_id_t srvc_id; 999 srvc_id.id.inst_id = (uint8_t) service_id_inst_id; 1000 srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0); 1001 set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb); 1002 1003 btgatt_gatt_id_t char_id; 1004 char_id.inst_id = (uint8_t) char_id_inst_id; 1005 set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb); 1006 1007 btgatt_gatt_id_t descr_id; 1008 descr_id.inst_id = (uint8_t) descr_id_inst_id; 1009 set_uuid(descr_id.uuid.uu, descr_id_uuid_msb, descr_id_uuid_lsb); 1010 1011 uint16_t len = (uint16_t) env->GetArrayLength(value); 1012 jbyte *p_value = env->GetByteArrayElements(value, NULL); 1013 if (p_value == NULL) return; 1014 1015 sGattIf->client->write_descriptor(conn_id, &srvc_id, &char_id, &descr_id, 1016 write_type, len, auth_req, (char*)p_value); 1017 env->ReleaseByteArrayElements(value, p_value, 0); 1018 } 1019 1020 static void gattClientRegisterForNotificationsNative(JNIEnv* env, jobject object, 1021 jint clientIf, jstring address, 1022 jint service_type, jint service_id_inst_id, 1023 jlong service_id_uuid_lsb, jlong service_id_uuid_msb, 1024 jint char_id_inst_id, 1025 jlong char_id_uuid_lsb, jlong char_id_uuid_msb, 1026 jboolean enable) 1027 { 1028 if (!sGattIf) return; 1029 1030 btgatt_srvc_id_t srvc_id; 1031 srvc_id.id.inst_id = (uint8_t) service_id_inst_id; 1032 srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0); 1033 set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb); 1034 1035 btgatt_gatt_id_t char_id; 1036 char_id.inst_id = (uint8_t) char_id_inst_id; 1037 set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb); 1038 1039 bt_bdaddr_t bd_addr; 1040 const char *c_address = env->GetStringUTFChars(address, NULL); 1041 bd_addr_str_to_addr(c_address, bd_addr.address); 1042 1043 if (enable) 1044 sGattIf->client->register_for_notification(clientIf, &bd_addr, &srvc_id, &char_id); 1045 else 1046 sGattIf->client->deregister_for_notification(clientIf, &bd_addr, &srvc_id, &char_id); 1047 } 1048 1049 static void gattClientReadRemoteRssiNative(JNIEnv* env, jobject object, jint clientif, 1050 jstring address) 1051 { 1052 if (!sGattIf) return; 1053 1054 bt_bdaddr_t bda; 1055 jstr2bdaddr(env, &bda, address); 1056 1057 sGattIf->client->read_remote_rssi(clientif, &bda); 1058 } 1059 1060 static void gattAdvertiseNative(JNIEnv *env, jobject object, 1061 jint client_if, jboolean start) 1062 { 1063 if (!sGattIf) return; 1064 sGattIf->client->listen(client_if, start); 1065 } 1066 1067 static void gattSetAdvDataNative(JNIEnv *env, jobject object, jint client_if, jboolean setScanRsp, 1068 jboolean inclName, jboolean inclTxPower, jint minInterval, jint maxInterval, 1069 jint appearance, jbyteArray manufacturerData, jbyteArray serviceData, 1070 jbyteArray serviceUuid) 1071 { 1072 if (!sGattIf) return; 1073 jbyte* arr_data = env->GetByteArrayElements(manufacturerData, NULL); 1074 uint16_t arr_len = (uint16_t) env->GetArrayLength(manufacturerData); 1075 1076 jbyte* service_data = env->GetByteArrayElements(serviceData, NULL); 1077 uint16_t service_data_len = (uint16_t) env->GetArrayLength(serviceData); 1078 1079 jbyte* service_uuid = env->GetByteArrayElements(serviceUuid, NULL); 1080 uint16_t service_uuid_len = (uint16_t) env->GetArrayLength(serviceUuid); 1081 1082 sGattIf->client->set_adv_data(client_if, setScanRsp, inclName, inclTxPower, 1083 minInterval, maxInterval, appearance, arr_len, (char*)arr_data, 1084 service_data_len, (char*)service_data, service_uuid_len, 1085 (char*)service_uuid); 1086 1087 env->ReleaseByteArrayElements(manufacturerData, arr_data, JNI_ABORT); 1088 env->ReleaseByteArrayElements(serviceData, service_data, JNI_ABORT); 1089 env->ReleaseByteArrayElements(serviceUuid, service_uuid, JNI_ABORT); 1090 } 1091 1092 1093 /** 1094 * Native server functions 1095 */ 1096 static void gattServerRegisterAppNative(JNIEnv* env, jobject object, 1097 jlong app_uuid_lsb, jlong app_uuid_msb ) 1098 { 1099 bt_uuid_t uuid; 1100 if (!sGattIf) return; 1101 set_uuid(uuid.uu, app_uuid_msb, app_uuid_lsb); 1102 sGattIf->server->register_server(&uuid); 1103 } 1104 1105 static void gattServerUnregisterAppNative(JNIEnv* env, jobject object, jint serverIf) 1106 { 1107 if (!sGattIf) return; 1108 sGattIf->server->unregister_server(serverIf); 1109 } 1110 1111 static void gattServerConnectNative(JNIEnv *env, jobject object, 1112 jint server_if, jstring address, jboolean is_direct) 1113 { 1114 if (!sGattIf) return; 1115 1116 bt_bdaddr_t bd_addr; 1117 const char *c_address = env->GetStringUTFChars(address, NULL); 1118 bd_addr_str_to_addr(c_address, bd_addr.address); 1119 1120 sGattIf->server->connect(server_if, &bd_addr, is_direct); 1121 } 1122 1123 static void gattServerDisconnectNative(JNIEnv* env, jobject object, jint serverIf, 1124 jstring address, jint conn_id) 1125 { 1126 if (!sGattIf) return; 1127 bt_bdaddr_t bda; 1128 jstr2bdaddr(env, &bda, address); 1129 sGattIf->server->disconnect(serverIf, &bda, conn_id); 1130 } 1131 1132 static void gattServerAddServiceNative (JNIEnv *env, jobject object, 1133 jint server_if, jint service_type, jint service_id_inst_id, 1134 jlong service_id_uuid_lsb, jlong service_id_uuid_msb, 1135 jint num_handles) 1136 { 1137 if (!sGattIf) return; 1138 1139 btgatt_srvc_id_t srvc_id; 1140 srvc_id.id.inst_id = (uint8_t) service_id_inst_id; 1141 srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0); 1142 set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb); 1143 1144 sGattIf->server->add_service(server_if, &srvc_id, num_handles); 1145 } 1146 1147 static void gattServerAddIncludedServiceNative (JNIEnv *env, jobject object, 1148 jint server_if, jint svc_handle, jint included_svc_handle) 1149 { 1150 if (!sGattIf) return; 1151 sGattIf->server->add_included_service(server_if, svc_handle, 1152 included_svc_handle); 1153 } 1154 1155 static void gattServerAddCharacteristicNative (JNIEnv *env, jobject object, 1156 jint server_if, jint svc_handle, 1157 jlong char_uuid_lsb, jlong char_uuid_msb, 1158 jint properties, jint permissions) 1159 { 1160 if (!sGattIf) return; 1161 1162 bt_uuid_t uuid; 1163 set_uuid(uuid.uu, char_uuid_msb, char_uuid_lsb); 1164 1165 sGattIf->server->add_characteristic(server_if, svc_handle, 1166 &uuid, properties, permissions); 1167 } 1168 1169 static void gattServerAddDescriptorNative (JNIEnv *env, jobject object, 1170 jint server_if, jint svc_handle, 1171 jlong desc_uuid_lsb, jlong desc_uuid_msb, 1172 jint permissions) 1173 { 1174 if (!sGattIf) return; 1175 1176 bt_uuid_t uuid; 1177 set_uuid(uuid.uu, desc_uuid_msb, desc_uuid_lsb); 1178 1179 sGattIf->server->add_descriptor(server_if, svc_handle, &uuid, permissions); 1180 } 1181 1182 static void gattServerStartServiceNative (JNIEnv *env, jobject object, 1183 jint server_if, jint svc_handle, jint transport ) 1184 { 1185 if (!sGattIf) return; 1186 sGattIf->server->start_service(server_if, svc_handle, transport); 1187 } 1188 1189 static void gattServerStopServiceNative (JNIEnv *env, jobject object, 1190 jint server_if, jint svc_handle) 1191 { 1192 if (!sGattIf) return; 1193 sGattIf->server->stop_service(server_if, svc_handle); 1194 } 1195 1196 static void gattServerDeleteServiceNative (JNIEnv *env, jobject object, 1197 jint server_if, jint svc_handle) 1198 { 1199 if (!sGattIf) return; 1200 sGattIf->server->delete_service(server_if, svc_handle); 1201 } 1202 1203 static void gattServerSendIndicationNative (JNIEnv *env, jobject object, 1204 jint server_if, jint attr_handle, jint conn_id, jbyteArray val) 1205 { 1206 if (!sGattIf) return; 1207 1208 jbyte* array = env->GetByteArrayElements(val, 0); 1209 int val_len = env->GetArrayLength(val); 1210 1211 sGattIf->server->send_indication(server_if, attr_handle, conn_id, val_len, 1212 /*confirm*/ 1, (char*)array); 1213 env->ReleaseByteArrayElements(val, array, JNI_ABORT); 1214 } 1215 1216 static void gattServerSendNotificationNative (JNIEnv *env, jobject object, 1217 jint server_if, jint attr_handle, jint conn_id, jbyteArray val) 1218 { 1219 if (!sGattIf) return; 1220 1221 jbyte* array = env->GetByteArrayElements(val, 0); 1222 int val_len = env->GetArrayLength(val); 1223 1224 sGattIf->server->send_indication(server_if, attr_handle, conn_id, val_len, 1225 /*confirm*/ 0, (char*)array); 1226 env->ReleaseByteArrayElements(val, array, JNI_ABORT); 1227 } 1228 1229 static void gattServerSendResponseNative (JNIEnv *env, jobject object, 1230 jint server_if, jint conn_id, jint trans_id, jint status, 1231 jint handle, jint offset, jbyteArray val, jint auth_req) 1232 { 1233 if (!sGattIf) return; 1234 1235 btgatt_response_t response; 1236 1237 response.attr_value.handle = handle; 1238 response.attr_value.auth_req = auth_req; 1239 response.attr_value.offset = offset; 1240 response.attr_value.len = 0; 1241 1242 if (val != NULL) 1243 { 1244 response.attr_value.len = (uint16_t) env->GetArrayLength(val); 1245 jbyte* array = env->GetByteArrayElements(val, 0); 1246 1247 for (int i = 0; i != response.attr_value.len; ++i) 1248 response.attr_value.value[i] = (uint8_t) array[i]; 1249 env->ReleaseByteArrayElements(val, array, JNI_ABORT); 1250 } 1251 1252 sGattIf->server->send_response(conn_id, trans_id, status, &response); 1253 } 1254 1255 static void gattTestNative(JNIEnv *env, jobject object, jint command, 1256 jlong uuid1_lsb, jlong uuid1_msb, jstring bda1, 1257 jint p1, jint p2, jint p3, jint p4, jint p5 ) 1258 { 1259 if (!sGattIf) return; 1260 1261 bt_bdaddr_t bt_bda1; 1262 jstr2bdaddr(env, &bt_bda1, bda1); 1263 1264 bt_uuid_t uuid1; 1265 set_uuid(uuid1.uu, uuid1_msb, uuid1_lsb); 1266 1267 btgatt_test_params_t params; 1268 params.bda1 = &bt_bda1; 1269 params.uuid1 = &uuid1; 1270 params.u1 = p1; 1271 params.u2 = p2; 1272 params.u3 = p3; 1273 params.u4 = p4; 1274 params.u5 = p5; 1275 sGattIf->client->test_command(command, ¶ms); 1276 } 1277 1278 /** 1279 * JNI function definitinos 1280 */ 1281 1282 static JNINativeMethod sMethods[] = { 1283 {"classInitNative", "()V", (void *) classInitNative}, 1284 {"initializeNative", "()V", (void *) initializeNative}, 1285 {"cleanupNative", "()V", (void *) cleanupNative}, 1286 1287 {"gattClientGetDeviceTypeNative", "(Ljava/lang/String;)I", (void *) gattClientGetDeviceTypeNative}, 1288 {"gattClientRegisterAppNative", "(JJ)V", (void *) gattClientRegisterAppNative}, 1289 {"gattClientUnregisterAppNative", "(I)V", (void *) gattClientUnregisterAppNative}, 1290 {"gattClientScanNative", "(IZ)V", (void *) gattClientScanNative}, 1291 {"gattClientConnectNative", "(ILjava/lang/String;Z)V", (void *) gattClientConnectNative}, 1292 {"gattClientDisconnectNative", "(ILjava/lang/String;I)V", (void *) gattClientDisconnectNative}, 1293 {"gattClientRefreshNative", "(ILjava/lang/String;)V", (void *) gattClientRefreshNative}, 1294 {"gattClientSearchServiceNative", "(IZJJ)V", (void *) gattClientSearchServiceNative}, 1295 {"gattClientGetCharacteristicNative", "(IIIJJIJJ)V", (void *) gattClientGetCharacteristicNative}, 1296 {"gattClientGetDescriptorNative", "(IIIJJIJJIJJ)V", (void *) gattClientGetDescriptorNative}, 1297 {"gattClientGetIncludedServiceNative", "(IIIJJIIJJ)V", (void *) gattClientGetIncludedServiceNative}, 1298 {"gattClientReadCharacteristicNative", "(IIIJJIJJI)V", (void *) gattClientReadCharacteristicNative}, 1299 {"gattClientReadDescriptorNative", "(IIIJJIJJIJJI)V", (void *) gattClientReadDescriptorNative}, 1300 {"gattClientWriteCharacteristicNative", "(IIIJJIJJII[B)V", (void *) gattClientWriteCharacteristicNative}, 1301 {"gattClientWriteDescriptorNative", "(IIIJJIJJIJJII[B)V", (void *) gattClientWriteDescriptorNative}, 1302 {"gattClientExecuteWriteNative", "(IZ)V", (void *) gattClientExecuteWriteNative}, 1303 {"gattClientRegisterForNotificationsNative", "(ILjava/lang/String;IIJJIJJZ)V", (void *) gattClientRegisterForNotificationsNative}, 1304 {"gattClientReadRemoteRssiNative", "(ILjava/lang/String;)V", (void *) gattClientReadRemoteRssiNative}, 1305 {"gattAdvertiseNative", "(IZ)V", (void *) gattAdvertiseNative}, 1306 1307 {"gattServerRegisterAppNative", "(JJ)V", (void *) gattServerRegisterAppNative}, 1308 {"gattServerUnregisterAppNative", "(I)V", (void *) gattServerUnregisterAppNative}, 1309 {"gattServerConnectNative", "(ILjava/lang/String;Z)V", (void *) gattServerConnectNative}, 1310 {"gattServerDisconnectNative", "(ILjava/lang/String;I)V", (void *) gattServerDisconnectNative}, 1311 {"gattServerAddServiceNative", "(IIIJJI)V", (void *) gattServerAddServiceNative}, 1312 {"gattServerAddIncludedServiceNative", "(III)V", (void *) gattServerAddIncludedServiceNative}, 1313 {"gattServerAddCharacteristicNative", "(IIJJII)V", (void *) gattServerAddCharacteristicNative}, 1314 {"gattServerAddDescriptorNative", "(IIJJI)V", (void *) gattServerAddDescriptorNative}, 1315 {"gattServerStartServiceNative", "(III)V", (void *) gattServerStartServiceNative}, 1316 {"gattServerStopServiceNative", "(II)V", (void *) gattServerStopServiceNative}, 1317 {"gattServerDeleteServiceNative", "(II)V", (void *) gattServerDeleteServiceNative}, 1318 {"gattServerSendIndicationNative", "(III[B)V", (void *) gattServerSendIndicationNative}, 1319 {"gattServerSendNotificationNative", "(III[B)V", (void *) gattServerSendNotificationNative}, 1320 {"gattServerSendResponseNative", "(IIIIII[BI)V", (void *) gattServerSendResponseNative}, 1321 1322 {"gattSetAdvDataNative", "(IZZZIII[B[B[B)V", (void *) gattSetAdvDataNative}, 1323 {"gattTestNative", "(IJJLjava/lang/String;IIIII)V", (void *) gattTestNative}, 1324 }; 1325 1326 int register_com_android_bluetooth_gatt(JNIEnv* env) 1327 { 1328 return jniRegisterNativeMethods(env, "com/android/bluetooth/gatt/GattService", 1329 sMethods, NELEM(sMethods)); 1330 } 1331 1332 } 1333