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