1 /* 2 ** Copyright 2006, 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 #define LOG_TAG "BT HSHFP" 18 19 #include "android_bluetooth_common.h" 20 #include "android_runtime/AndroidRuntime.h" 21 #include "JNIHelp.h" 22 #include "jni.h" 23 #include "utils/Log.h" 24 #include "utils/misc.h" 25 26 #include <stdio.h> 27 #include <string.h> 28 #include <stdlib.h> 29 #include <errno.h> 30 #include <unistd.h> 31 #include <fcntl.h> 32 #include <sys/socket.h> 33 #include <sys/uio.h> 34 #include <sys/poll.h> 35 36 #ifdef HAVE_BLUETOOTH 37 #include <bluetooth/bluetooth.h> 38 #include <bluetooth/rfcomm.h> 39 #include <bluetooth/sco.h> 40 #endif 41 42 namespace android { 43 44 #ifdef HAVE_BLUETOOTH 45 static jfieldID field_mNativeData; 46 static jfieldID field_mAddress; 47 static jfieldID field_mRfcommChannel; 48 static jfieldID field_mTimeoutRemainingMs; 49 50 typedef struct { 51 jstring address; 52 const char *c_address; 53 int rfcomm_channel; 54 int last_read_err; 55 int rfcomm_sock; 56 int rfcomm_connected; // -1 in progress, 0 not connected, 1 connected 57 int rfcomm_sock_flags; 58 } native_data_t; 59 60 static inline native_data_t * get_native_data(JNIEnv *env, jobject object) { 61 return (native_data_t *)(env->GetIntField(object, field_mNativeData)); 62 } 63 64 static const char CRLF[] = "\xd\xa"; 65 static const int CRLF_LEN = 2; 66 67 static inline int write_error_check(int fd, const char* line, int len) { 68 int ret; 69 errno = 0; 70 ret = write(fd, line, len); 71 if (ret < 0) { 72 ALOGE("%s: write() failed: %s (%d)", __FUNCTION__, strerror(errno), 73 errno); 74 return -1; 75 } 76 if (ret != len) { 77 ALOGE("%s: write() only wrote %d of %d bytes", __FUNCTION__, ret, len); 78 return -1; 79 } 80 return 0; 81 } 82 83 static int send_line(int fd, const char* line) { 84 int nw; 85 int len = strlen(line); 86 int llen = len + CRLF_LEN * 2 + 1; 87 char *buffer = (char *)calloc(llen, sizeof(char)); 88 89 snprintf(buffer, llen, "%s%s%s", CRLF, line, CRLF); 90 91 if (write_error_check(fd, buffer, llen - 1)) { 92 free(buffer); 93 return -1; 94 } 95 free(buffer); 96 return 0; 97 } 98 99 static void mask_eighth_bit(char *line) 100 { 101 for (;;line++) { 102 if (0 == *line) return; 103 *line &= 0x7F; 104 } 105 } 106 107 static const char* get_line(int fd, char *buf, int len, int timeout_ms, 108 int *err) { 109 char *bufit=buf; 110 int fd_flags = fcntl(fd, F_GETFL, 0); 111 struct pollfd pfd; 112 113 again: 114 *bufit = 0; 115 pfd.fd = fd; 116 pfd.events = POLLIN; 117 *err = errno = 0; 118 int ret = TEMP_FAILURE_RETRY(poll(&pfd, 1, timeout_ms)); 119 if (ret < 0) { 120 ALOGE("poll() error\n"); 121 *err = errno; 122 return NULL; 123 } 124 if (ret == 0) { 125 return NULL; 126 } 127 128 if (pfd.revents & (POLLHUP | POLLERR | POLLNVAL)) { 129 ALOGW("RFCOMM poll() returned success (%d), " 130 "but with an unexpected revents bitmask: %#x\n", ret, pfd.revents); 131 errno = EIO; 132 *err = errno; 133 return NULL; 134 } 135 136 while ((int)(bufit - buf) < (len - 1)) 137 { 138 errno = 0; 139 int rc = TEMP_FAILURE_RETRY(read(fd, bufit, 1)); 140 141 if (!rc) 142 break; 143 144 if (rc < 0) { 145 if (errno == EBUSY) { 146 ALOGI("read() error %s (%d): repeating read()...", 147 strerror(errno), errno); 148 goto again; 149 } 150 *err = errno; 151 ALOGE("read() error %s (%d)", strerror(errno), errno); 152 return NULL; 153 } 154 155 156 if (*bufit=='\xd') { 157 break; 158 } 159 160 if (*bufit=='\xa') 161 bufit = buf; 162 else 163 bufit++; 164 } 165 166 *bufit = 0; 167 168 // According to ITU V.250 section 5.1, IA5 7 bit chars are used, 169 // the eighth bit or higher bits are ignored if they exists 170 // We mask out only eighth bit, no higher bit, since we do char 171 // string here, not wide char. 172 // We added this processing due to 2 real world problems. 173 // 1 BMW 2005 E46 which sends binary junk 174 // 2 Audi 2010 A3, dial command use 0xAD (soft-hyphen) as number 175 // formater, which was rejected by the AT handler 176 mask_eighth_bit(buf); 177 178 return buf; 179 } 180 #endif 181 182 static void classInitNative(JNIEnv* env, jclass clazz) { 183 ALOGV("%s", __FUNCTION__); 184 #ifdef HAVE_BLUETOOTH 185 field_mNativeData = get_field(env, clazz, "mNativeData", "I"); 186 field_mAddress = get_field(env, clazz, "mAddress", "Ljava/lang/String;"); 187 field_mTimeoutRemainingMs = get_field(env, clazz, "mTimeoutRemainingMs", "I"); 188 field_mRfcommChannel = get_field(env, clazz, "mRfcommChannel", "I"); 189 #endif 190 } 191 192 static void initializeNativeDataNative(JNIEnv* env, jobject object, 193 jint socketFd) { 194 ALOGV("%s", __FUNCTION__); 195 #ifdef HAVE_BLUETOOTH 196 native_data_t *nat = (native_data_t *)calloc(1, sizeof(native_data_t)); 197 if (NULL == nat) { 198 ALOGE("%s: out of memory!", __FUNCTION__); 199 return; 200 } 201 202 env->SetIntField(object, field_mNativeData, (jint)nat); 203 nat->address = 204 (jstring)env->NewGlobalRef(env->GetObjectField(object, 205 field_mAddress)); 206 nat->c_address = env->GetStringUTFChars(nat->address, NULL); 207 nat->rfcomm_channel = env->GetIntField(object, field_mRfcommChannel); 208 nat->rfcomm_sock = socketFd; 209 nat->rfcomm_connected = socketFd >= 0; 210 if (nat->rfcomm_connected) 211 ALOGI("%s: ALREADY CONNECTED!", __FUNCTION__); 212 #endif 213 } 214 215 static void cleanupNativeDataNative(JNIEnv* env, jobject object) { 216 ALOGV("%s", __FUNCTION__); 217 #ifdef HAVE_BLUETOOTH 218 native_data_t *nat = 219 (native_data_t *)env->GetIntField(object, field_mNativeData); 220 env->ReleaseStringUTFChars(nat->address, nat->c_address); 221 env->DeleteGlobalRef(nat->address); 222 if (nat) 223 free(nat); 224 #endif 225 } 226 227 static jboolean connectNative(JNIEnv *env, jobject obj) 228 { 229 ALOGV("%s", __FUNCTION__); 230 #ifdef HAVE_BLUETOOTH 231 int lm; 232 struct sockaddr_rc addr; 233 native_data_t *nat = get_native_data(env, obj); 234 235 nat->rfcomm_sock = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); 236 237 if (nat->rfcomm_sock < 0) { 238 ALOGE("%s: Could not create RFCOMM socket: %s\n", __FUNCTION__, 239 strerror(errno)); 240 return JNI_FALSE; 241 } 242 243 if (debug_no_encrypt()) { 244 lm = RFCOMM_LM_AUTH; 245 } else { 246 lm = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT; 247 } 248 249 if (lm && setsockopt(nat->rfcomm_sock, SOL_RFCOMM, RFCOMM_LM, &lm, 250 sizeof(lm)) < 0) { 251 ALOGE("%s: Can't set RFCOMM link mode", __FUNCTION__); 252 close(nat->rfcomm_sock); 253 return JNI_FALSE; 254 } 255 256 memset(&addr, 0, sizeof(struct sockaddr_rc)); 257 get_bdaddr(nat->c_address, &addr.rc_bdaddr); 258 addr.rc_channel = nat->rfcomm_channel; 259 addr.rc_family = AF_BLUETOOTH; 260 nat->rfcomm_connected = 0; 261 while (nat->rfcomm_connected == 0) { 262 if (connect(nat->rfcomm_sock, (struct sockaddr *)&addr, 263 sizeof(addr)) < 0) { 264 if (errno == EINTR) continue; 265 ALOGE("%s: connect() failed: %s\n", __FUNCTION__, strerror(errno)); 266 close(nat->rfcomm_sock); 267 nat->rfcomm_sock = -1; 268 return JNI_FALSE; 269 } else { 270 nat->rfcomm_connected = 1; 271 } 272 } 273 274 return JNI_TRUE; 275 #else 276 return JNI_FALSE; 277 #endif 278 } 279 280 static jint connectAsyncNative(JNIEnv *env, jobject obj) { 281 ALOGV("%s", __FUNCTION__); 282 #ifdef HAVE_BLUETOOTH 283 struct sockaddr_rc addr; 284 native_data_t *nat = get_native_data(env, obj); 285 286 if (nat->rfcomm_connected) { 287 ALOGV("RFCOMM socket is already connected or connection is in progress."); 288 return 0; 289 } 290 291 if (nat->rfcomm_sock < 0) { 292 int lm; 293 294 nat->rfcomm_sock = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); 295 if (nat->rfcomm_sock < 0) { 296 ALOGE("%s: Could not create RFCOMM socket: %s\n", __FUNCTION__, 297 strerror(errno)); 298 return -1; 299 } 300 301 if (debug_no_encrypt()) { 302 lm = RFCOMM_LM_AUTH; 303 } else { 304 lm = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT; 305 } 306 307 if (lm && setsockopt(nat->rfcomm_sock, SOL_RFCOMM, RFCOMM_LM, &lm, 308 sizeof(lm)) < 0) { 309 ALOGE("%s: Can't set RFCOMM link mode", __FUNCTION__); 310 close(nat->rfcomm_sock); 311 return -1; 312 } 313 ALOGI("Created RFCOMM socket fd %d.", nat->rfcomm_sock); 314 } 315 316 memset(&addr, 0, sizeof(struct sockaddr_rc)); 317 get_bdaddr(nat->c_address, &addr.rc_bdaddr); 318 addr.rc_channel = nat->rfcomm_channel; 319 addr.rc_family = AF_BLUETOOTH; 320 if (nat->rfcomm_sock_flags >= 0) { 321 nat->rfcomm_sock_flags = fcntl(nat->rfcomm_sock, F_GETFL, 0); 322 if (fcntl(nat->rfcomm_sock, 323 F_SETFL, nat->rfcomm_sock_flags | O_NONBLOCK) >= 0) { 324 int rc; 325 nat->rfcomm_connected = 0; 326 errno = 0; 327 rc = connect(nat->rfcomm_sock, 328 (struct sockaddr *)&addr, 329 sizeof(addr)); 330 331 if (rc >= 0) { 332 nat->rfcomm_connected = 1; 333 ALOGI("async connect successful"); 334 return 0; 335 } 336 else if (rc < 0) { 337 if (errno == EINPROGRESS || errno == EAGAIN) 338 { 339 ALOGI("async connect is in progress (%s)", 340 strerror(errno)); 341 nat->rfcomm_connected = -1; 342 return 0; 343 } 344 else 345 { 346 ALOGE("async connect error: %s (%d)", strerror(errno), errno); 347 close(nat->rfcomm_sock); 348 nat->rfcomm_sock = -1; 349 return -errno; 350 } 351 } 352 } // fcntl(nat->rfcomm_sock ...) 353 } // if (nat->rfcomm_sock_flags >= 0) 354 #endif 355 return -1; 356 } 357 358 static jint waitForAsyncConnectNative(JNIEnv *env, jobject obj, 359 jint timeout_ms) { 360 ALOGV("%s", __FUNCTION__); 361 #ifdef HAVE_BLUETOOTH 362 struct sockaddr_rc addr; 363 native_data_t *nat = get_native_data(env, obj); 364 365 env->SetIntField(obj, field_mTimeoutRemainingMs, timeout_ms); 366 367 if (nat->rfcomm_connected > 0) { 368 ALOGI("RFCOMM is already connected!"); 369 return 1; 370 } 371 372 if (nat->rfcomm_sock >= 0 && nat->rfcomm_connected == 0) { 373 ALOGI("Re-opening RFCOMM socket."); 374 close(nat->rfcomm_sock); 375 nat->rfcomm_sock = -1; 376 } 377 int ret = connectAsyncNative(env, obj); 378 379 if (ret < 0) { 380 ALOGI("Failed to re-open RFCOMM socket!"); 381 return ret; 382 } 383 384 if (nat->rfcomm_sock >= 0) { 385 /* Do an asynchronous select() */ 386 int n; 387 fd_set rset, wset; 388 struct timeval to; 389 390 FD_ZERO(&rset); 391 FD_ZERO(&wset); 392 FD_SET(nat->rfcomm_sock, &rset); 393 FD_SET(nat->rfcomm_sock, &wset); 394 if (timeout_ms >= 0) { 395 to.tv_sec = timeout_ms / 1000; 396 to.tv_usec = 1000 * (timeout_ms % 1000); 397 } 398 n = select(nat->rfcomm_sock + 1, 399 &rset, 400 &wset, 401 NULL, 402 (timeout_ms < 0 ? NULL : &to)); 403 404 if (timeout_ms > 0) { 405 jint remaining = to.tv_sec*1000 + to.tv_usec/1000; 406 ALOGV("Remaining time %ldms", (long)remaining); 407 env->SetIntField(obj, field_mTimeoutRemainingMs, 408 remaining); 409 } 410 411 if (n <= 0) { 412 if (n < 0) { 413 ALOGE("select() on RFCOMM socket: %s (%d)", 414 strerror(errno), 415 errno); 416 return -errno; 417 } 418 return 0; 419 } 420 /* n must be equal to 1 and either rset or wset must have the 421 file descriptor set. */ 422 ALOGV("select() returned %d.", n); 423 if (FD_ISSET(nat->rfcomm_sock, &rset) || 424 FD_ISSET(nat->rfcomm_sock, &wset)) 425 { 426 /* A trial async read() will tell us if everything is OK. */ 427 { 428 char ch; 429 errno = 0; 430 int nr = TEMP_FAILURE_RETRY(read(nat->rfcomm_sock, &ch, 1)); 431 /* It should be that nr != 1 because we just opened a socket 432 and we haven't sent anything over it for the other side to 433 respond... but one can't be paranoid enough. 434 */ 435 if (nr >= 0 || errno != EAGAIN) { 436 ALOGE("RFCOMM async connect() error: %s (%d), nr = %d\n", 437 strerror(errno), 438 errno, 439 nr); 440 /* Clear the rfcomm_connected flag to cause this function 441 to re-create the socket and re-attempt the connect() 442 the next time it is called. 443 */ 444 nat->rfcomm_connected = 0; 445 /* Restore the blocking properties of the socket. */ 446 fcntl(nat->rfcomm_sock, F_SETFL, nat->rfcomm_sock_flags); 447 close(nat->rfcomm_sock); 448 nat->rfcomm_sock = -1; 449 return -errno; 450 } 451 } 452 /* Restore the blocking properties of the socket. */ 453 fcntl(nat->rfcomm_sock, F_SETFL, nat->rfcomm_sock_flags); 454 ALOGI("Successful RFCOMM socket connect."); 455 nat->rfcomm_connected = 1; 456 return 1; 457 } 458 } 459 else ALOGE("RFCOMM socket file descriptor %d is bad!", 460 nat->rfcomm_sock); 461 #endif 462 return -1; 463 } 464 465 static void disconnectNative(JNIEnv *env, jobject obj) { 466 ALOGV("%s", __FUNCTION__); 467 #ifdef HAVE_BLUETOOTH 468 native_data_t *nat = get_native_data(env, obj); 469 if (nat->rfcomm_sock >= 0) { 470 close(nat->rfcomm_sock); 471 nat->rfcomm_sock = -1; 472 nat->rfcomm_connected = 0; 473 } 474 #endif 475 } 476 477 static void pretty_log_urc(const char *urc) { 478 size_t i; 479 bool in_line_break = false; 480 char *buf = (char *)calloc(strlen(urc) + 1, sizeof(char)); 481 482 strcpy(buf, urc); 483 for (i = 0; i < strlen(buf); i++) { 484 switch(buf[i]) { 485 case '\r': 486 case '\n': 487 in_line_break = true; 488 buf[i] = ' '; 489 break; 490 default: 491 if (in_line_break) { 492 in_line_break = false; 493 buf[i-1] = '\n'; 494 } 495 } 496 } 497 IF_ALOGV() ALOG(LOG_VERBOSE, "Bluetooth AT sent", "%s", buf); 498 499 free(buf); 500 } 501 502 static jboolean sendURCNative(JNIEnv *env, jobject obj, jstring urc) { 503 #ifdef HAVE_BLUETOOTH 504 native_data_t *nat = get_native_data(env, obj); 505 if (nat->rfcomm_connected) { 506 const char *c_urc = env->GetStringUTFChars(urc, NULL); 507 jboolean ret = send_line(nat->rfcomm_sock, c_urc) == 0 ? JNI_TRUE : JNI_FALSE; 508 if (ret == JNI_TRUE) pretty_log_urc(c_urc); 509 env->ReleaseStringUTFChars(urc, c_urc); 510 return ret; 511 } 512 #endif 513 return JNI_FALSE; 514 } 515 516 static jstring readNative(JNIEnv *env, jobject obj, jint timeout_ms) { 517 #ifdef HAVE_BLUETOOTH 518 { 519 native_data_t *nat = get_native_data(env, obj); 520 if (nat->rfcomm_connected) { 521 char buf[256]; 522 const char *ret = get_line(nat->rfcomm_sock, 523 buf, sizeof(buf), 524 timeout_ms, 525 &nat->last_read_err); 526 return ret ? env->NewStringUTF(ret) : NULL; 527 } 528 return NULL; 529 } 530 #else 531 return NULL; 532 #endif 533 } 534 535 static jint getLastReadStatusNative(JNIEnv *env, jobject obj) { 536 #ifdef HAVE_BLUETOOTH 537 { 538 native_data_t *nat = get_native_data(env, obj); 539 if (nat->rfcomm_connected) 540 return (jint)nat->last_read_err; 541 return 0; 542 } 543 #else 544 return 0; 545 #endif 546 } 547 548 static JNINativeMethod sMethods[] = { 549 /* name, signature, funcPtr */ 550 {"classInitNative", "()V", (void*)classInitNative}, 551 {"initializeNativeDataNative", "(I)V", (void *)initializeNativeDataNative}, 552 {"cleanupNativeDataNative", "()V", (void *)cleanupNativeDataNative}, 553 {"connectNative", "()Z", (void *)connectNative}, 554 {"connectAsyncNative", "()I", (void *)connectAsyncNative}, 555 {"waitForAsyncConnectNative", "(I)I", (void *)waitForAsyncConnectNative}, 556 {"disconnectNative", "()V", (void *)disconnectNative}, 557 {"sendURCNative", "(Ljava/lang/String;)Z", (void *)sendURCNative}, 558 {"readNative", "(I)Ljava/lang/String;", (void *)readNative}, 559 {"getLastReadStatusNative", "()I", (void *)getLastReadStatusNative}, 560 }; 561 562 int register_android_bluetooth_HeadsetBase(JNIEnv *env) { 563 return AndroidRuntime::registerNativeMethods(env, 564 "android/bluetooth/HeadsetBase", sMethods, NELEM(sMethods)); 565 } 566 567 } /* namespace android */ 568