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