com_android_bluetooth_gatt.cpp revision a08fff0ae81757bdab00ae8865a906c711d5572f
1/* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 18#define LOG_TAG "BtGatt.JNI" 19 20#define LOG_NDEBUG 0 21 22#define CHECK_CALLBACK_ENV \ 23 if (!checkCallbackThread()) { \ 24 error("Callback: '%s' is not called on the correct thread", __FUNCTION__);\ 25 return; \ 26 } 27 28#include "com_android_bluetooth.h" 29#include "hardware/bt_gatt.h" 30#include "utils/Log.h" 31#include "android_runtime/AndroidRuntime.h" 32 33#include <string.h> 34 35#include <cutils/log.h> 36#define info(fmt, ...) ALOGI ("%s(L%d): " fmt,__FUNCTION__, __LINE__, ## __VA_ARGS__) 37#define debug(fmt, ...) ALOGD ("%s(L%d): " fmt,__FUNCTION__, __LINE__, ## __VA_ARGS__) 38#define warn(fmt, ...) ALOGW ("WARNING: %s(L%d): " fmt "##",__FUNCTION__, __LINE__, ## __VA_ARGS__) 39#define error(fmt, ...) ALOGE ("ERROR: %s(L%d): " fmt "##",__FUNCTION__, __LINE__, ## __VA_ARGS__) 40#define asrt(s) if(!(s)) ALOGE ("%s(L%d): ASSERT %s failed! ##",__FUNCTION__, __LINE__, #s) 41 42#define BD_ADDR_LEN 6 43 44#define UUID_PARAMS(uuid_ptr) \ 45 uuid_lsb(uuid_ptr), uuid_msb(uuid_ptr) 46 47#define GATT_ID_PARAMS(attr_ptr) \ 48 attr_ptr->inst_id, \ 49 UUID_PARAMS((&attr_ptr->uuid)) 50 51#define SRVC_ID_PARAMS(srvc_ptr) \ 52 (srvc_ptr->is_primary ? \ 53 BTGATT_SERVICE_TYPE_PRIMARY : BTGATT_SERVICE_TYPE_SECONDARY), \ 54 GATT_ID_PARAMS((&srvc_ptr->id)) 55 56 57static void set_uuid(uint8_t* uuid, jlong uuid_msb, jlong uuid_lsb) 58{ 59 for (int i = 0; i != 8; ++i) 60 { 61 uuid[i] = (uuid_lsb >> (8 * i)) & 0xFF; 62 uuid[i + 8] = (uuid_msb >> (8 * i)) & 0xFF; 63 } 64} 65 66static uint64_t uuid_lsb(bt_uuid_t* uuid) 67{ 68 uint64_t lsb = 0; 69 int i; 70 71 for (i = 7; i >= 0; i--) 72 { 73 lsb <<= 8; 74 lsb |= uuid->uu[i]; 75 } 76 77 return lsb; 78} 79 80static uint64_t uuid_msb(bt_uuid_t* uuid) 81{ 82 uint64_t msb = 0; 83 int i; 84 85 for (i = 15; i >= 8; i--) 86 { 87 msb <<= 8; 88 msb |= uuid->uu[i]; 89 } 90 91 return msb; 92} 93 94static void bd_addr_str_to_addr(const char* str, uint8_t *bd_addr) 95{ 96 int i; 97 char c; 98 99 c = *str++; 100 for (i = 0; i < BD_ADDR_LEN; i++) 101 { 102 if (c >= '0' && c <= '9') 103 bd_addr[i] = c - '0'; 104 else if (c >= 'a' && c <= 'z') 105 bd_addr[i] = c - 'a' + 10; 106 else // (c >= 'A' && c <= 'Z') 107 bd_addr[i] = c - 'A' + 10; 108 109 c = *str++; 110 if (c != ':') 111 { 112 bd_addr[i] <<= 4; 113 if (c >= '0' && c <= '9') 114 bd_addr[i] |= c - '0'; 115 else if (c >= 'a' && c <= 'z') 116 bd_addr[i] |= c - 'a' + 10; 117 else // (c >= 'A' && c <= 'Z') 118 bd_addr[i] |= c - 'A' + 10; 119 120 c = *str++; 121 } 122 123 c = *str++; 124 } 125} 126 127static void jstr2bdaddr(JNIEnv* env, bt_bdaddr_t *bda, jstring address) 128{ 129 const char* c_bda = env->GetStringUTFChars(address, NULL); 130 if (c_bda != NULL && bda != NULL && strlen(c_bda) == 17) 131 { 132 bd_addr_str_to_addr(c_bda, bda->address); 133 env->ReleaseStringUTFChars(address, c_bda); 134 } 135} 136 137namespace android { 138 139/** 140 * Client callback methods 141 */ 142 143static jmethodID method_onClientRegistered; 144static jmethodID method_onScanResult; 145static jmethodID method_onConnected; 146static jmethodID method_onDisconnected; 147static jmethodID method_onReadCharacteristic; 148static jmethodID method_onWriteCharacteristic; 149static jmethodID method_onExecuteCompleted; 150static jmethodID method_onSearchCompleted; 151static jmethodID method_onSearchResult; 152static jmethodID method_onReadDescrExtProp; 153static jmethodID method_onReadDescriptor; 154static jmethodID method_onWriteDescriptor; 155static jmethodID method_onNotify; 156static jmethodID method_onGetCharacteristic; 157static jmethodID method_onGetDescriptor; 158static jmethodID method_onGetIncludedService; 159static jmethodID method_onRegisterForNotifications; 160static jmethodID method_onReadRemoteRssi; 161 162/** 163 * Server callback methods 164 */ 165static jmethodID method_onServerRegistered; 166static jmethodID method_onClientConnected; 167static jmethodID method_onServiceAdded; 168static jmethodID method_onIncludedServiceAdded; 169static jmethodID method_onCharacteristicAdded; 170static jmethodID method_onDescriptorAdded; 171static jmethodID method_onServiceStarted; 172static jmethodID method_onServiceStopped; 173static jmethodID method_onServiceDeleted; 174static jmethodID method_onResponseSendCompleted; 175static jmethodID method_onAttributeRead; 176static jmethodID method_onAttributeWrite; 177static jmethodID method_onExecuteWrite; 178 179/** 180 * Static variables 181 */ 182 183static const btgatt_interface_t *sGattIf = NULL; 184static jobject mCallbacksObj = NULL; 185static JNIEnv *sCallbackEnv = NULL; 186 187static 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 199void 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 207void 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 228void 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 244void 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 259void 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 267void 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 275void btgattc_get_characteristic_cb(int conn_id, int status, 276 btgatt_srvc_id_t *srvc_id, btgatt_gatt_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), GATT_ID_PARAMS(char_id) 282 , char_prop); 283 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 284} 285 286void btgattc_get_descriptor_cb(int conn_id, int status, 287 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id, 288 btgatt_gatt_id_t *descr_id) 289{ 290 CHECK_CALLBACK_ENV 291 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onGetDescriptor 292 , conn_id, status, SRVC_ID_PARAMS(srvc_id), GATT_ID_PARAMS(char_id) 293 , GATT_ID_PARAMS(descr_id)); 294 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 295} 296 297void 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 306void btgattc_register_for_notification_cb(int conn_id, int registered, int status, 307 btgatt_srvc_id_t *srvc_id, btgatt_gatt_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), GATT_ID_PARAMS(char_id)); 312 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 313} 314 315void 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 , GATT_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 337void 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 , GATT_ID_PARAMS((&p_data->char_id)), p_data->value_type, jb); 356 sCallbackEnv->DeleteLocalRef(jb); 357 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 358} 359 360void 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 , GATT_ID_PARAMS((&p_data->char_id))); 366 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 367} 368 369void 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 377void 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 , GATT_ID_PARAMS((&p_data->char_id)), GATT_ID_PARAMS((&p_data->descr_id)) 394 , p_data->value_type, jb); 395 396 sCallbackEnv->DeleteLocalRef(jb); 397 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 398} 399 400void 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 , GATT_ID_PARAMS((&p_data->char_id)) 406 , GATT_ID_PARAMS((&p_data->descr_id))); 407 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 408} 409 410void btgattc_remote_rssi_cb(int client_if,bt_bdaddr_t* bda, int rssi, int status) 411{ 412 CHECK_CALLBACK_ENV 413 414 char c_address[32]; 415 snprintf(c_address, sizeof(c_address),"%02X:%02X:%02X:%02X:%02X:%02X", 416 bda->address[0], bda->address[1], bda->address[2], 417 bda->address[3], bda->address[4], bda->address[5]); 418 jstring address = sCallbackEnv->NewStringUTF(c_address); 419 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onReadRemoteRssi, 420 client_if, address, rssi, status); 421 sCallbackEnv->DeleteLocalRef(address); 422 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 423} 424 425static const btgatt_client_callbacks_t sGattClientCallbacks = { 426 btgattc_register_app_cb, 427 btgattc_scan_result_cb, 428 btgattc_open_cb, 429 btgattc_close_cb, 430 btgattc_search_complete_cb, 431 btgattc_search_result_cb, 432 btgattc_get_characteristic_cb, 433 btgattc_get_descriptor_cb, 434 btgattc_get_included_service_cb, 435 btgattc_register_for_notification_cb, 436 btgattc_notify_cb, 437 btgattc_read_characteristic_cb, 438 btgattc_write_characteristic_cb, 439 btgattc_read_descriptor_cb, 440 btgattc_write_descriptor_cb, 441 btgattc_execute_write_cb, 442 btgattc_remote_rssi_cb 443}; 444 445 446/** 447 * BTA server callbacks 448 */ 449 450void btgatts_register_app_cb(int status, int server_if, bt_uuid_t *uuid) 451{ 452 CHECK_CALLBACK_ENV 453 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerRegistered 454 , status, server_if, UUID_PARAMS(uuid)); 455 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 456} 457 458void btgatts_connection_cb(int conn_id, int server_if, int connected, bt_bdaddr_t *bda) 459{ 460 CHECK_CALLBACK_ENV 461 462 char c_address[32]; 463 sprintf(c_address, "%02X:%02X:%02X:%02X:%02X:%02X", 464 bda->address[0], bda->address[1], bda->address[2], 465 bda->address[3], bda->address[4], bda->address[5]); 466 467 jstring address = sCallbackEnv->NewStringUTF(c_address); 468 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientConnected, 469 address, connected, conn_id, server_if); 470 sCallbackEnv->DeleteLocalRef(address); 471 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 472} 473 474void btgatts_service_added_cb(int status, int server_if, 475 btgatt_srvc_id_t *srvc_id, int srvc_handle) 476{ 477 CHECK_CALLBACK_ENV 478 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceAdded, status, 479 server_if, SRVC_ID_PARAMS(srvc_id), 480 srvc_handle); 481 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 482} 483 484void btgatts_included_service_added_cb(int status, int server_if, 485 int srvc_handle, 486 int incl_srvc_handle) 487{ 488 CHECK_CALLBACK_ENV 489 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onIncludedServiceAdded, 490 status, server_if, srvc_handle, incl_srvc_handle); 491 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 492} 493 494void btgatts_characteristic_added_cb(int status, int server_if, bt_uuid_t *char_id, 495 int srvc_handle, int char_handle) 496{ 497 CHECK_CALLBACK_ENV 498 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onCharacteristicAdded, 499 status, server_if, UUID_PARAMS(char_id), 500 srvc_handle, char_handle); 501 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 502} 503 504void btgatts_descriptor_added_cb(int status, int server_if, 505 bt_uuid_t *descr_id, int srvc_handle, 506 int descr_handle) 507{ 508 CHECK_CALLBACK_ENV 509 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onDescriptorAdded, 510 status, server_if, UUID_PARAMS(descr_id), 511 srvc_handle, descr_handle); 512 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 513} 514 515void btgatts_service_started_cb(int status, int server_if, int srvc_handle) 516{ 517 CHECK_CALLBACK_ENV 518 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceStarted, status, 519 server_if, srvc_handle); 520 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 521} 522 523void btgatts_service_stopped_cb(int status, int server_if, int srvc_handle) 524{ 525 CHECK_CALLBACK_ENV 526 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceStopped, status, 527 server_if, srvc_handle); 528 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 529} 530 531void btgatts_service_deleted_cb(int status, int server_if, int srvc_handle) 532{ 533 CHECK_CALLBACK_ENV 534 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceDeleted, status, 535 server_if, srvc_handle); 536 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 537} 538 539void btgatts_request_read_cb(int conn_id, int trans_id, bt_bdaddr_t *bda, 540 int attr_handle, int offset, bool is_long) 541{ 542 CHECK_CALLBACK_ENV 543 544 char c_address[32]; 545 sprintf(c_address, "%02X:%02X:%02X:%02X:%02X:%02X", 546 bda->address[0], bda->address[1], bda->address[2], 547 bda->address[3], bda->address[4], bda->address[5]); 548 549 jstring address = sCallbackEnv->NewStringUTF(c_address); 550 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAttributeRead, 551 address, conn_id, trans_id, attr_handle, 552 offset, is_long); 553 sCallbackEnv->DeleteLocalRef(address); 554 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 555} 556 557void btgatts_request_write_cb(int conn_id, int trans_id, 558 bt_bdaddr_t *bda, int attr_handle, 559 int offset, int length, 560 bool need_rsp, bool is_prep, uint8_t* value) 561{ 562 CHECK_CALLBACK_ENV 563 564 char c_address[32]; 565 sprintf(c_address, "%02X:%02X:%02X:%02X:%02X:%02X", 566 bda->address[0], bda->address[1], bda->address[2], 567 bda->address[3], bda->address[4], bda->address[5]); 568 569 jstring address = sCallbackEnv->NewStringUTF(c_address); 570 571 jbyteArray val = sCallbackEnv->NewByteArray(length); 572 if (val) sCallbackEnv->SetByteArrayRegion(val, 0, length, (jbyte*)value); 573 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAttributeWrite, 574 address, conn_id, trans_id, attr_handle, 575 offset, length, need_rsp, is_prep, val); 576 sCallbackEnv->DeleteLocalRef(address); 577 sCallbackEnv->DeleteLocalRef(val); 578 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 579} 580 581void btgatts_request_exec_write_cb(int conn_id, int trans_id, 582 bt_bdaddr_t *bda, int exec_write) 583{ 584 CHECK_CALLBACK_ENV 585 586 char c_address[32]; 587 sprintf(c_address, "%02X:%02X:%02X:%02X:%02X:%02X", 588 bda->address[0], bda->address[1], bda->address[2], 589 bda->address[3], bda->address[4], bda->address[5]); 590 591 jstring address = sCallbackEnv->NewStringUTF(c_address); 592 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onExecuteWrite, 593 address, conn_id, trans_id, exec_write); 594 sCallbackEnv->DeleteLocalRef(address); 595 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 596} 597 598void btgatts_response_confirmation_cb(int status, int handle) 599{ 600 CHECK_CALLBACK_ENV 601 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onResponseSendCompleted, 602 status, handle); 603 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 604} 605 606static const btgatt_server_callbacks_t sGattServerCallbacks = { 607 btgatts_register_app_cb, 608 btgatts_connection_cb, 609 btgatts_service_added_cb, 610 btgatts_included_service_added_cb, 611 btgatts_characteristic_added_cb, 612 btgatts_descriptor_added_cb, 613 btgatts_service_started_cb, 614 btgatts_service_stopped_cb, 615 btgatts_service_deleted_cb, 616 btgatts_request_read_cb, 617 btgatts_request_write_cb, 618 btgatts_request_exec_write_cb, 619 btgatts_response_confirmation_cb 620}; 621 622/** 623 * GATT callbacks 624 */ 625 626static const btgatt_callbacks_t sGattCallbacks = { 627 sizeof(btgatt_callbacks_t), 628 &sGattClientCallbacks, 629 &sGattServerCallbacks 630}; 631 632/** 633 * Native function definitions 634 */ 635 636static void classInitNative(JNIEnv* env, jclass clazz) { 637 638 // Client callbacks 639 640 method_onClientRegistered = env->GetMethodID(clazz, "onClientRegistered", "(IIJJ)V"); 641 method_onScanResult = env->GetMethodID(clazz, "onScanResult", "(Ljava/lang/String;I[B)V"); 642 method_onConnected = env->GetMethodID(clazz, "onConnected", "(IIILjava/lang/String;)V"); 643 method_onDisconnected = env->GetMethodID(clazz, "onDisconnected", "(IIILjava/lang/String;)V"); 644 method_onReadCharacteristic = env->GetMethodID(clazz, "onReadCharacteristic", "(IIIIJJIJJI[B)V"); 645 method_onWriteCharacteristic = env->GetMethodID(clazz, "onWriteCharacteristic", "(IIIIJJIJJ)V"); 646 method_onExecuteCompleted = env->GetMethodID(clazz, "onExecuteCompleted", "(II)V"); 647 method_onSearchCompleted = env->GetMethodID(clazz, "onSearchCompleted", "(II)V"); 648 method_onSearchResult = env->GetMethodID(clazz, "onSearchResult", "(IIIJJ)V"); 649 method_onReadDescriptor = env->GetMethodID(clazz, "onReadDescriptor", "(IIIIJJIJJIJJI[B)V"); 650 method_onWriteDescriptor = env->GetMethodID(clazz, "onWriteDescriptor", "(IIIIJJIJJIJJ)V"); 651 method_onNotify = env->GetMethodID(clazz, "onNotify", "(ILjava/lang/String;IIJJIJJZ[B)V"); 652 method_onGetCharacteristic = env->GetMethodID(clazz, "onGetCharacteristic", "(IIIIJJIJJI)V"); 653 method_onGetDescriptor = env->GetMethodID(clazz, "onGetDescriptor", "(IIIIJJIJJIJJ)V"); 654 method_onGetIncludedService = env->GetMethodID(clazz, "onGetIncludedService", "(IIIIJJIIJJ)V"); 655 method_onRegisterForNotifications = env->GetMethodID(clazz, "onRegisterForNotifications", "(IIIIIJJIJJ)V"); 656 method_onReadRemoteRssi = env->GetMethodID(clazz, "onReadRemoteRssi", "(ILjava/lang/String;II)V"); 657 658 // Server callbacks 659 660 method_onServerRegistered = env->GetMethodID(clazz, "onServerRegistered", "(IIJJ)V"); 661 method_onClientConnected = env->GetMethodID(clazz, "onClientConnected", "(Ljava/lang/String;ZII)V"); 662 method_onServiceAdded = env->GetMethodID(clazz, "onServiceAdded", "(IIIIJJI)V"); 663 method_onIncludedServiceAdded = env->GetMethodID(clazz, "onIncludedServiceAdded", "(IIII)V"); 664 method_onCharacteristicAdded = env->GetMethodID(clazz, "onCharacteristicAdded", "(IIJJII)V"); 665 method_onDescriptorAdded = env->GetMethodID(clazz, "onDescriptorAdded", "(IIJJII)V"); 666 method_onServiceStarted = env->GetMethodID(clazz, "onServiceStarted", "(III)V"); 667 method_onServiceStopped = env->GetMethodID(clazz, "onServiceStopped", "(III)V"); 668 method_onServiceDeleted = env->GetMethodID(clazz, "onServiceDeleted", "(III)V"); 669 method_onResponseSendCompleted = env->GetMethodID(clazz, "onResponseSendCompleted", "(II)V"); 670 method_onAttributeRead= env->GetMethodID(clazz, "onAttributeRead", "(Ljava/lang/String;IIIIZ)V"); 671 method_onAttributeWrite= env->GetMethodID(clazz, "onAttributeWrite", "(Ljava/lang/String;IIIIIZZ[B)V"); 672 method_onExecuteWrite= env->GetMethodID(clazz, "onExecuteWrite", "(Ljava/lang/String;III)V"); 673 674 info("classInitNative: Success!"); 675} 676 677static const bt_interface_t* btIf; 678 679static void initializeNative(JNIEnv *env, jobject object) { 680 if(btIf) 681 return; 682 683 if ( (btIf = getBluetoothInterface()) == NULL) { 684 error("Bluetooth module is not loaded"); 685 return; 686 } 687 688 if (sGattIf != NULL) { 689 ALOGW("Cleaning up Bluetooth GATT Interface before initializing..."); 690 sGattIf->cleanup(); 691 sGattIf = NULL; 692 } 693 694 if (mCallbacksObj != NULL) { 695 ALOGW("Cleaning up Bluetooth GATT callback object"); 696 env->DeleteGlobalRef(mCallbacksObj); 697 mCallbacksObj = NULL; 698 } 699 700 if ( (sGattIf = (btgatt_interface_t *) 701 btIf->get_profile_interface(BT_PROFILE_GATT_ID)) == NULL) { 702 error("Failed to get Bluetooth GATT Interface"); 703 return; 704 } 705 706 bt_status_t status; 707 if ( (status = sGattIf->init(&sGattCallbacks)) != BT_STATUS_SUCCESS) { 708 error("Failed to initialize Bluetooth GATT, status: %d", status); 709 sGattIf = NULL; 710 return; 711 } 712 713 mCallbacksObj = env->NewGlobalRef(object); 714} 715 716static void cleanupNative(JNIEnv *env, jobject object) { 717 bt_status_t status; 718 if (!btIf) return; 719 720 if (sGattIf != NULL) { 721 sGattIf->cleanup(); 722 sGattIf = NULL; 723 } 724 725 if (mCallbacksObj != NULL) { 726 env->DeleteGlobalRef(mCallbacksObj); 727 mCallbacksObj = NULL; 728 } 729 btIf = NULL; 730} 731 732/** 733 * Native Client functions 734 */ 735 736static int gattClientGetDeviceTypeNative(JNIEnv* env, jobject object, jstring address) 737{ 738 if (!sGattIf) return 0; 739 bt_bdaddr_t bda; 740 jstr2bdaddr(env, &bda, address); 741 return sGattIf->client->get_device_type(&bda); 742} 743 744static void gattClientRegisterAppNative(JNIEnv* env, jobject object, 745 jlong app_uuid_lsb, jlong app_uuid_msb ) 746{ 747 bt_uuid_t uuid; 748 749 if (!sGattIf) return; 750 set_uuid(uuid.uu, app_uuid_msb, app_uuid_lsb); 751 sGattIf->client->register_client(&uuid); 752} 753 754static void gattClientUnregisterAppNative(JNIEnv* env, jobject object, jint clientIf) 755{ 756 if (!sGattIf) return; 757 sGattIf->client->unregister_client(clientIf); 758} 759 760static void gattClientScanNative(JNIEnv* env, jobject object, jint clientIf, jboolean start) 761{ 762 if (!sGattIf) return; 763 sGattIf->client->scan(clientIf, start); 764} 765 766static void gattClientConnectNative(JNIEnv* env, jobject object, jint clientif, 767 jstring address, jboolean isDirect) 768{ 769 if (!sGattIf) return; 770 771 bt_bdaddr_t bda; 772 jstr2bdaddr(env, &bda, address); 773 sGattIf->client->connect(clientif, &bda, isDirect); 774} 775 776static void gattClientDisconnectNative(JNIEnv* env, jobject object, jint clientIf, 777 jstring address, jint conn_id) 778{ 779 if (!sGattIf) return; 780 bt_bdaddr_t bda; 781 jstr2bdaddr(env, &bda, address); 782 sGattIf->client->disconnect(clientIf, &bda, conn_id); 783} 784 785static void gattClientRefreshNative(JNIEnv* env, jobject object, jint clientIf, 786 jstring address) 787{ 788 if (!sGattIf) return; 789 790 bt_bdaddr_t bda; 791 jstr2bdaddr(env, &bda, address); 792 sGattIf->client->refresh(clientIf, &bda); 793} 794 795static void gattClientSearchServiceNative(JNIEnv* env, jobject object, jint conn_id, 796 jboolean search_all, jlong service_uuid_lsb, jlong service_uuid_msb) 797{ 798 if (!sGattIf) return; 799 800 bt_uuid_t uuid; 801 set_uuid(uuid.uu, service_uuid_msb, service_uuid_lsb); 802 sGattIf->client->search_service(conn_id, search_all ? 0 : &uuid); 803} 804 805static void gattClientGetCharacteristicNative(JNIEnv* env, jobject object, 806 jint conn_id, 807 jint service_type, jint service_id_inst_id, 808 jlong service_id_uuid_lsb, jlong service_id_uuid_msb, 809 jint char_id_inst_id, 810 jlong char_id_uuid_lsb, jlong char_id_uuid_msb) 811{ 812 if (!sGattIf) return; 813 814 btgatt_srvc_id_t srvc_id; 815 srvc_id.id.inst_id = (uint8_t) service_id_inst_id; 816 srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0); 817 818 set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb); 819 820 btgatt_gatt_id_t char_id; 821 char_id.inst_id = (uint8_t) char_id_inst_id; 822 set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb); 823 824 if (char_id_uuid_lsb == 0) 825 { 826 sGattIf->client->get_characteristic(conn_id, &srvc_id, 0); 827 } else { 828 sGattIf->client->get_characteristic(conn_id, &srvc_id, &char_id); 829 } 830} 831 832static void gattClientGetDescriptorNative(JNIEnv* env, jobject object, 833 jint conn_id, 834 jint service_type, jint service_id_inst_id, 835 jlong service_id_uuid_lsb, jlong service_id_uuid_msb, 836 jint char_id_inst_id, 837 jlong char_id_uuid_lsb, jlong char_id_uuid_msb, 838 jint descr_id_inst_id, 839 jlong descr_id_uuid_lsb, jlong descr_id_uuid_msb) 840{ 841 if (!sGattIf) return; 842 843 btgatt_srvc_id_t srvc_id; 844 srvc_id.id.inst_id = (uint8_t) service_id_inst_id; 845 srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0); 846 set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb); 847 848 btgatt_gatt_id_t char_id; 849 char_id.inst_id = (uint8_t) char_id_inst_id; 850 set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb); 851 852 btgatt_gatt_id_t descr_id; 853 descr_id.inst_id = (uint8_t) descr_id_inst_id; 854 set_uuid(descr_id.uuid.uu, descr_id_uuid_msb, descr_id_uuid_lsb); 855 856 if (descr_id_uuid_lsb == 0) 857 { 858 sGattIf->client->get_descriptor(conn_id, &srvc_id, &char_id, 0); 859 } else { 860 sGattIf->client->get_descriptor(conn_id, &srvc_id, &char_id, &descr_id); 861 } 862} 863 864static void gattClientGetIncludedServiceNative(JNIEnv* env, jobject object, 865 jint conn_id, jint service_type, jint service_id_inst_id, 866 jlong service_id_uuid_lsb, jlong service_id_uuid_msb, 867 jint incl_service_id_inst_id, jint incl_service_type, 868 jlong incl_service_id_uuid_lsb, jlong incl_service_id_uuid_msb) 869{ 870 if (!sGattIf) return; 871 872 btgatt_srvc_id_t srvc_id; 873 srvc_id.id.inst_id = (uint8_t) service_id_inst_id; 874 srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0); 875 set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb); 876 877 btgatt_srvc_id_t incl_srvc_id; 878 incl_srvc_id.id.inst_id = (uint8_t) incl_service_id_inst_id; 879 incl_srvc_id.is_primary = (incl_service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0); 880 set_uuid(incl_srvc_id.id.uuid.uu, incl_service_id_uuid_msb, incl_service_id_uuid_lsb); 881 882 if (incl_service_id_uuid_lsb == 0) 883 { 884 sGattIf->client->get_included_service(conn_id, &srvc_id, 0); 885 } else { 886 sGattIf->client->get_included_service(conn_id, &srvc_id, &incl_srvc_id); 887 } 888} 889 890static void gattClientReadCharacteristicNative(JNIEnv* env, jobject object, 891 jint conn_id, jint service_type, jint service_id_inst_id, 892 jlong service_id_uuid_lsb, jlong service_id_uuid_msb, 893 jint char_id_inst_id, 894 jlong char_id_uuid_lsb, jlong char_id_uuid_msb, 895 jint authReq) 896{ 897 if (!sGattIf) return; 898 899 btgatt_srvc_id_t srvc_id; 900 srvc_id.id.inst_id = (uint8_t) service_id_inst_id; 901 srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0); 902 set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb); 903 904 btgatt_gatt_id_t char_id; 905 char_id.inst_id = (uint8_t) char_id_inst_id; 906 set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb); 907 908 sGattIf->client->read_characteristic(conn_id, &srvc_id, &char_id, authReq); 909} 910 911static void gattClientReadDescriptorNative(JNIEnv* env, jobject object, 912 jint conn_id, jint service_type, jint service_id_inst_id, 913 jlong service_id_uuid_lsb, jlong service_id_uuid_msb, 914 jint char_id_inst_id, 915 jlong char_id_uuid_lsb, jlong char_id_uuid_msb, 916 jint descr_id_inst_id, 917 jlong descr_id_uuid_lsb, jlong descr_id_uuid_msb, 918 jint authReq) 919{ 920 if (!sGattIf) return; 921 922 btgatt_srvc_id_t srvc_id; 923 srvc_id.id.inst_id = (uint8_t) service_id_inst_id; 924 srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0); 925 set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb); 926 927 btgatt_gatt_id_t char_id; 928 char_id.inst_id = (uint8_t) char_id_inst_id; 929 set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb); 930 931 btgatt_gatt_id_t descr_id; 932 descr_id.inst_id = (uint8_t) descr_id_inst_id; 933 set_uuid(descr_id.uuid.uu, descr_id_uuid_msb, descr_id_uuid_lsb); 934 935 sGattIf->client->read_descriptor(conn_id, &srvc_id, &char_id, &descr_id, authReq); 936} 937 938static void gattClientWriteCharacteristicNative(JNIEnv* env, jobject object, 939 jint conn_id, jint service_type, jint service_id_inst_id, 940 jlong service_id_uuid_lsb, jlong service_id_uuid_msb, 941 jint char_id_inst_id, 942 jlong char_id_uuid_lsb, jlong char_id_uuid_msb, 943 jint write_type, jint auth_req, jbyteArray value) 944{ 945 if (!sGattIf) return; 946 947 btgatt_srvc_id_t srvc_id; 948 srvc_id.id.inst_id = (uint8_t) service_id_inst_id; 949 srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0); 950 set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb); 951 952 btgatt_gatt_id_t char_id; 953 char_id.inst_id = (uint8_t) char_id_inst_id; 954 set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb); 955 956 uint16_t len = (uint16_t) env->GetArrayLength(value); 957 jbyte *p_value = env->GetByteArrayElements(value, NULL); 958 if (p_value == NULL) return; 959 960 sGattIf->client->write_characteristic(conn_id, &srvc_id, &char_id, 961 write_type, len, auth_req, (char*)p_value); 962 env->ReleaseByteArrayElements(value, p_value, 0); 963} 964 965static void gattClientExecuteWriteNative(JNIEnv* env, jobject object, 966 jint conn_id, jboolean execute) 967{ 968 if (!sGattIf) return; 969 sGattIf->client->execute_write(conn_id, execute ? 1 : 0); 970} 971 972static void gattClientWriteDescriptorNative(JNIEnv* env, jobject object, 973 jint conn_id, jint service_type, jint service_id_inst_id, 974 jlong service_id_uuid_lsb, jlong service_id_uuid_msb, 975 jint char_id_inst_id, 976 jlong char_id_uuid_lsb, jlong char_id_uuid_msb, 977 jint descr_id_inst_id, 978 jlong descr_id_uuid_lsb, jlong descr_id_uuid_msb, 979 jint write_type, jint auth_req, jbyteArray value) 980{ 981 if (!sGattIf) return; 982 983 if (value == NULL) { 984 warn("gattClientWriteDescriptorNative() ignoring NULL array"); 985 return; 986 } 987 988 btgatt_srvc_id_t srvc_id; 989 srvc_id.id.inst_id = (uint8_t) service_id_inst_id; 990 srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0); 991 set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb); 992 993 btgatt_gatt_id_t char_id; 994 char_id.inst_id = (uint8_t) char_id_inst_id; 995 set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb); 996 997 btgatt_gatt_id_t descr_id; 998 descr_id.inst_id = (uint8_t) descr_id_inst_id; 999 set_uuid(descr_id.uuid.uu, descr_id_uuid_msb, descr_id_uuid_lsb); 1000 1001 uint16_t len = (uint16_t) env->GetArrayLength(value); 1002 jbyte *p_value = env->GetByteArrayElements(value, NULL); 1003 if (p_value == NULL) return; 1004 1005 sGattIf->client->write_descriptor(conn_id, &srvc_id, &char_id, &descr_id, 1006 write_type, len, auth_req, (char*)p_value); 1007 env->ReleaseByteArrayElements(value, p_value, 0); 1008} 1009 1010static void gattClientRegisterForNotificationsNative(JNIEnv* env, jobject object, 1011 jint clientIf, jstring address, 1012 jint service_type, jint service_id_inst_id, 1013 jlong service_id_uuid_lsb, jlong service_id_uuid_msb, 1014 jint char_id_inst_id, 1015 jlong char_id_uuid_lsb, jlong char_id_uuid_msb, 1016 jboolean enable) 1017{ 1018 if (!sGattIf) return; 1019 1020 btgatt_srvc_id_t srvc_id; 1021 srvc_id.id.inst_id = (uint8_t) service_id_inst_id; 1022 srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0); 1023 set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb); 1024 1025 btgatt_gatt_id_t char_id; 1026 char_id.inst_id = (uint8_t) char_id_inst_id; 1027 set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb); 1028 1029 bt_bdaddr_t bd_addr; 1030 const char *c_address = env->GetStringUTFChars(address, NULL); 1031 bd_addr_str_to_addr(c_address, bd_addr.address); 1032 1033 if (enable) 1034 sGattIf->client->register_for_notification(clientIf, &bd_addr, &srvc_id, &char_id); 1035 else 1036 sGattIf->client->deregister_for_notification(clientIf, &bd_addr, &srvc_id, &char_id); 1037} 1038 1039static void gattClientReadRemoteRssiNative(JNIEnv* env, jobject object, jint clientif, 1040 jstring address) 1041{ 1042 if (!sGattIf) return; 1043 1044 bt_bdaddr_t bda; 1045 jstr2bdaddr(env, &bda, address); 1046 1047 sGattIf->client->read_remote_rssi(clientif, &bda); 1048} 1049 1050static void gattAdvertiseNative(JNIEnv *env, jobject object, 1051 jint client_if, jboolean start) 1052{ 1053 if (!sGattIf) return; 1054 sGattIf->client->listen(client_if, start); 1055} 1056 1057static void gattSetAdvDataNative(JNIEnv *env, jobject object, jint client_if, jboolean setScanRsp, 1058 jboolean inclName, jboolean inclTxPower, jint minInterval, jint maxInterval, 1059 jint appearance, jbyteArray manufacturerData, jbyteArray serviceData, 1060 jbyteArray serviceUuid) 1061{ 1062 if (!sGattIf) return; 1063 jbyte* arr_data = env->GetByteArrayElements(manufacturerData, NULL); 1064 uint16_t arr_len = (uint16_t) env->GetArrayLength(manufacturerData); 1065 1066 jbyte* service_data = env->GetByteArrayElements(serviceData, NULL); 1067 uint16_t service_data_len = (uint16_t) env->GetArrayLength(serviceData); 1068 1069 jbyte* service_uuid = env->GetByteArrayElements(serviceUuid, NULL); 1070 uint16_t service_uuid_len = (uint16_t) env->GetArrayLength(serviceUuid); 1071 1072 sGattIf->client->set_adv_data(client_if, setScanRsp, inclName, inclTxPower, 1073 minInterval, maxInterval, appearance, arr_len, (char*)arr_data, 1074 service_data_len, (char*)service_data, service_uuid_len, 1075 (char*)service_uuid); 1076 1077 env->ReleaseByteArrayElements(manufacturerData, arr_data, JNI_ABORT); 1078 env->ReleaseByteArrayElements(serviceData, service_data, JNI_ABORT); 1079 env->ReleaseByteArrayElements(serviceUuid, service_uuid, JNI_ABORT); 1080} 1081 1082 1083/** 1084 * Native server functions 1085 */ 1086static void gattServerRegisterAppNative(JNIEnv* env, jobject object, 1087 jlong app_uuid_lsb, jlong app_uuid_msb ) 1088{ 1089 bt_uuid_t uuid; 1090 if (!sGattIf) return; 1091 set_uuid(uuid.uu, app_uuid_msb, app_uuid_lsb); 1092 sGattIf->server->register_server(&uuid); 1093} 1094 1095static void gattServerUnregisterAppNative(JNIEnv* env, jobject object, jint serverIf) 1096{ 1097 if (!sGattIf) return; 1098 sGattIf->server->unregister_server(serverIf); 1099} 1100 1101static void gattServerConnectNative(JNIEnv *env, jobject object, 1102 jint server_if, jstring address, jboolean is_direct) 1103{ 1104 if (!sGattIf) return; 1105 1106 bt_bdaddr_t bd_addr; 1107 const char *c_address = env->GetStringUTFChars(address, NULL); 1108 bd_addr_str_to_addr(c_address, bd_addr.address); 1109 1110 sGattIf->server->connect(server_if, &bd_addr, is_direct); 1111} 1112 1113static void gattServerDisconnectNative(JNIEnv* env, jobject object, jint serverIf, 1114 jstring address, jint conn_id) 1115{ 1116 if (!sGattIf) return; 1117 bt_bdaddr_t bda; 1118 jstr2bdaddr(env, &bda, address); 1119 sGattIf->server->disconnect(serverIf, &bda, conn_id); 1120} 1121 1122static void gattServerAddServiceNative (JNIEnv *env, jobject object, 1123 jint server_if, jint service_type, jint service_id_inst_id, 1124 jlong service_id_uuid_lsb, jlong service_id_uuid_msb, 1125 jint num_handles) 1126{ 1127 if (!sGattIf) return; 1128 1129 btgatt_srvc_id_t srvc_id; 1130 srvc_id.id.inst_id = (uint8_t) service_id_inst_id; 1131 srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0); 1132 set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb); 1133 1134 sGattIf->server->add_service(server_if, &srvc_id, num_handles); 1135} 1136 1137static void gattServerAddIncludedServiceNative (JNIEnv *env, jobject object, 1138 jint server_if, jint svc_handle, jint included_svc_handle) 1139{ 1140 if (!sGattIf) return; 1141 sGattIf->server->add_included_service(server_if, svc_handle, 1142 included_svc_handle); 1143} 1144 1145static void gattServerAddCharacteristicNative (JNIEnv *env, jobject object, 1146 jint server_if, jint svc_handle, 1147 jlong char_uuid_lsb, jlong char_uuid_msb, 1148 jint properties, jint permissions) 1149{ 1150 if (!sGattIf) return; 1151 1152 bt_uuid_t uuid; 1153 set_uuid(uuid.uu, char_uuid_msb, char_uuid_lsb); 1154 1155 sGattIf->server->add_characteristic(server_if, svc_handle, 1156 &uuid, properties, permissions); 1157} 1158 1159static void gattServerAddDescriptorNative (JNIEnv *env, jobject object, 1160 jint server_if, jint svc_handle, 1161 jlong desc_uuid_lsb, jlong desc_uuid_msb, 1162 jint permissions) 1163{ 1164 if (!sGattIf) return; 1165 1166 bt_uuid_t uuid; 1167 set_uuid(uuid.uu, desc_uuid_msb, desc_uuid_lsb); 1168 1169 sGattIf->server->add_descriptor(server_if, svc_handle, &uuid, permissions); 1170} 1171 1172static void gattServerStartServiceNative (JNIEnv *env, jobject object, 1173 jint server_if, jint svc_handle, jint transport ) 1174{ 1175 if (!sGattIf) return; 1176 sGattIf->server->start_service(server_if, svc_handle, transport); 1177} 1178 1179static void gattServerStopServiceNative (JNIEnv *env, jobject object, 1180 jint server_if, jint svc_handle) 1181{ 1182 if (!sGattIf) return; 1183 sGattIf->server->stop_service(server_if, svc_handle); 1184} 1185 1186static void gattServerDeleteServiceNative (JNIEnv *env, jobject object, 1187 jint server_if, jint svc_handle) 1188{ 1189 if (!sGattIf) return; 1190 sGattIf->server->delete_service(server_if, svc_handle); 1191} 1192 1193static void gattServerSendIndicationNative (JNIEnv *env, jobject object, 1194 jint server_if, jint attr_handle, jint conn_id, jbyteArray val) 1195{ 1196 if (!sGattIf) return; 1197 1198 jbyte* array = env->GetByteArrayElements(val, 0); 1199 int val_len = env->GetArrayLength(val); 1200 1201 sGattIf->server->send_indication(server_if, attr_handle, conn_id, val_len, 1202 /*confirm*/ 1, (char*)array); 1203 env->ReleaseByteArrayElements(val, array, JNI_ABORT); 1204} 1205 1206static void gattServerSendNotificationNative (JNIEnv *env, jobject object, 1207 jint server_if, jint attr_handle, jint conn_id, jbyteArray val) 1208{ 1209 if (!sGattIf) return; 1210 1211 jbyte* array = env->GetByteArrayElements(val, 0); 1212 int val_len = env->GetArrayLength(val); 1213 1214 sGattIf->server->send_indication(server_if, attr_handle, conn_id, val_len, 1215 /*confirm*/ 0, (char*)array); 1216 env->ReleaseByteArrayElements(val, array, JNI_ABORT); 1217} 1218 1219static void gattServerSendResponseNative (JNIEnv *env, jobject object, 1220 jint server_if, jint conn_id, jint trans_id, jint status, 1221 jint handle, jint offset, jbyteArray val, jint auth_req) 1222{ 1223 if (!sGattIf) return; 1224 1225 btgatt_response_t response; 1226 1227 response.attr_value.handle = handle; 1228 response.attr_value.auth_req = auth_req; 1229 response.attr_value.offset = offset; 1230 response.attr_value.len = 0; 1231 1232 if (val != NULL) 1233 { 1234 response.attr_value.len = (uint16_t) env->GetArrayLength(val); 1235 jbyte* array = env->GetByteArrayElements(val, 0); 1236 1237 for (int i = 0; i != response.attr_value.len; ++i) 1238 response.attr_value.value[i] = (uint8_t) array[i]; 1239 env->ReleaseByteArrayElements(val, array, JNI_ABORT); 1240 } 1241 1242 sGattIf->server->send_response(conn_id, trans_id, status, &response); 1243} 1244 1245static void gattTestNative(JNIEnv *env, jobject object, jint command, 1246 jlong uuid1_lsb, jlong uuid1_msb, jstring bda1, 1247 jint p1, jint p2, jint p3, jint p4, jint p5 ) 1248{ 1249 if (!sGattIf) return; 1250 1251 bt_bdaddr_t bt_bda1; 1252 jstr2bdaddr(env, &bt_bda1, bda1); 1253 1254 bt_uuid_t uuid1; 1255 set_uuid(uuid1.uu, uuid1_msb, uuid1_lsb); 1256 1257 btgatt_test_params_t params; 1258 params.bda1 = &bt_bda1; 1259 params.uuid1 = &uuid1; 1260 params.u1 = p1; 1261 params.u2 = p2; 1262 params.u3 = p3; 1263 params.u4 = p4; 1264 params.u5 = p5; 1265 sGattIf->client->test_command(command, ¶ms); 1266} 1267 1268/** 1269 * JNI function definitinos 1270 */ 1271 1272static JNINativeMethod sMethods[] = { 1273 {"classInitNative", "()V", (void *) classInitNative}, 1274 {"initializeNative", "()V", (void *) initializeNative}, 1275 {"cleanupNative", "()V", (void *) cleanupNative}, 1276 1277 {"gattClientGetDeviceTypeNative", "(Ljava/lang/String;)I", (void *) gattClientGetDeviceTypeNative}, 1278 {"gattClientRegisterAppNative", "(JJ)V", (void *) gattClientRegisterAppNative}, 1279 {"gattClientUnregisterAppNative", "(I)V", (void *) gattClientUnregisterAppNative}, 1280 {"gattClientScanNative", "(IZ)V", (void *) gattClientScanNative}, 1281 {"gattClientConnectNative", "(ILjava/lang/String;Z)V", (void *) gattClientConnectNative}, 1282 {"gattClientDisconnectNative", "(ILjava/lang/String;I)V", (void *) gattClientDisconnectNative}, 1283 {"gattClientRefreshNative", "(ILjava/lang/String;)V", (void *) gattClientRefreshNative}, 1284 {"gattClientSearchServiceNative", "(IZJJ)V", (void *) gattClientSearchServiceNative}, 1285 {"gattClientGetCharacteristicNative", "(IIIJJIJJ)V", (void *) gattClientGetCharacteristicNative}, 1286 {"gattClientGetDescriptorNative", "(IIIJJIJJIJJ)V", (void *) gattClientGetDescriptorNative}, 1287 {"gattClientGetIncludedServiceNative", "(IIIJJIIJJ)V", (void *) gattClientGetIncludedServiceNative}, 1288 {"gattClientReadCharacteristicNative", "(IIIJJIJJI)V", (void *) gattClientReadCharacteristicNative}, 1289 {"gattClientReadDescriptorNative", "(IIIJJIJJIJJI)V", (void *) gattClientReadDescriptorNative}, 1290 {"gattClientWriteCharacteristicNative", "(IIIJJIJJII[B)V", (void *) gattClientWriteCharacteristicNative}, 1291 {"gattClientWriteDescriptorNative", "(IIIJJIJJIJJII[B)V", (void *) gattClientWriteDescriptorNative}, 1292 {"gattClientExecuteWriteNative", "(IZ)V", (void *) gattClientExecuteWriteNative}, 1293 {"gattClientRegisterForNotificationsNative", "(ILjava/lang/String;IIJJIJJZ)V", (void *) gattClientRegisterForNotificationsNative}, 1294 {"gattClientReadRemoteRssiNative", "(ILjava/lang/String;)V", (void *) gattClientReadRemoteRssiNative}, 1295 {"gattAdvertiseNative", "(IZ)V", (void *) gattAdvertiseNative}, 1296 1297 {"gattServerRegisterAppNative", "(JJ)V", (void *) gattServerRegisterAppNative}, 1298 {"gattServerUnregisterAppNative", "(I)V", (void *) gattServerUnregisterAppNative}, 1299 {"gattServerConnectNative", "(ILjava/lang/String;Z)V", (void *) gattServerConnectNative}, 1300 {"gattServerDisconnectNative", "(ILjava/lang/String;I)V", (void *) gattServerDisconnectNative}, 1301 {"gattServerAddServiceNative", "(IIIJJI)V", (void *) gattServerAddServiceNative}, 1302 {"gattServerAddIncludedServiceNative", "(III)V", (void *) gattServerAddIncludedServiceNative}, 1303 {"gattServerAddCharacteristicNative", "(IIJJII)V", (void *) gattServerAddCharacteristicNative}, 1304 {"gattServerAddDescriptorNative", "(IIJJI)V", (void *) gattServerAddDescriptorNative}, 1305 {"gattServerStartServiceNative", "(III)V", (void *) gattServerStartServiceNative}, 1306 {"gattServerStopServiceNative", "(II)V", (void *) gattServerStopServiceNative}, 1307 {"gattServerDeleteServiceNative", "(II)V", (void *) gattServerDeleteServiceNative}, 1308 {"gattServerSendIndicationNative", "(III[B)V", (void *) gattServerSendIndicationNative}, 1309 {"gattServerSendNotificationNative", "(III[B)V", (void *) gattServerSendNotificationNative}, 1310 {"gattServerSendResponseNative", "(IIIIII[BI)V", (void *) gattServerSendResponseNative}, 1311 1312 {"gattSetAdvDataNative", "(IZZZIII[B[B[B)V", (void *) gattSetAdvDataNative}, 1313 {"gattTestNative", "(IJJLjava/lang/String;IIIII)V", (void *) gattTestNative}, 1314}; 1315 1316int register_com_android_bluetooth_gatt(JNIEnv* env) 1317{ 1318 return jniRegisterNativeMethods(env, "com/android/bluetooth/gatt/GattService", 1319 sMethods, NELEM(sMethods)); 1320} 1321 1322} 1323