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