16c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie/*
2ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Copyright (C) 2012 The Android Open Source Project
3ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu *
4ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Licensed under the Apache License, Version 2.0 (the "License");
5ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * you may not use this file except in compliance with the License.
6ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * You may obtain a copy of the License at
7ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu *
8ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu *      http://www.apache.org/licenses/LICENSE-2.0
9ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu *
10ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Unless required by applicable law or agreed to in writing, software
11ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * distributed under the License is distributed on an "AS IS" BASIS,
12ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * See the License for the specific language governing permissions and
14ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * limitations under the License.
156c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie */
166c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
176c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie#define LOG_TAG "BluetoothHeadsetServiceJni"
186c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
196c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie#define LOG_NDEBUG 0
206c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
216c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie#define CHECK_CALLBACK_ENV                                                      \
226c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie   if (!checkCallbackThread()) {                                                \
23c55a9837c004044051b71bb47182ace156691283Matthew Xie       ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);\
246c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie       return;                                                                  \
256c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie   }
266c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
276c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie#include "com_android_bluetooth.h"
286c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie#include "hardware/bt_hf.h"
296c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie#include "utils/Log.h"
306c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie#include "android_runtime/AndroidRuntime.h"
316c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
326c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie#include <string.h>
336c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
346c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xienamespace android {
356c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
366c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jmethodID method_onConnectionStateChanged;
376c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jmethodID method_onAudioStateChanged;
386c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jmethodID method_onVrStateChanged;
396c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jmethodID method_onAnswerCall;
406c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jmethodID method_onHangupCall;
416c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jmethodID method_onVolumeChanged;
426c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jmethodID method_onDialCall;
436c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jmethodID method_onSendDtmf;
446c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jmethodID method_onNoiceReductionEnable;
45b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xiestatic jmethodID method_onWBS;
466c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jmethodID method_onAtChld;
476c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jmethodID method_onAtCnum;
486c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jmethodID method_onAtCind;
496c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jmethodID method_onAtCops;
506c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jmethodID method_onAtClcc;
516c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jmethodID method_onUnknownAt;
526c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jmethodID method_onKeyPressed;
532ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananthstatic jmethodID method_onAtBind;
542ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananthstatic jmethodID method_onAtBiev;
556c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
566c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic const bthf_interface_t *sBluetoothHfpInterface = NULL;
576c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jobject mCallbacksObj = NULL;
586c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic JNIEnv *sCallbackEnv = NULL;
596c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
606c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic bool checkCallbackThread() {
6193f548ff8560bdecdc4bdd2f91f7dacda1e6bbc3Kausik Sinnaswamy    // Always fetch the latest callbackEnv from AdapterService.
6293f548ff8560bdecdc4bdd2f91f7dacda1e6bbc3Kausik Sinnaswamy    // Caching this could cause this sCallbackEnv to go out-of-sync
6393f548ff8560bdecdc4bdd2f91f7dacda1e6bbc3Kausik Sinnaswamy    // with the AdapterService's ENV if an ASSOCIATE/DISASSOCIATE event
6493f548ff8560bdecdc4bdd2f91f7dacda1e6bbc3Kausik Sinnaswamy    // is received
6593f548ff8560bdecdc4bdd2f91f7dacda1e6bbc3Kausik Sinnaswamy    //if (sCallbackEnv == NULL) {
6693f548ff8560bdecdc4bdd2f91f7dacda1e6bbc3Kausik Sinnaswamy    sCallbackEnv = getCallbackEnv();
6793f548ff8560bdecdc4bdd2f91f7dacda1e6bbc3Kausik Sinnaswamy    //}
686c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    JNIEnv* env = AndroidRuntime::getJNIEnv();
696c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (sCallbackEnv != env || sCallbackEnv == NULL) return false;
706c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    return true;
716c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
726c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
73b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xiestatic jbyteArray marshall_bda(bt_bdaddr_t* bd_addr)
74b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie{
75b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    jbyteArray addr;
76b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
77b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    if (!addr) {
78b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie        ALOGE("Fail to new jbyteArray bd addr");
79b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
80b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie        return NULL;
81b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    }
82b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
83b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    return addr;
84b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie}
85b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie
866c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic void connection_state_callback(bthf_connection_state_t state, bt_bdaddr_t* bd_addr) {
876c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    jbyteArray addr;
886c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
89c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGI("%s", __FUNCTION__);
906c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
916c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    CHECK_CALLBACK_ENV
926c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
936c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (!addr) {
94c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Fail to new jbyteArray bd addr for connection state");
956c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
966c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        return;
976c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
986c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
996c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr);
1006c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnectionStateChanged,
1016c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                                 (jint) state, addr);
1026c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
1036c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    sCallbackEnv->DeleteLocalRef(addr);
1046c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
1056c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
1066c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic void audio_state_callback(bthf_audio_state_t state, bt_bdaddr_t* bd_addr) {
1076c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    jbyteArray addr;
1086c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
1096c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    CHECK_CALLBACK_ENV
1106c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
1116c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (!addr) {
112c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Fail to new jbyteArray bd addr for audio state");
1136c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
1146c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        return;
1156c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
1166c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
1176c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
1186c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAudioStateChanged, (jint) state, addr);
1196c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
1206c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    sCallbackEnv->DeleteLocalRef(addr);
1216c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
1226c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
12369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic void voice_recognition_callback(bthf_vr_state_t state, bt_bdaddr_t* bd_addr) {
12469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyteArray addr;
12569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
1266c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    CHECK_CALLBACK_ENV
12769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
12869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
12969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        ALOGE("Fail to new jbyteArray bd addr for audio state");
13069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
13169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return;
13269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
13369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
13469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
13569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onVrStateChanged, (jint) state, addr);
1366c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
13769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->DeleteLocalRef(addr);
1386c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
1396c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
14069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic void answer_call_callback(bt_bdaddr_t* bd_addr) {
14169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyteArray addr;
14269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
1436c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    CHECK_CALLBACK_ENV
14469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
14569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
14669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        ALOGE("Fail to new jbyteArray bd addr for audio state");
14769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
14869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return;
14969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
15069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
15169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
15269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAnswerCall, addr);
1536c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
15469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->DeleteLocalRef(addr);
1556c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
1566c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
15769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic void hangup_call_callback(bt_bdaddr_t* bd_addr) {
15869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyteArray addr;
15969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
1606c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    CHECK_CALLBACK_ENV
16169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
16269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
16369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        ALOGE("Fail to new jbyteArray bd addr for audio state");
16469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
16569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return;
16669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
16769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
16869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
16969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onHangupCall, addr);
1706c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
17169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->DeleteLocalRef(addr);
1726c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
1736c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
17469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic void volume_control_callback(bthf_volume_type_t type, int volume, bt_bdaddr_t* bd_addr) {
17569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyteArray addr;
17669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
1776c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    CHECK_CALLBACK_ENV
17869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
17969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
18069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        ALOGE("Fail to new jbyteArray bd addr for audio state");
18169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
18269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return;
18369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
18469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
18569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
18669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onVolumeChanged, (jint) type,
18769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava                                                  (jint) volume, addr);
1886c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
18969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->DeleteLocalRef(addr);
1906c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
1916c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
19269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic void dial_call_callback(char *number, bt_bdaddr_t* bd_addr) {
19369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyteArray addr;
19469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
1956c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    CHECK_CALLBACK_ENV
19669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
19769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
19869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        ALOGE("Fail to new jbyteArray bd addr for audio state");
19969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
20069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return;
20169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
20269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
20369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
204976912e5f597f015754aa67f2a74040e27f58eabSyed Ibrahim M    jstring js_number = sCallbackEnv->NewStringUTF(number);
2056c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onDialCall,
20669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava                                 js_number, addr);
2076c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
208976912e5f597f015754aa67f2a74040e27f58eabSyed Ibrahim M    sCallbackEnv->DeleteLocalRef(js_number);
20969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->DeleteLocalRef(addr);
2106c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
2116c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
21269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic void dtmf_cmd_callback(char dtmf, bt_bdaddr_t* bd_addr) {
21369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyteArray addr;
21469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
2156c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    CHECK_CALLBACK_ENV
21669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
21769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
21869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        ALOGE("Fail to new jbyteArray bd addr for audio state");
21969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
22069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return;
22169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
22269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
22369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
2246c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    // TBD dtmf has changed from int to char
22569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onSendDtmf, dtmf, addr);
2266c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
22769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->DeleteLocalRef(addr);
2286c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
2296c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
23069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic void noice_reduction_callback(bthf_nrec_t nrec, bt_bdaddr_t* bd_addr) {
23169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyteArray addr;
23269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
2336c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    CHECK_CALLBACK_ENV
23469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
23569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
23669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        ALOGE("Fail to new jbyteArray bd addr for audio state");
23769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
23869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return;
23969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
24069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
2416c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNoiceReductionEnable,
24269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava                                 nrec == BTHF_NREC_START, addr);
2436c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
24469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->DeleteLocalRef(addr);
2456c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
2466c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
247b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xiestatic void wbs_callback(bthf_wbs_config_t wbs_config, bt_bdaddr_t* bd_addr) {
248b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    jbyteArray addr;
249b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie
250b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    CHECK_CALLBACK_ENV
251b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie
252b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    if ((addr = marshall_bda(bd_addr)) == NULL)
253b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie        return;
254b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie
255b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onWBS, wbs_config, addr);
256b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
257b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    sCallbackEnv->DeleteLocalRef(addr);
258b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie}
259b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie
26069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic void at_chld_callback(bthf_chld_type_t chld, bt_bdaddr_t* bd_addr) {
26169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyteArray addr;
26269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
2636c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    CHECK_CALLBACK_ENV
26469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
26569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
26669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        ALOGE("Fail to new jbyteArray bd addr for audio state");
26769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
26869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return;
26969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
27069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
27169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
27269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtChld, chld, addr);
2736c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
27469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->DeleteLocalRef(addr);
2756c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
2766c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
27769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic void at_cnum_callback(bt_bdaddr_t* bd_addr) {
27869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyteArray addr;
27969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
2806c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    CHECK_CALLBACK_ENV
28169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
28269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
28369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        ALOGE("Fail to new jbyteArray bd addr for audio state");
28469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
28569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return;
28669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
28769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
28869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
28969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtCnum, addr);
2906c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
29169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->DeleteLocalRef(addr);
2926c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
2936c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
29469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic void at_cind_callback(bt_bdaddr_t* bd_addr) {
29569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyteArray addr;
29669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
2976c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    CHECK_CALLBACK_ENV
29869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
29969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
30069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        ALOGE("Fail to new jbyteArray bd addr for audio state");
30169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
30269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return;
30369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
30469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
30569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
30669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtCind, addr);
3076c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
30869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->DeleteLocalRef(addr);
3096c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
3106c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
31169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic void at_cops_callback(bt_bdaddr_t* bd_addr) {
31269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyteArray addr;
31369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
3146c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    CHECK_CALLBACK_ENV
31569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
31669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
31769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        ALOGE("Fail to new jbyteArray bd addr for audio state");
31869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
31969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return;
32069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
32169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
32269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
32369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtCops, addr);
3246c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
32569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->DeleteLocalRef(addr);
3266c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
3276c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
32869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic void at_clcc_callback(bt_bdaddr_t* bd_addr) {
32969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyteArray addr;
33069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
3316c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    CHECK_CALLBACK_ENV
33269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
33369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
33469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        ALOGE("Fail to new jbyteArray bd addr for audio state");
33569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
33669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return;
33769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
33869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
33969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
34069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtClcc, addr);
3416c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
34269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->DeleteLocalRef(addr);
3436c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
3446c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
34569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic void unknown_at_callback(char *at_string, bt_bdaddr_t* bd_addr) {
34669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyteArray addr;
34769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
3486c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    CHECK_CALLBACK_ENV
34969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
35069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
35169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        ALOGE("Fail to new jbyteArray bd addr for audio state");
35269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
35369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return;
35469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
35569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
35669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
357976912e5f597f015754aa67f2a74040e27f58eabSyed Ibrahim M    jstring js_at_string = sCallbackEnv->NewStringUTF(at_string);
3586c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onUnknownAt,
35969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava                                 js_at_string, addr);
3606c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
361976912e5f597f015754aa67f2a74040e27f58eabSyed Ibrahim M    sCallbackEnv->DeleteLocalRef(js_at_string);
36269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->DeleteLocalRef(addr);
3636c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
3646c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
36569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic void key_pressed_callback(bt_bdaddr_t* bd_addr) {
36669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyteArray addr;
36769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
3686c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    CHECK_CALLBACK_ENV
36969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
37069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
37169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        ALOGE("Fail to new jbyteArray bd addr for audio state");
37269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
37369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return;
37469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
37569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
37669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
37769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onKeyPressed, addr);
3786c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
37969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    sCallbackEnv->DeleteLocalRef(addr);
3806c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
3816c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
3822ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananthstatic void at_bind_callback(char *at_string, bt_bdaddr_t *bd_addr) {
3832ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth    CHECK_CALLBACK_ENV
3842ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth
3852ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth    jbyteArray addr = marshall_bda(bd_addr);
3862ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth    if (addr == NULL)
3872ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth        return;
3882ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth
3892ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth    jstring js_at_string = sCallbackEnv->NewStringUTF(at_string);
3902ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth
3912ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtBind, js_at_string, addr);
3922ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
3932ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth
3942ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth    sCallbackEnv->DeleteLocalRef(js_at_string);
3952ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth    sCallbackEnv->DeleteLocalRef(addr);
3962ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth}
3972ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth
3982ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananthstatic void at_biev_callback(bthf_hf_ind_type_t ind_id, int ind_value, bt_bdaddr_t *bd_addr) {
3992ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth    CHECK_CALLBACK_ENV
4002ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth
4012ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth    jbyteArray addr = marshall_bda(bd_addr);
4022ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth    if (addr == NULL)
4032ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth        return;
4042ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth
4052ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtBiev, ind_id, (jint)ind_value, addr);
4062ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
4072ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth    sCallbackEnv->DeleteLocalRef(addr);
4082ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth}
4092ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth
4106c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic bthf_callbacks_t sBluetoothHfpCallbacks = {
4116c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    sizeof(sBluetoothHfpCallbacks),
4126c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    connection_state_callback,
4136c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    audio_state_callback,
4146c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    voice_recognition_callback,
4156c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    answer_call_callback,
4166c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    hangup_call_callback,
4176c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    volume_control_callback,
4186c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    dial_call_callback,
4196c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    dtmf_cmd_callback,
4206c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    noice_reduction_callback,
421b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    wbs_callback,
4226c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    at_chld_callback,
4236c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    at_cnum_callback,
4246c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    at_cind_callback,
4256c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    at_cops_callback,
4266c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    at_clcc_callback,
4276c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    unknown_at_callback,
4282ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth    at_bind_callback,
4292ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth    at_biev_callback,
4306c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    key_pressed_callback
4316c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie};
4326c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
4336c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic void classInitNative(JNIEnv* env, jclass clazz) {
4346c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    method_onConnectionStateChanged =
4356c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        env->GetMethodID(clazz, "onConnectionStateChanged", "(I[B)V");
4366c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    method_onAudioStateChanged = env->GetMethodID(clazz, "onAudioStateChanged", "(I[B)V");
43769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    method_onVrStateChanged = env->GetMethodID(clazz, "onVrStateChanged", "(I[B)V");
43869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    method_onAnswerCall = env->GetMethodID(clazz, "onAnswerCall", "([B)V");
43969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    method_onHangupCall = env->GetMethodID(clazz, "onHangupCall", "([B)V");
44069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    method_onVolumeChanged = env->GetMethodID(clazz, "onVolumeChanged", "(II[B)V");
44169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    method_onDialCall = env->GetMethodID(clazz, "onDialCall", "(Ljava/lang/String;[B)V");
44269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    method_onSendDtmf = env->GetMethodID(clazz, "onSendDtmf", "(I[B)V");
44369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    method_onNoiceReductionEnable = env->GetMethodID(clazz, "onNoiceReductionEnable", "(Z[B)V");
444b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    method_onWBS = env->GetMethodID(clazz,"onWBS","(I[B)V");
44569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    method_onAtChld = env->GetMethodID(clazz, "onAtChld", "(I[B)V");
44669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    method_onAtCnum = env->GetMethodID(clazz, "onAtCnum", "([B)V");
44769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    method_onAtCind = env->GetMethodID(clazz, "onAtCind", "([B)V");
44869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    method_onAtCops = env->GetMethodID(clazz, "onAtCops", "([B)V");
44969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    method_onAtClcc = env->GetMethodID(clazz, "onAtClcc", "([B)V");
45069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    method_onUnknownAt = env->GetMethodID(clazz, "onUnknownAt", "(Ljava/lang/String;[B)V");
45169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    method_onKeyPressed = env->GetMethodID(clazz, "onKeyPressed", "([B)V");
4522ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth    method_onAtBind = env->GetMethodID(clazz, "onATBind", "(Ljava/lang/String;[B)V");
4532ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth    method_onAtBiev = env->GetMethodID(clazz, "onATBiev", "(II[B)V");
4546c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
455c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGI("%s: succeeds", __FUNCTION__);
4566c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
4576c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
45869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic void initializeNative(JNIEnv *env, jobject object, jint max_hf_clients) {
4596654f5c903de510a70f9e72cd5ad7837b615d93ffredc    const bt_interface_t* btInf;
4606654f5c903de510a70f9e72cd5ad7837b615d93ffredc    bt_status_t status;
4616654f5c903de510a70f9e72cd5ad7837b615d93ffredc
4626654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if ( (btInf = getBluetoothInterface()) == NULL) {
463e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("Bluetooth module is not loaded");
4646654f5c903de510a70f9e72cd5ad7837b615d93ffredc        return;
4656654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
4666654f5c903de510a70f9e72cd5ad7837b615d93ffredc
4676654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if (sBluetoothHfpInterface !=NULL) {
468e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGW("Cleaning up Bluetooth Handsfree Interface before initializing...");
4696654f5c903de510a70f9e72cd5ad7837b615d93ffredc        sBluetoothHfpInterface->cleanup();
4706654f5c903de510a70f9e72cd5ad7837b615d93ffredc        sBluetoothHfpInterface = NULL;
4716654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
4726654f5c903de510a70f9e72cd5ad7837b615d93ffredc
4736654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if (mCallbacksObj != NULL) {
474e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGW("Cleaning up Bluetooth Handsfree callback object");
4756654f5c903de510a70f9e72cd5ad7837b615d93ffredc        env->DeleteGlobalRef(mCallbacksObj);
4766654f5c903de510a70f9e72cd5ad7837b615d93ffredc        mCallbacksObj = NULL;
4776654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
4786654f5c903de510a70f9e72cd5ad7837b615d93ffredc
4796654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if ( (sBluetoothHfpInterface = (bthf_interface_t *)
4806654f5c903de510a70f9e72cd5ad7837b615d93ffredc          btInf->get_profile_interface(BT_PROFILE_HANDSFREE_ID)) == NULL) {
481e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("Failed to get Bluetooth Handsfree Interface");
4826654f5c903de510a70f9e72cd5ad7837b615d93ffredc        return;
4836654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
4846654f5c903de510a70f9e72cd5ad7837b615d93ffredc
48569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if ( (status = sBluetoothHfpInterface->init(&sBluetoothHfpCallbacks,
48669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava          max_hf_clients)) != BT_STATUS_SUCCESS) {
487e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("Failed to initialize Bluetooth HFP, status: %d", status);
4886654f5c903de510a70f9e72cd5ad7837b615d93ffredc        sBluetoothHfpInterface = NULL;
4896654f5c903de510a70f9e72cd5ad7837b615d93ffredc        return;
4906654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
4916654f5c903de510a70f9e72cd5ad7837b615d93ffredc
4926c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    mCallbacksObj = env->NewGlobalRef(object);
4936c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
4946c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
4956654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic void cleanupNative(JNIEnv *env, jobject object) {
4966654f5c903de510a70f9e72cd5ad7837b615d93ffredc    const bt_interface_t* btInf;
4976654f5c903de510a70f9e72cd5ad7837b615d93ffredc
4986654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if ( (btInf = getBluetoothInterface()) == NULL) {
499e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("Bluetooth module is not loaded");
5006654f5c903de510a70f9e72cd5ad7837b615d93ffredc        return;
5016654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
5026654f5c903de510a70f9e72cd5ad7837b615d93ffredc
5036654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if (sBluetoothHfpInterface !=NULL) {
504e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGW("Cleaning up Bluetooth Handsfree Interface...");
5056654f5c903de510a70f9e72cd5ad7837b615d93ffredc        sBluetoothHfpInterface->cleanup();
5066654f5c903de510a70f9e72cd5ad7837b615d93ffredc        sBluetoothHfpInterface = NULL;
5076654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
5086654f5c903de510a70f9e72cd5ad7837b615d93ffredc
5096654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if (mCallbacksObj != NULL) {
510e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGW("Cleaning up Bluetooth Handsfree callback object");
5116654f5c903de510a70f9e72cd5ad7837b615d93ffredc        env->DeleteGlobalRef(mCallbacksObj);
5126654f5c903de510a70f9e72cd5ad7837b615d93ffredc        mCallbacksObj = NULL;
5136654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
5146654f5c903de510a70f9e72cd5ad7837b615d93ffredc}
5156654f5c903de510a70f9e72cd5ad7837b615d93ffredc
5166c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jboolean connectHfpNative(JNIEnv *env, jobject object, jbyteArray address) {
5176c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    jbyte *addr;
5186c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    bt_status_t status;
5196c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
520c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGI("%s: sBluetoothHfpInterface: %p", __FUNCTION__, sBluetoothHfpInterface);
5216c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (!sBluetoothHfpInterface) return JNI_FALSE;
5226c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
5236c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    addr = env->GetByteArrayElements(address, NULL);
5246c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (!addr) {
5256c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        jniThrowIOException(env, EINVAL);
5266c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        return JNI_FALSE;
5276c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
5286c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
5296c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if ((status = sBluetoothHfpInterface->connect((bt_bdaddr_t *)addr)) != BT_STATUS_SUCCESS) {
530c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Failed HF connection, status: %d", status);
5316c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
5326c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    env->ReleaseByteArrayElements(address, addr, 0);
5336c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
5346c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
5356c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
5366c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jboolean disconnectHfpNative(JNIEnv *env, jobject object, jbyteArray address) {
5376c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    jbyte *addr;
5386c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    bt_status_t status;
5396c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
5406c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (!sBluetoothHfpInterface) return JNI_FALSE;
5416c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
5426c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    addr = env->GetByteArrayElements(address, NULL);
5436c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (!addr) {
5446c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        jniThrowIOException(env, EINVAL);
5456c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        return JNI_FALSE;
5466c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
5476c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
5486c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if ( (status = sBluetoothHfpInterface->disconnect((bt_bdaddr_t *)addr)) != BT_STATUS_SUCCESS) {
549c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Failed HF disconnection, status: %d", status);
5506c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
5516c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    env->ReleaseByteArrayElements(address, addr, 0);
5526c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
5536c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
5546c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
5556c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jboolean connectAudioNative(JNIEnv *env, jobject object, jbyteArray address) {
5566c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    jbyte *addr;
5576c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    bt_status_t status;
5586c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
5596c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (!sBluetoothHfpInterface) return JNI_FALSE;
5606c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
5616c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    addr = env->GetByteArrayElements(address, NULL);
5626c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (!addr) {
5636c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        jniThrowIOException(env, EINVAL);
5646c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        return JNI_FALSE;
5656c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
5666c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
5676c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if ( (status = sBluetoothHfpInterface->connect_audio((bt_bdaddr_t *)addr)) !=
5686c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie         BT_STATUS_SUCCESS) {
569c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Failed HF audio connection, status: %d", status);
5706c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
5716c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    env->ReleaseByteArrayElements(address, addr, 0);
5726c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
5736c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
5746c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
5756c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jboolean disconnectAudioNative(JNIEnv *env, jobject object, jbyteArray address) {
5766c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    jbyte *addr;
5776c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    bt_status_t status;
5786c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
5796c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (!sBluetoothHfpInterface) return JNI_FALSE;
5806c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
5816c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    addr = env->GetByteArrayElements(address, NULL);
5826c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (!addr) {
5836c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        jniThrowIOException(env, EINVAL);
5846c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        return JNI_FALSE;
5856c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
5866c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
5876c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if ( (status = sBluetoothHfpInterface->disconnect_audio((bt_bdaddr_t *) addr)) !=
5886c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie         BT_STATUS_SUCCESS) {
589c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Failed HF audio disconnection, status: %d", status);
5906c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
5916c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    env->ReleaseByteArrayElements(address, addr, 0);
5926c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
5936c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
5946c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
59569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic jboolean startVoiceRecognitionNative(JNIEnv *env, jobject object, jbyteArray address) {
59669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyte *addr;
5976c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    bt_status_t status;
5986c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (!sBluetoothHfpInterface) return JNI_FALSE;
5996c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
60069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = env->GetByteArrayElements(address, NULL);
60169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
60269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        jniThrowIOException(env, EINVAL);
60369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return JNI_FALSE;
60469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
60569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
60669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if ( (status = sBluetoothHfpInterface->start_voice_recognition((bt_bdaddr_t *) addr))
60769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava                                          != BT_STATUS_SUCCESS) {
608c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Failed to start voice recognition, status: %d", status);
6096c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
61069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    env->ReleaseByteArrayElements(address, addr, 0);
6116c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
6126c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
6136c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
61469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic jboolean stopVoiceRecognitionNative(JNIEnv *env, jobject object, jbyteArray address) {
61569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyte *addr;
6166c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    bt_status_t status;
6176c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (!sBluetoothHfpInterface) return JNI_FALSE;
6186c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
61969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = env->GetByteArrayElements(address, NULL);
62069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
62169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        jniThrowIOException(env, EINVAL);
62269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return JNI_FALSE;
62369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
62469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
62569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if ( (status = sBluetoothHfpInterface->stop_voice_recognition((bt_bdaddr_t *) addr))
62669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava                                     != BT_STATUS_SUCCESS) {
627c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Failed to stop voice recognition, status: %d", status);
6286c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
62969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    env->ReleaseByteArrayElements(address, addr, 0);
6306c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
6316c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
6326c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
63369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic jboolean setVolumeNative(JNIEnv *env, jobject object, jint volume_type,
63469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava                                     jint volume, jbyteArray address) {
63569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyte *addr;
6366c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    bt_status_t status;
6376c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (!sBluetoothHfpInterface) return JNI_FALSE;
6386c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
63969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = env->GetByteArrayElements(address, NULL);
64069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
64169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        jniThrowIOException(env, EINVAL);
64269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return JNI_FALSE;
64369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
64469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
6456c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if ( (status = sBluetoothHfpInterface->volume_control((bthf_volume_type_t) volume_type,
64669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava                                volume, (bt_bdaddr_t *) addr)) != BT_STATUS_SUCCESS) {
647c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("FAILED to control volume, status: %d", status);
6486c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
64969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    env->ReleaseByteArrayElements(address, addr, 0);
6506c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
6516c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
6526c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
6536c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jboolean notifyDeviceStatusNative(JNIEnv *env, jobject object,
6546c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                                         jint network_state, jint service_type, jint signal,
6556c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                                         jint battery_charge) {
6566c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    bt_status_t status;
6576c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (!sBluetoothHfpInterface) return JNI_FALSE;
6586c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
6596c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if ( (status = sBluetoothHfpInterface->device_status_notification
6606c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie          ((bthf_network_state_t) network_state, (bthf_service_type_t) service_type,
6616c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie           signal, battery_charge)) != BT_STATUS_SUCCESS) {
662c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("FAILED to notify device status, status: %d", status);
6636c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
6646c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
6656c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
6666c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
66769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic jboolean copsResponseNative(JNIEnv *env, jobject object, jstring operator_str,
66869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava                                              jbyteArray address) {
66969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyte *addr;
6706c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    bt_status_t status;
6716c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    const char *operator_name;
6726c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (!sBluetoothHfpInterface) return JNI_FALSE;
6736c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
67469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = env->GetByteArrayElements(address, NULL);
67569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
67669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        jniThrowIOException(env, EINVAL);
67769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return JNI_FALSE;
67869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
67969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
6806c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    operator_name = env->GetStringUTFChars(operator_str, NULL);
6816c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
68269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if ( (status = sBluetoothHfpInterface->cops_response(operator_name,(bt_bdaddr_t *) addr))
68369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava                                                  != BT_STATUS_SUCCESS) {
684c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Failed sending cops response, status: %d", status);
6856c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
68669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    env->ReleaseByteArrayElements(address, addr, 0);
6876c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    env->ReleaseStringUTFChars(operator_str, operator_name);
6886c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
6896c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
6906c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
6916c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jboolean cindResponseNative(JNIEnv *env, jobject object,
6926c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                                   jint service, jint num_active, jint num_held, jint call_state,
69369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava                                   jint signal, jint roam, jint battery_charge, jbyteArray address) {
69469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyte *addr;
6956c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    bt_status_t status;
69669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
69769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    ALOGI("%s: sBluetoothHfpInterface: %p", __FUNCTION__, sBluetoothHfpInterface);
6986c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (!sBluetoothHfpInterface) return JNI_FALSE;
6996c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
70069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = env->GetByteArrayElements(address, NULL);
70169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
70269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        jniThrowIOException(env, EINVAL);
70369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return JNI_FALSE;
70469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
70569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
7066c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if ( (status = sBluetoothHfpInterface->cind_response(service, num_active, num_held,
7076c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                       (bthf_call_state_t) call_state,
70869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava                       signal, roam, battery_charge, (bt_bdaddr_t *)addr)) != BT_STATUS_SUCCESS) {
709c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Failed cind_response, status: %d", status);
7106c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
71169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    env->ReleaseByteArrayElements(address, addr, 0);
7126c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
7136c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
7146c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
7152ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananthstatic jboolean bindResponseNative(JNIEnv *env,jobject object,
7162ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth                                jint ind_id, jboolean ind_status,
7172ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth                                jbyteArray address) {
7182ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth    ALOGI("%s: sBluetoothHfpInterface: %p", __FUNCTION__, sBluetoothHfpInterface);
7192ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth
7202ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth    if (!sBluetoothHfpInterface)
7212ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth        return JNI_FALSE;
7222ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth
7232ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth    jbyte *addr = env->GetByteArrayElements(address, NULL);
7242ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth    if (!addr) {
7252ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth        jniThrowIOException(env, EINVAL);
7262ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth        return JNI_FALSE;
7272ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth    }
7282ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth
7292ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth    bt_status_t status = sBluetoothHfpInterface->bind_response((bthf_hf_ind_type_t) ind_id,
7302ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth                   ind_status ? BTHF_HF_IND_ENABLED : BTHF_HF_IND_DISABLED,
7312ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth                   (bt_bdaddr_t *)addr);
7322ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth
7332ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth    if (status != BT_STATUS_SUCCESS)
7342ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth        ALOGE("%s: Failed bind_response, status: %d", __FUNCTION__, status);
7352ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth
7362ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth    env->ReleaseByteArrayElements(address, addr, 0);
7372ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth    return (status == BT_STATUS_SUCCESS ? JNI_TRUE : JNI_FALSE);
7382ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth}
7396c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
74069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic jboolean atResponseStringNative(JNIEnv *env, jobject object, jstring response_str,
74169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava                                                 jbyteArray address) {
74269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyte *addr;
7436c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    bt_status_t status;
7446c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    const char *response;
7456c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (!sBluetoothHfpInterface) return JNI_FALSE;
7466c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
74769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = env->GetByteArrayElements(address, NULL);
74869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
74969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        jniThrowIOException(env, EINVAL);
75069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return JNI_FALSE;
75169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
75269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
7536c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    response = env->GetStringUTFChars(response_str, NULL);
7546c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
75569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if ( (status = sBluetoothHfpInterface->formatted_at_response(response,
75669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava                            (bt_bdaddr_t *)addr))!= BT_STATUS_SUCCESS) {
757c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Failed formatted AT response, status: %d", status);
7586c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
75969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    env->ReleaseByteArrayElements(address, addr, 0);
7606c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    env->ReleaseStringUTFChars(response_str, response);
7616c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
7626c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
7636c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
76469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastavastatic jboolean atResponseCodeNative(JNIEnv *env, jobject object, jint response_code,
76569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava                                             jint cmee_code, jbyteArray address) {
76669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyte *addr;
7676c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    bt_status_t status;
7686c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (!sBluetoothHfpInterface) return JNI_FALSE;
7696c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
77069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = env->GetByteArrayElements(address, NULL);
77169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
77269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        jniThrowIOException(env, EINVAL);
77369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return JNI_FALSE;
77469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
77569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
77669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if ( (status = sBluetoothHfpInterface->at_response((bthf_at_response_t) response_code,
77769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava              cmee_code, (bt_bdaddr_t *)addr)) != BT_STATUS_SUCCESS) {
778c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Failed AT response, status: %d", status);
7796c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
78069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    env->ReleaseByteArrayElements(address, addr, 0);
7816c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
7826c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
7836c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
7846c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jboolean clccResponseNative(JNIEnv *env, jobject object, jint index, jint dir,
7856c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                                   jint callStatus, jint mode, jboolean mpty, jstring number_str,
78669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava                                   jint type, jbyteArray address) {
78769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    jbyte *addr;
7886c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    bt_status_t status;
789bbbfba6398ac613896a4456fae1c9bf909c28bf2Ravi Nagarajan    const char *number = NULL;
7906c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (!sBluetoothHfpInterface) return JNI_FALSE;
7916c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
79269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    addr = env->GetByteArrayElements(address, NULL);
79369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    if (!addr) {
79469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        jniThrowIOException(env, EINVAL);
79569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava        return JNI_FALSE;
79669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    }
79769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava
798bbbfba6398ac613896a4456fae1c9bf909c28bf2Ravi Nagarajan    if (number_str)
799bbbfba6398ac613896a4456fae1c9bf909c28bf2Ravi Nagarajan        number = env->GetStringUTFChars(number_str, NULL);
8006c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
8016c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if ( (status = sBluetoothHfpInterface->clcc_response(index, (bthf_call_direction_t) dir,
80269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava                (bthf_call_state_t) callStatus,  (bthf_call_mode_t) mode,
80369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava                mpty ? BTHF_CALL_MPTY_TYPE_MULTI : BTHF_CALL_MPTY_TYPE_SINGLE,
80469d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava                number, (bthf_call_addrtype_t) type, (bt_bdaddr_t *)addr)) != BT_STATUS_SUCCESS) {
805c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Failed sending CLCC response, status: %d", status);
8066c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
80769d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    env->ReleaseByteArrayElements(address, addr, 0);
808bbbfba6398ac613896a4456fae1c9bf909c28bf2Ravi Nagarajan    if (number)
809bbbfba6398ac613896a4456fae1c9bf909c28bf2Ravi Nagarajan        env->ReleaseStringUTFChars(number_str, number);
8106c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
8116c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
8126c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
8136c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic jboolean phoneStateChangeNative(JNIEnv *env, jobject object, jint num_active, jint num_held,
8146c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                                       jint call_state, jstring number_str, jint type) {
8156c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    bt_status_t status;
8166c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    const char *number;
8176c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if (!sBluetoothHfpInterface) return JNI_FALSE;
8186c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
8196c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    number = env->GetStringUTFChars(number_str, NULL);
8206c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
8216c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    if ( (status = sBluetoothHfpInterface->phone_state_change(num_active, num_held,
8226c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                       (bthf_call_state_t) call_state, number,
8236c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                       (bthf_call_addrtype_t) type)) != BT_STATUS_SUCCESS) {
824c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Failed report phone state change, status: %d", status);
8256c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
8266c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    env->ReleaseStringUTFChars(number_str, number);
8276c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
8286c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
8296c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
830b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie
831b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xiestatic jboolean configureWBSNative(JNIEnv *env, jobject object, jbyteArray address,
832b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie                                   jint codec_config) {
833b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    jbyte *addr;
834b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    bt_status_t status;
835b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie
836b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    if (!sBluetoothHfpInterface) return JNI_FALSE;
837b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie
838b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    addr = env->GetByteArrayElements(address, NULL);
839b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    if (!addr) {
840b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie        jniThrowIOException(env, EINVAL);
841b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie        return JNI_FALSE;
842b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    }
843b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie
844b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    if ((status = sBluetoothHfpInterface->configure_wbs((bt_bdaddr_t *)addr,
845b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie                   (bthf_wbs_config_t)codec_config)) != BT_STATUS_SUCCESS){
846b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie        ALOGE("Failed HF WBS codec config, status: %d", status);
847b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    }
848b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    env->ReleaseByteArrayElements(address, addr, 0);
849b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
850b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie}
851b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie
852b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie
8536c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiestatic JNINativeMethod sMethods[] = {
8546c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    {"classInitNative", "()V", (void *) classInitNative},
85569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    {"initializeNative", "(I)V", (void *) initializeNative},
8566654f5c903de510a70f9e72cd5ad7837b615d93ffredc    {"cleanupNative", "()V", (void *) cleanupNative},
8576c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    {"connectHfpNative", "([B)Z", (void *) connectHfpNative},
8586c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    {"disconnectHfpNative", "([B)Z", (void *) disconnectHfpNative},
8596c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    {"connectAudioNative", "([B)Z", (void *) connectAudioNative},
8606c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    {"disconnectAudioNative", "([B)Z", (void *) disconnectAudioNative},
86169d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    {"startVoiceRecognitionNative", "([B)Z", (void *) startVoiceRecognitionNative},
86269d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    {"stopVoiceRecognitionNative", "([B)Z", (void *) stopVoiceRecognitionNative},
86369d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    {"setVolumeNative", "(II[B)Z", (void *) setVolumeNative},
8646c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    {"notifyDeviceStatusNative", "(IIII)Z", (void *) notifyDeviceStatusNative},
86569d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    {"copsResponseNative", "(Ljava/lang/String;[B)Z", (void *) copsResponseNative},
86669d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    {"cindResponseNative", "(IIIIIII[B)Z", (void *) cindResponseNative},
8672ab50a41dac634a78cef60a419c3bcc848c1aa78Mudumba Ananth    {"bindResponseNative", "(IZ[B)Z", (void *)bindResponseNative},
86869d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    {"atResponseStringNative", "(Ljava/lang/String;[B)Z", (void *) atResponseStringNative},
86969d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    {"atResponseCodeNative", "(II[B)Z", (void *)atResponseCodeNative},
87069d4ca45a25e86823fbdb754ca6a3995f8131d59Nitin Srivastava    {"clccResponseNative", "(IIIIZLjava/lang/String;I[B)Z", (void *) clccResponseNative},
8716c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    {"phoneStateChangeNative", "(IIILjava/lang/String;I)Z", (void *) phoneStateChangeNative},
872b6132733b6e386cc8c93b5598c72ed8efe04bf3eMatthew Xie    {"configureWBSNative", "([BI)Z", (void *) configureWBSNative},
8736c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie};
8746c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
8756c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xieint register_com_android_bluetooth_hfp(JNIEnv* env)
8766c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie{
8776c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    return jniRegisterNativeMethods(env, "com/android/bluetooth/hfp/HeadsetStateMachine",
8786c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                                    sMethods, NELEM(sMethods));
8796c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
8806c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
8816c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie} /* namespace android */
882