summaryrefslogtreecommitdiffstats
path: root/core/jni
diff options
context:
space:
mode:
authorMatthew Xie <mattx@google.com>2012-07-16 21:09:13 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2012-07-16 21:09:13 -0700
commitd4d4e715c5f4423b9fadce77b120b8488e011337 (patch)
treecf2e85c3dd7a9877427a6238452a5f07ccd48403 /core/jni
parent9e4a6baee333b3ea5e8e2c291a8c94d4e8aabf75 (diff)
parent313a2167098ce8498db3a50d70724f260e8169c0 (diff)
downloadframeworks_base-d4d4e715c5f4423b9fadce77b120b8488e011337.zip
frameworks_base-d4d4e715c5f4423b9fadce77b120b8488e011337.tar.gz
frameworks_base-d4d4e715c5f4423b9fadce77b120b8488e011337.tar.bz2
Merge "Delete various Bluetooth files for stack integration."
Diffstat (limited to 'core/jni')
-rw-r--r--core/jni/Android.mk8
-rw-r--r--core/jni/AndroidRuntime.cpp12
-rw-r--r--core/jni/android_bluetooth_BluetoothAudioGateway.cpp553
-rw-r--r--core/jni/android_bluetooth_BluetoothSocket.cpp588
-rw-r--r--core/jni/android_bluetooth_HeadsetBase.cpp567
-rw-r--r--core/jni/android_bluetooth_c.c31
-rw-r--r--core/jni/android_bluetooth_c.h39
-rw-r--r--core/jni/android_bluetooth_common.cpp867
-rw-r--r--core/jni/android_bluetooth_common.h215
-rw-r--r--core/jni/android_server_BluetoothA2dpService.cpp344
-rw-r--r--core/jni/android_server_BluetoothEventLoop.cpp1585
-rw-r--r--core/jni/android_server_BluetoothService.cpp1785
12 files changed, 0 insertions, 6594 deletions
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index eb39b12..99ec057 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -138,14 +138,6 @@ LOCAL_SRC_FILES:= \
android_util_FileObserver.cpp \
android/opengl/poly_clip.cpp.arm \
android/opengl/util.cpp.arm \
- android_bluetooth_HeadsetBase.cpp \
- android_bluetooth_common.cpp \
- android_bluetooth_BluetoothAudioGateway.cpp \
- android_bluetooth_BluetoothSocket.cpp \
- android_bluetooth_c.c \
- android_server_BluetoothService.cpp \
- android_server_BluetoothEventLoop.cpp \
- android_server_BluetoothA2dpService.cpp \
android_server_NetworkManagementSocketTagger.cpp \
android_server_Watchdog.cpp \
android_ddm_DdmHandleNativeHeap.cpp \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 532a6e5..f0dd321 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -150,12 +150,6 @@ extern int register_android_net_wifi_WifiManager(JNIEnv* env);
extern int register_android_text_AndroidCharacter(JNIEnv *env);
extern int register_android_text_AndroidBidi(JNIEnv *env);
extern int register_android_opengl_classes(JNIEnv *env);
-extern int register_android_bluetooth_HeadsetBase(JNIEnv* env);
-extern int register_android_bluetooth_BluetoothAudioGateway(JNIEnv* env);
-extern int register_android_bluetooth_BluetoothSocket(JNIEnv *env);
-extern int register_android_server_BluetoothService(JNIEnv* env);
-extern int register_android_server_BluetoothEventLoop(JNIEnv *env);
-extern int register_android_server_BluetoothA2dpService(JNIEnv* env);
extern int register_android_server_NetworkManagementSocketTagger(JNIEnv* env);
extern int register_android_server_Watchdog(JNIEnv* env);
extern int register_android_ddm_DdmHandleNativeHeap(JNIEnv *env);
@@ -1172,12 +1166,6 @@ static const RegJNIRec gRegJNI[] = {
REG_JNI(register_android_media_ToneGenerator),
REG_JNI(register_android_opengl_classes),
- REG_JNI(register_android_bluetooth_HeadsetBase),
- REG_JNI(register_android_bluetooth_BluetoothAudioGateway),
- REG_JNI(register_android_bluetooth_BluetoothSocket),
- REG_JNI(register_android_server_BluetoothService),
- REG_JNI(register_android_server_BluetoothEventLoop),
- REG_JNI(register_android_server_BluetoothA2dpService),
REG_JNI(register_android_server_NetworkManagementSocketTagger),
REG_JNI(register_android_server_Watchdog),
REG_JNI(register_android_ddm_DdmHandleNativeHeap),
diff --git a/core/jni/android_bluetooth_BluetoothAudioGateway.cpp b/core/jni/android_bluetooth_BluetoothAudioGateway.cpp
deleted file mode 100644
index 294c626..0000000
--- a/core/jni/android_bluetooth_BluetoothAudioGateway.cpp
+++ /dev/null
@@ -1,553 +0,0 @@
-/*
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#define LOG_TAG "BluetoothAudioGateway.cpp"
-
-#include "android_bluetooth_common.h"
-#include "android_bluetooth_c.h"
-#include "android_runtime/AndroidRuntime.h"
-#include "JNIHelp.h"
-#include "jni.h"
-#include "utils/Log.h"
-#include "utils/misc.h"
-
-#define USE_ACCEPT_DIRECTLY (0)
-#define USE_SELECT (0) /* 1 for select(), 0 for poll(); used only when
- USE_ACCEPT_DIRECTLY == 0 */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/uio.h>
-#include <ctype.h>
-
-#if USE_SELECT
-#include <sys/select.h>
-#else
-#include <sys/poll.h>
-#endif
-
-#ifdef HAVE_BLUETOOTH
-#include <bluetooth/bluetooth.h>
-#include <bluetooth/rfcomm.h>
-#include <bluetooth/sco.h>
-#endif
-
-namespace android {
-
-#ifdef HAVE_BLUETOOTH
-static jfieldID field_mNativeData;
- /* in */
-static jfieldID field_mHandsfreeAgRfcommChannel;
-static jfieldID field_mHeadsetAgRfcommChannel;
- /* out */
-static jfieldID field_mTimeoutRemainingMs; /* out */
-
-static jfieldID field_mConnectingHeadsetAddress;
-static jfieldID field_mConnectingHeadsetRfcommChannel; /* -1 when not connected */
-static jfieldID field_mConnectingHeadsetSocketFd;
-
-static jfieldID field_mConnectingHandsfreeAddress;
-static jfieldID field_mConnectingHandsfreeRfcommChannel; /* -1 when not connected */
-static jfieldID field_mConnectingHandsfreeSocketFd;
-
-
-typedef struct {
- int hcidev;
- int hf_ag_rfcomm_channel;
- int hs_ag_rfcomm_channel;
- int hf_ag_rfcomm_sock;
- int hs_ag_rfcomm_sock;
-} native_data_t;
-
-static inline native_data_t * get_native_data(JNIEnv *env, jobject object) {
- return (native_data_t *)(env->GetIntField(object,
- field_mNativeData));
-}
-
-static int setup_listening_socket(int dev, int channel);
-#endif
-
-static void classInitNative(JNIEnv* env, jclass clazz) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-
- /* in */
- field_mNativeData = get_field(env, clazz, "mNativeData", "I");
- field_mHandsfreeAgRfcommChannel =
- get_field(env, clazz, "mHandsfreeAgRfcommChannel", "I");
- field_mHeadsetAgRfcommChannel =
- get_field(env, clazz, "mHeadsetAgRfcommChannel", "I");
-
- /* out */
- field_mConnectingHeadsetAddress =
- get_field(env, clazz,
- "mConnectingHeadsetAddress", "Ljava/lang/String;");
- field_mConnectingHeadsetRfcommChannel =
- get_field(env, clazz, "mConnectingHeadsetRfcommChannel", "I");
- field_mConnectingHeadsetSocketFd =
- get_field(env, clazz, "mConnectingHeadsetSocketFd", "I");
-
- field_mConnectingHandsfreeAddress =
- get_field(env, clazz,
- "mConnectingHandsfreeAddress", "Ljava/lang/String;");
- field_mConnectingHandsfreeRfcommChannel =
- get_field(env, clazz, "mConnectingHandsfreeRfcommChannel", "I");
- field_mConnectingHandsfreeSocketFd =
- get_field(env, clazz, "mConnectingHandsfreeSocketFd", "I");
-
- field_mTimeoutRemainingMs =
- get_field(env, clazz, "mTimeoutRemainingMs", "I");
-#endif
-}
-
-static void initializeNativeDataNative(JNIEnv* env, jobject object) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- native_data_t *nat = (native_data_t *)calloc(1, sizeof(native_data_t));
- if (NULL == nat) {
- ALOGE("%s: out of memory!", __FUNCTION__);
- return;
- }
-
- nat->hcidev = BLUETOOTH_ADAPTER_HCI_NUM;
-
- env->SetIntField(object, field_mNativeData, (jint)nat);
- nat->hf_ag_rfcomm_channel =
- env->GetIntField(object, field_mHandsfreeAgRfcommChannel);
- nat->hs_ag_rfcomm_channel =
- env->GetIntField(object, field_mHeadsetAgRfcommChannel);
- ALOGV("HF RFCOMM channel = %d.", nat->hf_ag_rfcomm_channel);
- ALOGV("HS RFCOMM channel = %d.", nat->hs_ag_rfcomm_channel);
-
- /* Set the default values of these to -1. */
- env->SetIntField(object, field_mConnectingHeadsetRfcommChannel, -1);
- env->SetIntField(object, field_mConnectingHandsfreeRfcommChannel, -1);
-
- nat->hf_ag_rfcomm_sock = -1;
- nat->hs_ag_rfcomm_sock = -1;
-#endif
-}
-
-static void cleanupNativeDataNative(JNIEnv* env, jobject object) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- native_data_t *nat = get_native_data(env, object);
- if (nat) {
- free(nat);
- }
-#endif
-}
-
-#ifdef HAVE_BLUETOOTH
-
-#if USE_ACCEPT_DIRECTLY==0
-static int set_nb(int sk, bool nb) {
- int flags = fcntl(sk, F_GETFL);
- if (flags < 0) {
- ALOGE("Can't get socket flags with fcntl(): %s (%d)",
- strerror(errno), errno);
- close(sk);
- return -1;
- }
- flags &= ~O_NONBLOCK;
- if (nb) flags |= O_NONBLOCK;
- int status = fcntl(sk, F_SETFL, flags);
- if (status < 0) {
- ALOGE("Can't set socket to nonblocking mode with fcntl(): %s (%d)",
- strerror(errno), errno);
- close(sk);
- return -1;
- }
- return 0;
-}
-#endif /*USE_ACCEPT_DIRECTLY==0*/
-
-static int do_accept(JNIEnv* env, jobject object, int ag_fd,
- jfieldID out_fd,
- jfieldID out_address,
- jfieldID out_channel) {
-
-#if USE_ACCEPT_DIRECTLY==0
- if (set_nb(ag_fd, true) < 0)
- return -1;
-#endif
-
- struct sockaddr_rc raddr;
- int alen = sizeof(raddr);
- int nsk = TEMP_FAILURE_RETRY(accept(ag_fd, (struct sockaddr *) &raddr, &alen));
- if (nsk < 0) {
- ALOGE("Error on accept from socket fd %d: %s (%d).",
- ag_fd,
- strerror(errno),
- errno);
-#if USE_ACCEPT_DIRECTLY==0
- set_nb(ag_fd, false);
-#endif
- return -1;
- }
-
- env->SetIntField(object, out_fd, nsk);
- env->SetIntField(object, out_channel, raddr.rc_channel);
-
- char addr[BTADDR_SIZE];
- get_bdaddr_as_string(&raddr.rc_bdaddr, addr);
- env->SetObjectField(object, out_address, env->NewStringUTF(addr));
-
- ALOGI("Successful accept() on AG socket %d: new socket %d, address %s, RFCOMM channel %d",
- ag_fd,
- nsk,
- addr,
- raddr.rc_channel);
-#if USE_ACCEPT_DIRECTLY==0
- set_nb(ag_fd, false);
-#endif
- return 0;
-}
-
-#if USE_SELECT
-static inline int on_accept_set_fields(JNIEnv* env, jobject object,
- fd_set *rset, int ag_fd,
- jfieldID out_fd,
- jfieldID out_address,
- jfieldID out_channel) {
-
- env->SetIntField(object, out_channel, -1);
-
- if (ag_fd >= 0 && FD_ISSET(ag_fd, &rset)) {
- return do_accept(env, object, ag_fd,
- out_fd, out_address, out_channel);
- }
- else {
- ALOGI("fd = %d, FD_ISSET() = %d",
- ag_fd,
- FD_ISSET(ag_fd, &rset));
- if (ag_fd >= 0 && !FD_ISSET(ag_fd, &rset)) {
- ALOGE("WTF???");
- return -1;
- }
- }
-
- return 0;
-}
-#endif
-#endif /* HAVE_BLUETOOTH */
-
-static jboolean waitForHandsfreeConnectNative(JNIEnv* env, jobject object,
- jint timeout_ms) {
-// ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-
- env->SetIntField(object, field_mTimeoutRemainingMs, timeout_ms);
-
- int n = 0;
- native_data_t *nat = get_native_data(env, object);
-#if USE_ACCEPT_DIRECTLY
- if (nat->hf_ag_rfcomm_channel > 0) {
- ALOGI("Setting HF AG server socket to RFCOMM port %d!",
- nat->hf_ag_rfcomm_channel);
- struct timeval tv;
- int len = sizeof(tv);
- if (getsockopt(nat->hf_ag_rfcomm_channel,
- SOL_SOCKET, SO_RCVTIMEO, &tv, &len) < 0) {
- ALOGE("getsockopt(%d, SOL_SOCKET, SO_RCVTIMEO): %s (%d)",
- nat->hf_ag_rfcomm_channel,
- strerror(errno),
- errno);
- return JNI_FALSE;
- }
- ALOGI("Current HF AG server socket RCVTIMEO is (%d(s), %d(us))!",
- (int)tv.tv_sec, (int)tv.tv_usec);
- if (timeout_ms >= 0) {
- tv.tv_sec = timeout_ms / 1000;
- tv.tv_usec = 1000 * (timeout_ms % 1000);
- if (setsockopt(nat->hf_ag_rfcomm_channel,
- SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
- ALOGE("setsockopt(%d, SOL_SOCKET, SO_RCVTIMEO): %s (%d)",
- nat->hf_ag_rfcomm_channel,
- strerror(errno),
- errno);
- return JNI_FALSE;
- }
- ALOGI("Changed HF AG server socket RCVTIMEO to (%d(s), %d(us))!",
- (int)tv.tv_sec, (int)tv.tv_usec);
- }
-
- if (!do_accept(env, object, nat->hf_ag_rfcomm_sock,
- field_mConnectingHandsfreeSocketFd,
- field_mConnectingHandsfreeAddress,
- field_mConnectingHandsfreeRfcommChannel))
- {
- env->SetIntField(object, field_mTimeoutRemainingMs, 0);
- return JNI_TRUE;
- }
- return JNI_FALSE;
- }
-#else
-#if USE_SELECT
- fd_set rset;
- FD_ZERO(&rset);
- int cnt = 0;
- if (nat->hf_ag_rfcomm_channel > 0) {
- ALOGI("Setting HF AG server socket to RFCOMM port %d!",
- nat->hf_ag_rfcomm_channel);
- cnt++;
- FD_SET(nat->hf_ag_rfcomm_sock, &rset);
- }
- if (nat->hs_ag_rfcomm_channel > 0) {
- ALOGI("Setting HS AG server socket to RFCOMM port %d!",
- nat->hs_ag_rfcomm_channel);
- cnt++;
- FD_SET(nat->hs_ag_rfcomm_sock, &rset);
- }
- if (cnt == 0) {
- ALOGE("Neither HF nor HS listening sockets are open!");
- return JNI_FALSE;
- }
-
- struct timeval to;
- if (timeout_ms >= 0) {
- to.tv_sec = timeout_ms / 1000;
- to.tv_usec = 1000 * (timeout_ms % 1000);
- }
- n = TEMP_FAILURE_RETRY(select(
- MAX(nat->hf_ag_rfcomm_sock, nat->hs_ag_rfcomm_sock) + 1,
- &rset,
- NULL,
- NULL,
- (timeout_ms < 0 ? NULL : &to)));
- if (timeout_ms > 0) {
- jint remaining = to.tv_sec*1000 + to.tv_usec/1000;
- ALOGI("Remaining time %ldms", (long)remaining);
- env->SetIntField(object, field_mTimeoutRemainingMs,
- remaining);
- }
-
- ALOGI("listening select() returned %d", n);
-
- if (n <= 0) {
- if (n < 0) {
- ALOGE("listening select() on RFCOMM sockets: %s (%d)",
- strerror(errno),
- errno);
- }
- return JNI_FALSE;
- }
-
- n = on_accept_set_fields(env, object,
- &rset, nat->hf_ag_rfcomm_sock,
- field_mConnectingHandsfreeSocketFd,
- field_mConnectingHandsfreeAddress,
- field_mConnectingHandsfreeRfcommChannel);
-
- n += on_accept_set_fields(env, object,
- &rset, nat->hs_ag_rfcomm_sock,
- field_mConnectingHeadsetSocketFd,
- field_mConnectingHeadsetAddress,
- field_mConnectingHeadsetRfcommChannel);
-
- return !n ? JNI_TRUE : JNI_FALSE;
-#else
- struct pollfd fds[2];
- int cnt = 0;
- if (nat->hf_ag_rfcomm_channel > 0) {
-// ALOGI("Setting HF AG server socket %d to RFCOMM port %d!",
-// nat->hf_ag_rfcomm_sock,
-// nat->hf_ag_rfcomm_channel);
- fds[cnt].fd = nat->hf_ag_rfcomm_sock;
- fds[cnt].events = POLLIN | POLLPRI | POLLOUT | POLLERR;
- cnt++;
- }
- if (nat->hs_ag_rfcomm_channel > 0) {
-// ALOGI("Setting HS AG server socket %d to RFCOMM port %d!",
-// nat->hs_ag_rfcomm_sock,
-// nat->hs_ag_rfcomm_channel);
- fds[cnt].fd = nat->hs_ag_rfcomm_sock;
- fds[cnt].events = POLLIN | POLLPRI | POLLOUT | POLLERR;
- cnt++;
- }
- if (cnt == 0) {
- ALOGE("Neither HF nor HS listening sockets are open!");
- return JNI_FALSE;
- }
- n = TEMP_FAILURE_RETRY(poll(fds, cnt, timeout_ms));
- if (n <= 0) {
- if (n < 0) {
- ALOGE("listening poll() on RFCOMM sockets: %s (%d)",
- strerror(errno),
- errno);
- }
- else {
- env->SetIntField(object, field_mTimeoutRemainingMs, 0);
-// ALOGI("listening poll() on RFCOMM socket timed out");
- }
- return JNI_FALSE;
- }
-
- //ALOGI("listening poll() on RFCOMM socket returned %d", n);
- int err = 0;
- for (cnt = 0; cnt < (int)(sizeof(fds)/sizeof(fds[0])); cnt++) {
- //ALOGI("Poll on fd %d revent = %d.", fds[cnt].fd, fds[cnt].revents);
- if (fds[cnt].fd == nat->hf_ag_rfcomm_sock) {
- if (fds[cnt].revents & (POLLIN | POLLPRI | POLLOUT)) {
- ALOGI("Accepting HF connection.\n");
- err += do_accept(env, object, fds[cnt].fd,
- field_mConnectingHandsfreeSocketFd,
- field_mConnectingHandsfreeAddress,
- field_mConnectingHandsfreeRfcommChannel);
- n--;
- }
- }
- else if (fds[cnt].fd == nat->hs_ag_rfcomm_sock) {
- if (fds[cnt].revents & (POLLIN | POLLPRI | POLLOUT)) {
- ALOGI("Accepting HS connection.\n");
- err += do_accept(env, object, fds[cnt].fd,
- field_mConnectingHeadsetSocketFd,
- field_mConnectingHeadsetAddress,
- field_mConnectingHeadsetRfcommChannel);
- n--;
- }
- }
- } /* for */
-
- if (n != 0) {
- ALOGI("Bogus poll(): %d fake pollfd entrie(s)!", n);
- return JNI_FALSE;
- }
-
- return !err ? JNI_TRUE : JNI_FALSE;
-#endif /* USE_SELECT */
-#endif /* USE_ACCEPT_DIRECTLY */
-#else
- return JNI_FALSE;
-#endif /* HAVE_BLUETOOTH */
-}
-
-static jboolean setUpListeningSocketsNative(JNIEnv* env, jobject object) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- native_data_t *nat = get_native_data(env, object);
-
- nat->hf_ag_rfcomm_sock =
- setup_listening_socket(nat->hcidev, nat->hf_ag_rfcomm_channel);
- if (nat->hf_ag_rfcomm_sock < 0)
- return JNI_FALSE;
-
- nat->hs_ag_rfcomm_sock =
- setup_listening_socket(nat->hcidev, nat->hs_ag_rfcomm_channel);
- if (nat->hs_ag_rfcomm_sock < 0) {
- close(nat->hf_ag_rfcomm_sock);
- nat->hf_ag_rfcomm_sock = -1;
- return JNI_FALSE;
- }
-
- return JNI_TRUE;
-#else
- return JNI_FALSE;
-#endif /* HAVE_BLUETOOTH */
-}
-
-#ifdef HAVE_BLUETOOTH
-static int setup_listening_socket(int dev, int channel) {
- struct sockaddr_rc laddr;
- int sk, lm;
-
- sk = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
- if (sk < 0) {
- ALOGE("Can't create RFCOMM socket");
- return -1;
- }
-
- if (debug_no_encrypt()) {
- lm = RFCOMM_LM_AUTH;
- } else {
- lm = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT;
- }
-
- if (lm && setsockopt(sk, SOL_RFCOMM, RFCOMM_LM, &lm, sizeof(lm)) < 0) {
- ALOGE("Can't set RFCOMM link mode");
- close(sk);
- return -1;
- }
-
- laddr.rc_family = AF_BLUETOOTH;
- bdaddr_t any = android_bluetooth_bdaddr_any();
- memcpy(&laddr.rc_bdaddr, &any, sizeof(bdaddr_t));
- laddr.rc_channel = channel;
-
- if (bind(sk, (struct sockaddr *)&laddr, sizeof(laddr)) < 0) {
- ALOGE("Can't bind RFCOMM socket");
- close(sk);
- return -1;
- }
-
- listen(sk, 10);
- return sk;
-}
-#endif /* HAVE_BLUETOOTH */
-
-/*
- private native void tearDownListeningSocketsNative();
-*/
-static void tearDownListeningSocketsNative(JNIEnv *env, jobject object) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- native_data_t *nat = get_native_data(env, object);
-
- if (nat->hf_ag_rfcomm_sock > 0) {
- if (close(nat->hf_ag_rfcomm_sock) < 0) {
- ALOGE("Could not close HF server socket: %s (%d)\n",
- strerror(errno), errno);
- }
- nat->hf_ag_rfcomm_sock = -1;
- }
- if (nat->hs_ag_rfcomm_sock > 0) {
- if (close(nat->hs_ag_rfcomm_sock) < 0) {
- ALOGE("Could not close HS server socket: %s (%d)\n",
- strerror(errno), errno);
- }
- nat->hs_ag_rfcomm_sock = -1;
- }
-#endif /* HAVE_BLUETOOTH */
-}
-
-static JNINativeMethod sMethods[] = {
- /* name, signature, funcPtr */
-
- {"classInitNative", "()V", (void*)classInitNative},
- {"initializeNativeDataNative", "()V", (void *)initializeNativeDataNative},
- {"cleanupNativeDataNative", "()V", (void *)cleanupNativeDataNative},
-
- {"setUpListeningSocketsNative", "()Z", (void *)setUpListeningSocketsNative},
- {"tearDownListeningSocketsNative", "()V", (void *)tearDownListeningSocketsNative},
- {"waitForHandsfreeConnectNative", "(I)Z", (void *)waitForHandsfreeConnectNative},
-};
-
-int register_android_bluetooth_BluetoothAudioGateway(JNIEnv *env) {
- return AndroidRuntime::registerNativeMethods(env,
- "android/bluetooth/BluetoothAudioGateway", sMethods,
- NELEM(sMethods));
-}
-
-} /* namespace android */
diff --git a/core/jni/android_bluetooth_BluetoothSocket.cpp b/core/jni/android_bluetooth_BluetoothSocket.cpp
deleted file mode 100644
index d9ff36a..0000000
--- a/core/jni/android_bluetooth_BluetoothSocket.cpp
+++ /dev/null
@@ -1,588 +0,0 @@
-/*
- * Copyright 2009, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "BluetoothSocket.cpp"
-
-#include "android_bluetooth_common.h"
-#include "android_bluetooth_c.h"
-#include "android_runtime/AndroidRuntime.h"
-#include "JNIHelp.h"
-#include "utils/Log.h"
-#include "cutils/abort_socket.h"
-
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-
-#ifdef HAVE_BLUETOOTH
-#include <bluetooth/bluetooth.h>
-#include <bluetooth/rfcomm.h>
-#include <bluetooth/l2cap.h>
-#include <bluetooth/sco.h>
-#endif
-
-#define TYPE_AS_STR(t) \
- ((t) == TYPE_RFCOMM ? "RFCOMM" : ((t) == TYPE_SCO ? "SCO" : "L2CAP"))
-
-namespace android {
-
-static jfieldID field_mAuth; /* read-only */
-static jfieldID field_mEncrypt; /* read-only */
-static jfieldID field_mType; /* read-only */
-static jfieldID field_mAddress; /* read-only */
-static jfieldID field_mPort; /* read-only */
-static jfieldID field_mSocketData;
-static jmethodID method_BluetoothSocket_ctor;
-static jclass class_BluetoothSocket;
-
-/* Keep TYPE_RFCOMM etc in sync with BluetoothSocket.java */
-static const int TYPE_RFCOMM = 1;
-static const int TYPE_SCO = 2;
-static const int TYPE_L2CAP = 3; // TODO: Test l2cap code paths
-
-static const int RFCOMM_SO_SNDBUF = 70 * 1024; // 70 KB send buffer
-
-static void abortNative(JNIEnv *env, jobject obj);
-static void destroyNative(JNIEnv *env, jobject obj);
-
-static struct asocket *get_socketData(JNIEnv *env, jobject obj) {
- struct asocket *s =
- (struct asocket *) env->GetIntField(obj, field_mSocketData);
- if (!s)
- jniThrowException(env, "java/io/IOException", "null socketData");
- return s;
-}
-
-static void initSocketFromFdNative(JNIEnv *env, jobject obj, jint fd) {
-#ifdef HAVE_BLUETOOTH
- ALOGV("%s", __FUNCTION__);
-
- struct asocket *s = asocket_init(fd);
-
- if (!s) {
- ALOGV("asocket_init() failed, throwing");
- jniThrowIOException(env, errno);
- return;
- }
-
- env->SetIntField(obj, field_mSocketData, (jint)s);
-
- return;
-#endif
- jniThrowIOException(env, ENOSYS);
-}
-
-static void initSocketNative(JNIEnv *env, jobject obj) {
-#ifdef HAVE_BLUETOOTH
- ALOGV("%s", __FUNCTION__);
-
- int fd;
- int lm = 0;
- int sndbuf;
- jboolean auth;
- jboolean encrypt;
- jint type;
-
- type = env->GetIntField(obj, field_mType);
-
- switch (type) {
- case TYPE_RFCOMM:
- fd = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
- break;
- case TYPE_SCO:
- fd = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO);
- break;
- case TYPE_L2CAP:
- fd = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
- break;
- default:
- jniThrowIOException(env, ENOSYS);
- return;
- }
-
- if (fd < 0) {
- ALOGV("socket() failed, throwing");
- jniThrowIOException(env, errno);
- return;
- }
-
- auth = env->GetBooleanField(obj, field_mAuth);
- encrypt = env->GetBooleanField(obj, field_mEncrypt);
-
- /* kernel does not yet support LM for SCO */
- switch (type) {
- case TYPE_RFCOMM:
- lm |= auth ? RFCOMM_LM_AUTH : 0;
- lm |= encrypt ? RFCOMM_LM_ENCRYPT : 0;
- lm |= (auth && encrypt) ? RFCOMM_LM_SECURE : 0;
- break;
- case TYPE_L2CAP:
- lm |= auth ? L2CAP_LM_AUTH : 0;
- lm |= encrypt ? L2CAP_LM_ENCRYPT : 0;
- lm |= (auth && encrypt) ? L2CAP_LM_SECURE : 0;
- break;
- }
-
- if (lm) {
- if (setsockopt(fd, SOL_RFCOMM, RFCOMM_LM, &lm, sizeof(lm))) {
- ALOGV("setsockopt(RFCOMM_LM) failed, throwing");
- jniThrowIOException(env, errno);
- return;
- }
- }
-
- if (type == TYPE_RFCOMM) {
- sndbuf = RFCOMM_SO_SNDBUF;
- if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf))) {
- ALOGV("setsockopt(SO_SNDBUF) failed, throwing");
- jniThrowIOException(env, errno);
- return;
- }
- }
-
- ALOGV("...fd %d created (%s, lm = %x)", fd, TYPE_AS_STR(type), lm);
-
- initSocketFromFdNative(env, obj, fd);
- return;
-#endif
- jniThrowIOException(env, ENOSYS);
-}
-
-static void connectNative(JNIEnv *env, jobject obj) {
-#ifdef HAVE_BLUETOOTH
- ALOGV("%s", __FUNCTION__);
-
- int ret;
- jint type;
- const char *c_address;
- jstring address;
- bdaddr_t bdaddress;
- socklen_t addr_sz;
- struct sockaddr *addr;
- struct asocket *s = get_socketData(env, obj);
- int retry = 0;
-
- if (!s)
- return;
-
- type = env->GetIntField(obj, field_mType);
-
- /* parse address into bdaddress */
- address = (jstring) env->GetObjectField(obj, field_mAddress);
- c_address = env->GetStringUTFChars(address, NULL);
- if (get_bdaddr(c_address, &bdaddress)) {
- env->ReleaseStringUTFChars(address, c_address);
- jniThrowIOException(env, EINVAL);
- return;
- }
- env->ReleaseStringUTFChars(address, c_address);
-
- switch (type) {
- case TYPE_RFCOMM:
- struct sockaddr_rc addr_rc;
- addr = (struct sockaddr *)&addr_rc;
- addr_sz = sizeof(addr_rc);
-
- memset(addr, 0, addr_sz);
- addr_rc.rc_family = AF_BLUETOOTH;
- addr_rc.rc_channel = env->GetIntField(obj, field_mPort);
- memcpy(&addr_rc.rc_bdaddr, &bdaddress, sizeof(bdaddr_t));
-
- break;
- case TYPE_SCO:
- struct sockaddr_sco addr_sco;
- addr = (struct sockaddr *)&addr_sco;
- addr_sz = sizeof(addr_sco);
-
- memset(addr, 0, addr_sz);
- addr_sco.sco_family = AF_BLUETOOTH;
- memcpy(&addr_sco.sco_bdaddr, &bdaddress, sizeof(bdaddr_t));
-
- break;
- case TYPE_L2CAP:
- struct sockaddr_l2 addr_l2;
- addr = (struct sockaddr *)&addr_l2;
- addr_sz = sizeof(addr_l2);
-
- memset(addr, 0, addr_sz);
- addr_l2.l2_family = AF_BLUETOOTH;
- addr_l2.l2_psm = env->GetIntField(obj, field_mPort);
- memcpy(&addr_l2.l2_bdaddr, &bdaddress, sizeof(bdaddr_t));
-
- break;
- default:
- jniThrowIOException(env, ENOSYS);
- return;
- }
-
-connect:
- ret = asocket_connect(s, addr, addr_sz, -1);
- ALOGV("...connect(%d, %s) = %d (errno %d)",
- s->fd, TYPE_AS_STR(type), ret, errno);
-
- if (ret && errno == EALREADY && retry < 2) {
- /* workaround for bug 5082381 (EALREADY on ACL collision):
- * retry the connect. Unfortunately we have to create a new fd.
- * It's not ideal to switch the fd underneath the object, but
- * is currently safe */
- ALOGD("Hit bug 5082381 (EALREADY on ACL collision), trying workaround");
- usleep(100000);
- retry++;
- abortNative(env, obj);
- destroyNative(env, obj);
- initSocketNative(env, obj);
- if (env->ExceptionOccurred()) {
- return;
- }
- goto connect;
- }
- if (!ret && retry > 0)
- ALOGD("...workaround ok");
-
- if (ret)
- jniThrowIOException(env, errno);
-
- return;
-#endif
- jniThrowIOException(env, ENOSYS);
-}
-
-/* Returns errno instead of throwing, so java can check errno */
-static int bindListenNative(JNIEnv *env, jobject obj) {
-#ifdef HAVE_BLUETOOTH
- ALOGV("%s", __FUNCTION__);
-
- jint type;
- socklen_t addr_sz;
- struct sockaddr *addr;
- bdaddr_t bdaddr = android_bluetooth_bdaddr_any();
- struct asocket *s = get_socketData(env, obj);
-
- if (!s)
- return EINVAL;
-
- type = env->GetIntField(obj, field_mType);
-
- switch (type) {
- case TYPE_RFCOMM:
- struct sockaddr_rc addr_rc;
- addr = (struct sockaddr *)&addr_rc;
- addr_sz = sizeof(addr_rc);
-
- memset(addr, 0, addr_sz);
- addr_rc.rc_family = AF_BLUETOOTH;
- addr_rc.rc_channel = env->GetIntField(obj, field_mPort);
- memcpy(&addr_rc.rc_bdaddr, &bdaddr, sizeof(bdaddr_t));
- break;
- case TYPE_SCO:
- struct sockaddr_sco addr_sco;
- addr = (struct sockaddr *)&addr_sco;
- addr_sz = sizeof(addr_sco);
-
- memset(addr, 0, addr_sz);
- addr_sco.sco_family = AF_BLUETOOTH;
- memcpy(&addr_sco.sco_bdaddr, &bdaddr, sizeof(bdaddr_t));
- break;
- case TYPE_L2CAP:
- struct sockaddr_l2 addr_l2;
- addr = (struct sockaddr *)&addr_l2;
- addr_sz = sizeof(addr_l2);
-
- memset(addr, 0, addr_sz);
- addr_l2.l2_family = AF_BLUETOOTH;
- addr_l2.l2_psm = env->GetIntField(obj, field_mPort);
- memcpy(&addr_l2.l2_bdaddr, &bdaddr, sizeof(bdaddr_t));
- break;
- default:
- return ENOSYS;
- }
-
- if (bind(s->fd, addr, addr_sz)) {
- ALOGV("...bind(%d) gave errno %d", s->fd, errno);
- return errno;
- }
-
- if (listen(s->fd, 1)) {
- ALOGV("...listen(%d) gave errno %d", s->fd, errno);
- return errno;
- }
-
- ALOGV("...bindListenNative(%d) success", s->fd);
-
- return 0;
-
-#endif
- return ENOSYS;
-}
-
-static jobject acceptNative(JNIEnv *env, jobject obj, int timeout) {
-#ifdef HAVE_BLUETOOTH
- ALOGV("%s", __FUNCTION__);
-
- int fd;
- jint type;
- struct sockaddr *addr;
- socklen_t addr_sz;
- jstring addr_jstr;
- char addr_cstr[BTADDR_SIZE];
- bdaddr_t *bdaddr;
- jboolean auth;
- jboolean encrypt;
-
- struct asocket *s = get_socketData(env, obj);
-
- if (!s)
- return NULL;
-
- type = env->GetIntField(obj, field_mType);
-
- switch (type) {
- case TYPE_RFCOMM:
- struct sockaddr_rc addr_rc;
- addr = (struct sockaddr *)&addr_rc;
- addr_sz = sizeof(addr_rc);
- bdaddr = &addr_rc.rc_bdaddr;
- memset(addr, 0, addr_sz);
- break;
- case TYPE_SCO:
- struct sockaddr_sco addr_sco;
- addr = (struct sockaddr *)&addr_sco;
- addr_sz = sizeof(addr_sco);
- bdaddr = &addr_sco.sco_bdaddr;
- memset(addr, 0, addr_sz);
- break;
- case TYPE_L2CAP:
- struct sockaddr_l2 addr_l2;
- addr = (struct sockaddr *)&addr_l2;
- addr_sz = sizeof(addr_l2);
- bdaddr = &addr_l2.l2_bdaddr;
- memset(addr, 0, addr_sz);
- break;
- default:
- jniThrowIOException(env, ENOSYS);
- return NULL;
- }
-
- fd = asocket_accept(s, addr, &addr_sz, timeout);
-
- ALOGV("...accept(%d, %s) = %d (errno %d)",
- s->fd, TYPE_AS_STR(type), fd, errno);
-
- if (fd < 0) {
- jniThrowIOException(env, errno);
- return NULL;
- }
-
- /* Connected - return new BluetoothSocket */
- auth = env->GetBooleanField(obj, field_mAuth);
- encrypt = env->GetBooleanField(obj, field_mEncrypt);
-
- get_bdaddr_as_string(bdaddr, addr_cstr);
-
- addr_jstr = env->NewStringUTF(addr_cstr);
- return env->NewObject(class_BluetoothSocket, method_BluetoothSocket_ctor,
- type, fd, auth, encrypt, addr_jstr, -1);
-
-#endif
- jniThrowIOException(env, ENOSYS);
- return NULL;
-}
-
-static jint availableNative(JNIEnv *env, jobject obj) {
-#ifdef HAVE_BLUETOOTH
- ALOGV("%s", __FUNCTION__);
-
- int available;
- struct asocket *s = get_socketData(env, obj);
-
- if (!s)
- return -1;
-
- if (ioctl(s->fd, FIONREAD, &available) < 0) {
- jniThrowIOException(env, errno);
- return -1;
- }
-
- return available;
-
-#endif
- jniThrowIOException(env, ENOSYS);
- return -1;
-}
-
-static jint readNative(JNIEnv *env, jobject obj, jbyteArray jb, jint offset,
- jint length) {
-#ifdef HAVE_BLUETOOTH
- ALOGV("%s", __FUNCTION__);
-
- int ret;
- jbyte *b;
- int sz;
- struct asocket *s = get_socketData(env, obj);
-
- if (!s)
- return -1;
- if (jb == NULL) {
- jniThrowIOException(env, EINVAL);
- return -1;
- }
- sz = env->GetArrayLength(jb);
- if (offset < 0 || length < 0 || offset + length > sz) {
- jniThrowIOException(env, EINVAL);
- return -1;
- }
-
- b = env->GetByteArrayElements(jb, NULL);
- if (b == NULL) {
- jniThrowIOException(env, EINVAL);
- return -1;
- }
-
- ret = asocket_read(s, &b[offset], length, -1);
- if (ret < 0) {
- jniThrowIOException(env, errno);
- env->ReleaseByteArrayElements(jb, b, JNI_ABORT);
- return -1;
- }
-
- env->ReleaseByteArrayElements(jb, b, 0);
- return (jint)ret;
-
-#endif
- jniThrowIOException(env, ENOSYS);
- return -1;
-}
-
-static jint writeNative(JNIEnv *env, jobject obj, jbyteArray jb, jint offset,
- jint length) {
-#ifdef HAVE_BLUETOOTH
- ALOGV("%s", __FUNCTION__);
-
- int ret, total;
- jbyte *b;
- int sz;
- struct asocket *s = get_socketData(env, obj);
-
- if (!s)
- return -1;
- if (jb == NULL) {
- jniThrowIOException(env, EINVAL);
- return -1;
- }
- sz = env->GetArrayLength(jb);
- if (offset < 0 || length < 0 || offset + length > sz) {
- jniThrowIOException(env, EINVAL);
- return -1;
- }
-
- b = env->GetByteArrayElements(jb, NULL);
- if (b == NULL) {
- jniThrowIOException(env, EINVAL);
- return -1;
- }
-
- total = 0;
- while (length > 0) {
- ret = asocket_write(s, &b[offset], length, -1);
- if (ret < 0) {
- jniThrowIOException(env, errno);
- env->ReleaseByteArrayElements(jb, b, JNI_ABORT);
- return -1;
- }
- offset += ret;
- total += ret;
- length -= ret;
- }
-
- env->ReleaseByteArrayElements(jb, b, JNI_ABORT); // no need to commit
- return (jint)total;
-
-#endif
- jniThrowIOException(env, ENOSYS);
- return -1;
-}
-
-static void abortNative(JNIEnv *env, jobject obj) {
-#ifdef HAVE_BLUETOOTH
- ALOGV("%s", __FUNCTION__);
- struct asocket *s = get_socketData(env, obj);
-
- if (!s)
- return;
-
- asocket_abort(s);
-
- ALOGV("...asocket_abort(%d) complete", s->fd);
- return;
-#endif
- jniThrowIOException(env, ENOSYS);
-}
-
-static void destroyNative(JNIEnv *env, jobject obj) {
-#ifdef HAVE_BLUETOOTH
- ALOGV("%s", __FUNCTION__);
- struct asocket *s = get_socketData(env, obj);
- int fd = s->fd;
-
- if (!s)
- return;
-
- asocket_destroy(s);
-
- ALOGV("...asocket_destroy(%d) complete", fd);
- return;
-#endif
- jniThrowIOException(env, ENOSYS);
-}
-
-static void throwErrnoNative(JNIEnv *env, jobject obj, jint err) {
- jniThrowIOException(env, err);
-}
-
-static JNINativeMethod sMethods[] = {
- {"initSocketNative", "()V", (void*) initSocketNative},
- {"initSocketFromFdNative", "(I)V", (void*) initSocketFromFdNative},
- {"connectNative", "()V", (void *) connectNative},
- {"bindListenNative", "()I", (void *) bindListenNative},
- {"acceptNative", "(I)Landroid/bluetooth/BluetoothSocket;", (void *) acceptNative},
- {"availableNative", "()I", (void *) availableNative},
- {"readNative", "([BII)I", (void *) readNative},
- {"writeNative", "([BII)I", (void *) writeNative},
- {"abortNative", "()V", (void *) abortNative},
- {"destroyNative", "()V", (void *) destroyNative},
- {"throwErrnoNative", "(I)V", (void *) throwErrnoNative},
-};
-
-int register_android_bluetooth_BluetoothSocket(JNIEnv *env) {
- jclass clazz = env->FindClass("android/bluetooth/BluetoothSocket");
- if (clazz == NULL)
- return -1;
- class_BluetoothSocket = (jclass) env->NewGlobalRef(clazz);
- field_mType = env->GetFieldID(clazz, "mType", "I");
- field_mAddress = env->GetFieldID(clazz, "mAddress", "Ljava/lang/String;");
- field_mPort = env->GetFieldID(clazz, "mPort", "I");
- field_mAuth = env->GetFieldID(clazz, "mAuth", "Z");
- field_mEncrypt = env->GetFieldID(clazz, "mEncrypt", "Z");
- field_mSocketData = env->GetFieldID(clazz, "mSocketData", "I");
- method_BluetoothSocket_ctor = env->GetMethodID(clazz, "<init>", "(IIZZLjava/lang/String;I)V");
- return AndroidRuntime::registerNativeMethods(env,
- "android/bluetooth/BluetoothSocket", sMethods, NELEM(sMethods));
-}
-
-} /* namespace android */
-
diff --git a/core/jni/android_bluetooth_HeadsetBase.cpp b/core/jni/android_bluetooth_HeadsetBase.cpp
deleted file mode 100644
index 34447ef..0000000
--- a/core/jni/android_bluetooth_HeadsetBase.cpp
+++ /dev/null
@@ -1,567 +0,0 @@
-/*
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#define LOG_TAG "BT HSHFP"
-
-#include "android_bluetooth_common.h"
-#include "android_runtime/AndroidRuntime.h"
-#include "JNIHelp.h"
-#include "jni.h"
-#include "utils/Log.h"
-#include "utils/misc.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-#include <sys/poll.h>
-
-#ifdef HAVE_BLUETOOTH
-#include <bluetooth/bluetooth.h>
-#include <bluetooth/rfcomm.h>
-#include <bluetooth/sco.h>
-#endif
-
-namespace android {
-
-#ifdef HAVE_BLUETOOTH
-static jfieldID field_mNativeData;
-static jfieldID field_mAddress;
-static jfieldID field_mRfcommChannel;
-static jfieldID field_mTimeoutRemainingMs;
-
-typedef struct {
- jstring address;
- const char *c_address;
- int rfcomm_channel;
- int last_read_err;
- int rfcomm_sock;
- int rfcomm_connected; // -1 in progress, 0 not connected, 1 connected
- int rfcomm_sock_flags;
-} native_data_t;
-
-static inline native_data_t * get_native_data(JNIEnv *env, jobject object) {
- return (native_data_t *)(env->GetIntField(object, field_mNativeData));
-}
-
-static const char CRLF[] = "\xd\xa";
-static const int CRLF_LEN = 2;
-
-static inline int write_error_check(int fd, const char* line, int len) {
- int ret;
- errno = 0;
- ret = write(fd, line, len);
- if (ret < 0) {
- ALOGE("%s: write() failed: %s (%d)", __FUNCTION__, strerror(errno),
- errno);
- return -1;
- }
- if (ret != len) {
- ALOGE("%s: write() only wrote %d of %d bytes", __FUNCTION__, ret, len);
- return -1;
- }
- return 0;
-}
-
-static int send_line(int fd, const char* line) {
- int nw;
- int len = strlen(line);
- int llen = len + CRLF_LEN * 2 + 1;
- char *buffer = (char *)calloc(llen, sizeof(char));
-
- snprintf(buffer, llen, "%s%s%s", CRLF, line, CRLF);
-
- if (write_error_check(fd, buffer, llen - 1)) {
- free(buffer);
- return -1;
- }
- free(buffer);
- return 0;
-}
-
-static void mask_eighth_bit(char *line)
-{
- for (;;line++) {
- if (0 == *line) return;
- *line &= 0x7F;
- }
-}
-
-static const char* get_line(int fd, char *buf, int len, int timeout_ms,
- int *err) {
- char *bufit=buf;
- int fd_flags = fcntl(fd, F_GETFL, 0);
- struct pollfd pfd;
-
-again:
- *bufit = 0;
- pfd.fd = fd;
- pfd.events = POLLIN;
- *err = errno = 0;
- int ret = TEMP_FAILURE_RETRY(poll(&pfd, 1, timeout_ms));
- if (ret < 0) {
- ALOGE("poll() error\n");
- *err = errno;
- return NULL;
- }
- if (ret == 0) {
- return NULL;
- }
-
- if (pfd.revents & (POLLHUP | POLLERR | POLLNVAL)) {
- ALOGW("RFCOMM poll() returned success (%d), "
- "but with an unexpected revents bitmask: %#x\n", ret, pfd.revents);
- errno = EIO;
- *err = errno;
- return NULL;
- }
-
- while ((int)(bufit - buf) < (len - 1))
- {
- errno = 0;
- int rc = TEMP_FAILURE_RETRY(read(fd, bufit, 1));
-
- if (!rc)
- break;
-
- if (rc < 0) {
- if (errno == EBUSY) {
- ALOGI("read() error %s (%d): repeating read()...",
- strerror(errno), errno);
- goto again;
- }
- *err = errno;
- ALOGE("read() error %s (%d)", strerror(errno), errno);
- return NULL;
- }
-
-
- if (*bufit=='\xd') {
- break;
- }
-
- if (*bufit=='\xa')
- bufit = buf;
- else
- bufit++;
- }
-
- *bufit = 0;
-
- // According to ITU V.250 section 5.1, IA5 7 bit chars are used,
- // the eighth bit or higher bits are ignored if they exists
- // We mask out only eighth bit, no higher bit, since we do char
- // string here, not wide char.
- // We added this processing due to 2 real world problems.
- // 1 BMW 2005 E46 which sends binary junk
- // 2 Audi 2010 A3, dial command use 0xAD (soft-hyphen) as number
- // formater, which was rejected by the AT handler
- mask_eighth_bit(buf);
-
- return buf;
-}
-#endif
-
-static void classInitNative(JNIEnv* env, jclass clazz) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- field_mNativeData = get_field(env, clazz, "mNativeData", "I");
- field_mAddress = get_field(env, clazz, "mAddress", "Ljava/lang/String;");
- field_mTimeoutRemainingMs = get_field(env, clazz, "mTimeoutRemainingMs", "I");
- field_mRfcommChannel = get_field(env, clazz, "mRfcommChannel", "I");
-#endif
-}
-
-static void initializeNativeDataNative(JNIEnv* env, jobject object,
- jint socketFd) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- native_data_t *nat = (native_data_t *)calloc(1, sizeof(native_data_t));
- if (NULL == nat) {
- ALOGE("%s: out of memory!", __FUNCTION__);
- return;
- }
-
- env->SetIntField(object, field_mNativeData, (jint)nat);
- nat->address =
- (jstring)env->NewGlobalRef(env->GetObjectField(object,
- field_mAddress));
- nat->c_address = env->GetStringUTFChars(nat->address, NULL);
- nat->rfcomm_channel = env->GetIntField(object, field_mRfcommChannel);
- nat->rfcomm_sock = socketFd;
- nat->rfcomm_connected = socketFd >= 0;
- if (nat->rfcomm_connected)
- ALOGI("%s: ALREADY CONNECTED!", __FUNCTION__);
-#endif
-}
-
-static void cleanupNativeDataNative(JNIEnv* env, jobject object) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- native_data_t *nat =
- (native_data_t *)env->GetIntField(object, field_mNativeData);
- env->ReleaseStringUTFChars(nat->address, nat->c_address);
- env->DeleteGlobalRef(nat->address);
- if (nat)
- free(nat);
-#endif
-}
-
-static jboolean connectNative(JNIEnv *env, jobject obj)
-{
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- int lm;
- struct sockaddr_rc addr;
- native_data_t *nat = get_native_data(env, obj);
-
- nat->rfcomm_sock = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
-
- if (nat->rfcomm_sock < 0) {
- ALOGE("%s: Could not create RFCOMM socket: %s\n", __FUNCTION__,
- strerror(errno));
- return JNI_FALSE;
- }
-
- if (debug_no_encrypt()) {
- lm = RFCOMM_LM_AUTH;
- } else {
- lm = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT;
- }
-
- if (lm && setsockopt(nat->rfcomm_sock, SOL_RFCOMM, RFCOMM_LM, &lm,
- sizeof(lm)) < 0) {
- ALOGE("%s: Can't set RFCOMM link mode", __FUNCTION__);
- close(nat->rfcomm_sock);
- return JNI_FALSE;
- }
-
- memset(&addr, 0, sizeof(struct sockaddr_rc));
- get_bdaddr(nat->c_address, &addr.rc_bdaddr);
- addr.rc_channel = nat->rfcomm_channel;
- addr.rc_family = AF_BLUETOOTH;
- nat->rfcomm_connected = 0;
- while (nat->rfcomm_connected == 0) {
- if (connect(nat->rfcomm_sock, (struct sockaddr *)&addr,
- sizeof(addr)) < 0) {
- if (errno == EINTR) continue;
- ALOGE("%s: connect() failed: %s\n", __FUNCTION__, strerror(errno));
- close(nat->rfcomm_sock);
- nat->rfcomm_sock = -1;
- return JNI_FALSE;
- } else {
- nat->rfcomm_connected = 1;
- }
- }
-
- return JNI_TRUE;
-#else
- return JNI_FALSE;
-#endif
-}
-
-static jint connectAsyncNative(JNIEnv *env, jobject obj) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- struct sockaddr_rc addr;
- native_data_t *nat = get_native_data(env, obj);
-
- if (nat->rfcomm_connected) {
- ALOGV("RFCOMM socket is already connected or connection is in progress.");
- return 0;
- }
-
- if (nat->rfcomm_sock < 0) {
- int lm;
-
- nat->rfcomm_sock = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
- if (nat->rfcomm_sock < 0) {
- ALOGE("%s: Could not create RFCOMM socket: %s\n", __FUNCTION__,
- strerror(errno));
- return -1;
- }
-
- if (debug_no_encrypt()) {
- lm = RFCOMM_LM_AUTH;
- } else {
- lm = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT;
- }
-
- if (lm && setsockopt(nat->rfcomm_sock, SOL_RFCOMM, RFCOMM_LM, &lm,
- sizeof(lm)) < 0) {
- ALOGE("%s: Can't set RFCOMM link mode", __FUNCTION__);
- close(nat->rfcomm_sock);
- return -1;
- }
- ALOGI("Created RFCOMM socket fd %d.", nat->rfcomm_sock);
- }
-
- memset(&addr, 0, sizeof(struct sockaddr_rc));
- get_bdaddr(nat->c_address, &addr.rc_bdaddr);
- addr.rc_channel = nat->rfcomm_channel;
- addr.rc_family = AF_BLUETOOTH;
- if (nat->rfcomm_sock_flags >= 0) {
- nat->rfcomm_sock_flags = fcntl(nat->rfcomm_sock, F_GETFL, 0);
- if (fcntl(nat->rfcomm_sock,
- F_SETFL, nat->rfcomm_sock_flags | O_NONBLOCK) >= 0) {
- int rc;
- nat->rfcomm_connected = 0;
- errno = 0;
- rc = connect(nat->rfcomm_sock,
- (struct sockaddr *)&addr,
- sizeof(addr));
-
- if (rc >= 0) {
- nat->rfcomm_connected = 1;
- ALOGI("async connect successful");
- return 0;
- }
- else if (rc < 0) {
- if (errno == EINPROGRESS || errno == EAGAIN)
- {
- ALOGI("async connect is in progress (%s)",
- strerror(errno));
- nat->rfcomm_connected = -1;
- return 0;
- }
- else
- {
- ALOGE("async connect error: %s (%d)", strerror(errno), errno);
- close(nat->rfcomm_sock);
- nat->rfcomm_sock = -1;
- return -errno;
- }
- }
- } // fcntl(nat->rfcomm_sock ...)
- } // if (nat->rfcomm_sock_flags >= 0)
-#endif
- return -1;
-}
-
-static jint waitForAsyncConnectNative(JNIEnv *env, jobject obj,
- jint timeout_ms) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- struct sockaddr_rc addr;
- native_data_t *nat = get_native_data(env, obj);
-
- env->SetIntField(obj, field_mTimeoutRemainingMs, timeout_ms);
-
- if (nat->rfcomm_connected > 0) {
- ALOGI("RFCOMM is already connected!");
- return 1;
- }
-
- if (nat->rfcomm_sock >= 0 && nat->rfcomm_connected == 0) {
- ALOGI("Re-opening RFCOMM socket.");
- close(nat->rfcomm_sock);
- nat->rfcomm_sock = -1;
- }
- int ret = connectAsyncNative(env, obj);
-
- if (ret < 0) {
- ALOGI("Failed to re-open RFCOMM socket!");
- return ret;
- }
-
- if (nat->rfcomm_sock >= 0) {
- /* Do an asynchronous select() */
- int n;
- fd_set rset, wset;
- struct timeval to;
-
- FD_ZERO(&rset);
- FD_ZERO(&wset);
- FD_SET(nat->rfcomm_sock, &rset);
- FD_SET(nat->rfcomm_sock, &wset);
- if (timeout_ms >= 0) {
- to.tv_sec = timeout_ms / 1000;
- to.tv_usec = 1000 * (timeout_ms % 1000);
- }
- n = select(nat->rfcomm_sock + 1,
- &rset,
- &wset,
- NULL,
- (timeout_ms < 0 ? NULL : &to));
-
- if (timeout_ms > 0) {
- jint remaining = to.tv_sec*1000 + to.tv_usec/1000;
- ALOGV("Remaining time %ldms", (long)remaining);
- env->SetIntField(obj, field_mTimeoutRemainingMs,
- remaining);
- }
-
- if (n <= 0) {
- if (n < 0) {
- ALOGE("select() on RFCOMM socket: %s (%d)",
- strerror(errno),
- errno);
- return -errno;
- }
- return 0;
- }
- /* n must be equal to 1 and either rset or wset must have the
- file descriptor set. */
- ALOGV("select() returned %d.", n);
- if (FD_ISSET(nat->rfcomm_sock, &rset) ||
- FD_ISSET(nat->rfcomm_sock, &wset))
- {
- /* A trial async read() will tell us if everything is OK. */
- {
- char ch;
- errno = 0;
- int nr = TEMP_FAILURE_RETRY(read(nat->rfcomm_sock, &ch, 1));
- /* It should be that nr != 1 because we just opened a socket
- and we haven't sent anything over it for the other side to
- respond... but one can't be paranoid enough.
- */
- if (nr >= 0 || errno != EAGAIN) {
- ALOGE("RFCOMM async connect() error: %s (%d), nr = %d\n",
- strerror(errno),
- errno,
- nr);
- /* Clear the rfcomm_connected flag to cause this function
- to re-create the socket and re-attempt the connect()
- the next time it is called.
- */
- nat->rfcomm_connected = 0;
- /* Restore the blocking properties of the socket. */
- fcntl(nat->rfcomm_sock, F_SETFL, nat->rfcomm_sock_flags);
- close(nat->rfcomm_sock);
- nat->rfcomm_sock = -1;
- return -errno;
- }
- }
- /* Restore the blocking properties of the socket. */
- fcntl(nat->rfcomm_sock, F_SETFL, nat->rfcomm_sock_flags);
- ALOGI("Successful RFCOMM socket connect.");
- nat->rfcomm_connected = 1;
- return 1;
- }
- }
- else ALOGE("RFCOMM socket file descriptor %d is bad!",
- nat->rfcomm_sock);
-#endif
- return -1;
-}
-
-static void disconnectNative(JNIEnv *env, jobject obj) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- native_data_t *nat = get_native_data(env, obj);
- if (nat->rfcomm_sock >= 0) {
- close(nat->rfcomm_sock);
- nat->rfcomm_sock = -1;
- nat->rfcomm_connected = 0;
- }
-#endif
-}
-
-static void pretty_log_urc(const char *urc) {
- size_t i;
- bool in_line_break = false;
- char *buf = (char *)calloc(strlen(urc) + 1, sizeof(char));
-
- strcpy(buf, urc);
- for (i = 0; i < strlen(buf); i++) {
- switch(buf[i]) {
- case '\r':
- case '\n':
- in_line_break = true;
- buf[i] = ' ';
- break;
- default:
- if (in_line_break) {
- in_line_break = false;
- buf[i-1] = '\n';
- }
- }
- }
- IF_ALOGV() ALOG(LOG_VERBOSE, "Bluetooth AT sent", "%s", buf);
-
- free(buf);
-}
-
-static jboolean sendURCNative(JNIEnv *env, jobject obj, jstring urc) {
-#ifdef HAVE_BLUETOOTH
- native_data_t *nat = get_native_data(env, obj);
- if (nat->rfcomm_connected) {
- const char *c_urc = env->GetStringUTFChars(urc, NULL);
- jboolean ret = send_line(nat->rfcomm_sock, c_urc) == 0 ? JNI_TRUE : JNI_FALSE;
- if (ret == JNI_TRUE) pretty_log_urc(c_urc);
- env->ReleaseStringUTFChars(urc, c_urc);
- return ret;
- }
-#endif
- return JNI_FALSE;
-}
-
-static jstring readNative(JNIEnv *env, jobject obj, jint timeout_ms) {
-#ifdef HAVE_BLUETOOTH
- {
- native_data_t *nat = get_native_data(env, obj);
- if (nat->rfcomm_connected) {
- char buf[256];
- const char *ret = get_line(nat->rfcomm_sock,
- buf, sizeof(buf),
- timeout_ms,
- &nat->last_read_err);
- return ret ? env->NewStringUTF(ret) : NULL;
- }
- return NULL;
- }
-#else
- return NULL;
-#endif
-}
-
-static jint getLastReadStatusNative(JNIEnv *env, jobject obj) {
-#ifdef HAVE_BLUETOOTH
- {
- native_data_t *nat = get_native_data(env, obj);
- if (nat->rfcomm_connected)
- return (jint)nat->last_read_err;
- return 0;
- }
-#else
- return 0;
-#endif
-}
-
-static JNINativeMethod sMethods[] = {
- /* name, signature, funcPtr */
- {"classInitNative", "()V", (void*)classInitNative},
- {"initializeNativeDataNative", "(I)V", (void *)initializeNativeDataNative},
- {"cleanupNativeDataNative", "()V", (void *)cleanupNativeDataNative},
- {"connectNative", "()Z", (void *)connectNative},
- {"connectAsyncNative", "()I", (void *)connectAsyncNative},
- {"waitForAsyncConnectNative", "(I)I", (void *)waitForAsyncConnectNative},
- {"disconnectNative", "()V", (void *)disconnectNative},
- {"sendURCNative", "(Ljava/lang/String;)Z", (void *)sendURCNative},
- {"readNative", "(I)Ljava/lang/String;", (void *)readNative},
- {"getLastReadStatusNative", "()I", (void *)getLastReadStatusNative},
-};
-
-int register_android_bluetooth_HeadsetBase(JNIEnv *env) {
- return AndroidRuntime::registerNativeMethods(env,
- "android/bluetooth/HeadsetBase", sMethods, NELEM(sMethods));
-}
-
-} /* namespace android */
diff --git a/core/jni/android_bluetooth_c.c b/core/jni/android_bluetooth_c.c
deleted file mode 100644
index b4c6727..0000000
--- a/core/jni/android_bluetooth_c.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
-** Copyright 2011, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#ifdef HAVE_BLUETOOTH
-
-#include "android_bluetooth_c.h"
-
-/*
- * A C helper for creating a bdaddr_t object with the value BDADDR_ANY.
- * We have to do this in C because the macro BDADDR_ANY in bluetooth.h
- * is not valid C++ code.
- */
-bdaddr_t android_bluetooth_bdaddr_any(void)
-{
- bdaddr_t any = *BDADDR_ANY;
- return any;
-}
-#endif
diff --git a/core/jni/android_bluetooth_c.h b/core/jni/android_bluetooth_c.h
deleted file mode 100644
index e890244..0000000
--- a/core/jni/android_bluetooth_c.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
-** Copyright 2010, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#ifndef ANDROID_BLUETOOTH_C_H
-#define ANDROID_BLUETOOTH_C_H
-#ifdef HAVE_BLUETOOTH
-
-#include <bluetooth/bluetooth.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * A C helper for creating a bdaddr_t object with the value BDADDR_ANY.
- * We have to do this in C because the macro BDADDR_ANY in bluetooth.h
- * is not valid C++ code.
- */
-bdaddr_t android_bluetooth_bdaddr_any(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /*HAVE_BLUETOOTH*/
-#endif /*ANDROID_BLUETOOTH_C_H*/
diff --git a/core/jni/android_bluetooth_common.cpp b/core/jni/android_bluetooth_common.cpp
deleted file mode 100644
index 5cdaa6c..0000000
--- a/core/jni/android_bluetooth_common.cpp
+++ /dev/null
@@ -1,867 +0,0 @@
-/*
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#define LOG_TAG "bluetooth_common.cpp"
-
-#include "android_bluetooth_common.h"
-#include "JNIHelp.h"
-#include "jni.h"
-#include "utils/Log.h"
-#include "utils/misc.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-#include <cutils/properties.h>
-
-#ifdef HAVE_BLUETOOTH
-#include <dbus/dbus.h>
-#endif
-
-namespace android {
-
-#ifdef HAVE_BLUETOOTH
-
-static Properties remote_device_properties[] = {
- {"Address", DBUS_TYPE_STRING},
- {"Name", DBUS_TYPE_STRING},
- {"Icon", DBUS_TYPE_STRING},
- {"Class", DBUS_TYPE_UINT32},
- {"UUIDs", DBUS_TYPE_ARRAY},
- {"Services", DBUS_TYPE_ARRAY},
- {"Paired", DBUS_TYPE_BOOLEAN},
- {"Connected", DBUS_TYPE_BOOLEAN},
- {"Trusted", DBUS_TYPE_BOOLEAN},
- {"Blocked", DBUS_TYPE_BOOLEAN},
- {"Alias", DBUS_TYPE_STRING},
- {"Nodes", DBUS_TYPE_ARRAY},
- {"Adapter", DBUS_TYPE_OBJECT_PATH},
- {"LegacyPairing", DBUS_TYPE_BOOLEAN},
- {"RSSI", DBUS_TYPE_INT16},
- {"TX", DBUS_TYPE_UINT32},
- {"Broadcaster", DBUS_TYPE_BOOLEAN}
-};
-
-static Properties adapter_properties[] = {
- {"Address", DBUS_TYPE_STRING},
- {"Name", DBUS_TYPE_STRING},
- {"Class", DBUS_TYPE_UINT32},
- {"Powered", DBUS_TYPE_BOOLEAN},
- {"Discoverable", DBUS_TYPE_BOOLEAN},
- {"DiscoverableTimeout", DBUS_TYPE_UINT32},
- {"Pairable", DBUS_TYPE_BOOLEAN},
- {"PairableTimeout", DBUS_TYPE_UINT32},
- {"Discovering", DBUS_TYPE_BOOLEAN},
- {"Devices", DBUS_TYPE_ARRAY},
- {"UUIDs", DBUS_TYPE_ARRAY},
-};
-
-static Properties input_properties[] = {
- {"Connected", DBUS_TYPE_BOOLEAN},
-};
-
-static Properties pan_properties[] = {
- {"Connected", DBUS_TYPE_BOOLEAN},
- {"Interface", DBUS_TYPE_STRING},
- {"UUID", DBUS_TYPE_STRING},
-};
-
-static Properties health_device_properties[] = {
- {"MainChannel", DBUS_TYPE_OBJECT_PATH},
-};
-
-static Properties health_channel_properties[] = {
- {"Type", DBUS_TYPE_STRING},
- {"Device", DBUS_TYPE_OBJECT_PATH},
- {"Application", DBUS_TYPE_OBJECT_PATH},
-};
-
-typedef union {
- char *str_val;
- int int_val;
- char **array_val;
-} property_value;
-
-jfieldID get_field(JNIEnv *env, jclass clazz, const char *member,
- const char *mtype) {
- jfieldID field = env->GetFieldID(clazz, member, mtype);
- if (field == NULL) {
- ALOGE("Can't find member %s", member);
- }
- return field;
-}
-
-typedef struct {
- void (*user_cb)(DBusMessage *, void *, void *);
- void *user;
- void *nat;
- JNIEnv *env;
-} dbus_async_call_t;
-
-void dbus_func_args_async_callback(DBusPendingCall *call, void *data) {
-
- dbus_async_call_t *req = (dbus_async_call_t *)data;
- DBusMessage *msg;
-
- /* This is guaranteed to be non-NULL, because this function is called only
- when once the remote method invokation returns. */
- msg = dbus_pending_call_steal_reply(call);
-
- if (msg) {
- if (req->user_cb) {
- // The user may not deref the message object.
- req->user_cb(msg, req->user, req->nat);
- }
- dbus_message_unref(msg);
- }
-
- //dbus_message_unref(req->method);
- dbus_pending_call_cancel(call);
- dbus_pending_call_unref(call);
- free(req);
-}
-
-static dbus_bool_t dbus_func_args_async_valist(JNIEnv *env,
- DBusConnection *conn,
- int timeout_ms,
- void (*user_cb)(DBusMessage *,
- void *,
- void*),
- void *user,
- void *nat,
- const char *path,
- const char *ifc,
- const char *func,
- int first_arg_type,
- va_list args) {
- DBusMessage *msg = NULL;
- const char *name;
- dbus_async_call_t *pending;
- dbus_bool_t reply = FALSE;
-
- /* Compose the command */
- msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC, path, ifc, func);
-
- if (msg == NULL) {
- ALOGE("Could not allocate D-Bus message object!");
- goto done;
- }
-
- /* append arguments */
- if (!dbus_message_append_args_valist(msg, first_arg_type, args)) {
- ALOGE("Could not append argument to method call!");
- goto done;
- }
-
- /* Make the call. */
- pending = (dbus_async_call_t *)malloc(sizeof(dbus_async_call_t));
- if (pending) {
- DBusPendingCall *call;
-
- pending->env = env;
- pending->user_cb = user_cb;
- pending->user = user;
- pending->nat = nat;
- //pending->method = msg;
-
- reply = dbus_connection_send_with_reply(conn, msg,
- &call,
- timeout_ms);
- if (reply == TRUE) {
- dbus_pending_call_set_notify(call,
- dbus_func_args_async_callback,
- pending,
- NULL);
- }
- }
-
-done:
- if (msg) dbus_message_unref(msg);
- return reply;
-}
-
-dbus_bool_t dbus_func_args_async(JNIEnv *env,
- DBusConnection *conn,
- int timeout_ms,
- void (*reply)(DBusMessage *, void *, void*),
- void *user,
- void *nat,
- const char *path,
- const char *ifc,
- const char *func,
- int first_arg_type,
- ...) {
- dbus_bool_t ret;
- va_list lst;
- va_start(lst, first_arg_type);
-
- ret = dbus_func_args_async_valist(env, conn,
- timeout_ms,
- reply, user, nat,
- path, ifc, func,
- first_arg_type, lst);
- va_end(lst);
- return ret;
-}
-
-// If err is NULL, then any errors will be ALOGE'd, and free'd and the reply
-// will be NULL.
-// If err is not NULL, then it is assumed that dbus_error_init was already
-// called, and error's will be returned to the caller without logging. The
-// return value is NULL iff an error was set. The client must free the error if
-// set.
-DBusMessage * dbus_func_args_timeout_valist(JNIEnv *env,
- DBusConnection *conn,
- int timeout_ms,
- DBusError *err,
- const char *path,
- const char *ifc,
- const char *func,
- int first_arg_type,
- va_list args) {
-
- DBusMessage *msg = NULL, *reply = NULL;
- const char *name;
- bool return_error = (err != NULL);
-
- if (!return_error) {
- err = (DBusError*)malloc(sizeof(DBusError));
- dbus_error_init(err);
- }
-
- /* Compose the command */
- msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC, path, ifc, func);
-
- if (msg == NULL) {
- ALOGE("Could not allocate D-Bus message object!");
- goto done;
- }
-
- /* append arguments */
- if (!dbus_message_append_args_valist(msg, first_arg_type, args)) {
- ALOGE("Could not append argument to method call!");
- goto done;
- }
-
- /* Make the call. */
- reply = dbus_connection_send_with_reply_and_block(conn, msg, timeout_ms, err);
- if (!return_error && dbus_error_is_set(err)) {
- LOG_AND_FREE_DBUS_ERROR_WITH_MSG(err, msg);
- }
-
-done:
- if (!return_error) {
- free(err);
- }
- if (msg) dbus_message_unref(msg);
- return reply;
-}
-
-DBusMessage * dbus_func_args_timeout(JNIEnv *env,
- DBusConnection *conn,
- int timeout_ms,
- const char *path,
- const char *ifc,
- const char *func,
- int first_arg_type,
- ...) {
- DBusMessage *ret;
- va_list lst;
- va_start(lst, first_arg_type);
- ret = dbus_func_args_timeout_valist(env, conn, timeout_ms, NULL,
- path, ifc, func,
- first_arg_type, lst);
- va_end(lst);
- return ret;
-}
-
-DBusMessage * dbus_func_args(JNIEnv *env,
- DBusConnection *conn,
- const char *path,
- const char *ifc,
- const char *func,
- int first_arg_type,
- ...) {
- DBusMessage *ret;
- va_list lst;
- va_start(lst, first_arg_type);
- ret = dbus_func_args_timeout_valist(env, conn, -1, NULL,
- path, ifc, func,
- first_arg_type, lst);
- va_end(lst);
- return ret;
-}
-
-DBusMessage * dbus_func_args_error(JNIEnv *env,
- DBusConnection *conn,
- DBusError *err,
- const char *path,
- const char *ifc,
- const char *func,
- int first_arg_type,
- ...) {
- DBusMessage *ret;
- va_list lst;
- va_start(lst, first_arg_type);
- ret = dbus_func_args_timeout_valist(env, conn, -1, err,
- path, ifc, func,
- first_arg_type, lst);
- va_end(lst);
- return ret;
-}
-
-jint dbus_returns_unixfd(JNIEnv *env, DBusMessage *reply) {
-
- DBusError err;
- jint ret = -1;
-
- dbus_error_init(&err);
- if (!dbus_message_get_args(reply, &err,
- DBUS_TYPE_UNIX_FD, &ret,
- DBUS_TYPE_INVALID)) {
- LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, reply);
- }
- dbus_message_unref(reply);
- return ret;
-}
-
-
-jint dbus_returns_int32(JNIEnv *env, DBusMessage *reply) {
-
- DBusError err;
- jint ret = -1;
-
- dbus_error_init(&err);
- if (!dbus_message_get_args(reply, &err,
- DBUS_TYPE_INT32, &ret,
- DBUS_TYPE_INVALID)) {
- LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, reply);
- }
- dbus_message_unref(reply);
- return ret;
-}
-
-jint dbus_returns_uint32(JNIEnv *env, DBusMessage *reply) {
-
- DBusError err;
- jint ret = -1;
-
- dbus_error_init(&err);
- if (!dbus_message_get_args(reply, &err,
- DBUS_TYPE_UINT32, &ret,
- DBUS_TYPE_INVALID)) {
- LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, reply);
- }
- dbus_message_unref(reply);
- return ret;
-}
-
-jstring dbus_returns_string(JNIEnv *env, DBusMessage *reply) {
-
- DBusError err;
- jstring ret = NULL;
- const char *name;
-
- dbus_error_init(&err);
- if (dbus_message_get_args(reply, &err,
- DBUS_TYPE_STRING, &name,
- DBUS_TYPE_INVALID)) {
- ret = env->NewStringUTF(name);
- } else {
- LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, reply);
- }
- dbus_message_unref(reply);
-
- return ret;
-}
-
-jboolean dbus_returns_boolean(JNIEnv *env, DBusMessage *reply) {
- DBusError err;
- jboolean ret = JNI_FALSE;
- dbus_bool_t val = FALSE;
-
- dbus_error_init(&err);
-
- /* Check the return value. */
- if (dbus_message_get_args(reply, &err,
- DBUS_TYPE_BOOLEAN, &val,
- DBUS_TYPE_INVALID)) {
- ret = val == TRUE ? JNI_TRUE : JNI_FALSE;
- } else {
- LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, reply);
- }
-
- dbus_message_unref(reply);
- return ret;
-}
-
-static void set_object_array_element(JNIEnv *env, jobjectArray strArray,
- const char *value, int index) {
- jstring obj;
- obj = env->NewStringUTF(value);
- env->SetObjectArrayElement(strArray, index, obj);
- env->DeleteLocalRef(obj);
-}
-
-jobjectArray dbus_returns_array_of_object_path(JNIEnv *env,
- DBusMessage *reply) {
-
- DBusError err;
- char **list;
- int i, len;
- jobjectArray strArray = NULL;
-
- dbus_error_init(&err);
- if (dbus_message_get_args (reply,
- &err,
- DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH,
- &list, &len,
- DBUS_TYPE_INVALID)) {
- jclass stringClass;
- jstring classNameStr;
-
- stringClass = env->FindClass("java/lang/String");
- strArray = env->NewObjectArray(len, stringClass, NULL);
-
- for (i = 0; i < len; i++)
- set_object_array_element(env, strArray, list[i], i);
- } else {
- LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, reply);
- }
-
- dbus_message_unref(reply);
- return strArray;
-}
-
-jobjectArray dbus_returns_array_of_strings(JNIEnv *env, DBusMessage *reply) {
-
- DBusError err;
- char **list;
- int i, len;
- jobjectArray strArray = NULL;
-
- dbus_error_init(&err);
- if (dbus_message_get_args (reply,
- &err,
- DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
- &list, &len,
- DBUS_TYPE_INVALID)) {
- jclass stringClass;
- jstring classNameStr;
-
- //ALOGV("%s: there are %d elements in string array!", __FUNCTION__, len);
-
- stringClass = env->FindClass("java/lang/String");
- strArray = env->NewObjectArray(len, stringClass, NULL);
-
- for (i = 0; i < len; i++)
- set_object_array_element(env, strArray, list[i], i);
- } else {
- LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, reply);
- }
-
- dbus_message_unref(reply);
- return strArray;
-}
-
-jbyteArray dbus_returns_array_of_bytes(JNIEnv *env, DBusMessage *reply) {
-
- DBusError err;
- int i, len;
- jbyte *list;
- jbyteArray byteArray = NULL;
-
- dbus_error_init(&err);
- if (dbus_message_get_args(reply, &err,
- DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &list, &len,
- DBUS_TYPE_INVALID)) {
- //ALOGV("%s: there are %d elements in byte array!", __FUNCTION__, len);
- byteArray = env->NewByteArray(len);
- if (byteArray)
- env->SetByteArrayRegion(byteArray, 0, len, list);
-
- } else {
- LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, reply);
- }
-
- dbus_message_unref(reply);
- return byteArray;
-}
-
-void append_variant(DBusMessageIter *iter, int type, void *val)
-{
- DBusMessageIter value_iter;
- char var_type[2] = { type, '\0'};
- dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, var_type, &value_iter);
- dbus_message_iter_append_basic(&value_iter, type, val);
- dbus_message_iter_close_container(iter, &value_iter);
-}
-
-static void dict_append_entry(DBusMessageIter *dict,
- const char *key, int type, void *val)
-{
- DBusMessageIter dict_entry;
- dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
- NULL, &dict_entry);
-
- dbus_message_iter_append_basic(&dict_entry, DBUS_TYPE_STRING, &key);
- append_variant(&dict_entry, type, val);
- dbus_message_iter_close_container(dict, &dict_entry);
-}
-
-static void append_dict_valist(DBusMessageIter *iterator, const char *first_key,
- va_list var_args)
-{
- DBusMessageIter dict;
- int val_type;
- const char *val_key;
- void *val;
-
- dbus_message_iter_open_container(iterator, DBUS_TYPE_ARRAY,
- DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
- DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
- DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
-
- val_key = first_key;
- while (val_key) {
- val_type = va_arg(var_args, int);
- val = va_arg(var_args, void *);
- dict_append_entry(&dict, val_key, val_type, val);
- val_key = va_arg(var_args, char *);
- }
-
- dbus_message_iter_close_container(iterator, &dict);
-}
-
-void append_dict_args(DBusMessage *reply, const char *first_key, ...)
-{
- DBusMessageIter iter;
- va_list var_args;
-
- dbus_message_iter_init_append(reply, &iter);
-
- va_start(var_args, first_key);
- append_dict_valist(&iter, first_key, var_args);
- va_end(var_args);
-}
-
-
-int get_property(DBusMessageIter iter, Properties *properties,
- int max_num_properties, int *prop_index, property_value *value, int *len) {
- DBusMessageIter prop_val, array_val_iter;
- char *property = NULL;
- uint32_t array_type;
- char *str_val;
- int i, j, type, int_val;
-
- if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
- return -1;
- dbus_message_iter_get_basic(&iter, &property);
- if (!dbus_message_iter_next(&iter))
- return -1;
- if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
- return -1;
- for (i = 0; i < max_num_properties; i++) {
- if (!strncmp(property, properties[i].name, strlen(property)))
- break;
- }
- *prop_index = i;
- if (i == max_num_properties)
- return -1;
-
- dbus_message_iter_recurse(&iter, &prop_val);
- type = properties[*prop_index].type;
- if (dbus_message_iter_get_arg_type(&prop_val) != type) {
- ALOGE("Property type mismatch in get_property: %d, expected:%d, index:%d",
- dbus_message_iter_get_arg_type(&prop_val), type, *prop_index);
- return -1;
- }
-
- switch(type) {
- case DBUS_TYPE_STRING:
- case DBUS_TYPE_OBJECT_PATH:
- dbus_message_iter_get_basic(&prop_val, &value->str_val);
- *len = 1;
- break;
- case DBUS_TYPE_UINT32:
- case DBUS_TYPE_INT16:
- case DBUS_TYPE_BOOLEAN:
- dbus_message_iter_get_basic(&prop_val, &int_val);
- value->int_val = int_val;
- *len = 1;
- break;
- case DBUS_TYPE_ARRAY:
- dbus_message_iter_recurse(&prop_val, &array_val_iter);
- array_type = dbus_message_iter_get_arg_type(&array_val_iter);
- *len = 0;
- value->array_val = NULL;
- if (array_type == DBUS_TYPE_OBJECT_PATH ||
- array_type == DBUS_TYPE_STRING){
- j = 0;
- do {
- j ++;
- } while(dbus_message_iter_next(&array_val_iter));
- dbus_message_iter_recurse(&prop_val, &array_val_iter);
- // Allocate an array of char *
- *len = j;
- char **tmp = (char **)malloc(sizeof(char *) * *len);
- if (!tmp)
- return -1;
- j = 0;
- do {
- dbus_message_iter_get_basic(&array_val_iter, &tmp[j]);
- j ++;
- } while(dbus_message_iter_next(&array_val_iter));
- value->array_val = tmp;
- }
- break;
- default:
- return -1;
- }
- return 0;
-}
-
-void create_prop_array(JNIEnv *env, jobjectArray strArray, Properties *property,
- property_value *value, int len, int *array_index ) {
- char **prop_val = NULL;
- char buf[32] = {'\0'}, buf1[32] = {'\0'};
- int i;
-
- char *name = property->name;
- int prop_type = property->type;
-
- set_object_array_element(env, strArray, name, *array_index);
- *array_index += 1;
-
- if (prop_type == DBUS_TYPE_UINT32 || prop_type == DBUS_TYPE_INT16) {
- sprintf(buf, "%d", value->int_val);
- set_object_array_element(env, strArray, buf, *array_index);
- *array_index += 1;
- } else if (prop_type == DBUS_TYPE_BOOLEAN) {
- sprintf(buf, "%s", value->int_val ? "true" : "false");
-
- set_object_array_element(env, strArray, buf, *array_index);
- *array_index += 1;
- } else if (prop_type == DBUS_TYPE_ARRAY) {
- // Write the length first
- sprintf(buf1, "%d", len);
- set_object_array_element(env, strArray, buf1, *array_index);
- *array_index += 1;
-
- prop_val = value->array_val;
- for (i = 0; i < len; i++) {
- set_object_array_element(env, strArray, prop_val[i], *array_index);
- *array_index += 1;
- }
- } else {
- set_object_array_element(env, strArray, (const char *) value->str_val, *array_index);
- *array_index += 1;
- }
-}
-
-jobjectArray parse_properties(JNIEnv *env, DBusMessageIter *iter, Properties *properties,
- const int max_num_properties) {
- DBusMessageIter dict_entry, dict;
- jobjectArray strArray = NULL;
- property_value value;
- int i, size = 0,array_index = 0;
- int len = 0, prop_type = DBUS_TYPE_INVALID, prop_index = -1, type;
- struct {
- property_value value;
- int len;
- bool used;
- } values[max_num_properties];
- int t, j;
-
- jclass stringClass = env->FindClass("java/lang/String");
- DBusError err;
- dbus_error_init(&err);
-
- for (i = 0; i < max_num_properties; i++) {
- values[i].used = false;
- }
-
- if(dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
- goto failure;
- dbus_message_iter_recurse(iter, &dict);
- do {
- len = 0;
- if (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_DICT_ENTRY)
- goto failure;
- dbus_message_iter_recurse(&dict, &dict_entry);
-
- if (!get_property(dict_entry, properties, max_num_properties, &prop_index,
- &value, &len)) {
- size += 2;
- if (properties[prop_index].type == DBUS_TYPE_ARRAY)
- size += len;
- values[prop_index].value = value;
- values[prop_index].len = len;
- values[prop_index].used = true;
- } else {
- goto failure;
- }
- } while(dbus_message_iter_next(&dict));
-
- strArray = env->NewObjectArray(size, stringClass, NULL);
-
- for (i = 0; i < max_num_properties; i++) {
- if (values[i].used) {
- create_prop_array(env, strArray, &properties[i], &values[i].value, values[i].len,
- &array_index);
-
- if (properties[i].type == DBUS_TYPE_ARRAY && values[i].used
- && values[i].value.array_val != NULL)
- free(values[i].value.array_val);
- }
-
- }
- return strArray;
-
-failure:
- if (dbus_error_is_set(&err))
- LOG_AND_FREE_DBUS_ERROR(&err);
- for (i = 0; i < max_num_properties; i++)
- if (properties[i].type == DBUS_TYPE_ARRAY && values[i].used == true
- && values[i].value.array_val != NULL)
- free(values[i].value.array_val);
- return NULL;
-}
-
-jobjectArray parse_property_change(JNIEnv *env, DBusMessage *msg,
- Properties *properties, int max_num_properties) {
- DBusMessageIter iter;
- DBusError err;
- jobjectArray strArray = NULL;
- jclass stringClass= env->FindClass("java/lang/String");
- int len = 0, prop_index = -1;
- int array_index = 0, size = 0;
- property_value value;
-
- dbus_error_init(&err);
- if (!dbus_message_iter_init(msg, &iter))
- goto failure;
-
- if (!get_property(iter, properties, max_num_properties,
- &prop_index, &value, &len)) {
- size += 2;
- if (properties[prop_index].type == DBUS_TYPE_ARRAY)
- size += len;
- strArray = env->NewObjectArray(size, stringClass, NULL);
-
- create_prop_array(env, strArray, &properties[prop_index],
- &value, len, &array_index);
-
- if (properties[prop_index].type == DBUS_TYPE_ARRAY && value.array_val != NULL)
- free(value.array_val);
-
- return strArray;
- }
-failure:
- LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
- return NULL;
-}
-
-jobjectArray parse_adapter_property_change(JNIEnv *env, DBusMessage *msg) {
- return parse_property_change(env, msg, (Properties *) &adapter_properties,
- sizeof(adapter_properties) / sizeof(Properties));
-}
-
-jobjectArray parse_remote_device_property_change(JNIEnv *env, DBusMessage *msg) {
- return parse_property_change(env, msg, (Properties *) &remote_device_properties,
- sizeof(remote_device_properties) / sizeof(Properties));
-}
-
-jobjectArray parse_input_property_change(JNIEnv *env, DBusMessage *msg) {
- return parse_property_change(env, msg, (Properties *) &input_properties,
- sizeof(input_properties) / sizeof(Properties));
-}
-
-jobjectArray parse_pan_property_change(JNIEnv *env, DBusMessage *msg) {
- return parse_property_change(env, msg, (Properties *) &pan_properties,
- sizeof(pan_properties) / sizeof(Properties));
-}
-
-jobjectArray parse_adapter_properties(JNIEnv *env, DBusMessageIter *iter) {
- return parse_properties(env, iter, (Properties *) &adapter_properties,
- sizeof(adapter_properties) / sizeof(Properties));
-}
-
-jobjectArray parse_remote_device_properties(JNIEnv *env, DBusMessageIter *iter) {
- return parse_properties(env, iter, (Properties *) &remote_device_properties,
- sizeof(remote_device_properties) / sizeof(Properties));
-}
-
-jobjectArray parse_input_properties(JNIEnv *env, DBusMessageIter *iter) {
- return parse_properties(env, iter, (Properties *) &input_properties,
- sizeof(input_properties) / sizeof(Properties));
-}
-
-jobjectArray parse_health_device_properties(JNIEnv *env, DBusMessageIter *iter) {
- return parse_properties(env, iter, (Properties *) &health_device_properties,
- sizeof(health_device_properties) / sizeof(Properties));
-}
-
-jobjectArray parse_health_device_property_change(JNIEnv *env, DBusMessage *msg) {
- return parse_property_change(env, msg, (Properties *) &health_device_properties,
- sizeof(health_device_properties) / sizeof(Properties));
-}
-
-jobjectArray parse_health_channel_properties(JNIEnv *env, DBusMessageIter *iter) {
- return parse_properties(env, iter, (Properties *) &health_channel_properties,
- sizeof(health_channel_properties) / sizeof(Properties));
-}
-
-int get_bdaddr(const char *str, bdaddr_t *ba) {
- char *d = ((char *)ba) + 5, *endp;
- int i;
- for(i = 0; i < 6; i++) {
- *d-- = strtol(str, &endp, 16);
- if (*endp != ':' && i != 5) {
- memset(ba, 0, sizeof(bdaddr_t));
- return -1;
- }
- str = endp + 1;
- }
- return 0;
-}
-
-void get_bdaddr_as_string(const bdaddr_t *ba, char *str) {
- const uint8_t *b = (const uint8_t *)ba;
- sprintf(str, "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
- b[5], b[4], b[3], b[2], b[1], b[0]);
-}
-
-bool debug_no_encrypt() {
- return false;
-#if 0
- char value[PROPERTY_VALUE_MAX] = "";
-
- property_get("debug.bt.no_encrypt", value, "");
- if (!strncmp("true", value, PROPERTY_VALUE_MAX) ||
- !strncmp("1", value, PROPERTY_VALUE_MAX)) {
- ALOGD("mandatory bluetooth encryption disabled");
- return true;
- } else {
- return false;
- }
-#endif
-}
-#endif
-
-} /* namespace android */
diff --git a/core/jni/android_bluetooth_common.h b/core/jni/android_bluetooth_common.h
deleted file mode 100644
index daf4bb2..0000000
--- a/core/jni/android_bluetooth_common.h
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#ifndef ANDROID_BLUETOOTH_COMMON_H
-#define ANDROID_BLUETOOTH_COMMON_H
-
-// Set to 0 to enable verbose bluetooth logging
-#define LOG_NDEBUG 1
-
-#include "jni.h"
-#include "utils/Log.h"
-
-#include <errno.h>
-#include <pthread.h>
-#include <stdint.h>
-#include <sys/poll.h>
-
-#ifdef HAVE_BLUETOOTH
-#include <dbus/dbus.h>
-#include <bluetooth/bluetooth.h>
-#endif
-
-namespace android {
-
-#ifdef HAVE_BLUETOOTH
-#define BLUEZ_DBUS_BASE_PATH "/org/bluez"
-#define BLUEZ_DBUS_BASE_IFC "org.bluez"
-#define BLUEZ_ERROR_IFC "org.bluez.Error"
-
-// It would be nicer to retrieve this from bluez using GetDefaultAdapter,
-// but this is only possible when the adapter is up (and hcid is running).
-// It is much easier just to hardcode bluetooth adapter to hci0
-#define BLUETOOTH_ADAPTER_HCI_NUM 0
-#define BLUEZ_ADAPTER_OBJECT_NAME BLUEZ_DBUS_BASE_PATH "/hci0"
-
-#define BTADDR_SIZE 18 // size of BT address character array (including null)
-
-// size of the dbus event loops pollfd structure, hopefully never to be grown
-#define DEFAULT_INITIAL_POLLFD_COUNT 8
-
-jfieldID get_field(JNIEnv *env,
- jclass clazz,
- const char *member,
- const char *mtype);
-
-// ALOGE and free a D-Bus error
-// Using #define so that __FUNCTION__ resolves usefully
-#define LOG_AND_FREE_DBUS_ERROR_WITH_MSG(err, msg) \
- { ALOGE("%s: D-Bus error in %s: %s (%s)", __FUNCTION__, \
- dbus_message_get_member((msg)), (err)->name, (err)->message); \
- dbus_error_free((err)); }
-#define LOG_AND_FREE_DBUS_ERROR(err) \
- { ALOGE("%s: D-Bus error: %s (%s)", __FUNCTION__, \
- (err)->name, (err)->message); \
- dbus_error_free((err)); }
-
-struct event_loop_native_data_t {
- DBusConnection *conn;
- const char *adapter;
-
- /* protects the thread */
- pthread_mutex_t thread_mutex;
- pthread_t thread;
- /* our comms socket */
- /* mem for the list of sockets to listen to */
- struct pollfd *pollData;
- int pollMemberCount;
- int pollDataSize;
- /* mem for matching set of dbus watch ptrs */
- DBusWatch **watchData;
- /* pair of sockets for event loop control, Reader and Writer */
- int controlFdR;
- int controlFdW;
- /* our vm and env Version for future env generation */
- JavaVM *vm;
- int envVer;
- /* reference to our java self */
- jobject me;
- /* flag to indicate if the event loop thread is running */
- bool running;
-};
-
-struct _Properties {
- char name[32];
- int type;
-};
-typedef struct _Properties Properties;
-
-dbus_bool_t dbus_func_args_async(JNIEnv *env,
- DBusConnection *conn,
- int timeout_ms,
- void (*reply)(DBusMessage *, void *, void *),
- void *user,
- void *nat,
- const char *path,
- const char *ifc,
- const char *func,
- int first_arg_type,
- ...);
-
-DBusMessage * dbus_func_args(JNIEnv *env,
- DBusConnection *conn,
- const char *path,
- const char *ifc,
- const char *func,
- int first_arg_type,
- ...);
-
-DBusMessage * dbus_func_args_error(JNIEnv *env,
- DBusConnection *conn,
- DBusError *err,
- const char *path,
- const char *ifc,
- const char *func,
- int first_arg_type,
- ...);
-
-DBusMessage * dbus_func_args_timeout(JNIEnv *env,
- DBusConnection *conn,
- int timeout_ms,
- const char *path,
- const char *ifc,
- const char *func,
- int first_arg_type,
- ...);
-
-DBusMessage * dbus_func_args_timeout_valist(JNIEnv *env,
- DBusConnection *conn,
- int timeout_ms,
- DBusError *err,
- const char *path,
- const char *ifc,
- const char *func,
- int first_arg_type,
- va_list args);
-
-jint dbus_returns_int32(JNIEnv *env, DBusMessage *reply);
-jint dbus_returns_uint32(JNIEnv *env, DBusMessage *reply);
-jint dbus_returns_unixfd(JNIEnv *env, DBusMessage *reply);
-jstring dbus_returns_string(JNIEnv *env, DBusMessage *reply);
-jboolean dbus_returns_boolean(JNIEnv *env, DBusMessage *reply);
-jobjectArray dbus_returns_array_of_strings(JNIEnv *env, DBusMessage *reply);
-jobjectArray dbus_returns_array_of_object_path(JNIEnv *env, DBusMessage *reply);
-jbyteArray dbus_returns_array_of_bytes(JNIEnv *env, DBusMessage *reply);
-
-jobjectArray parse_properties(JNIEnv *env, DBusMessageIter *iter, Properties *properties,
- const int max_num_properties);
-jobjectArray parse_property_change(JNIEnv *env, DBusMessage *msg,
- Properties *properties, int max_num_properties);
-jobjectArray parse_adapter_properties(JNIEnv *env, DBusMessageIter *iter);
-jobjectArray parse_remote_device_properties(JNIEnv *env, DBusMessageIter *iter);
-jobjectArray parse_remote_device_property_change(JNIEnv *env, DBusMessage *msg);
-jobjectArray parse_adapter_property_change(JNIEnv *env, DBusMessage *msg);
-jobjectArray parse_input_properties(JNIEnv *env, DBusMessageIter *iter);
-jobjectArray parse_health_device_properties(JNIEnv *env, DBusMessageIter *iter);
-jobjectArray parse_health_channel_properties(JNIEnv *env, DBusMessageIter *iter);
-jobjectArray parse_input_property_change(JNIEnv *env, DBusMessage *msg);
-jobjectArray parse_pan_property_change(JNIEnv *env, DBusMessage *msg);
-jobjectArray parse_health_device_property_change(JNIEnv *env, DBusMessage *msg);
-
-void append_dict_args(DBusMessage *reply, const char *first_key, ...);
-void append_variant(DBusMessageIter *iter, int type, void *val);
-int get_bdaddr(const char *str, bdaddr_t *ba);
-void get_bdaddr_as_string(const bdaddr_t *ba, char *str);
-
-bool debug_no_encrypt();
-
-
-// Result codes from Bluez DBus calls
-#define BOND_RESULT_ERROR -1
-#define BOND_RESULT_SUCCESS 0
-#define BOND_RESULT_AUTH_FAILED 1
-#define BOND_RESULT_AUTH_REJECTED 2
-#define BOND_RESULT_AUTH_CANCELED 3
-#define BOND_RESULT_REMOTE_DEVICE_DOWN 4
-#define BOND_RESULT_DISCOVERY_IN_PROGRESS 5
-#define BOND_RESULT_AUTH_TIMEOUT 6
-#define BOND_RESULT_REPEATED_ATTEMPTS 7
-
-#define PAN_DISCONNECT_FAILED_NOT_CONNECTED 1000
-#define PAN_CONNECT_FAILED_ALREADY_CONNECTED 1001
-#define PAN_CONNECT_FAILED_ATTEMPT_FAILED 1002
-#define PAN_OPERATION_GENERIC_FAILURE 1003
-#define PAN_OPERATION_SUCCESS 1004
-
-#define INPUT_DISCONNECT_FAILED_NOT_CONNECTED 5000
-#define INPUT_CONNECT_FAILED_ALREADY_CONNECTED 5001
-#define INPUT_CONNECT_FAILED_ATTEMPT_FAILED 5002
-#define INPUT_OPERATION_GENERIC_FAILURE 5003
-#define INPUT_OPERATION_SUCCESS 5004
-
-#define HEALTH_OPERATION_SUCCESS 6000
-#define HEALTH_OPERATION_ERROR 6001
-#define HEALTH_OPERATION_INVALID_ARGS 6002
-#define HEALTH_OPERATION_GENERIC_FAILURE 6003
-#define HEALTH_OPERATION_NOT_FOUND 6004
-#define HEALTH_OPERATION_NOT_ALLOWED 6005
-
-#endif
-} /* namespace android */
-
-#endif/*ANDROID_BLUETOOTH_COMMON_H*/
diff --git a/core/jni/android_server_BluetoothA2dpService.cpp b/core/jni/android_server_BluetoothA2dpService.cpp
deleted file mode 100644
index d065a9e..0000000
--- a/core/jni/android_server_BluetoothA2dpService.cpp
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
-** Copyright 2008, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#define LOG_TAG "BluetoothA2dpService.cpp"
-
-#include "android_bluetooth_common.h"
-#include "android_runtime/AndroidRuntime.h"
-#include "JNIHelp.h"
-#include "jni.h"
-#include "utils/Log.h"
-#include "utils/misc.h"
-
-#include <ctype.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#ifdef HAVE_BLUETOOTH
-#include <dbus/dbus.h>
-#endif
-
-namespace android {
-
-#ifdef HAVE_BLUETOOTH
-static jmethodID method_onSinkPropertyChanged;
-static jmethodID method_onConnectSinkResult;
-
-typedef struct {
- JavaVM *vm;
- int envVer;
- DBusConnection *conn;
- jobject me; // for callbacks to java
-} native_data_t;
-
-static native_data_t *nat = NULL; // global native data
-static void onConnectSinkResult(DBusMessage *msg, void *user, void *n);
-
-static Properties sink_properties[] = {
- {"State", DBUS_TYPE_STRING},
- {"Connected", DBUS_TYPE_BOOLEAN},
- {"Playing", DBUS_TYPE_BOOLEAN},
- };
-#endif
-
-/* Returns true on success (even if adapter is present but disabled).
- * Return false if dbus is down, or another serious error (out of memory)
-*/
-static bool initNative(JNIEnv* env, jobject object) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- nat = (native_data_t *)calloc(1, sizeof(native_data_t));
- if (NULL == nat) {
- ALOGE("%s: out of memory!", __FUNCTION__);
- return false;
- }
- env->GetJavaVM( &(nat->vm) );
- nat->envVer = env->GetVersion();
- nat->me = env->NewGlobalRef(object);
-
- DBusError err;
- dbus_error_init(&err);
- dbus_threads_init_default();
- nat->conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
- if (dbus_error_is_set(&err)) {
- ALOGE("Could not get onto the system bus: %s", err.message);
- dbus_error_free(&err);
- return false;
- }
- dbus_connection_set_exit_on_disconnect(nat->conn, FALSE);
-#endif /*HAVE_BLUETOOTH*/
- return true;
-}
-
-static void cleanupNative(JNIEnv* env, jobject object) {
-#ifdef HAVE_BLUETOOTH
- ALOGV("%s", __FUNCTION__);
- if (nat) {
- dbus_connection_close(nat->conn);
- env->DeleteGlobalRef(nat->me);
- free(nat);
- nat = NULL;
- }
-#endif
-}
-
-static jobjectArray getSinkPropertiesNative(JNIEnv *env, jobject object,
- jstring path) {
-#ifdef HAVE_BLUETOOTH
- ALOGV("%s", __FUNCTION__);
- if (nat) {
- DBusMessage *msg, *reply;
- DBusError err;
- dbus_error_init(&err);
-
- const char *c_path = env->GetStringUTFChars(path, NULL);
- reply = dbus_func_args_timeout(env,
- nat->conn, -1, c_path,
- "org.bluez.AudioSink", "GetProperties",
- DBUS_TYPE_INVALID);
- env->ReleaseStringUTFChars(path, c_path);
- if (!reply && dbus_error_is_set(&err)) {
- LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, reply);
- return NULL;
- } else if (!reply) {
- ALOGE("DBus reply is NULL in function %s", __FUNCTION__);
- return NULL;
- }
- DBusMessageIter iter;
- if (dbus_message_iter_init(reply, &iter))
- return parse_properties(env, &iter, (Properties *)&sink_properties,
- sizeof(sink_properties) / sizeof(Properties));
- }
-#endif
- return NULL;
-}
-
-
-static jboolean connectSinkNative(JNIEnv *env, jobject object, jstring path) {
-#ifdef HAVE_BLUETOOTH
- ALOGV("%s", __FUNCTION__);
- if (nat) {
- const char *c_path = env->GetStringUTFChars(path, NULL);
- int len = env->GetStringLength(path) + 1;
- char *context_path = (char *)calloc(len, sizeof(char));
- strlcpy(context_path, c_path, len); // for callback
-
- bool ret = dbus_func_args_async(env, nat->conn, -1, onConnectSinkResult, context_path,
- nat, c_path, "org.bluez.AudioSink", "Connect",
- DBUS_TYPE_INVALID);
-
- env->ReleaseStringUTFChars(path, c_path);
- return ret ? JNI_TRUE : JNI_FALSE;
- }
-#endif
- return JNI_FALSE;
-}
-
-static jboolean disconnectSinkNative(JNIEnv *env, jobject object,
- jstring path) {
-#ifdef HAVE_BLUETOOTH
- ALOGV("%s", __FUNCTION__);
- if (nat) {
- const char *c_path = env->GetStringUTFChars(path, NULL);
-
- bool ret = dbus_func_args_async(env, nat->conn, -1, NULL, NULL, nat,
- c_path, "org.bluez.AudioSink", "Disconnect",
- DBUS_TYPE_INVALID);
-
- env->ReleaseStringUTFChars(path, c_path);
- return ret ? JNI_TRUE : JNI_FALSE;
- }
-#endif
- return JNI_FALSE;
-}
-
-static jboolean suspendSinkNative(JNIEnv *env, jobject object,
- jstring path) {
-#ifdef HAVE_BLUETOOTH
- ALOGV("%s", __FUNCTION__);
- if (nat) {
- const char *c_path = env->GetStringUTFChars(path, NULL);
- bool ret = dbus_func_args_async(env, nat->conn, -1, NULL, NULL, nat,
- c_path, "org.bluez.audio.Sink", "Suspend",
- DBUS_TYPE_INVALID);
- env->ReleaseStringUTFChars(path, c_path);
- return ret ? JNI_TRUE : JNI_FALSE;
- }
-#endif
- return JNI_FALSE;
-}
-
-static jboolean resumeSinkNative(JNIEnv *env, jobject object,
- jstring path) {
-#ifdef HAVE_BLUETOOTH
- ALOGV("%s", __FUNCTION__);
- if (nat) {
- const char *c_path = env->GetStringUTFChars(path, NULL);
- bool ret = dbus_func_args_async(env, nat->conn, -1, NULL, NULL, nat,
- c_path, "org.bluez.audio.Sink", "Resume",
- DBUS_TYPE_INVALID);
- env->ReleaseStringUTFChars(path, c_path);
- return ret ? JNI_TRUE : JNI_FALSE;
- }
-#endif
- return JNI_FALSE;
-}
-
-static jboolean avrcpVolumeUpNative(JNIEnv *env, jobject object,
- jstring path) {
-#ifdef HAVE_BLUETOOTH
- ALOGV("%s", __FUNCTION__);
- if (nat) {
- const char *c_path = env->GetStringUTFChars(path, NULL);
- bool ret = dbus_func_args_async(env, nat->conn, -1, NULL, NULL, nat,
- c_path, "org.bluez.Control", "VolumeUp",
- DBUS_TYPE_INVALID);
- env->ReleaseStringUTFChars(path, c_path);
- return ret ? JNI_TRUE : JNI_FALSE;
- }
-#endif
- return JNI_FALSE;
-}
-
-static jboolean avrcpVolumeDownNative(JNIEnv *env, jobject object,
- jstring path) {
-#ifdef HAVE_BLUETOOTH
- ALOGV("%s", __FUNCTION__);
- if (nat) {
- const char *c_path = env->GetStringUTFChars(path, NULL);
- bool ret = dbus_func_args_async(env, nat->conn, -1, NULL, NULL, nat,
- c_path, "org.bluez.Control", "VolumeDown",
- DBUS_TYPE_INVALID);
- env->ReleaseStringUTFChars(path, c_path);
- return ret ? JNI_TRUE : JNI_FALSE;
- }
-#endif
- return JNI_FALSE;
-}
-
-#ifdef HAVE_BLUETOOTH
-DBusHandlerResult a2dp_event_filter(DBusMessage *msg, JNIEnv *env) {
- DBusError err;
-
- if (!nat) {
- ALOGV("... skipping %s\n", __FUNCTION__);
- ALOGV("... ignored\n");
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
- }
-
- dbus_error_init(&err);
-
- if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_SIGNAL) {
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
- }
-
- DBusHandlerResult result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
- if (dbus_message_is_signal(msg, "org.bluez.AudioSink",
- "PropertyChanged")) {
- jobjectArray str_array =
- parse_property_change(env, msg, (Properties *)&sink_properties,
- sizeof(sink_properties) / sizeof(Properties));
- const char *c_path = dbus_message_get_path(msg);
- jstring path = env->NewStringUTF(c_path);
- env->CallVoidMethod(nat->me,
- method_onSinkPropertyChanged,
- path,
- str_array);
- env->DeleteLocalRef(path);
- result = DBUS_HANDLER_RESULT_HANDLED;
- return result;
- } else {
- ALOGV("... ignored");
- }
- if (env->ExceptionCheck()) {
- ALOGE("VM Exception occurred while handling %s.%s (%s) in %s,"
- " leaving for VM",
- dbus_message_get_interface(msg), dbus_message_get_member(msg),
- dbus_message_get_path(msg), __FUNCTION__);
- }
-
- return result;
-}
-
-void onConnectSinkResult(DBusMessage *msg, void *user, void *n) {
- ALOGV("%s", __FUNCTION__);
-
- native_data_t *nat = (native_data_t *)n;
- const char *path = (const char *)user;
- DBusError err;
- dbus_error_init(&err);
- JNIEnv *env;
- nat->vm->GetEnv((void**)&env, nat->envVer);
-
-
- bool result = JNI_TRUE;
- if (dbus_set_error_from_message(&err, msg)) {
- LOG_AND_FREE_DBUS_ERROR(&err);
- result = JNI_FALSE;
- }
- ALOGV("... Device Path = %s, result = %d", path, result);
-
- jstring jPath = env->NewStringUTF(path);
- env->CallVoidMethod(nat->me,
- method_onConnectSinkResult,
- jPath,
- result);
- env->DeleteLocalRef(jPath);
- free(user);
-}
-
-
-#endif
-
-
-static JNINativeMethod sMethods[] = {
- {"initNative", "()Z", (void *)initNative},
- {"cleanupNative", "()V", (void *)cleanupNative},
-
- /* Bluez audio 4.47 API */
- {"connectSinkNative", "(Ljava/lang/String;)Z", (void *)connectSinkNative},
- {"disconnectSinkNative", "(Ljava/lang/String;)Z", (void *)disconnectSinkNative},
- {"suspendSinkNative", "(Ljava/lang/String;)Z", (void*)suspendSinkNative},
- {"resumeSinkNative", "(Ljava/lang/String;)Z", (void*)resumeSinkNative},
- {"getSinkPropertiesNative", "(Ljava/lang/String;)[Ljava/lang/Object;",
- (void *)getSinkPropertiesNative},
- {"avrcpVolumeUpNative", "(Ljava/lang/String;)Z", (void*)avrcpVolumeUpNative},
- {"avrcpVolumeDownNative", "(Ljava/lang/String;)Z", (void*)avrcpVolumeDownNative},
-};
-
-int register_android_server_BluetoothA2dpService(JNIEnv *env) {
- jclass clazz = env->FindClass("android/server/BluetoothA2dpService");
- if (clazz == NULL) {
- ALOGE("Can't find android/server/BluetoothA2dpService");
- return -1;
- }
-
-#ifdef HAVE_BLUETOOTH
- method_onSinkPropertyChanged = env->GetMethodID(clazz, "onSinkPropertyChanged",
- "(Ljava/lang/String;[Ljava/lang/String;)V");
- method_onConnectSinkResult = env->GetMethodID(clazz, "onConnectSinkResult",
- "(Ljava/lang/String;Z)V");
-#endif
-
- return AndroidRuntime::registerNativeMethods(env,
- "android/server/BluetoothA2dpService", sMethods, NELEM(sMethods));
-}
-
-} /* namespace android */
diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp
deleted file mode 100644
index 8a69ba4..0000000
--- a/core/jni/android_server_BluetoothEventLoop.cpp
+++ /dev/null
@@ -1,1585 +0,0 @@
-/*
-** Copyright 2008, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#define LOG_TAG "BluetoothEventLoop.cpp"
-
-#include "android_bluetooth_common.h"
-#include "android_runtime/AndroidRuntime.h"
-#include "cutils/sockets.h"
-#include "JNIHelp.h"
-#include "jni.h"
-#include "utils/Log.h"
-#include "utils/misc.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-
-#ifdef HAVE_BLUETOOTH
-#include <dbus/dbus.h>
-#endif
-
-namespace android {
-
-#define CREATE_DEVICE_ALREADY_EXISTS 1
-#define CREATE_DEVICE_SUCCESS 0
-#define CREATE_DEVICE_FAILED -1
-
-#ifdef HAVE_BLUETOOTH
-static jfieldID field_mNativeData;
-
-static jmethodID method_onPropertyChanged;
-static jmethodID method_onDevicePropertyChanged;
-static jmethodID method_onDeviceFound;
-static jmethodID method_onDeviceDisappeared;
-static jmethodID method_onDeviceCreated;
-static jmethodID method_onDeviceRemoved;
-static jmethodID method_onDeviceDisconnectRequested;
-static jmethodID method_onNetworkDeviceDisconnected;
-static jmethodID method_onNetworkDeviceConnected;
-
-static jmethodID method_onCreatePairedDeviceResult;
-static jmethodID method_onCreateDeviceResult;
-static jmethodID method_onDiscoverServicesResult;
-static jmethodID method_onGetDeviceServiceChannelResult;
-
-static jmethodID method_onRequestPinCode;
-static jmethodID method_onRequestPasskey;
-static jmethodID method_onRequestPasskeyConfirmation;
-static jmethodID method_onRequestPairingConsent;
-static jmethodID method_onDisplayPasskey;
-static jmethodID method_onRequestOobData;
-static jmethodID method_onAgentOutOfBandDataAvailable;
-static jmethodID method_onAgentAuthorize;
-static jmethodID method_onAgentCancel;
-
-static jmethodID method_onInputDevicePropertyChanged;
-static jmethodID method_onInputDeviceConnectionResult;
-static jmethodID method_onPanDevicePropertyChanged;
-static jmethodID method_onPanDeviceConnectionResult;
-static jmethodID method_onHealthDevicePropertyChanged;
-static jmethodID method_onHealthDeviceChannelChanged;
-static jmethodID method_onHealthDeviceConnectionResult;
-
-typedef event_loop_native_data_t native_data_t;
-
-#define EVENT_LOOP_REFS 10
-
-static inline native_data_t * get_native_data(JNIEnv *env, jobject object) {
- return (native_data_t *)(env->GetIntField(object,
- field_mNativeData));
-}
-
-native_data_t *get_EventLoop_native_data(JNIEnv *env, jobject object) {
- return get_native_data(env, object);
-}
-
-#endif
-static void classInitNative(JNIEnv* env, jclass clazz) {
- ALOGV("%s", __FUNCTION__);
-
-#ifdef HAVE_BLUETOOTH
- method_onPropertyChanged = env->GetMethodID(clazz, "onPropertyChanged",
- "([Ljava/lang/String;)V");
- method_onDevicePropertyChanged = env->GetMethodID(clazz,
- "onDevicePropertyChanged",
- "(Ljava/lang/String;[Ljava/lang/String;)V");
- method_onDeviceFound = env->GetMethodID(clazz, "onDeviceFound",
- "(Ljava/lang/String;[Ljava/lang/String;)V");
- method_onDeviceDisappeared = env->GetMethodID(clazz, "onDeviceDisappeared",
- "(Ljava/lang/String;)V");
- method_onDeviceCreated = env->GetMethodID(clazz, "onDeviceCreated", "(Ljava/lang/String;)V");
- method_onDeviceRemoved = env->GetMethodID(clazz, "onDeviceRemoved", "(Ljava/lang/String;)V");
- method_onDeviceDisconnectRequested = env->GetMethodID(clazz, "onDeviceDisconnectRequested",
- "(Ljava/lang/String;)V");
- method_onNetworkDeviceConnected = env->GetMethodID(clazz, "onNetworkDeviceConnected",
- "(Ljava/lang/String;Ljava/lang/String;I)V");
- method_onNetworkDeviceDisconnected = env->GetMethodID(clazz, "onNetworkDeviceDisconnected",
- "(Ljava/lang/String;)V");
-
- method_onCreatePairedDeviceResult = env->GetMethodID(clazz, "onCreatePairedDeviceResult",
- "(Ljava/lang/String;I)V");
- method_onCreateDeviceResult = env->GetMethodID(clazz, "onCreateDeviceResult",
- "(Ljava/lang/String;I)V");
- method_onDiscoverServicesResult = env->GetMethodID(clazz, "onDiscoverServicesResult",
- "(Ljava/lang/String;Z)V");
-
- method_onAgentAuthorize = env->GetMethodID(clazz, "onAgentAuthorize",
- "(Ljava/lang/String;Ljava/lang/String;I)V");
- method_onAgentOutOfBandDataAvailable = env->GetMethodID(clazz, "onAgentOutOfBandDataAvailable",
- "(Ljava/lang/String;)Z");
- method_onAgentCancel = env->GetMethodID(clazz, "onAgentCancel", "()V");
- method_onRequestPinCode = env->GetMethodID(clazz, "onRequestPinCode",
- "(Ljava/lang/String;I)V");
- method_onRequestPasskey = env->GetMethodID(clazz, "onRequestPasskey",
- "(Ljava/lang/String;I)V");
- method_onRequestPasskeyConfirmation = env->GetMethodID(clazz, "onRequestPasskeyConfirmation",
- "(Ljava/lang/String;II)V");
- method_onRequestPairingConsent = env->GetMethodID(clazz, "onRequestPairingConsent",
- "(Ljava/lang/String;I)V");
- method_onDisplayPasskey = env->GetMethodID(clazz, "onDisplayPasskey",
- "(Ljava/lang/String;II)V");
- method_onInputDevicePropertyChanged = env->GetMethodID(clazz, "onInputDevicePropertyChanged",
- "(Ljava/lang/String;[Ljava/lang/String;)V");
- method_onInputDeviceConnectionResult = env->GetMethodID(clazz, "onInputDeviceConnectionResult",
- "(Ljava/lang/String;I)V");
- method_onPanDevicePropertyChanged = env->GetMethodID(clazz, "onPanDevicePropertyChanged",
- "(Ljava/lang/String;[Ljava/lang/String;)V");
- method_onPanDeviceConnectionResult = env->GetMethodID(clazz, "onPanDeviceConnectionResult",
- "(Ljava/lang/String;I)V");
- method_onHealthDeviceConnectionResult = env->GetMethodID(clazz,
- "onHealthDeviceConnectionResult",
- "(II)V");
- method_onHealthDevicePropertyChanged = env->GetMethodID(clazz, "onHealthDevicePropertyChanged",
- "(Ljava/lang/String;[Ljava/lang/String;)V");
- method_onHealthDeviceChannelChanged = env->GetMethodID(clazz, "onHealthDeviceChannelChanged",
- "(Ljava/lang/String;Ljava/lang/String;Z)V");
- method_onRequestOobData = env->GetMethodID(clazz, "onRequestOobData",
- "(Ljava/lang/String;I)V");
-
- field_mNativeData = env->GetFieldID(clazz, "mNativeData", "I");
-#endif
-}
-
-static void initializeNativeDataNative(JNIEnv* env, jobject object) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- native_data_t *nat = (native_data_t *)calloc(1, sizeof(native_data_t));
- if (NULL == nat) {
- ALOGE("%s: out of memory!", __FUNCTION__);
- return;
- }
-
- pthread_mutex_init(&(nat->thread_mutex), NULL);
-
- env->SetIntField(object, field_mNativeData, (jint)nat);
-
- {
- DBusError err;
- dbus_error_init(&err);
- dbus_threads_init_default();
- nat->conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
- if (dbus_error_is_set(&err)) {
- ALOGE("%s: Could not get onto the system bus!", __FUNCTION__);
- dbus_error_free(&err);
- }
- dbus_connection_set_exit_on_disconnect(nat->conn, FALSE);
- }
-#endif
-}
-
-static void cleanupNativeDataNative(JNIEnv* env, jobject object) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- native_data_t *nat =
- (native_data_t *)env->GetIntField(object, field_mNativeData);
-
- pthread_mutex_destroy(&(nat->thread_mutex));
-
- if (nat) {
- free(nat);
- }
-#endif
-}
-
-#ifdef HAVE_BLUETOOTH
-static DBusHandlerResult event_filter(DBusConnection *conn, DBusMessage *msg,
- void *data);
-DBusHandlerResult agent_event_filter(DBusConnection *conn,
- DBusMessage *msg,
- void *data);
-static int register_agent(native_data_t *nat,
- const char *agent_path, const char *capabilities);
-
-static const DBusObjectPathVTable agent_vtable = {
- NULL, agent_event_filter, NULL, NULL, NULL, NULL
-};
-
-static unsigned int unix_events_to_dbus_flags(short events) {
- return (events & DBUS_WATCH_READABLE ? POLLIN : 0) |
- (events & DBUS_WATCH_WRITABLE ? POLLOUT : 0) |
- (events & DBUS_WATCH_ERROR ? POLLERR : 0) |
- (events & DBUS_WATCH_HANGUP ? POLLHUP : 0);
-}
-
-static short dbus_flags_to_unix_events(unsigned int flags) {
- return (flags & POLLIN ? DBUS_WATCH_READABLE : 0) |
- (flags & POLLOUT ? DBUS_WATCH_WRITABLE : 0) |
- (flags & POLLERR ? DBUS_WATCH_ERROR : 0) |
- (flags & POLLHUP ? DBUS_WATCH_HANGUP : 0);
-}
-
-static jboolean setUpEventLoop(native_data_t *nat) {
- ALOGV("%s", __FUNCTION__);
-
- if (nat != NULL && nat->conn != NULL) {
- dbus_threads_init_default();
- DBusError err;
- dbus_error_init(&err);
-
- const char *agent_path = "/android/bluetooth/agent";
- const char *capabilities = "DisplayYesNo";
- if (register_agent(nat, agent_path, capabilities) < 0) {
- dbus_connection_unregister_object_path (nat->conn, agent_path);
- return JNI_FALSE;
- }
-
- // Add a filter for all incoming messages
- if (!dbus_connection_add_filter(nat->conn, event_filter, nat, NULL)){
- return JNI_FALSE;
- }
-
- // Set which messages will be processed by this dbus connection
- dbus_bus_add_match(nat->conn,
- "type='signal',interface='org.freedesktop.DBus'",
- &err);
- if (dbus_error_is_set(&err)) {
- LOG_AND_FREE_DBUS_ERROR(&err);
- return JNI_FALSE;
- }
- dbus_bus_add_match(nat->conn,
- "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Adapter'",
- &err);
- if (dbus_error_is_set(&err)) {
- LOG_AND_FREE_DBUS_ERROR(&err);
- return JNI_FALSE;
- }
- dbus_bus_add_match(nat->conn,
- "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Device'",
- &err);
- if (dbus_error_is_set(&err)) {
- LOG_AND_FREE_DBUS_ERROR(&err);
- return JNI_FALSE;
- }
- dbus_bus_add_match(nat->conn,
- "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Input'",
- &err);
- if (dbus_error_is_set(&err)) {
- LOG_AND_FREE_DBUS_ERROR(&err);
- return JNI_FALSE;
- }
- dbus_bus_add_match(nat->conn,
- "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Network'",
- &err);
- if (dbus_error_is_set(&err)) {
- LOG_AND_FREE_DBUS_ERROR(&err);
- return JNI_FALSE;
- }
- dbus_bus_add_match(nat->conn,
- "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".NetworkServer'",
- &err);
- if (dbus_error_is_set(&err)) {
- LOG_AND_FREE_DBUS_ERROR(&err);
- return JNI_FALSE;
- }
-
- dbus_bus_add_match(nat->conn,
- "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".HealthDevice'",
- &err);
- if (dbus_error_is_set(&err)) {
- LOG_AND_FREE_DBUS_ERROR(&err);
- return JNI_FALSE;
- }
-
- dbus_bus_add_match(nat->conn,
- "type='signal',interface='org.bluez.AudioSink'",
- &err);
- if (dbus_error_is_set(&err)) {
- LOG_AND_FREE_DBUS_ERROR(&err);
- return JNI_FALSE;
- }
-
- return JNI_TRUE;
- }
- return JNI_FALSE;
-}
-
-
-const char * get_adapter_path(DBusConnection *conn) {
- DBusMessage *msg = NULL, *reply = NULL;
- DBusError err;
- const char *device_path = NULL;
- int attempt = 0;
-
- for (attempt = 0; attempt < 1000 && reply == NULL; attempt ++) {
- msg = dbus_message_new_method_call("org.bluez", "/",
- "org.bluez.Manager", "DefaultAdapter");
- if (!msg) {
- ALOGE("%s: Can't allocate new method call for get_adapter_path!",
- __FUNCTION__);
- return NULL;
- }
- dbus_message_append_args(msg, DBUS_TYPE_INVALID);
- dbus_error_init(&err);
- reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err);
-
- if (!reply) {
- if (dbus_error_is_set(&err)) {
- if (dbus_error_has_name(&err,
- "org.freedesktop.DBus.Error.ServiceUnknown")) {
- // bluetoothd is still down, retry
- LOG_AND_FREE_DBUS_ERROR(&err);
- usleep(10000); // 10 ms
- continue;
- } else {
- // Some other error we weren't expecting
- LOG_AND_FREE_DBUS_ERROR(&err);
- }
- }
- goto failed;
- }
- }
- if (attempt == 1000) {
- ALOGE("Time out while trying to get Adapter path, is bluetoothd up ?");
- goto failed;
- }
-
- if (!dbus_message_get_args(reply, &err, DBUS_TYPE_OBJECT_PATH,
- &device_path, DBUS_TYPE_INVALID)
- || !device_path){
- if (dbus_error_is_set(&err)) {
- LOG_AND_FREE_DBUS_ERROR(&err);
- }
- goto failed;
- }
- dbus_message_unref(msg);
- return device_path;
-
-failed:
- dbus_message_unref(msg);
- return NULL;
-}
-
-static int register_agent(native_data_t *nat,
- const char * agent_path, const char * capabilities)
-{
- DBusMessage *msg, *reply;
- DBusError err;
- dbus_bool_t oob = TRUE;
-
- if (!dbus_connection_register_object_path(nat->conn, agent_path,
- &agent_vtable, nat)) {
- ALOGE("%s: Can't register object path %s for agent!",
- __FUNCTION__, agent_path);
- return -1;
- }
-
- nat->adapter = get_adapter_path(nat->conn);
- if (nat->adapter == NULL) {
- return -1;
- }
- msg = dbus_message_new_method_call("org.bluez", nat->adapter,
- "org.bluez.Adapter", "RegisterAgent");
- if (!msg) {
- ALOGE("%s: Can't allocate new method call for agent!",
- __FUNCTION__);
- return -1;
- }
- dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, &agent_path,
- DBUS_TYPE_STRING, &capabilities,
- DBUS_TYPE_INVALID);
-
- dbus_error_init(&err);
- reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);
- dbus_message_unref(msg);
-
- if (!reply) {
- ALOGE("%s: Can't register agent!", __FUNCTION__);
- if (dbus_error_is_set(&err)) {
- LOG_AND_FREE_DBUS_ERROR(&err);
- }
- return -1;
- }
-
- dbus_message_unref(reply);
- dbus_connection_flush(nat->conn);
-
- return 0;
-}
-
-static void tearDownEventLoop(native_data_t *nat) {
- ALOGV("%s", __FUNCTION__);
- if (nat != NULL && nat->conn != NULL) {
-
- DBusMessage *msg, *reply;
- DBusError err;
- dbus_error_init(&err);
- const char * agent_path = "/android/bluetooth/agent";
-
- msg = dbus_message_new_method_call("org.bluez",
- nat->adapter,
- "org.bluez.Adapter",
- "UnregisterAgent");
- if (msg != NULL) {
- dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, &agent_path,
- DBUS_TYPE_INVALID);
- reply = dbus_connection_send_with_reply_and_block(nat->conn,
- msg, -1, &err);
-
- if (!reply) {
- if (dbus_error_is_set(&err)) {
- LOG_AND_FREE_DBUS_ERROR(&err);
- dbus_error_free(&err);
- }
- } else {
- dbus_message_unref(reply);
- }
- dbus_message_unref(msg);
- } else {
- ALOGE("%s: Can't create new method call!", __FUNCTION__);
- }
-
- dbus_connection_flush(nat->conn);
- dbus_connection_unregister_object_path(nat->conn, agent_path);
-
- dbus_bus_remove_match(nat->conn,
- "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".AudioSink'",
- &err);
- if (dbus_error_is_set(&err)) {
- LOG_AND_FREE_DBUS_ERROR(&err);
- }
- dbus_bus_remove_match(nat->conn,
- "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Device'",
- &err);
- if (dbus_error_is_set(&err)) {
- LOG_AND_FREE_DBUS_ERROR(&err);
- }
- dbus_bus_remove_match(nat->conn,
- "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Input'",
- &err);
- if (dbus_error_is_set(&err)) {
- LOG_AND_FREE_DBUS_ERROR(&err);
- }
- dbus_bus_remove_match(nat->conn,
- "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Network'",
- &err);
- if (dbus_error_is_set(&err)) {
- LOG_AND_FREE_DBUS_ERROR(&err);
- }
- dbus_bus_remove_match(nat->conn,
- "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".NetworkServer'",
- &err);
- if (dbus_error_is_set(&err)) {
- LOG_AND_FREE_DBUS_ERROR(&err);
- }
- dbus_bus_remove_match(nat->conn,
- "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".HealthDevice'",
- &err);
- if (dbus_error_is_set(&err)) {
- LOG_AND_FREE_DBUS_ERROR(&err);
- }
- dbus_bus_remove_match(nat->conn,
- "type='signal',interface='org.bluez.audio.Manager'",
- &err);
- if (dbus_error_is_set(&err)) {
- LOG_AND_FREE_DBUS_ERROR(&err);
- }
- dbus_bus_remove_match(nat->conn,
- "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Adapter'",
- &err);
- if (dbus_error_is_set(&err)) {
- LOG_AND_FREE_DBUS_ERROR(&err);
- }
- dbus_bus_remove_match(nat->conn,
- "type='signal',interface='org.freedesktop.DBus'",
- &err);
- if (dbus_error_is_set(&err)) {
- LOG_AND_FREE_DBUS_ERROR(&err);
- }
-
- dbus_connection_remove_filter(nat->conn, event_filter, nat);
- }
-}
-
-
-#define EVENT_LOOP_EXIT 1
-#define EVENT_LOOP_ADD 2
-#define EVENT_LOOP_REMOVE 3
-#define EVENT_LOOP_WAKEUP 4
-
-dbus_bool_t dbusAddWatch(DBusWatch *watch, void *data) {
- native_data_t *nat = (native_data_t *)data;
-
- if (dbus_watch_get_enabled(watch)) {
- // note that we can't just send the watch and inspect it later
- // because we may get a removeWatch call before this data is reacted
- // to by our eventloop and remove this watch.. reading the add first
- // and then inspecting the recently deceased watch would be bad.
- char control = EVENT_LOOP_ADD;
- write(nat->controlFdW, &control, sizeof(char));
-
- int fd = dbus_watch_get_fd(watch);
- write(nat->controlFdW, &fd, sizeof(int));
-
- unsigned int flags = dbus_watch_get_flags(watch);
- write(nat->controlFdW, &flags, sizeof(unsigned int));
-
- write(nat->controlFdW, &watch, sizeof(DBusWatch*));
- }
- return true;
-}
-
-void dbusRemoveWatch(DBusWatch *watch, void *data) {
- native_data_t *nat = (native_data_t *)data;
-
- char control = EVENT_LOOP_REMOVE;
- write(nat->controlFdW, &control, sizeof(char));
-
- int fd = dbus_watch_get_fd(watch);
- write(nat->controlFdW, &fd, sizeof(int));
-
- unsigned int flags = dbus_watch_get_flags(watch);
- write(nat->controlFdW, &flags, sizeof(unsigned int));
-}
-
-void dbusToggleWatch(DBusWatch *watch, void *data) {
- if (dbus_watch_get_enabled(watch)) {
- dbusAddWatch(watch, data);
- } else {
- dbusRemoveWatch(watch, data);
- }
-}
-
-void dbusWakeup(void *data) {
- native_data_t *nat = (native_data_t *)data;
-
- char control = EVENT_LOOP_WAKEUP;
- write(nat->controlFdW, &control, sizeof(char));
-}
-
-static void handleWatchAdd(native_data_t *nat) {
- DBusWatch *watch;
- int newFD;
- unsigned int flags;
-
- read(nat->controlFdR, &newFD, sizeof(int));
- read(nat->controlFdR, &flags, sizeof(unsigned int));
- read(nat->controlFdR, &watch, sizeof(DBusWatch *));
- short events = dbus_flags_to_unix_events(flags);
-
- for (int y = 0; y<nat->pollMemberCount; y++) {
- if ((nat->pollData[y].fd == newFD) &&
- (nat->pollData[y].events == events)) {
- ALOGV("DBusWatch duplicate add");
- return;
- }
- }
- if (nat->pollMemberCount == nat->pollDataSize) {
- ALOGV("Bluetooth EventLoop poll struct growing");
- struct pollfd *temp = (struct pollfd *)malloc(
- sizeof(struct pollfd) * (nat->pollMemberCount+1));
- if (!temp) {
- return;
- }
- memcpy(temp, nat->pollData, sizeof(struct pollfd) *
- nat->pollMemberCount);
- free(nat->pollData);
- nat->pollData = temp;
- DBusWatch **temp2 = (DBusWatch **)malloc(sizeof(DBusWatch *) *
- (nat->pollMemberCount+1));
- if (!temp2) {
- return;
- }
- memcpy(temp2, nat->watchData, sizeof(DBusWatch *) *
- nat->pollMemberCount);
- free(nat->watchData);
- nat->watchData = temp2;
- nat->pollDataSize++;
- }
- nat->pollData[nat->pollMemberCount].fd = newFD;
- nat->pollData[nat->pollMemberCount].revents = 0;
- nat->pollData[nat->pollMemberCount].events = events;
- nat->watchData[nat->pollMemberCount] = watch;
- nat->pollMemberCount++;
-}
-
-static void handleWatchRemove(native_data_t *nat) {
- int removeFD;
- unsigned int flags;
-
- read(nat->controlFdR, &removeFD, sizeof(int));
- read(nat->controlFdR, &flags, sizeof(unsigned int));
- short events = dbus_flags_to_unix_events(flags);
-
- for (int y = 0; y < nat->pollMemberCount; y++) {
- if ((nat->pollData[y].fd == removeFD) &&
- (nat->pollData[y].events == events)) {
- int newCount = --nat->pollMemberCount;
- // copy the last live member over this one
- nat->pollData[y].fd = nat->pollData[newCount].fd;
- nat->pollData[y].events = nat->pollData[newCount].events;
- nat->pollData[y].revents = nat->pollData[newCount].revents;
- nat->watchData[y] = nat->watchData[newCount];
- return;
- }
- }
- ALOGW("WatchRemove given with unknown watch");
-}
-
-static void *eventLoopMain(void *ptr) {
- native_data_t *nat = (native_data_t *)ptr;
- JNIEnv *env;
-
- JavaVMAttachArgs args;
- char name[] = "BT EventLoop";
- args.version = nat->envVer;
- args.name = name;
- args.group = NULL;
-
- nat->vm->AttachCurrentThread(&env, &args);
-
- dbus_connection_set_watch_functions(nat->conn, dbusAddWatch,
- dbusRemoveWatch, dbusToggleWatch, ptr, NULL);
- dbus_connection_set_wakeup_main_function(nat->conn, dbusWakeup, ptr, NULL);
-
- nat->running = true;
-
- while (1) {
- for (int i = 0; i < nat->pollMemberCount; i++) {
- if (!nat->pollData[i].revents) {
- continue;
- }
- if (nat->pollData[i].fd == nat->controlFdR) {
- char data;
- while (recv(nat->controlFdR, &data, sizeof(char), MSG_DONTWAIT)
- != -1) {
- switch (data) {
- case EVENT_LOOP_EXIT:
- {
- dbus_connection_set_watch_functions(nat->conn,
- NULL, NULL, NULL, NULL, NULL);
- tearDownEventLoop(nat);
- nat->vm->DetachCurrentThread();
-
- int fd = nat->controlFdR;
- nat->controlFdR = 0;
- close(fd);
- return NULL;
- }
- case EVENT_LOOP_ADD:
- {
- handleWatchAdd(nat);
- break;
- }
- case EVENT_LOOP_REMOVE:
- {
- handleWatchRemove(nat);
- break;
- }
- case EVENT_LOOP_WAKEUP:
- {
- // noop
- break;
- }
- }
- }
- } else {
- short events = nat->pollData[i].revents;
- unsigned int flags = unix_events_to_dbus_flags(events);
- dbus_watch_handle(nat->watchData[i], flags);
- nat->pollData[i].revents = 0;
- // can only do one - it may have caused a 'remove'
- break;
- }
- }
- while (dbus_connection_dispatch(nat->conn) ==
- DBUS_DISPATCH_DATA_REMAINS) {
- }
-
- poll(nat->pollData, nat->pollMemberCount, -1);
- }
-}
-#endif // HAVE_BLUETOOTH
-
-static jboolean startEventLoopNative(JNIEnv *env, jobject object) {
- jboolean result = JNI_FALSE;
-#ifdef HAVE_BLUETOOTH
- event_loop_native_data_t *nat = get_native_data(env, object);
-
- pthread_mutex_lock(&(nat->thread_mutex));
-
- nat->running = false;
-
- if (nat->pollData) {
- ALOGW("trying to start EventLoop a second time!");
- pthread_mutex_unlock( &(nat->thread_mutex) );
- return JNI_FALSE;
- }
-
- nat->pollData = (struct pollfd *)calloc(
- DEFAULT_INITIAL_POLLFD_COUNT, sizeof(struct pollfd));
- if (!nat->pollData) {
- ALOGE("out of memory error starting EventLoop!");
- goto done;
- }
-
- nat->watchData = (DBusWatch **)calloc(
- DEFAULT_INITIAL_POLLFD_COUNT, sizeof(DBusWatch *));
- if (!nat->watchData) {
- ALOGE("out of memory error starting EventLoop!");
- goto done;
- }
-
- nat->pollDataSize = DEFAULT_INITIAL_POLLFD_COUNT;
- nat->pollMemberCount = 1;
-
- if (socketpair(AF_LOCAL, SOCK_STREAM, 0, &(nat->controlFdR))) {
- ALOGE("Error getting BT control socket");
- goto done;
- }
- nat->pollData[0].fd = nat->controlFdR;
- nat->pollData[0].events = POLLIN;
-
- env->GetJavaVM( &(nat->vm) );
- nat->envVer = env->GetVersion();
-
- nat->me = env->NewGlobalRef(object);
-
- if (setUpEventLoop(nat) != JNI_TRUE) {
- ALOGE("failure setting up Event Loop!");
- goto done;
- }
-
- pthread_create(&(nat->thread), NULL, eventLoopMain, nat);
- result = JNI_TRUE;
-
-done:
- if (JNI_FALSE == result) {
- if (nat->controlFdW) {
- close(nat->controlFdW);
- nat->controlFdW = 0;
- }
- if (nat->controlFdR) {
- close(nat->controlFdR);
- nat->controlFdR = 0;
- }
- if (nat->me) env->DeleteGlobalRef(nat->me);
- nat->me = NULL;
- if (nat->pollData) free(nat->pollData);
- nat->pollData = NULL;
- if (nat->watchData) free(nat->watchData);
- nat->watchData = NULL;
- nat->pollDataSize = 0;
- nat->pollMemberCount = 0;
- }
-
- pthread_mutex_unlock(&(nat->thread_mutex));
-#endif // HAVE_BLUETOOTH
- return result;
-}
-
-static void stopEventLoopNative(JNIEnv *env, jobject object) {
-#ifdef HAVE_BLUETOOTH
- native_data_t *nat = get_native_data(env, object);
-
- pthread_mutex_lock(&(nat->thread_mutex));
- if (nat->pollData) {
- char data = EVENT_LOOP_EXIT;
- ssize_t t = write(nat->controlFdW, &data, sizeof(char));
- void *ret;
- pthread_join(nat->thread, &ret);
-
- env->DeleteGlobalRef(nat->me);
- nat->me = NULL;
- free(nat->pollData);
- nat->pollData = NULL;
- free(nat->watchData);
- nat->watchData = NULL;
- nat->pollDataSize = 0;
- nat->pollMemberCount = 0;
-
- int fd = nat->controlFdW;
- nat->controlFdW = 0;
- close(fd);
- }
- nat->running = false;
- pthread_mutex_unlock(&(nat->thread_mutex));
-#endif // HAVE_BLUETOOTH
-}
-
-static jboolean isEventLoopRunningNative(JNIEnv *env, jobject object) {
- jboolean result = JNI_FALSE;
-#ifdef HAVE_BLUETOOTH
- native_data_t *nat = get_native_data(env, object);
-
- pthread_mutex_lock(&(nat->thread_mutex));
- if (nat->running) {
- result = JNI_TRUE;
- }
- pthread_mutex_unlock(&(nat->thread_mutex));
-
-#endif // HAVE_BLUETOOTH
- return result;
-}
-
-#ifdef HAVE_BLUETOOTH
-extern DBusHandlerResult a2dp_event_filter(DBusMessage *msg, JNIEnv *env);
-
-// Called by dbus during WaitForAndDispatchEventNative()
-static DBusHandlerResult event_filter(DBusConnection *conn, DBusMessage *msg,
- void *data) {
- native_data_t *nat;
- JNIEnv *env;
- DBusError err;
- DBusHandlerResult ret;
-
- dbus_error_init(&err);
-
- nat = (native_data_t *)data;
- nat->vm->GetEnv((void**)&env, nat->envVer);
- if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_SIGNAL) {
- ALOGV("%s: not interested (not a signal).", __FUNCTION__);
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
- }
-
- ALOGV("%s: Received signal %s:%s from %s", __FUNCTION__,
- dbus_message_get_interface(msg), dbus_message_get_member(msg),
- dbus_message_get_path(msg));
-
- env->PushLocalFrame(EVENT_LOOP_REFS);
- if (dbus_message_is_signal(msg,
- "org.bluez.Adapter",
- "DeviceFound")) {
- char *c_address;
- DBusMessageIter iter;
- jobjectArray str_array = NULL;
- if (dbus_message_iter_init(msg, &iter)) {
- dbus_message_iter_get_basic(&iter, &c_address);
- if (dbus_message_iter_next(&iter))
- str_array =
- parse_remote_device_properties(env, &iter);
- }
- if (str_array != NULL) {
- env->CallVoidMethod(nat->me,
- method_onDeviceFound,
- env->NewStringUTF(c_address),
- str_array);
- } else
- LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
- goto success;
- } else if (dbus_message_is_signal(msg,
- "org.bluez.Adapter",
- "DeviceDisappeared")) {
- char *c_address;
- if (dbus_message_get_args(msg, &err,
- DBUS_TYPE_STRING, &c_address,
- DBUS_TYPE_INVALID)) {
- ALOGV("... address = %s", c_address);
- env->CallVoidMethod(nat->me, method_onDeviceDisappeared,
- env->NewStringUTF(c_address));
- } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
- goto success;
- } else if (dbus_message_is_signal(msg,
- "org.bluez.Adapter",
- "DeviceCreated")) {
- char *c_object_path;
- if (dbus_message_get_args(msg, &err,
- DBUS_TYPE_OBJECT_PATH, &c_object_path,
- DBUS_TYPE_INVALID)) {
- ALOGV("... address = %s", c_object_path);
- env->CallVoidMethod(nat->me,
- method_onDeviceCreated,
- env->NewStringUTF(c_object_path));
- } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
- goto success;
- } else if (dbus_message_is_signal(msg,
- "org.bluez.Adapter",
- "DeviceRemoved")) {
- char *c_object_path;
- if (dbus_message_get_args(msg, &err,
- DBUS_TYPE_OBJECT_PATH, &c_object_path,
- DBUS_TYPE_INVALID)) {
- ALOGV("... Object Path = %s", c_object_path);
- env->CallVoidMethod(nat->me,
- method_onDeviceRemoved,
- env->NewStringUTF(c_object_path));
- } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
- goto success;
- } else if (dbus_message_is_signal(msg,
- "org.bluez.Adapter",
- "PropertyChanged")) {
- jobjectArray str_array = parse_adapter_property_change(env, msg);
- if (str_array != NULL) {
- /* Check if bluetoothd has (re)started, if so update the path. */
- jstring property =(jstring) env->GetObjectArrayElement(str_array, 0);
- const char *c_property = env->GetStringUTFChars(property, NULL);
- if (!strncmp(c_property, "Powered", strlen("Powered"))) {
- jstring value =
- (jstring) env->GetObjectArrayElement(str_array, 1);
- const char *c_value = env->GetStringUTFChars(value, NULL);
- if (!strncmp(c_value, "true", strlen("true")))
- nat->adapter = get_adapter_path(nat->conn);
- env->ReleaseStringUTFChars(value, c_value);
- }
- env->ReleaseStringUTFChars(property, c_property);
-
- env->CallVoidMethod(nat->me,
- method_onPropertyChanged,
- str_array);
- } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
- goto success;
- } else if (dbus_message_is_signal(msg,
- "org.bluez.Device",
- "PropertyChanged")) {
- jobjectArray str_array = parse_remote_device_property_change(env, msg);
- if (str_array != NULL) {
- const char *remote_device_path = dbus_message_get_path(msg);
- env->CallVoidMethod(nat->me,
- method_onDevicePropertyChanged,
- env->NewStringUTF(remote_device_path),
- str_array);
- } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
- goto success;
- } else if (dbus_message_is_signal(msg,
- "org.bluez.Device",
- "DisconnectRequested")) {
- const char *remote_device_path = dbus_message_get_path(msg);
- env->CallVoidMethod(nat->me,
- method_onDeviceDisconnectRequested,
- env->NewStringUTF(remote_device_path));
- goto success;
- } else if (dbus_message_is_signal(msg,
- "org.bluez.Input",
- "PropertyChanged")) {
-
- jobjectArray str_array =
- parse_input_property_change(env, msg);
- if (str_array != NULL) {
- const char *c_path = dbus_message_get_path(msg);
- env->CallVoidMethod(nat->me,
- method_onInputDevicePropertyChanged,
- env->NewStringUTF(c_path),
- str_array);
- } else {
- LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
- }
- goto success;
- } else if (dbus_message_is_signal(msg,
- "org.bluez.Network",
- "PropertyChanged")) {
-
- jobjectArray str_array =
- parse_pan_property_change(env, msg);
- if (str_array != NULL) {
- const char *c_path = dbus_message_get_path(msg);
- env->CallVoidMethod(nat->me,
- method_onPanDevicePropertyChanged,
- env->NewStringUTF(c_path),
- str_array);
- } else {
- LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
- }
- goto success;
- } else if (dbus_message_is_signal(msg,
- "org.bluez.NetworkServer",
- "DeviceDisconnected")) {
- char *c_address;
- if (dbus_message_get_args(msg, &err,
- DBUS_TYPE_STRING, &c_address,
- DBUS_TYPE_INVALID)) {
- env->CallVoidMethod(nat->me,
- method_onNetworkDeviceDisconnected,
- env->NewStringUTF(c_address));
- } else {
- LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
- }
- goto success;
- } else if (dbus_message_is_signal(msg,
- "org.bluez.NetworkServer",
- "DeviceConnected")) {
- char *c_address;
- char *c_iface;
- uint16_t uuid;
-
- if (dbus_message_get_args(msg, &err,
- DBUS_TYPE_STRING, &c_address,
- DBUS_TYPE_STRING, &c_iface,
- DBUS_TYPE_UINT16, &uuid,
- DBUS_TYPE_INVALID)) {
- env->CallVoidMethod(nat->me,
- method_onNetworkDeviceConnected,
- env->NewStringUTF(c_address),
- env->NewStringUTF(c_iface),
- uuid);
- } else {
- LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
- }
- goto success;
- } else if (dbus_message_is_signal(msg,
- "org.bluez.HealthDevice",
- "ChannelConnected")) {
- const char *c_path = dbus_message_get_path(msg);
- const char *c_channel_path;
- jboolean exists = JNI_TRUE;
- if (dbus_message_get_args(msg, &err,
- DBUS_TYPE_OBJECT_PATH, &c_channel_path,
- DBUS_TYPE_INVALID)) {
- env->CallVoidMethod(nat->me,
- method_onHealthDeviceChannelChanged,
- env->NewStringUTF(c_path),
- env->NewStringUTF(c_channel_path),
- exists);
- } else {
- LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
- }
- goto success;
- } else if (dbus_message_is_signal(msg,
- "org.bluez.HealthDevice",
- "ChannelDeleted")) {
-
- const char *c_path = dbus_message_get_path(msg);
- const char *c_channel_path;
- jboolean exists = JNI_FALSE;
- if (dbus_message_get_args(msg, &err,
- DBUS_TYPE_OBJECT_PATH, &c_channel_path,
- DBUS_TYPE_INVALID)) {
- env->CallVoidMethod(nat->me,
- method_onHealthDeviceChannelChanged,
- env->NewStringUTF(c_path),
- env->NewStringUTF(c_channel_path),
- exists);
- } else {
- LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
- }
- goto success;
- } else if (dbus_message_is_signal(msg,
- "org.bluez.HealthDevice",
- "PropertyChanged")) {
- jobjectArray str_array =
- parse_health_device_property_change(env, msg);
- if (str_array != NULL) {
- const char *c_path = dbus_message_get_path(msg);
- env->CallVoidMethod(nat->me,
- method_onHealthDevicePropertyChanged,
- env->NewStringUTF(c_path),
- str_array);
- } else {
- LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
- }
- goto success;
- }
-
- ret = a2dp_event_filter(msg, env);
- env->PopLocalFrame(NULL);
- return ret;
-
-success:
- env->PopLocalFrame(NULL);
- return DBUS_HANDLER_RESULT_HANDLED;
-}
-
-// Called by dbus during WaitForAndDispatchEventNative()
-DBusHandlerResult agent_event_filter(DBusConnection *conn,
- DBusMessage *msg, void *data) {
- native_data_t *nat = (native_data_t *)data;
- JNIEnv *env;
- if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_METHOD_CALL) {
- ALOGV("%s: not interested (not a method call).", __FUNCTION__);
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
- }
- ALOGI("%s: Received method %s:%s", __FUNCTION__,
- dbus_message_get_interface(msg), dbus_message_get_member(msg));
-
- if (nat == NULL) return DBUS_HANDLER_RESULT_HANDLED;
-
- nat->vm->GetEnv((void**)&env, nat->envVer);
- env->PushLocalFrame(EVENT_LOOP_REFS);
-
- if (dbus_message_is_method_call(msg,
- "org.bluez.Agent", "Cancel")) {
- env->CallVoidMethod(nat->me, method_onAgentCancel);
- // reply
- DBusMessage *reply = dbus_message_new_method_return(msg);
- if (!reply) {
- ALOGE("%s: Cannot create message reply\n", __FUNCTION__);
- goto failure;
- }
- dbus_connection_send(nat->conn, reply, NULL);
- dbus_message_unref(reply);
- goto success;
-
- } else if (dbus_message_is_method_call(msg,
- "org.bluez.Agent", "Authorize")) {
- char *object_path;
- const char *uuid;
- if (!dbus_message_get_args(msg, NULL,
- DBUS_TYPE_OBJECT_PATH, &object_path,
- DBUS_TYPE_STRING, &uuid,
- DBUS_TYPE_INVALID)) {
- ALOGE("%s: Invalid arguments for Authorize() method", __FUNCTION__);
- goto failure;
- }
-
- ALOGV("... object_path = %s", object_path);
- ALOGV("... uuid = %s", uuid);
-
- dbus_message_ref(msg); // increment refcount because we pass to java
- env->CallVoidMethod(nat->me, method_onAgentAuthorize,
- env->NewStringUTF(object_path), env->NewStringUTF(uuid),
- int(msg));
-
- goto success;
- } else if (dbus_message_is_method_call(msg,
- "org.bluez.Agent", "OutOfBandAvailable")) {
- char *object_path;
- if (!dbus_message_get_args(msg, NULL,
- DBUS_TYPE_OBJECT_PATH, &object_path,
- DBUS_TYPE_INVALID)) {
- ALOGE("%s: Invalid arguments for OutOfBandData available() method", __FUNCTION__);
- goto failure;
- }
-
- ALOGV("... object_path = %s", object_path);
-
- bool available =
- env->CallBooleanMethod(nat->me, method_onAgentOutOfBandDataAvailable,
- env->NewStringUTF(object_path));
-
-
- // reply
- if (available) {
- DBusMessage *reply = dbus_message_new_method_return(msg);
- if (!reply) {
- ALOGE("%s: Cannot create message reply\n", __FUNCTION__);
- goto failure;
- }
- dbus_connection_send(nat->conn, reply, NULL);
- dbus_message_unref(reply);
- } else {
- DBusMessage *reply = dbus_message_new_error(msg,
- "org.bluez.Error.DoesNotExist", "OutofBand data not available");
- if (!reply) {
- ALOGE("%s: Cannot create message reply\n", __FUNCTION__);
- goto failure;
- }
- dbus_connection_send(nat->conn, reply, NULL);
- dbus_message_unref(reply);
- }
- goto success;
- } else if (dbus_message_is_method_call(msg,
- "org.bluez.Agent", "RequestPinCode")) {
- char *object_path;
- if (!dbus_message_get_args(msg, NULL,
- DBUS_TYPE_OBJECT_PATH, &object_path,
- DBUS_TYPE_INVALID)) {
- ALOGE("%s: Invalid arguments for RequestPinCode() method", __FUNCTION__);
- goto failure;
- }
-
- dbus_message_ref(msg); // increment refcount because we pass to java
- env->CallVoidMethod(nat->me, method_onRequestPinCode,
- env->NewStringUTF(object_path),
- int(msg));
- goto success;
- } else if (dbus_message_is_method_call(msg,
- "org.bluez.Agent", "RequestPasskey")) {
- char *object_path;
- if (!dbus_message_get_args(msg, NULL,
- DBUS_TYPE_OBJECT_PATH, &object_path,
- DBUS_TYPE_INVALID)) {
- ALOGE("%s: Invalid arguments for RequestPasskey() method", __FUNCTION__);
- goto failure;
- }
-
- dbus_message_ref(msg); // increment refcount because we pass to java
- env->CallVoidMethod(nat->me, method_onRequestPasskey,
- env->NewStringUTF(object_path),
- int(msg));
- goto success;
- } else if (dbus_message_is_method_call(msg,
- "org.bluez.Agent", "RequestOobData")) {
- char *object_path;
- if (!dbus_message_get_args(msg, NULL,
- DBUS_TYPE_OBJECT_PATH, &object_path,
- DBUS_TYPE_INVALID)) {
- ALOGE("%s: Invalid arguments for RequestOobData() method", __FUNCTION__);
- goto failure;
- }
-
- dbus_message_ref(msg); // increment refcount because we pass to java
- env->CallVoidMethod(nat->me, method_onRequestOobData,
- env->NewStringUTF(object_path),
- int(msg));
- goto success;
- } else if (dbus_message_is_method_call(msg,
- "org.bluez.Agent", "DisplayPasskey")) {
- char *object_path;
- uint32_t passkey;
- if (!dbus_message_get_args(msg, NULL,
- DBUS_TYPE_OBJECT_PATH, &object_path,
- DBUS_TYPE_UINT32, &passkey,
- DBUS_TYPE_INVALID)) {
- ALOGE("%s: Invalid arguments for RequestPasskey() method", __FUNCTION__);
- goto failure;
- }
-
- dbus_message_ref(msg); // increment refcount because we pass to java
- env->CallVoidMethod(nat->me, method_onDisplayPasskey,
- env->NewStringUTF(object_path),
- passkey,
- int(msg));
- goto success;
- } else if (dbus_message_is_method_call(msg,
- "org.bluez.Agent", "RequestConfirmation")) {
- char *object_path;
- uint32_t passkey;
- if (!dbus_message_get_args(msg, NULL,
- DBUS_TYPE_OBJECT_PATH, &object_path,
- DBUS_TYPE_UINT32, &passkey,
- DBUS_TYPE_INVALID)) {
- ALOGE("%s: Invalid arguments for RequestConfirmation() method", __FUNCTION__);
- goto failure;
- }
-
- dbus_message_ref(msg); // increment refcount because we pass to java
- env->CallVoidMethod(nat->me, method_onRequestPasskeyConfirmation,
- env->NewStringUTF(object_path),
- passkey,
- int(msg));
- goto success;
- } else if (dbus_message_is_method_call(msg,
- "org.bluez.Agent", "RequestPairingConsent")) {
- char *object_path;
- if (!dbus_message_get_args(msg, NULL,
- DBUS_TYPE_OBJECT_PATH, &object_path,
- DBUS_TYPE_INVALID)) {
- ALOGE("%s: Invalid arguments for RequestPairingConsent() method", __FUNCTION__);
- goto failure;
- }
-
- dbus_message_ref(msg); // increment refcount because we pass to java
- env->CallVoidMethod(nat->me, method_onRequestPairingConsent,
- env->NewStringUTF(object_path),
- int(msg));
- goto success;
- } else if (dbus_message_is_method_call(msg,
- "org.bluez.Agent", "Release")) {
- // reply
- DBusMessage *reply = dbus_message_new_method_return(msg);
- if (!reply) {
- ALOGE("%s: Cannot create message reply\n", __FUNCTION__);
- goto failure;
- }
- dbus_connection_send(nat->conn, reply, NULL);
- dbus_message_unref(reply);
- goto success;
- } else {
- ALOGV("%s:%s is ignored", dbus_message_get_interface(msg), dbus_message_get_member(msg));
- }
-
-failure:
- env->PopLocalFrame(NULL);
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
-success:
- env->PopLocalFrame(NULL);
- return DBUS_HANDLER_RESULT_HANDLED;
-
-}
-#endif
-
-
-#ifdef HAVE_BLUETOOTH
-
-void onCreatePairedDeviceResult(DBusMessage *msg, void *user, void *n) {
- ALOGV("%s", __FUNCTION__);
-
- native_data_t *nat = (native_data_t *)n;
- const char *address = (const char *)user;
- DBusError err;
- dbus_error_init(&err);
- JNIEnv *env;
- jstring addr;
-
- nat->vm->GetEnv((void**)&env, nat->envVer);
-
- ALOGV("... address = %s", address);
-
- jint result = BOND_RESULT_SUCCESS;
- if (dbus_set_error_from_message(&err, msg)) {
- if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AuthenticationFailed")) {
- // Pins did not match, or remote device did not respond to pin
- // request in time
- ALOGV("... error = %s (%s)\n", err.name, err.message);
- result = BOND_RESULT_AUTH_FAILED;
- } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AuthenticationRejected")) {
- // We rejected pairing, or the remote side rejected pairing. This
- // happens if either side presses 'cancel' at the pairing dialog.
- ALOGV("... error = %s (%s)\n", err.name, err.message);
- result = BOND_RESULT_AUTH_REJECTED;
- } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AuthenticationCanceled")) {
- // Not sure if this happens
- ALOGV("... error = %s (%s)\n", err.name, err.message);
- result = BOND_RESULT_AUTH_CANCELED;
- } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.ConnectionAttemptFailed")) {
- // Other device is not responding at all
- ALOGV("... error = %s (%s)\n", err.name, err.message);
- result = BOND_RESULT_REMOTE_DEVICE_DOWN;
- } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AlreadyExists")) {
- // already bonded
- ALOGV("... error = %s (%s)\n", err.name, err.message);
- result = BOND_RESULT_SUCCESS;
- } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.InProgress") &&
- !strcmp(err.message, "Bonding in progress")) {
- ALOGV("... error = %s (%s)\n", err.name, err.message);
- goto done;
- } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.InProgress") &&
- !strcmp(err.message, "Discover in progress")) {
- ALOGV("... error = %s (%s)\n", err.name, err.message);
- result = BOND_RESULT_DISCOVERY_IN_PROGRESS;
- } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.RepeatedAttempts")) {
- ALOGV("... error = %s (%s)\n", err.name, err.message);
- result = BOND_RESULT_REPEATED_ATTEMPTS;
- } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AuthenticationTimeout")) {
- ALOGV("... error = %s (%s)\n", err.name, err.message);
- result = BOND_RESULT_AUTH_TIMEOUT;
- } else {
- ALOGE("%s: D-Bus error: %s (%s)\n", __FUNCTION__, err.name, err.message);
- result = BOND_RESULT_ERROR;
- }
- }
-
- addr = env->NewStringUTF(address);
- env->CallVoidMethod(nat->me,
- method_onCreatePairedDeviceResult,
- addr,
- result);
- env->DeleteLocalRef(addr);
-done:
- dbus_error_free(&err);
- free(user);
-}
-
-void onCreateDeviceResult(DBusMessage *msg, void *user, void *n) {
- ALOGV("%s", __FUNCTION__);
-
- native_data_t *nat = (native_data_t *)n;
- const char *address= (const char *)user;
- DBusError err;
- dbus_error_init(&err);
- JNIEnv *env;
- nat->vm->GetEnv((void**)&env, nat->envVer);
-
- ALOGV("... Address = %s", address);
-
- jint result = CREATE_DEVICE_SUCCESS;
- if (dbus_set_error_from_message(&err, msg)) {
- if (dbus_error_has_name(&err, "org.bluez.Error.AlreadyExists")) {
- result = CREATE_DEVICE_ALREADY_EXISTS;
- } else {
- result = CREATE_DEVICE_FAILED;
- }
- LOG_AND_FREE_DBUS_ERROR(&err);
- }
- jstring addr = env->NewStringUTF(address);
- env->CallVoidMethod(nat->me,
- method_onCreateDeviceResult,
- addr,
- result);
- env->DeleteLocalRef(addr);
- free(user);
-}
-
-void onDiscoverServicesResult(DBusMessage *msg, void *user, void *n) {
- ALOGV("%s", __FUNCTION__);
-
- native_data_t *nat = (native_data_t *)n;
- const char *path = (const char *)user;
- DBusError err;
- dbus_error_init(&err);
- JNIEnv *env;
- nat->vm->GetEnv((void**)&env, nat->envVer);
-
- ALOGV("... Device Path = %s", path);
-
- bool result = JNI_TRUE;
- if (dbus_set_error_from_message(&err, msg)) {
- LOG_AND_FREE_DBUS_ERROR(&err);
- result = JNI_FALSE;
- }
- jstring jPath = env->NewStringUTF(path);
- env->CallVoidMethod(nat->me,
- method_onDiscoverServicesResult,
- jPath,
- result);
- env->DeleteLocalRef(jPath);
- free(user);
-}
-
-void onGetDeviceServiceChannelResult(DBusMessage *msg, void *user, void *n) {
- ALOGV("%s", __FUNCTION__);
-
- const char *address = (const char *) user;
- native_data_t *nat = (native_data_t *) n;
-
- DBusError err;
- dbus_error_init(&err);
- JNIEnv *env;
- nat->vm->GetEnv((void**)&env, nat->envVer);
-
- jint channel = -2;
-
- ALOGV("... address = %s", address);
-
- if (dbus_set_error_from_message(&err, msg) ||
- !dbus_message_get_args(msg, &err,
- DBUS_TYPE_INT32, &channel,
- DBUS_TYPE_INVALID)) {
- ALOGE("%s: D-Bus error: %s (%s)\n", __FUNCTION__, err.name, err.message);
- dbus_error_free(&err);
- }
-
-done:
- jstring addr = env->NewStringUTF(address);
- env->CallVoidMethod(nat->me,
- method_onGetDeviceServiceChannelResult,
- addr,
- channel);
- env->DeleteLocalRef(addr);
- free(user);
-}
-
-void onInputDeviceConnectionResult(DBusMessage *msg, void *user, void *n) {
- ALOGV("%s", __FUNCTION__);
-
- native_data_t *nat = (native_data_t *)n;
- const char *path = (const char *)user;
- DBusError err;
- dbus_error_init(&err);
- JNIEnv *env;
- nat->vm->GetEnv((void**)&env, nat->envVer);
-
- jint result = INPUT_OPERATION_SUCCESS;
- if (dbus_set_error_from_message(&err, msg)) {
- if (!strcmp(err.name, BLUEZ_ERROR_IFC ".ConnectionAttemptFailed")) {
- result = INPUT_CONNECT_FAILED_ATTEMPT_FAILED;
- } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".AlreadyConnected")) {
- result = INPUT_CONNECT_FAILED_ALREADY_CONNECTED;
- } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".Failed")) {
- // TODO():This is flaky, need to change Bluez to add new error codes
- if (!strcmp(err.message, "Transport endpoint is not connected")) {
- result = INPUT_DISCONNECT_FAILED_NOT_CONNECTED;
- } else {
- result = INPUT_OPERATION_GENERIC_FAILURE;
- }
- } else {
- result = INPUT_OPERATION_GENERIC_FAILURE;
- }
- LOG_AND_FREE_DBUS_ERROR(&err);
- }
-
- ALOGV("... Device Path = %s, result = %d", path, result);
- jstring jPath = env->NewStringUTF(path);
- env->CallVoidMethod(nat->me,
- method_onInputDeviceConnectionResult,
- jPath,
- result);
- env->DeleteLocalRef(jPath);
- free(user);
-}
-
-void onPanDeviceConnectionResult(DBusMessage *msg, void *user, void *n) {
- ALOGV("%s", __FUNCTION__);
-
- native_data_t *nat = (native_data_t *)n;
- const char *path = (const char *)user;
- DBusError err;
- dbus_error_init(&err);
- JNIEnv *env;
- nat->vm->GetEnv((void**)&env, nat->envVer);
-
- jint result = PAN_OPERATION_SUCCESS;
- if (dbus_set_error_from_message(&err, msg)) {
- if (!strcmp(err.name, BLUEZ_ERROR_IFC ".ConnectionAttemptFailed")) {
- result = PAN_CONNECT_FAILED_ATTEMPT_FAILED;
- } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".Failed")) {
- // TODO():This is flaky, need to change Bluez to add new error codes
- if (!strcmp(err.message, "Device already connected")) {
- result = PAN_CONNECT_FAILED_ALREADY_CONNECTED;
- } else if (!strcmp(err.message, "Device not connected")) {
- result = PAN_DISCONNECT_FAILED_NOT_CONNECTED;
- } else {
- result = PAN_OPERATION_GENERIC_FAILURE;
- }
- } else {
- result = PAN_OPERATION_GENERIC_FAILURE;
- }
- LOG_AND_FREE_DBUS_ERROR(&err);
- }
-
- ALOGV("... Pan Device Path = %s, result = %d", path, result);
- jstring jPath = env->NewStringUTF(path);
- env->CallVoidMethod(nat->me,
- method_onPanDeviceConnectionResult,
- jPath,
- result);
- env->DeleteLocalRef(jPath);
- free(user);
-}
-
-void onHealthDeviceConnectionResult(DBusMessage *msg, void *user, void *n) {
- ALOGV("%s", __FUNCTION__);
-
- native_data_t *nat = (native_data_t *)n;
- DBusError err;
- dbus_error_init(&err);
- JNIEnv *env;
- nat->vm->GetEnv((void**)&env, nat->envVer);
-
- jint result = HEALTH_OPERATION_SUCCESS;
- if (dbus_set_error_from_message(&err, msg)) {
- if (!strcmp(err.name, BLUEZ_ERROR_IFC ".InvalidArgs")) {
- result = HEALTH_OPERATION_INVALID_ARGS;
- } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".HealthError")) {
- result = HEALTH_OPERATION_ERROR;
- } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".NotFound")) {
- result = HEALTH_OPERATION_NOT_FOUND;
- } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".NotAllowed")) {
- result = HEALTH_OPERATION_NOT_ALLOWED;
- } else {
- result = HEALTH_OPERATION_GENERIC_FAILURE;
- }
- LOG_AND_FREE_DBUS_ERROR(&err);
- }
-
- jint code = *(int *) user;
- ALOGV("... Health Device Code = %d, result = %d", code, result);
- env->CallVoidMethod(nat->me,
- method_onHealthDeviceConnectionResult,
- code,
- result);
- free(user);
-}
-#endif
-
-static JNINativeMethod sMethods[] = {
- /* name, signature, funcPtr */
- {"classInitNative", "()V", (void *)classInitNative},
- {"initializeNativeDataNative", "()V", (void *)initializeNativeDataNative},
- {"cleanupNativeDataNative", "()V", (void *)cleanupNativeDataNative},
- {"startEventLoopNative", "()V", (void *)startEventLoopNative},
- {"stopEventLoopNative", "()V", (void *)stopEventLoopNative},
- {"isEventLoopRunningNative", "()Z", (void *)isEventLoopRunningNative}
-};
-
-int register_android_server_BluetoothEventLoop(JNIEnv *env) {
- return AndroidRuntime::registerNativeMethods(env,
- "android/server/BluetoothEventLoop", sMethods, NELEM(sMethods));
-}
-
-} /* namespace android */
diff --git a/core/jni/android_server_BluetoothService.cpp b/core/jni/android_server_BluetoothService.cpp
deleted file mode 100644
index 6c11121..0000000
--- a/core/jni/android_server_BluetoothService.cpp
+++ /dev/null
@@ -1,1785 +0,0 @@
-/*
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#define DBUS_ADAPTER_IFACE BLUEZ_DBUS_BASE_IFC ".Adapter"
-#define DBUS_DEVICE_IFACE BLUEZ_DBUS_BASE_IFC ".Device"
-#define DBUS_INPUT_IFACE BLUEZ_DBUS_BASE_IFC ".Input"
-#define DBUS_NETWORK_IFACE BLUEZ_DBUS_BASE_IFC ".Network"
-#define DBUS_NETWORKSERVER_IFACE BLUEZ_DBUS_BASE_IFC ".NetworkServer"
-#define DBUS_HEALTH_MANAGER_PATH "/org/bluez"
-#define DBUS_HEALTH_MANAGER_IFACE BLUEZ_DBUS_BASE_IFC ".HealthManager"
-#define DBUS_HEALTH_DEVICE_IFACE BLUEZ_DBUS_BASE_IFC ".HealthDevice"
-#define DBUS_HEALTH_CHANNEL_IFACE BLUEZ_DBUS_BASE_IFC ".HealthChannel"
-
-#define LOG_TAG "BluetoothService.cpp"
-
-#include "android_bluetooth_common.h"
-#include "android_runtime/AndroidRuntime.h"
-#include "android_util_Binder.h"
-#include "JNIHelp.h"
-#include "jni.h"
-#include "utils/Log.h"
-#include "utils/misc.h"
-
-#include <ctype.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-
-#ifdef HAVE_BLUETOOTH
-#include <dbus/dbus.h>
-#include <bluedroid/bluetooth.h>
-#endif
-
-#include <cutils/properties.h>
-
-namespace android {
-
-#define BLUETOOTH_CLASS_ERROR 0xFF000000
-#define PROPERTIES_NREFS 10
-
-#ifdef HAVE_BLUETOOTH
-// We initialize these variables when we load class
-// android.server.BluetoothService
-static jfieldID field_mNativeData;
-static jfieldID field_mEventLoop;
-
-typedef struct {
- JNIEnv *env;
- DBusConnection *conn;
- const char *adapter; // dbus object name of the local adapter
-} native_data_t;
-
-extern event_loop_native_data_t *get_EventLoop_native_data(JNIEnv *,
- jobject);
-extern DBusHandlerResult agent_event_filter(DBusConnection *conn,
- DBusMessage *msg,
- void *data);
-void onCreatePairedDeviceResult(DBusMessage *msg, void *user, void *nat);
-void onDiscoverServicesResult(DBusMessage *msg, void *user, void *nat);
-void onCreateDeviceResult(DBusMessage *msg, void *user, void *nat);
-void onInputDeviceConnectionResult(DBusMessage *msg, void *user, void *nat);
-void onPanDeviceConnectionResult(DBusMessage *msg, void *user, void *nat);
-void onHealthDeviceConnectionResult(DBusMessage *msg, void *user, void *nat);
-
-
-/** Get native data stored in the opaque (Java code maintained) pointer mNativeData
- * Perform quick sanity check, if there are any problems return NULL
- */
-static inline native_data_t * get_native_data(JNIEnv *env, jobject object) {
- native_data_t *nat =
- (native_data_t *)(env->GetIntField(object, field_mNativeData));
- if (nat == NULL || nat->conn == NULL) {
- ALOGE("Uninitialized native data\n");
- return NULL;
- }
- return nat;
-}
-#endif
-
-static void classInitNative(JNIEnv* env, jclass clazz) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- field_mNativeData = get_field(env, clazz, "mNativeData", "I");
- field_mEventLoop = get_field(env, clazz, "mEventLoop",
- "Landroid/server/BluetoothEventLoop;");
-#endif
-}
-
-/* Returns true on success (even if adapter is present but disabled).
- * Return false if dbus is down, or another serious error (out of memory)
-*/
-static bool initializeNativeDataNative(JNIEnv* env, jobject object) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- native_data_t *nat = (native_data_t *)calloc(1, sizeof(native_data_t));
- if (NULL == nat) {
- ALOGE("%s: out of memory!", __FUNCTION__);
- return false;
- }
- nat->env = env;
-
- env->SetIntField(object, field_mNativeData, (jint)nat);
- DBusError err;
- dbus_error_init(&err);
- dbus_threads_init_default();
- nat->conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
- if (dbus_error_is_set(&err)) {
- ALOGE("Could not get onto the system bus: %s", err.message);
- dbus_error_free(&err);
- return false;
- }
- dbus_connection_set_exit_on_disconnect(nat->conn, FALSE);
-#endif /*HAVE_BLUETOOTH*/
- return true;
-}
-
-static const char *get_adapter_path(JNIEnv* env, jobject object) {
-#ifdef HAVE_BLUETOOTH
- event_loop_native_data_t *event_nat =
- get_EventLoop_native_data(env, env->GetObjectField(object,
- field_mEventLoop));
- if (event_nat == NULL)
- return NULL;
- return event_nat->adapter;
-#else
- return NULL;
-#endif
-}
-
-// This function is called when the adapter is enabled.
-static jboolean setupNativeDataNative(JNIEnv* env, jobject object) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- native_data_t *nat =
- (native_data_t *)env->GetIntField(object, field_mNativeData);
- event_loop_native_data_t *event_nat =
- get_EventLoop_native_data(env, env->GetObjectField(object,
- field_mEventLoop));
- // Register agent for remote devices.
- const char *device_agent_path = "/android/bluetooth/remote_device_agent";
- static const DBusObjectPathVTable agent_vtable = {
- NULL, agent_event_filter, NULL, NULL, NULL, NULL };
-
- if (!dbus_connection_register_object_path(nat->conn, device_agent_path,
- &agent_vtable, event_nat)) {
- ALOGE("%s: Can't register object path %s for remote device agent!",
- __FUNCTION__, device_agent_path);
- return JNI_FALSE;
- }
-#endif /*HAVE_BLUETOOTH*/
- return JNI_TRUE;
-}
-
-static jboolean tearDownNativeDataNative(JNIEnv *env, jobject object) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- native_data_t *nat =
- (native_data_t *)env->GetIntField(object, field_mNativeData);
- if (nat != NULL) {
- const char *device_agent_path =
- "/android/bluetooth/remote_device_agent";
- dbus_connection_unregister_object_path (nat->conn, device_agent_path);
- }
-#endif /*HAVE_BLUETOOTH*/
- return JNI_TRUE;
-}
-
-static void cleanupNativeDataNative(JNIEnv* env, jobject object) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- native_data_t *nat =
- (native_data_t *)env->GetIntField(object, field_mNativeData);
- if (nat) {
- free(nat);
- nat = NULL;
- }
-#endif
-}
-
-static jstring getAdapterPathNative(JNIEnv *env, jobject object) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- native_data_t *nat = get_native_data(env, object);
- if (nat) {
- return (env->NewStringUTF(get_adapter_path(env, object)));
- }
-#endif
- return NULL;
-}
-
-
-static jboolean startDiscoveryNative(JNIEnv *env, jobject object) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- DBusMessage *msg = NULL;
- DBusMessage *reply = NULL;
- DBusError err;
- const char *name;
- jboolean ret = JNI_FALSE;
-
- native_data_t *nat = get_native_data(env, object);
- if (nat == NULL) {
- goto done;
- }
-
- dbus_error_init(&err);
-
- /* Compose the command */
- msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
- get_adapter_path(env, object),
- DBUS_ADAPTER_IFACE, "StartDiscovery");
-
- if (msg == NULL) {
- if (dbus_error_is_set(&err)) {
- LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
- }
- goto done;
- }
-
- /* Send the command. */
- reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);
- if (dbus_error_is_set(&err)) {
- LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
- ret = JNI_FALSE;
- goto done;
- }
-
- ret = JNI_TRUE;
-done:
- if (reply) dbus_message_unref(reply);
- if (msg) dbus_message_unref(msg);
- return ret;
-#else
- return JNI_FALSE;
-#endif
-}
-
-static jboolean stopDiscoveryNative(JNIEnv *env, jobject object) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- DBusMessage *msg = NULL;
- DBusMessage *reply = NULL;
- DBusError err;
- const char *name;
- native_data_t *nat;
- jboolean ret = JNI_FALSE;
-
- dbus_error_init(&err);
-
- nat = get_native_data(env, object);
- if (nat == NULL) {
- goto done;
- }
-
- /* Compose the command */
- msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
- get_adapter_path(env, object),
- DBUS_ADAPTER_IFACE, "StopDiscovery");
- if (msg == NULL) {
- if (dbus_error_is_set(&err))
- LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
- goto done;
- }
-
- /* Send the command. */
- reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);
- if (dbus_error_is_set(&err)) {
- if(strncmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.NotAuthorized",
- strlen(BLUEZ_DBUS_BASE_IFC ".Error.NotAuthorized")) == 0) {
- // hcid sends this if there is no active discovery to cancel
- ALOGV("%s: There was no active discovery to cancel", __FUNCTION__);
- dbus_error_free(&err);
- } else {
- LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
- }
- goto done;
- }
-
- ret = JNI_TRUE;
-done:
- if (msg) dbus_message_unref(msg);
- if (reply) dbus_message_unref(reply);
- return ret;
-#else
- return JNI_FALSE;
-#endif
-}
-
-static jbyteArray readAdapterOutOfBandDataNative(JNIEnv *env, jobject object) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- native_data_t *nat = get_native_data(env, object);
- DBusError err;
- jbyte *hash, *randomizer;
- jbyteArray byteArray = NULL;
- int hash_len, r_len;
- if (nat) {
- DBusMessage *reply = dbus_func_args(env, nat->conn,
- get_adapter_path(env, object),
- DBUS_ADAPTER_IFACE, "ReadLocalOutOfBandData",
- DBUS_TYPE_INVALID);
- if (!reply) return NULL;
-
- dbus_error_init(&err);
- if (dbus_message_get_args(reply, &err,
- DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &hash, &hash_len,
- DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &randomizer, &r_len,
- DBUS_TYPE_INVALID)) {
- if (hash_len == 16 && r_len == 16) {
- byteArray = env->NewByteArray(32);
- if (byteArray) {
- env->SetByteArrayRegion(byteArray, 0, 16, hash);
- env->SetByteArrayRegion(byteArray, 16, 16, randomizer);
- }
- } else {
- ALOGE("readAdapterOutOfBandDataNative: Hash len = %d, R len = %d",
- hash_len, r_len);
- }
- } else {
- LOG_AND_FREE_DBUS_ERROR(&err);
- }
- dbus_message_unref(reply);
- return byteArray;
- }
-#endif
- return NULL;
-}
-
-static jboolean createPairedDeviceNative(JNIEnv *env, jobject object,
- jstring address, jint timeout_ms) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- native_data_t *nat = get_native_data(env, object);
- jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
- struct event_loop_native_data_t *eventLoopNat =
- get_EventLoop_native_data(env, eventLoop);
-
- if (nat && eventLoopNat) {
- const char *c_address = env->GetStringUTFChars(address, NULL);
- ALOGV("... address = %s", c_address);
- char *context_address = (char *)calloc(BTADDR_SIZE, sizeof(char));
- const char *capabilities = "DisplayYesNo";
- const char *agent_path = "/android/bluetooth/remote_device_agent";
-
- strlcpy(context_address, c_address, BTADDR_SIZE); // for callback
- bool ret = dbus_func_args_async(env, nat->conn, (int)timeout_ms,
- onCreatePairedDeviceResult, // callback
- context_address,
- eventLoopNat,
- get_adapter_path(env, object),
- DBUS_ADAPTER_IFACE,
- "CreatePairedDevice",
- DBUS_TYPE_STRING, &c_address,
- DBUS_TYPE_OBJECT_PATH, &agent_path,
- DBUS_TYPE_STRING, &capabilities,
- DBUS_TYPE_INVALID);
- env->ReleaseStringUTFChars(address, c_address);
- return ret ? JNI_TRUE : JNI_FALSE;
-
- }
-#endif
- return JNI_FALSE;
-}
-
-static jboolean createPairedDeviceOutOfBandNative(JNIEnv *env, jobject object,
- jstring address, jint timeout_ms) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- native_data_t *nat = get_native_data(env, object);
- jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
- struct event_loop_native_data_t *eventLoopNat =
- get_EventLoop_native_data(env, eventLoop);
-
- if (nat && eventLoopNat) {
- const char *c_address = env->GetStringUTFChars(address, NULL);
- ALOGV("... address = %s", c_address);
- char *context_address = (char *)calloc(BTADDR_SIZE, sizeof(char));
- const char *capabilities = "DisplayYesNo";
- const char *agent_path = "/android/bluetooth/remote_device_agent";
-
- strlcpy(context_address, c_address, BTADDR_SIZE); // for callback
- bool ret = dbus_func_args_async(env, nat->conn, (int)timeout_ms,
- onCreatePairedDeviceResult, // callback
- context_address,
- eventLoopNat,
- get_adapter_path(env, object),
- DBUS_ADAPTER_IFACE,
- "CreatePairedDeviceOutOfBand",
- DBUS_TYPE_STRING, &c_address,
- DBUS_TYPE_OBJECT_PATH, &agent_path,
- DBUS_TYPE_STRING, &capabilities,
- DBUS_TYPE_INVALID);
- env->ReleaseStringUTFChars(address, c_address);
- return ret ? JNI_TRUE : JNI_FALSE;
- }
-#endif
- return JNI_FALSE;
-}
-
-static jint getDeviceServiceChannelNative(JNIEnv *env, jobject object,
- jstring path,
- jstring pattern, jint attr_id) {
-#ifdef HAVE_BLUETOOTH
- ALOGV("%s", __FUNCTION__);
- native_data_t *nat = get_native_data(env, object);
- jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
- struct event_loop_native_data_t *eventLoopNat =
- get_EventLoop_native_data(env, eventLoop);
- if (nat && eventLoopNat) {
- const char *c_pattern = env->GetStringUTFChars(pattern, NULL);
- const char *c_path = env->GetStringUTFChars(path, NULL);
- ALOGV("... pattern = %s", c_pattern);
- ALOGV("... attr_id = %#X", attr_id);
- DBusMessage *reply =
- dbus_func_args(env, nat->conn, c_path,
- DBUS_DEVICE_IFACE, "GetServiceAttributeValue",
- DBUS_TYPE_STRING, &c_pattern,
- DBUS_TYPE_UINT16, &attr_id,
- DBUS_TYPE_INVALID);
- env->ReleaseStringUTFChars(pattern, c_pattern);
- env->ReleaseStringUTFChars(path, c_path);
- return reply ? dbus_returns_int32(env, reply) : -1;
- }
-#endif
- return -1;
-}
-
-static jboolean cancelDeviceCreationNative(JNIEnv *env, jobject object,
- jstring address) {
- ALOGV("%s", __FUNCTION__);
- jboolean result = JNI_FALSE;
-#ifdef HAVE_BLUETOOTH
- native_data_t *nat = get_native_data(env, object);
- if (nat) {
- const char *c_address = env->GetStringUTFChars(address, NULL);
- DBusError err;
- dbus_error_init(&err);
- ALOGV("... address = %s", c_address);
- DBusMessage *reply =
- dbus_func_args_timeout(env, nat->conn, -1,
- get_adapter_path(env, object),
- DBUS_ADAPTER_IFACE, "CancelDeviceCreation",
- DBUS_TYPE_STRING, &c_address,
- DBUS_TYPE_INVALID);
- env->ReleaseStringUTFChars(address, c_address);
- if (!reply) {
- if (dbus_error_is_set(&err)) {
- LOG_AND_FREE_DBUS_ERROR(&err);
- } else
- ALOGE("DBus reply is NULL in function %s", __FUNCTION__);
- return JNI_FALSE;
- } else {
- result = JNI_TRUE;
- }
- dbus_message_unref(reply);
- }
-#endif
- return JNI_FALSE;
-}
-
-static jboolean removeDeviceNative(JNIEnv *env, jobject object, jstring object_path) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- native_data_t *nat = get_native_data(env, object);
- if (nat) {
- const char *c_object_path = env->GetStringUTFChars(object_path, NULL);
- bool ret = dbus_func_args_async(env, nat->conn, -1,
- NULL,
- NULL,
- NULL,
- get_adapter_path(env, object),
- DBUS_ADAPTER_IFACE,
- "RemoveDevice",
- DBUS_TYPE_OBJECT_PATH, &c_object_path,
- DBUS_TYPE_INVALID);
- env->ReleaseStringUTFChars(object_path, c_object_path);
- return ret ? JNI_TRUE : JNI_FALSE;
- }
-#endif
- return JNI_FALSE;
-}
-
-static jint enableNative(JNIEnv *env, jobject object) {
-#ifdef HAVE_BLUETOOTH
- ALOGV("%s", __FUNCTION__);
- return bt_enable();
-#endif
- return -1;
-}
-
-static jint disableNative(JNIEnv *env, jobject object) {
-#ifdef HAVE_BLUETOOTH
- ALOGV("%s", __FUNCTION__);
- return bt_disable();
-#endif
- return -1;
-}
-
-static jint isEnabledNative(JNIEnv *env, jobject object) {
-#ifdef HAVE_BLUETOOTH
- ALOGV("%s", __FUNCTION__);
- return bt_is_enabled();
-#endif
- return -1;
-}
-
-static jboolean setPairingConfirmationNative(JNIEnv *env, jobject object,
- jstring address, bool confirm,
- int nativeData) {
-#ifdef HAVE_BLUETOOTH
- ALOGV("%s", __FUNCTION__);
- native_data_t *nat = get_native_data(env, object);
- if (nat) {
- DBusMessage *msg = (DBusMessage *)nativeData;
- DBusMessage *reply;
- if (confirm) {
- reply = dbus_message_new_method_return(msg);
- } else {
- reply = dbus_message_new_error(msg,
- "org.bluez.Error.Rejected", "User rejected confirmation");
- }
-
- if (!reply) {
- ALOGE("%s: Cannot create message reply to RequestPasskeyConfirmation or"
- "RequestPairingConsent to D-Bus\n", __FUNCTION__);
- dbus_message_unref(msg);
- return JNI_FALSE;
- }
-
- dbus_connection_send(nat->conn, reply, NULL);
- dbus_message_unref(msg);
- dbus_message_unref(reply);
- return JNI_TRUE;
- }
-#endif
- return JNI_FALSE;
-}
-
-static jboolean setPasskeyNative(JNIEnv *env, jobject object, jstring address,
- int passkey, int nativeData) {
-#ifdef HAVE_BLUETOOTH
- ALOGV("%s", __FUNCTION__);
- native_data_t *nat = get_native_data(env, object);
- if (nat) {
- DBusMessage *msg = (DBusMessage *)nativeData;
- DBusMessage *reply = dbus_message_new_method_return(msg);
- if (!reply) {
- ALOGE("%s: Cannot create message reply to return Passkey code to "
- "D-Bus\n", __FUNCTION__);
- dbus_message_unref(msg);
- return JNI_FALSE;
- }
-
- dbus_message_append_args(reply, DBUS_TYPE_UINT32, (uint32_t *)&passkey,
- DBUS_TYPE_INVALID);
-
- dbus_connection_send(nat->conn, reply, NULL);
- dbus_message_unref(msg);
- dbus_message_unref(reply);
- return JNI_TRUE;
- }
-#endif
- return JNI_FALSE;
-}
-
-static jboolean setRemoteOutOfBandDataNative(JNIEnv *env, jobject object, jstring address,
- jbyteArray hash, jbyteArray randomizer, int nativeData) {
-#ifdef HAVE_BLUETOOTH
- ALOGV("%s", __FUNCTION__);
- native_data_t *nat = get_native_data(env, object);
- if (nat) {
- DBusMessage *msg = (DBusMessage *)nativeData;
- DBusMessage *reply = dbus_message_new_method_return(msg);
- jbyte *h_ptr = env->GetByteArrayElements(hash, NULL);
- jbyte *r_ptr = env->GetByteArrayElements(randomizer, NULL);
- if (!reply) {
- ALOGE("%s: Cannot create message reply to return remote OOB data to "
- "D-Bus\n", __FUNCTION__);
- dbus_message_unref(msg);
- return JNI_FALSE;
- }
-
- dbus_message_append_args(reply,
- DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &h_ptr, 16,
- DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &r_ptr, 16,
- DBUS_TYPE_INVALID);
-
- env->ReleaseByteArrayElements(hash, h_ptr, 0);
- env->ReleaseByteArrayElements(randomizer, r_ptr, 0);
-
- dbus_connection_send(nat->conn, reply, NULL);
- dbus_message_unref(msg);
- dbus_message_unref(reply);
- return JNI_TRUE;
- }
-#endif
- return JNI_FALSE;
-}
-
-static jboolean setAuthorizationNative(JNIEnv *env, jobject object, jstring address,
- jboolean val, int nativeData) {
-#ifdef HAVE_BLUETOOTH
- ALOGV("%s", __FUNCTION__);
- native_data_t *nat = get_native_data(env, object);
- if (nat) {
- DBusMessage *msg = (DBusMessage *)nativeData;
- DBusMessage *reply;
- if (val) {
- reply = dbus_message_new_method_return(msg);
- } else {
- reply = dbus_message_new_error(msg,
- "org.bluez.Error.Rejected", "Authorization rejected");
- }
- if (!reply) {
- ALOGE("%s: Cannot create message reply D-Bus\n", __FUNCTION__);
- dbus_message_unref(msg);
- return JNI_FALSE;
- }
-
- dbus_connection_send(nat->conn, reply, NULL);
- dbus_message_unref(msg);
- dbus_message_unref(reply);
- return JNI_TRUE;
- }
-#endif
- return JNI_FALSE;
-}
-
-static jboolean setPinNative(JNIEnv *env, jobject object, jstring address,
- jstring pin, int nativeData) {
-#ifdef HAVE_BLUETOOTH
- ALOGV("%s", __FUNCTION__);
- native_data_t *nat = get_native_data(env, object);
- if (nat) {
- DBusMessage *msg = (DBusMessage *)nativeData;
- DBusMessage *reply = dbus_message_new_method_return(msg);
- if (!reply) {
- ALOGE("%s: Cannot create message reply to return PIN code to "
- "D-Bus\n", __FUNCTION__);
- dbus_message_unref(msg);
- return JNI_FALSE;
- }
-
- const char *c_pin = env->GetStringUTFChars(pin, NULL);
-
- dbus_message_append_args(reply, DBUS_TYPE_STRING, &c_pin,
- DBUS_TYPE_INVALID);
-
- dbus_connection_send(nat->conn, reply, NULL);
- dbus_message_unref(msg);
- dbus_message_unref(reply);
- env->ReleaseStringUTFChars(pin, c_pin);
- return JNI_TRUE;
- }
-#endif
- return JNI_FALSE;
-}
-
-static jboolean cancelPairingUserInputNative(JNIEnv *env, jobject object,
- jstring address, int nativeData) {
-#ifdef HAVE_BLUETOOTH
- ALOGV("%s", __FUNCTION__);
- native_data_t *nat = get_native_data(env, object);
- if (nat) {
- DBusMessage *msg = (DBusMessage *)nativeData;
- DBusMessage *reply = dbus_message_new_error(msg,
- "org.bluez.Error.Canceled", "Pairing User Input was canceled");
- if (!reply) {
- ALOGE("%s: Cannot create message reply to return cancelUserInput to"
- "D-BUS\n", __FUNCTION__);
- dbus_message_unref(msg);
- return JNI_FALSE;
- }
-
- dbus_connection_send(nat->conn, reply, NULL);
- dbus_message_unref(msg);
- dbus_message_unref(reply);
- return JNI_TRUE;
- }
-#endif
- return JNI_FALSE;
-}
-
-static jobjectArray getDevicePropertiesNative(JNIEnv *env, jobject object,
- jstring path)
-{
-#ifdef HAVE_BLUETOOTH
- ALOGV("%s", __FUNCTION__);
- native_data_t *nat = get_native_data(env, object);
- if (nat) {
- DBusMessage *msg, *reply;
- DBusError err;
- dbus_error_init(&err);
-
- const char *c_path = env->GetStringUTFChars(path, NULL);
- reply = dbus_func_args_timeout(env,
- nat->conn, -1, c_path,
- DBUS_DEVICE_IFACE, "GetProperties",
- DBUS_TYPE_INVALID);
- env->ReleaseStringUTFChars(path, c_path);
-
- if (!reply) {
- if (dbus_error_is_set(&err)) {
- LOG_AND_FREE_DBUS_ERROR(&err);
- } else
- ALOGE("DBus reply is NULL in function %s", __FUNCTION__);
- return NULL;
- }
- env->PushLocalFrame(PROPERTIES_NREFS);
-
- DBusMessageIter iter;
- jobjectArray str_array = NULL;
- if (dbus_message_iter_init(reply, &iter))
- str_array = parse_remote_device_properties(env, &iter);
- dbus_message_unref(reply);
-
- return (jobjectArray) env->PopLocalFrame(str_array);
- }
-#endif
- return NULL;
-}
-
-static jobjectArray getAdapterPropertiesNative(JNIEnv *env, jobject object) {
-#ifdef HAVE_BLUETOOTH
- ALOGV("%s", __FUNCTION__);
- native_data_t *nat = get_native_data(env, object);
- if (nat) {
- DBusMessage *msg, *reply;
- DBusError err;
- dbus_error_init(&err);
-
- reply = dbus_func_args_timeout(env,
- nat->conn, -1, get_adapter_path(env, object),
- DBUS_ADAPTER_IFACE, "GetProperties",
- DBUS_TYPE_INVALID);
- if (!reply) {
- if (dbus_error_is_set(&err)) {
- LOG_AND_FREE_DBUS_ERROR(&err);
- } else
- ALOGE("DBus reply is NULL in function %s", __FUNCTION__);
- return NULL;
- }
- env->PushLocalFrame(PROPERTIES_NREFS);
-
- DBusMessageIter iter;
- jobjectArray str_array = NULL;
- if (dbus_message_iter_init(reply, &iter))
- str_array = parse_adapter_properties(env, &iter);
- dbus_message_unref(reply);
-
- return (jobjectArray) env->PopLocalFrame(str_array);
- }
-#endif
- return NULL;
-}
-
-static jboolean setAdapterPropertyNative(JNIEnv *env, jobject object, jstring key,
- void *value, jint type) {
-#ifdef HAVE_BLUETOOTH
- ALOGV("%s", __FUNCTION__);
- native_data_t *nat = get_native_data(env, object);
- if (nat) {
- DBusMessage *msg;
- DBusMessageIter iter;
- dbus_bool_t reply = JNI_FALSE;
- const char *c_key = env->GetStringUTFChars(key, NULL);
-
- msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
- get_adapter_path(env, object),
- DBUS_ADAPTER_IFACE, "SetProperty");
- if (!msg) {
- ALOGE("%s: Can't allocate new method call for GetProperties!",
- __FUNCTION__);
- env->ReleaseStringUTFChars(key, c_key);
- return JNI_FALSE;
- }
-
- dbus_message_append_args(msg, DBUS_TYPE_STRING, &c_key, DBUS_TYPE_INVALID);
- dbus_message_iter_init_append(msg, &iter);
- append_variant(&iter, type, value);
-
- // Asynchronous call - the callbacks come via propertyChange
- reply = dbus_connection_send_with_reply(nat->conn, msg, NULL, -1);
- dbus_message_unref(msg);
-
- env->ReleaseStringUTFChars(key, c_key);
- return reply ? JNI_TRUE : JNI_FALSE;
-
- }
-#endif
- return JNI_FALSE;
-}
-
-static jboolean setAdapterPropertyStringNative(JNIEnv *env, jobject object, jstring key,
- jstring value) {
-#ifdef HAVE_BLUETOOTH
- const char *c_value = env->GetStringUTFChars(value, NULL);
- jboolean ret = setAdapterPropertyNative(env, object, key, (void *)&c_value, DBUS_TYPE_STRING);
- env->ReleaseStringUTFChars(value, (char *)c_value);
- return ret;
-#else
- return JNI_FALSE;
-#endif
-}
-
-static jboolean setAdapterPropertyIntegerNative(JNIEnv *env, jobject object, jstring key,
- jint value) {
-#ifdef HAVE_BLUETOOTH
- return setAdapterPropertyNative(env, object, key, (void *)&value, DBUS_TYPE_UINT32);
-#else
- return JNI_FALSE;
-#endif
-}
-
-static jboolean setAdapterPropertyBooleanNative(JNIEnv *env, jobject object, jstring key,
- jint value) {
-#ifdef HAVE_BLUETOOTH
- return setAdapterPropertyNative(env, object, key, (void *)&value, DBUS_TYPE_BOOLEAN);
-#else
- return JNI_FALSE;
-#endif
-}
-
-static jboolean setDevicePropertyNative(JNIEnv *env, jobject object, jstring path,
- jstring key, void *value, jint type) {
-#ifdef HAVE_BLUETOOTH
- ALOGV("%s", __FUNCTION__);
- native_data_t *nat = get_native_data(env, object);
- if (nat) {
- DBusMessage *msg;
- DBusMessageIter iter;
- dbus_bool_t reply = JNI_FALSE;
-
- const char *c_key = env->GetStringUTFChars(key, NULL);
- const char *c_path = env->GetStringUTFChars(path, NULL);
-
- msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
- c_path, DBUS_DEVICE_IFACE, "SetProperty");
- if (!msg) {
- ALOGE("%s: Can't allocate new method call for device SetProperty!", __FUNCTION__);
- env->ReleaseStringUTFChars(key, c_key);
- env->ReleaseStringUTFChars(path, c_path);
- return JNI_FALSE;
- }
-
- dbus_message_append_args(msg, DBUS_TYPE_STRING, &c_key, DBUS_TYPE_INVALID);
- dbus_message_iter_init_append(msg, &iter);
- append_variant(&iter, type, value);
-
- // Asynchronous call - the callbacks come via Device propertyChange
- reply = dbus_connection_send_with_reply(nat->conn, msg, NULL, -1);
- dbus_message_unref(msg);
-
- env->ReleaseStringUTFChars(path, c_path);
- env->ReleaseStringUTFChars(key, c_key);
-
- return reply ? JNI_TRUE : JNI_FALSE;
- }
-#endif
- return JNI_FALSE;
-}
-
-static jboolean setDevicePropertyBooleanNative(JNIEnv *env, jobject object,
- jstring path, jstring key, jint value) {
-#ifdef HAVE_BLUETOOTH
- return setDevicePropertyNative(env, object, path, key,
- (void *)&value, DBUS_TYPE_BOOLEAN);
-#else
- return JNI_FALSE;
-#endif
-}
-
-static jboolean setDevicePropertyStringNative(JNIEnv *env, jobject object,
- jstring path, jstring key, jstring value) {
-#ifdef HAVE_BLUETOOTH
- const char *c_value = env->GetStringUTFChars(value, NULL);
- jboolean ret = setDevicePropertyNative(env, object, path, key,
- (void *)&c_value, DBUS_TYPE_STRING);
- env->ReleaseStringUTFChars(value, (char *)c_value);
- return ret;
-#else
- return JNI_FALSE;
-#endif
-}
-
-static jboolean createDeviceNative(JNIEnv *env, jobject object,
- jstring address) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- native_data_t *nat = get_native_data(env, object);
- jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
- struct event_loop_native_data_t *eventLoopNat =
- get_EventLoop_native_data(env, eventLoop);
-
- if (nat && eventLoopNat) {
- const char *c_address = env->GetStringUTFChars(address, NULL);
- ALOGV("... address = %s", c_address);
- char *context_address = (char *)calloc(BTADDR_SIZE, sizeof(char));
- strlcpy(context_address, c_address, BTADDR_SIZE); // for callback
-
- bool ret = dbus_func_args_async(env, nat->conn, -1,
- onCreateDeviceResult,
- context_address,
- eventLoopNat,
- get_adapter_path(env, object),
- DBUS_ADAPTER_IFACE,
- "CreateDevice",
- DBUS_TYPE_STRING, &c_address,
- DBUS_TYPE_INVALID);
- env->ReleaseStringUTFChars(address, c_address);
- return ret ? JNI_TRUE : JNI_FALSE;
- }
-#endif
- return JNI_FALSE;
-}
-
-static jboolean discoverServicesNative(JNIEnv *env, jobject object,
- jstring path, jstring pattern) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- native_data_t *nat = get_native_data(env, object);
- jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
- struct event_loop_native_data_t *eventLoopNat =
- get_EventLoop_native_data(env, eventLoop);
-
- if (nat && eventLoopNat) {
- const char *c_path = env->GetStringUTFChars(path, NULL);
- const char *c_pattern = env->GetStringUTFChars(pattern, NULL);
- int len = env->GetStringLength(path) + 1;
- char *context_path = (char *)calloc(len, sizeof(char));
- strlcpy(context_path, c_path, len); // for callback
-
- ALOGV("... Object Path = %s", c_path);
- ALOGV("... Pattern = %s, strlen = %d", c_pattern, strlen(c_pattern));
-
- bool ret = dbus_func_args_async(env, nat->conn, -1,
- onDiscoverServicesResult,
- context_path,
- eventLoopNat,
- c_path,
- DBUS_DEVICE_IFACE,
- "DiscoverServices",
- DBUS_TYPE_STRING, &c_pattern,
- DBUS_TYPE_INVALID);
- env->ReleaseStringUTFChars(path, c_path);
- env->ReleaseStringUTFChars(pattern, c_pattern);
- return ret ? JNI_TRUE : JNI_FALSE;
- }
-#endif
- return JNI_FALSE;
-}
-
-#ifdef HAVE_BLUETOOTH
-static jintArray extract_handles(JNIEnv *env, DBusMessage *reply) {
- jint *handles;
- jintArray handleArray = NULL;
- int len;
-
- DBusError err;
- dbus_error_init(&err);
-
- if (dbus_message_get_args(reply, &err,
- DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &handles, &len,
- DBUS_TYPE_INVALID)) {
- handleArray = env->NewIntArray(len);
- if (handleArray) {
- env->SetIntArrayRegion(handleArray, 0, len, handles);
- } else {
- ALOGE("Null array in extract_handles");
- }
- } else {
- LOG_AND_FREE_DBUS_ERROR(&err);
- }
- return handleArray;
-}
-#endif
-
-static jintArray addReservedServiceRecordsNative(JNIEnv *env, jobject object,
- jintArray uuids) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- DBusMessage *reply = NULL;
-
- native_data_t *nat = get_native_data(env, object);
-
- jint* svc_classes = env->GetIntArrayElements(uuids, NULL);
- if (!svc_classes) return NULL;
-
- int len = env->GetArrayLength(uuids);
- reply = dbus_func_args(env, nat->conn,
- get_adapter_path(env, object),
- DBUS_ADAPTER_IFACE, "AddReservedServiceRecords",
- DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
- &svc_classes, len, DBUS_TYPE_INVALID);
- env->ReleaseIntArrayElements(uuids, svc_classes, 0);
- return reply ? extract_handles(env, reply) : NULL;
-
-#endif
- return NULL;
-}
-
-static jboolean removeReservedServiceRecordsNative(JNIEnv *env, jobject object,
- jintArray handles) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- native_data_t *nat = get_native_data(env, object);
- jint *values = env->GetIntArrayElements(handles, NULL);
- DBusMessage *msg = NULL;
- DBusMessage *reply = NULL;
- if (values == NULL) return JNI_FALSE;
-
- jsize len = env->GetArrayLength(handles);
-
- reply = dbus_func_args(env, nat->conn,
- get_adapter_path(env, object),
- DBUS_ADAPTER_IFACE, "RemoveReservedServiceRecords",
- DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
- &values, len, DBUS_TYPE_INVALID);
- env->ReleaseIntArrayElements(handles, values, 0);
- return reply ? JNI_TRUE : JNI_FALSE;
-#endif
- return JNI_FALSE;
-}
-
-static jint addRfcommServiceRecordNative(JNIEnv *env, jobject object,
- jstring name, jlong uuidMsb, jlong uuidLsb, jshort channel) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- native_data_t *nat = get_native_data(env, object);
- if (nat) {
- const char *c_name = env->GetStringUTFChars(name, NULL);
- ALOGV("... name = %s", c_name);
- ALOGV("... uuid1 = %llX", uuidMsb);
- ALOGV("... uuid2 = %llX", uuidLsb);
- ALOGV("... channel = %d", channel);
- DBusMessage *reply = dbus_func_args(env, nat->conn,
- get_adapter_path(env, object),
- DBUS_ADAPTER_IFACE, "AddRfcommServiceRecord",
- DBUS_TYPE_STRING, &c_name,
- DBUS_TYPE_UINT64, &uuidMsb,
- DBUS_TYPE_UINT64, &uuidLsb,
- DBUS_TYPE_UINT16, &channel,
- DBUS_TYPE_INVALID);
- env->ReleaseStringUTFChars(name, c_name);
- return reply ? dbus_returns_uint32(env, reply) : -1;
- }
-#endif
- return -1;
-}
-
-static jboolean removeServiceRecordNative(JNIEnv *env, jobject object, jint handle) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- native_data_t *nat = get_native_data(env, object);
- if (nat) {
- ALOGV("... handle = %X", handle);
- DBusMessage *reply = dbus_func_args(env, nat->conn,
- get_adapter_path(env, object),
- DBUS_ADAPTER_IFACE, "RemoveServiceRecord",
- DBUS_TYPE_UINT32, &handle,
- DBUS_TYPE_INVALID);
- return reply ? JNI_TRUE : JNI_FALSE;
- }
-#endif
- return JNI_FALSE;
-}
-
-static jboolean setLinkTimeoutNative(JNIEnv *env, jobject object, jstring object_path,
- jint num_slots) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- native_data_t *nat = get_native_data(env, object);
- if (nat) {
- const char *c_object_path = env->GetStringUTFChars(object_path, NULL);
- DBusMessage *reply = dbus_func_args(env, nat->conn,
- get_adapter_path(env, object),
- DBUS_ADAPTER_IFACE, "SetLinkTimeout",
- DBUS_TYPE_OBJECT_PATH, &c_object_path,
- DBUS_TYPE_UINT32, &num_slots,
- DBUS_TYPE_INVALID);
- env->ReleaseStringUTFChars(object_path, c_object_path);
- return reply ? JNI_TRUE : JNI_FALSE;
- }
-#endif
- return JNI_FALSE;
-}
-
-static jboolean connectInputDeviceNative(JNIEnv *env, jobject object, jstring path) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- native_data_t *nat = get_native_data(env, object);
- jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
- struct event_loop_native_data_t *eventLoopNat =
- get_EventLoop_native_data(env, eventLoop);
-
- if (nat && eventLoopNat) {
- const char *c_path = env->GetStringUTFChars(path, NULL);
-
- int len = env->GetStringLength(path) + 1;
- char *context_path = (char *)calloc(len, sizeof(char));
- strlcpy(context_path, c_path, len); // for callback
-
- bool ret = dbus_func_args_async(env, nat->conn, -1, onInputDeviceConnectionResult,
- context_path, eventLoopNat, c_path, DBUS_INPUT_IFACE,
- "Connect",
- DBUS_TYPE_INVALID);
-
- env->ReleaseStringUTFChars(path, c_path);
- return ret ? JNI_TRUE : JNI_FALSE;
- }
-#endif
- return JNI_FALSE;
-}
-
-static jboolean disconnectInputDeviceNative(JNIEnv *env, jobject object,
- jstring path) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- native_data_t *nat = get_native_data(env, object);
- jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
- struct event_loop_native_data_t *eventLoopNat =
- get_EventLoop_native_data(env, eventLoop);
-
- if (nat && eventLoopNat) {
- const char *c_path = env->GetStringUTFChars(path, NULL);
-
- int len = env->GetStringLength(path) + 1;
- char *context_path = (char *)calloc(len, sizeof(char));
- strlcpy(context_path, c_path, len); // for callback
-
- bool ret = dbus_func_args_async(env, nat->conn, -1, onInputDeviceConnectionResult,
- context_path, eventLoopNat, c_path, DBUS_INPUT_IFACE,
- "Disconnect",
- DBUS_TYPE_INVALID);
-
- env->ReleaseStringUTFChars(path, c_path);
- return ret ? JNI_TRUE : JNI_FALSE;
- }
-#endif
- return JNI_FALSE;
-}
-
-static jboolean setBluetoothTetheringNative(JNIEnv *env, jobject object, jboolean value,
- jstring src_role, jstring bridge) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- native_data_t *nat = get_native_data(env, object);
- if (nat) {
- DBusMessage *reply;
- const char *c_role = env->GetStringUTFChars(src_role, NULL);
- const char *c_bridge = env->GetStringUTFChars(bridge, NULL);
- if (value) {
- ALOGE("setBluetoothTetheringNative true");
- reply = dbus_func_args(env, nat->conn,
- get_adapter_path(env, object),
- DBUS_NETWORKSERVER_IFACE,
- "Register",
- DBUS_TYPE_STRING, &c_role,
- DBUS_TYPE_STRING, &c_bridge,
- DBUS_TYPE_INVALID);
- } else {
- ALOGE("setBluetoothTetheringNative false");
- reply = dbus_func_args(env, nat->conn,
- get_adapter_path(env, object),
- DBUS_NETWORKSERVER_IFACE,
- "Unregister",
- DBUS_TYPE_STRING, &c_role,
- DBUS_TYPE_INVALID);
- }
- env->ReleaseStringUTFChars(src_role, c_role);
- env->ReleaseStringUTFChars(bridge, c_bridge);
- return reply ? JNI_TRUE : JNI_FALSE;
- }
-#endif
- return JNI_FALSE;
-}
-
-static jboolean connectPanDeviceNative(JNIEnv *env, jobject object, jstring path,
- jstring dstRole) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- ALOGE("connectPanDeviceNative");
- native_data_t *nat = get_native_data(env, object);
- jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
- struct event_loop_native_data_t *eventLoopNat =
- get_EventLoop_native_data(env, eventLoop);
-
- if (nat && eventLoopNat) {
- const char *c_path = env->GetStringUTFChars(path, NULL);
- const char *dst = env->GetStringUTFChars(dstRole, NULL);
-
- int len = env->GetStringLength(path) + 1;
- char *context_path = (char *)calloc(len, sizeof(char));
- strlcpy(context_path, c_path, len); // for callback
-
- bool ret = dbus_func_args_async(env, nat->conn, -1,onPanDeviceConnectionResult,
- context_path, eventLoopNat, c_path,
- DBUS_NETWORK_IFACE, "Connect",
- DBUS_TYPE_STRING, &dst,
- DBUS_TYPE_INVALID);
-
- env->ReleaseStringUTFChars(path, c_path);
- env->ReleaseStringUTFChars(dstRole, dst);
- return ret ? JNI_TRUE : JNI_FALSE;
- }
-#endif
- return JNI_FALSE;
-}
-
-static jboolean disconnectPanDeviceNative(JNIEnv *env, jobject object,
- jstring path) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- ALOGE("disconnectPanDeviceNative");
- native_data_t *nat = get_native_data(env, object);
- jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
- struct event_loop_native_data_t *eventLoopNat =
- get_EventLoop_native_data(env, eventLoop);
-
- if (nat && eventLoopNat) {
- const char *c_path = env->GetStringUTFChars(path, NULL);
-
- int len = env->GetStringLength(path) + 1;
- char *context_path = (char *)calloc(len, sizeof(char));
- strlcpy(context_path, c_path, len); // for callback
-
- bool ret = dbus_func_args_async(env, nat->conn, -1,onPanDeviceConnectionResult,
- context_path, eventLoopNat, c_path,
- DBUS_NETWORK_IFACE, "Disconnect",
- DBUS_TYPE_INVALID);
-
- env->ReleaseStringUTFChars(path, c_path);
- return ret ? JNI_TRUE : JNI_FALSE;
- }
-#endif
- return JNI_FALSE;
-}
-
-static jboolean disconnectPanServerDeviceNative(JNIEnv *env, jobject object,
- jstring path, jstring address,
- jstring iface) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- ALOGE("disconnectPanServerDeviceNative");
- native_data_t *nat = get_native_data(env, object);
- jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
- struct event_loop_native_data_t *eventLoopNat =
- get_EventLoop_native_data(env, eventLoop);
-
- if (nat && eventLoopNat) {
- const char *c_address = env->GetStringUTFChars(address, NULL);
- const char *c_path = env->GetStringUTFChars(path, NULL);
- const char *c_iface = env->GetStringUTFChars(iface, NULL);
-
- int len = env->GetStringLength(path) + 1;
- char *context_path = (char *)calloc(len, sizeof(char));
- strlcpy(context_path, c_path, len); // for callback
-
- bool ret = dbus_func_args_async(env, nat->conn, -1,
- onPanDeviceConnectionResult,
- context_path, eventLoopNat,
- get_adapter_path(env, object),
- DBUS_NETWORKSERVER_IFACE,
- "DisconnectDevice",
- DBUS_TYPE_STRING, &c_address,
- DBUS_TYPE_STRING, &c_iface,
- DBUS_TYPE_INVALID);
-
- env->ReleaseStringUTFChars(address, c_address);
- env->ReleaseStringUTFChars(iface, c_iface);
- env->ReleaseStringUTFChars(path, c_path);
- return ret ? JNI_TRUE : JNI_FALSE;
- }
-#endif
- return JNI_FALSE;
-}
-
-static jstring registerHealthApplicationNative(JNIEnv *env, jobject object,
- jint dataType, jstring role,
- jstring name, jstring channelType) {
- ALOGV("%s", __FUNCTION__);
- jstring path = NULL;
-#ifdef HAVE_BLUETOOTH
- native_data_t *nat = get_native_data(env, object);
- if (nat) {
- const char *c_role = env->GetStringUTFChars(role, NULL);
- const char *c_name = env->GetStringUTFChars(name, NULL);
- const char *c_channel_type = env->GetStringUTFChars(channelType, NULL);
- char *c_path;
- DBusMessage *msg, *reply;
- DBusError err;
- dbus_error_init(&err);
-
- msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
- DBUS_HEALTH_MANAGER_PATH,
- DBUS_HEALTH_MANAGER_IFACE,
- "CreateApplication");
-
- if (msg == NULL) {
- ALOGE("Could not allocate D-Bus message object!");
- return NULL;
- }
-
- /* append arguments */
- append_dict_args(msg,
- "DataType", DBUS_TYPE_UINT16, &dataType,
- "Role", DBUS_TYPE_STRING, &c_role,
- "Description", DBUS_TYPE_STRING, &c_name,
- "ChannelType", DBUS_TYPE_STRING, &c_channel_type,
- DBUS_TYPE_INVALID);
-
-
- /* Make the call. */
- reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);
-
- env->ReleaseStringUTFChars(role, c_role);
- env->ReleaseStringUTFChars(name, c_name);
- env->ReleaseStringUTFChars(channelType, c_channel_type);
-
- if (!reply) {
- if (dbus_error_is_set(&err)) {
- LOG_AND_FREE_DBUS_ERROR(&err);
- }
- } else {
- if (!dbus_message_get_args(reply, &err,
- DBUS_TYPE_OBJECT_PATH, &c_path,
- DBUS_TYPE_INVALID)) {
- if (dbus_error_is_set(&err)) {
- LOG_AND_FREE_DBUS_ERROR(&err);
- }
- } else {
- path = env->NewStringUTF(c_path);
- }
- dbus_message_unref(reply);
- }
- }
-#endif
- return path;
-}
-
-static jstring registerSinkHealthApplicationNative(JNIEnv *env, jobject object,
- jint dataType, jstring role,
- jstring name) {
- ALOGV("%s", __FUNCTION__);
- jstring path = NULL;
-#ifdef HAVE_BLUETOOTH
- native_data_t *nat = get_native_data(env, object);
- if (nat) {
- const char *c_role = env->GetStringUTFChars(role, NULL);
- const char *c_name = env->GetStringUTFChars(name, NULL);
- char *c_path;
-
- DBusMessage *msg, *reply;
- DBusError err;
- dbus_error_init(&err);
-
- msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
- DBUS_HEALTH_MANAGER_PATH,
- DBUS_HEALTH_MANAGER_IFACE,
- "CreateApplication");
-
- if (msg == NULL) {
- ALOGE("Could not allocate D-Bus message object!");
- return NULL;
- }
-
- /* append arguments */
- append_dict_args(msg,
- "DataType", DBUS_TYPE_UINT16, &dataType,
- "Role", DBUS_TYPE_STRING, &c_role,
- "Description", DBUS_TYPE_STRING, &c_name,
- DBUS_TYPE_INVALID);
-
-
- /* Make the call. */
- reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);
-
- env->ReleaseStringUTFChars(role, c_role);
- env->ReleaseStringUTFChars(name, c_name);
-
- if (!reply) {
- if (dbus_error_is_set(&err)) {
- LOG_AND_FREE_DBUS_ERROR(&err);
- }
- } else {
- if (!dbus_message_get_args(reply, &err,
- DBUS_TYPE_OBJECT_PATH, &c_path,
- DBUS_TYPE_INVALID)) {
- if (dbus_error_is_set(&err)) {
- LOG_AND_FREE_DBUS_ERROR(&err);
- }
- } else {
- path = env->NewStringUTF(c_path);
- }
- dbus_message_unref(reply);
- }
- }
-#endif
- return path;
-}
-
-static jboolean unregisterHealthApplicationNative(JNIEnv *env, jobject object,
- jstring path) {
- ALOGV("%s", __FUNCTION__);
- jboolean result = JNI_FALSE;
-#ifdef HAVE_BLUETOOTH
- native_data_t *nat = get_native_data(env, object);
- if (nat) {
- const char *c_path = env->GetStringUTFChars(path, NULL);
- DBusError err;
- dbus_error_init(&err);
- DBusMessage *reply =
- dbus_func_args_timeout(env, nat->conn, -1,
- DBUS_HEALTH_MANAGER_PATH,
- DBUS_HEALTH_MANAGER_IFACE, "DestroyApplication",
- DBUS_TYPE_OBJECT_PATH, &c_path,
- DBUS_TYPE_INVALID);
-
- env->ReleaseStringUTFChars(path, c_path);
-
- if (!reply) {
- if (dbus_error_is_set(&err)) {
- LOG_AND_FREE_DBUS_ERROR(&err);
- }
- } else {
- result = JNI_TRUE;
- }
- }
-#endif
- return result;
-}
-
-static jboolean createChannelNative(JNIEnv *env, jobject object,
- jstring devicePath, jstring appPath, jstring config,
- jint code) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- native_data_t *nat = get_native_data(env, object);
- jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
- struct event_loop_native_data_t *eventLoopNat =
- get_EventLoop_native_data(env, eventLoop);
-
- if (nat && eventLoopNat) {
- const char *c_device_path = env->GetStringUTFChars(devicePath, NULL);
- const char *c_app_path = env->GetStringUTFChars(appPath, NULL);
- const char *c_config = env->GetStringUTFChars(config, NULL);
- int *data = (int *) malloc(sizeof(int));
- if (data == NULL) return JNI_FALSE;
-
- *data = code;
- bool ret = dbus_func_args_async(env, nat->conn, -1, onHealthDeviceConnectionResult,
- data, eventLoopNat, c_device_path,
- DBUS_HEALTH_DEVICE_IFACE, "CreateChannel",
- DBUS_TYPE_OBJECT_PATH, &c_app_path,
- DBUS_TYPE_STRING, &c_config,
- DBUS_TYPE_INVALID);
-
-
- env->ReleaseStringUTFChars(devicePath, c_device_path);
- env->ReleaseStringUTFChars(appPath, c_app_path);
- env->ReleaseStringUTFChars(config, c_config);
-
- return ret ? JNI_TRUE : JNI_FALSE;
- }
-#endif
- return JNI_FALSE;
-}
-
-static jboolean destroyChannelNative(JNIEnv *env, jobject object, jstring devicePath,
- jstring channelPath, jint code) {
- ALOGE("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- native_data_t *nat = get_native_data(env, object);
- jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
- struct event_loop_native_data_t *eventLoopNat =
- get_EventLoop_native_data(env, eventLoop);
-
- if (nat && eventLoopNat) {
- const char *c_device_path = env->GetStringUTFChars(devicePath, NULL);
- const char *c_channel_path = env->GetStringUTFChars(channelPath, NULL);
- int *data = (int *) malloc(sizeof(int));
- if (data == NULL) return JNI_FALSE;
-
- *data = code;
- bool ret = dbus_func_args_async(env, nat->conn, -1, onHealthDeviceConnectionResult,
- data, eventLoopNat, c_device_path,
- DBUS_HEALTH_DEVICE_IFACE, "DestroyChannel",
- DBUS_TYPE_OBJECT_PATH, &c_channel_path,
- DBUS_TYPE_INVALID);
-
- env->ReleaseStringUTFChars(devicePath, c_device_path);
- env->ReleaseStringUTFChars(channelPath, c_channel_path);
-
- return ret ? JNI_TRUE : JNI_FALSE;
- }
-#endif
- return JNI_FALSE;
-}
-
-static jstring getMainChannelNative(JNIEnv *env, jobject object, jstring devicePath) {
- ALOGE("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- native_data_t *nat = get_native_data(env, object);
- if (nat) {
- const char *c_device_path = env->GetStringUTFChars(devicePath, NULL);
- DBusError err;
- dbus_error_init(&err);
-
- DBusMessage *reply = dbus_func_args(env, nat->conn,
- c_device_path,
- DBUS_HEALTH_DEVICE_IFACE, "GetProperties",
- DBUS_TYPE_INVALID);
- env->ReleaseStringUTFChars(devicePath, c_device_path);
-
- if (!reply) {
- if (dbus_error_is_set(&err)) {
- LOG_AND_FREE_DBUS_ERROR(&err);
- }
- } else {
- DBusMessageIter iter;
- jobjectArray str_array = NULL;
- if (dbus_message_iter_init(reply, &iter))
- str_array = parse_health_device_properties(env, &iter);
- dbus_message_unref(reply);
- jstring path = (jstring) env->GetObjectArrayElement(str_array, 1);
-
- return path;
- }
- }
-#endif
- return NULL;
-}
-
-static jstring getChannelApplicationNative(JNIEnv *env, jobject object, jstring channelPath) {
- ALOGE("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- native_data_t *nat = get_native_data(env, object);
- if (nat) {
- const char *c_channel_path = env->GetStringUTFChars(channelPath, NULL);
- DBusError err;
- dbus_error_init(&err);
-
- DBusMessage *reply = dbus_func_args(env, nat->conn,
- c_channel_path,
- DBUS_HEALTH_CHANNEL_IFACE, "GetProperties",
- DBUS_TYPE_INVALID);
- env->ReleaseStringUTFChars(channelPath, c_channel_path);
-
- if (!reply) {
- if (dbus_error_is_set(&err)) {
- LOG_AND_FREE_DBUS_ERROR(&err);
- }
- } else {
- DBusMessageIter iter;
- jobjectArray str_array = NULL;
- if (dbus_message_iter_init(reply, &iter))
- str_array = parse_health_channel_properties(env, &iter);
- dbus_message_unref(reply);
-
- jint len = env->GetArrayLength(str_array);
-
- jstring name, path;
- const char *c_name;
-
- for (int i = 0; i < len; i+=2) {
- name = (jstring) env->GetObjectArrayElement(str_array, i);
- c_name = env->GetStringUTFChars(name, NULL);
-
- if (!strcmp(c_name, "Application")) {
- path = (jstring) env->GetObjectArrayElement(str_array, i+1);
- env->ReleaseStringUTFChars(name, c_name);
- return path;
- }
- env->ReleaseStringUTFChars(name, c_name);
- }
- }
- }
-#endif
- return NULL;
-}
-
-static jboolean releaseChannelFdNative(JNIEnv *env, jobject object, jstring channelPath) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- native_data_t *nat = get_native_data(env, object);
- if (nat) {
- const char *c_channel_path = env->GetStringUTFChars(channelPath, NULL);
- DBusError err;
- dbus_error_init(&err);
-
- DBusMessage *reply = dbus_func_args(env, nat->conn,
- c_channel_path,
- DBUS_HEALTH_CHANNEL_IFACE, "Release",
- DBUS_TYPE_INVALID);
- env->ReleaseStringUTFChars(channelPath, c_channel_path);
-
- return reply ? JNI_TRUE : JNI_FALSE;
- }
-#endif
- return JNI_FALSE;
-}
-
-static jobject getChannelFdNative(JNIEnv *env, jobject object, jstring channelPath) {
- ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- native_data_t *nat = get_native_data(env, object);
- if (nat) {
- const char *c_channel_path = env->GetStringUTFChars(channelPath, NULL);
- int32_t fd;
- DBusError err;
- dbus_error_init(&err);
-
- DBusMessage *reply = dbus_func_args(env, nat->conn,
- c_channel_path,
- DBUS_HEALTH_CHANNEL_IFACE, "Acquire",
- DBUS_TYPE_INVALID);
- env->ReleaseStringUTFChars(channelPath, c_channel_path);
-
- if (!reply) {
- if (dbus_error_is_set(&err)) {
- LOG_AND_FREE_DBUS_ERROR(&err);
- }
- return NULL;
- }
-
- fd = dbus_returns_unixfd(env, reply);
- if (fd == -1) return NULL;
-
- int flags = fcntl(fd, F_GETFL);
- if (flags < 0) {
- ALOGE("Can't get flags with fcntl(): %s (%d)",
- strerror(errno), errno);
- releaseChannelFdNative(env, object, channelPath);
- close(fd);
- return NULL;
- }
-
- flags &= ~O_NONBLOCK;
- int status = fcntl(fd, F_SETFL, flags);
- if (status < 0) {
- ALOGE("Can't set flags with fcntl(): %s (%d)",
- strerror(errno), errno);
- releaseChannelFdNative(env, object, channelPath);
- close(fd);
- return NULL;
- }
-
- // Create FileDescriptor object
- jobject fileDesc = jniCreateFileDescriptor(env, fd);
- if (fileDesc == NULL) {
- // FileDescriptor constructor has thrown an exception
- releaseChannelFdNative(env, object, channelPath);
- close(fd);
- return NULL;
- }
-
- // Wrap it in a ParcelFileDescriptor
- jobject parcelFileDesc = newParcelFileDescriptor(env, fileDesc);
- if (parcelFileDesc == NULL) {
- // ParcelFileDescriptor constructor has thrown an exception
- releaseChannelFdNative(env, object, channelPath);
- close(fd);
- return NULL;
- }
-
- return parcelFileDesc;
- }
-#endif
- return NULL;
-}
-
-
-
-static JNINativeMethod sMethods[] = {
- /* name, signature, funcPtr */
- {"classInitNative", "()V", (void*)classInitNative},
- {"initializeNativeDataNative", "()V", (void *)initializeNativeDataNative},
- {"setupNativeDataNative", "()Z", (void *)setupNativeDataNative},
- {"tearDownNativeDataNative", "()Z", (void *)tearDownNativeDataNative},
- {"cleanupNativeDataNative", "()V", (void *)cleanupNativeDataNative},
- {"getAdapterPathNative", "()Ljava/lang/String;", (void*)getAdapterPathNative},
-
- {"isEnabledNative", "()I", (void *)isEnabledNative},
- {"enableNative", "()I", (void *)enableNative},
- {"disableNative", "()I", (void *)disableNative},
-
- {"getAdapterPropertiesNative", "()[Ljava/lang/Object;", (void *)getAdapterPropertiesNative},
- {"getDevicePropertiesNative", "(Ljava/lang/String;)[Ljava/lang/Object;",
- (void *)getDevicePropertiesNative},
- {"setAdapterPropertyStringNative", "(Ljava/lang/String;Ljava/lang/String;)Z",
- (void *)setAdapterPropertyStringNative},
- {"setAdapterPropertyBooleanNative", "(Ljava/lang/String;I)Z",
- (void *)setAdapterPropertyBooleanNative},
- {"setAdapterPropertyIntegerNative", "(Ljava/lang/String;I)Z",
- (void *)setAdapterPropertyIntegerNative},
-
- {"startDiscoveryNative", "()Z", (void*)startDiscoveryNative},
- {"stopDiscoveryNative", "()Z", (void *)stopDiscoveryNative},
-
- {"readAdapterOutOfBandDataNative", "()[B", (void *)readAdapterOutOfBandDataNative},
- {"createPairedDeviceNative", "(Ljava/lang/String;I)Z", (void *)createPairedDeviceNative},
- {"createPairedDeviceOutOfBandNative", "(Ljava/lang/String;I)Z",
- (void *)createPairedDeviceOutOfBandNative},
- {"cancelDeviceCreationNative", "(Ljava/lang/String;)Z", (void *)cancelDeviceCreationNative},
- {"removeDeviceNative", "(Ljava/lang/String;)Z", (void *)removeDeviceNative},
- {"getDeviceServiceChannelNative", "(Ljava/lang/String;Ljava/lang/String;I)I",
- (void *)getDeviceServiceChannelNative},
-
- {"setPairingConfirmationNative", "(Ljava/lang/String;ZI)Z",
- (void *)setPairingConfirmationNative},
- {"setPasskeyNative", "(Ljava/lang/String;II)Z", (void *)setPasskeyNative},
- {"setRemoteOutOfBandDataNative", "(Ljava/lang/String;[B[BI)Z", (void *)setRemoteOutOfBandDataNative},
- {"setAuthorizationNative", "(Ljava/lang/String;ZI)Z", (void *)setAuthorizationNative},
- {"setPinNative", "(Ljava/lang/String;Ljava/lang/String;I)Z", (void *)setPinNative},
- {"cancelPairingUserInputNative", "(Ljava/lang/String;I)Z",
- (void *)cancelPairingUserInputNative},
- {"setDevicePropertyBooleanNative", "(Ljava/lang/String;Ljava/lang/String;I)Z",
- (void *)setDevicePropertyBooleanNative},
- {"setDevicePropertyStringNative", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z",
- (void *)setDevicePropertyStringNative},
- {"createDeviceNative", "(Ljava/lang/String;)Z", (void *)createDeviceNative},
- {"discoverServicesNative", "(Ljava/lang/String;Ljava/lang/String;)Z", (void *)discoverServicesNative},
- {"addRfcommServiceRecordNative", "(Ljava/lang/String;JJS)I", (void *)addRfcommServiceRecordNative},
- {"removeServiceRecordNative", "(I)Z", (void *)removeServiceRecordNative},
- {"addReservedServiceRecordsNative", "([I)[I", (void *) addReservedServiceRecordsNative},
- {"removeReservedServiceRecordsNative", "([I)Z", (void *) removeReservedServiceRecordsNative},
- {"setLinkTimeoutNative", "(Ljava/lang/String;I)Z", (void *)setLinkTimeoutNative},
- // HID functions
- {"connectInputDeviceNative", "(Ljava/lang/String;)Z", (void *)connectInputDeviceNative},
- {"disconnectInputDeviceNative", "(Ljava/lang/String;)Z", (void *)disconnectInputDeviceNative},
-
- {"setBluetoothTetheringNative", "(ZLjava/lang/String;Ljava/lang/String;)Z",
- (void *)setBluetoothTetheringNative},
- {"connectPanDeviceNative", "(Ljava/lang/String;Ljava/lang/String;)Z",
- (void *)connectPanDeviceNative},
- {"disconnectPanDeviceNative", "(Ljava/lang/String;)Z", (void *)disconnectPanDeviceNative},
- {"disconnectPanServerDeviceNative", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z",
- (void *)disconnectPanServerDeviceNative},
- // Health function
- {"registerHealthApplicationNative",
- "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
- (void *)registerHealthApplicationNative},
- {"registerHealthApplicationNative",
- "(ILjava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
- (void *)registerSinkHealthApplicationNative},
-
- {"unregisterHealthApplicationNative", "(Ljava/lang/String;)Z",
- (void *)unregisterHealthApplicationNative},
- {"createChannelNative", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)Z",
- (void *)createChannelNative},
- {"destroyChannelNative", "(Ljava/lang/String;Ljava/lang/String;I)Z",
- (void *)destroyChannelNative},
- {"getMainChannelNative", "(Ljava/lang/String;)Ljava/lang/String;", (void *)getMainChannelNative},
- {"getChannelApplicationNative", "(Ljava/lang/String;)Ljava/lang/String;",
- (void *)getChannelApplicationNative},
- {"getChannelFdNative", "(Ljava/lang/String;)Landroid/os/ParcelFileDescriptor;", (void *)getChannelFdNative},
- {"releaseChannelFdNative", "(Ljava/lang/String;)Z", (void *)releaseChannelFdNative},
-};
-
-
-int register_android_server_BluetoothService(JNIEnv *env) {
- return AndroidRuntime::registerNativeMethods(env,
- "android/server/BluetoothService", sMethods, NELEM(sMethods));
-}
-
-} /* namespace android */