/*
 * Copyright (C) 2013 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 "BtGatt.JNI"

#define LOG_NDEBUG 0

#define CHECK_CALLBACK_ENV                                                      \
   if (!checkCallbackThread()) {                                                \
       error("Callback: '%s' is not called on the correct thread", __FUNCTION__);\
       return;                                                                  \
   }

#include "com_android_bluetooth.h"
#include "hardware/bt_gatt.h"
#include "utils/Log.h"
#include "android_runtime/AndroidRuntime.h"

#include <string.h>

#include <cutils/log.h>
#define info(fmt, ...)  ALOGI ("%s(L%d): " fmt,__FUNCTION__, __LINE__,  ## __VA_ARGS__)
#define debug(fmt, ...) ALOGD ("%s(L%d): " fmt,__FUNCTION__, __LINE__,  ## __VA_ARGS__)
#define warn(fmt, ...) ALOGW ("WARNING: %s(L%d): " fmt "##",__FUNCTION__, __LINE__, ## __VA_ARGS__)
#define error(fmt, ...) ALOGE ("ERROR: %s(L%d): " fmt "##",__FUNCTION__, __LINE__, ## __VA_ARGS__)
#define asrt(s) if(!(s)) ALOGE ("%s(L%d): ASSERT %s failed! ##",__FUNCTION__, __LINE__, #s)

#define BD_ADDR_LEN 6

#define UUID_PARAMS(uuid_ptr) \
    uuid_lsb(uuid_ptr),  uuid_msb(uuid_ptr)

#define GATT_ID_PARAMS(attr_ptr) \
    attr_ptr->inst_id, \
    UUID_PARAMS((&attr_ptr->uuid))

#define SRVC_ID_PARAMS(srvc_ptr) \
    (srvc_ptr->is_primary ? \
    BTGATT_SERVICE_TYPE_PRIMARY : BTGATT_SERVICE_TYPE_SECONDARY), \
    GATT_ID_PARAMS((&srvc_ptr->id))


static void set_uuid(uint8_t* uuid, jlong uuid_msb, jlong uuid_lsb)
{
    for (int i = 0; i != 8; ++i)
    {
        uuid[i]     = (uuid_lsb >> (8 * i)) & 0xFF;
        uuid[i + 8] = (uuid_msb >> (8 * i)) & 0xFF;
    }
}

static uint64_t uuid_lsb(bt_uuid_t* uuid)
{
    uint64_t  lsb = 0;
    int i;

    for (i = 7; i >= 0; i--)
    {
        lsb <<= 8;
        lsb |= uuid->uu[i];
    }

    return lsb;
}

static uint64_t uuid_msb(bt_uuid_t* uuid)
{
    uint64_t msb = 0;
    int i;

    for (i = 15; i >= 8; i--)
    {
        msb <<= 8;
        msb |= uuid->uu[i];
    }

    return msb;
}

static void bd_addr_str_to_addr(const char* str, uint8_t *bd_addr)
{
    int    i;
    char   c;

    c = *str++;
    for (i = 0; i < BD_ADDR_LEN; i++)
    {
        if (c >= '0' && c <= '9')
            bd_addr[i] = c - '0';
        else if (c >= 'a' && c <= 'z')
            bd_addr[i] = c - 'a' + 10;
        else   // (c >= 'A' && c <= 'Z')
            bd_addr[i] = c - 'A' + 10;

        c = *str++;
        if (c != ':')
        {
            bd_addr[i] <<= 4;
            if (c >= '0' && c <= '9')
                bd_addr[i] |= c - '0';
            else if (c >= 'a' && c <= 'z')
                bd_addr[i] |= c - 'a' + 10;
            else   // (c >= 'A' && c <= 'Z')
                bd_addr[i] |= c - 'A' + 10;

            c = *str++;
        }

        c = *str++;
    }
}

static void jstr2bdaddr(JNIEnv* env, bt_bdaddr_t *bda, jstring address)
{
    const char* c_bda = env->GetStringUTFChars(address, NULL);
    if (c_bda != NULL && bda != NULL && strlen(c_bda) == 17)
    {
        bd_addr_str_to_addr(c_bda, bda->address);
        env->ReleaseStringUTFChars(address, c_bda);
    }
}

namespace android {

/**
 * Client callback methods
 */

static jmethodID method_onClientRegistered;
static jmethodID method_onScanResult;
static jmethodID method_onConnected;
static jmethodID method_onDisconnected;
static jmethodID method_onReadCharacteristic;
static jmethodID method_onWriteCharacteristic;
static jmethodID method_onExecuteCompleted;
static jmethodID method_onSearchCompleted;
static jmethodID method_onSearchResult;
static jmethodID method_onReadDescriptor;
static jmethodID method_onWriteDescriptor;
static jmethodID method_onNotify;
static jmethodID method_onGetCharacteristic;
static jmethodID method_onGetDescriptor;
static jmethodID method_onGetIncludedService;
static jmethodID method_onRegisterForNotifications;
static jmethodID method_onReadRemoteRssi;
static jmethodID method_onAdvertiseCallback;
static jmethodID method_onConfigureMTU;
static jmethodID method_onScanFilterConfig;
static jmethodID method_onScanFilterParamsConfigured;
static jmethodID method_onScanFilterEnableDisabled;
static jmethodID method_onMultiAdvEnable;
static jmethodID method_onMultiAdvUpdate;
static jmethodID method_onMultiAdvSetAdvData;
static jmethodID method_onMultiAdvDisable;
static jmethodID method_onClientCongestion;
static jmethodID method_onBatchScanStorageConfigured;
static jmethodID method_onBatchScanStartStopped;
static jmethodID method_onBatchScanReports;
static jmethodID method_onBatchScanThresholdCrossed;
static jmethodID method_onTrackAdvFoundLost;

/**
 * Server callback methods
 */
static jmethodID method_onServerRegistered;
static jmethodID method_onClientConnected;
static jmethodID method_onServiceAdded;
static jmethodID method_onIncludedServiceAdded;
static jmethodID method_onCharacteristicAdded;
static jmethodID method_onDescriptorAdded;
static jmethodID method_onServiceStarted;
static jmethodID method_onServiceStopped;
static jmethodID method_onServiceDeleted;
static jmethodID method_onResponseSendCompleted;
static jmethodID method_onAttributeRead;
static jmethodID method_onAttributeWrite;
static jmethodID method_onExecuteWrite;
static jmethodID method_onNotificationSent;
static jmethodID method_onServerCongestion;
static jmethodID method_onServerMtuChanged;

/**
 * Static variables
 */

static const btgatt_interface_t *sGattIf = NULL;
static jobject mCallbacksObj = NULL;
static JNIEnv *sCallbackEnv = NULL;

static bool checkCallbackThread() {
    sCallbackEnv = getCallbackEnv();

    JNIEnv* env = AndroidRuntime::getJNIEnv();
    if (sCallbackEnv != env || sCallbackEnv == NULL) return false;
    return true;
}

/**
 * BTA client callbacks
 */

void btgattc_register_app_cb(int status, int clientIf, bt_uuid_t *app_uuid)
{
    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientRegistered, status,
        clientIf, UUID_PARAMS(app_uuid));
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgattc_scan_result_cb(bt_bdaddr_t* bda, int rssi, uint8_t* adv_data)
{
    CHECK_CALLBACK_ENV

    char c_address[32];
    snprintf(c_address, sizeof(c_address),"%02X:%02X:%02X:%02X:%02X:%02X",
        bda->address[0], bda->address[1], bda->address[2],
        bda->address[3], bda->address[4], bda->address[5]);

    jstring address = sCallbackEnv->NewStringUTF(c_address);
    jbyteArray jb = sCallbackEnv->NewByteArray(62);
    sCallbackEnv->SetByteArrayRegion(jb, 0, 62, (jbyte *) adv_data);

    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScanResult
        , address, rssi, jb);

    sCallbackEnv->DeleteLocalRef(address);
    sCallbackEnv->DeleteLocalRef(jb);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgattc_open_cb(int conn_id, int status, int clientIf, bt_bdaddr_t* bda)
{
    CHECK_CALLBACK_ENV

    char c_address[32];
    snprintf(c_address, sizeof(c_address),"%02X:%02X:%02X:%02X:%02X:%02X",
        bda->address[0], bda->address[1], bda->address[2],
        bda->address[3], bda->address[4], bda->address[5]);

    jstring address = sCallbackEnv->NewStringUTF(c_address);
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnected,
        clientIf, conn_id, status, address);
    sCallbackEnv->DeleteLocalRef(address);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgattc_close_cb(int conn_id, int status, int clientIf, bt_bdaddr_t* bda)
{
    CHECK_CALLBACK_ENV
    char c_address[32];
    snprintf(c_address, sizeof(c_address),"%02X:%02X:%02X:%02X:%02X:%02X",
        bda->address[0], bda->address[1], bda->address[2],
        bda->address[3], bda->address[4], bda->address[5]);

    jstring address = sCallbackEnv->NewStringUTF(c_address);
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onDisconnected,
        clientIf, conn_id, status, address);
    sCallbackEnv->DeleteLocalRef(address);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgattc_search_complete_cb(int conn_id, int status)
{
    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onSearchCompleted,
                                 conn_id, status);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgattc_search_result_cb(int conn_id, btgatt_srvc_id_t *srvc_id)
{
    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onSearchResult, conn_id,
        SRVC_ID_PARAMS(srvc_id));
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgattc_get_characteristic_cb(int conn_id, int status,
                btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
                int char_prop)
{
    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onGetCharacteristic
        , conn_id, status, SRVC_ID_PARAMS(srvc_id), GATT_ID_PARAMS(char_id)
        , char_prop);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgattc_get_descriptor_cb(int conn_id, int status,
                btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
                btgatt_gatt_id_t *descr_id)
{
    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onGetDescriptor
        , conn_id, status, SRVC_ID_PARAMS(srvc_id), GATT_ID_PARAMS(char_id)
        , GATT_ID_PARAMS(descr_id));
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgattc_get_included_service_cb(int conn_id, int status,
                btgatt_srvc_id_t *srvc_id, btgatt_srvc_id_t *incl_srvc_id)
{
    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onGetIncludedService
        , conn_id, status, SRVC_ID_PARAMS(srvc_id), SRVC_ID_PARAMS(incl_srvc_id));
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgattc_register_for_notification_cb(int conn_id, int registered, int status,
                                          btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id)
{
    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onRegisterForNotifications
        , conn_id, status, registered, SRVC_ID_PARAMS(srvc_id), GATT_ID_PARAMS(char_id));
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgattc_notify_cb(int conn_id, btgatt_notify_params_t *p_data)
{
    CHECK_CALLBACK_ENV

    char c_address[32];
    snprintf(c_address, sizeof(c_address), "%02X:%02X:%02X:%02X:%02X:%02X",
        p_data->bda.address[0], p_data->bda.address[1], p_data->bda.address[2],
        p_data->bda.address[3], p_data->bda.address[4], p_data->bda.address[5]);

    jstring address = sCallbackEnv->NewStringUTF(c_address);
    jbyteArray jb = sCallbackEnv->NewByteArray(p_data->len);
    sCallbackEnv->SetByteArrayRegion(jb, 0, p_data->len, (jbyte *) p_data->value);

    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNotify
        , conn_id, address, SRVC_ID_PARAMS((&p_data->srvc_id))
        , GATT_ID_PARAMS((&p_data->char_id)), p_data->is_notify, jb);

    sCallbackEnv->DeleteLocalRef(address);
    sCallbackEnv->DeleteLocalRef(jb);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgattc_read_characteristic_cb(int conn_id, int status, btgatt_read_params_t *p_data)
{
    CHECK_CALLBACK_ENV

    jbyteArray jb;
    if ( status == 0 )      //successful
    {
        jb = sCallbackEnv->NewByteArray(p_data->value.len);
        sCallbackEnv->SetByteArrayRegion(jb, 0, p_data->value.len,
            (jbyte *) p_data->value.value);
    } else {
        uint8_t value = 0;
        jb = sCallbackEnv->NewByteArray(1);
        sCallbackEnv->SetByteArrayRegion(jb, 0, 1, (jbyte *) &value);
    }

    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onReadCharacteristic
        , conn_id, status, SRVC_ID_PARAMS((&p_data->srvc_id))
        , GATT_ID_PARAMS((&p_data->char_id)), p_data->value_type, jb);
    sCallbackEnv->DeleteLocalRef(jb);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgattc_write_characteristic_cb(int conn_id, int status, btgatt_write_params_t *p_data)
{
    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onWriteCharacteristic
        , conn_id, status, SRVC_ID_PARAMS((&p_data->srvc_id))
        , GATT_ID_PARAMS((&p_data->char_id)));
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgattc_execute_write_cb(int conn_id, int status)
{
    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onExecuteCompleted
        , conn_id, status);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgattc_read_descriptor_cb(int conn_id, int status, btgatt_read_params_t *p_data)
{
    CHECK_CALLBACK_ENV

    jbyteArray jb;
    if ( p_data->value.len != 0 )
    {
        jb = sCallbackEnv->NewByteArray(p_data->value.len);
        sCallbackEnv->SetByteArrayRegion(jb, 0, p_data->value.len,
                                (jbyte *) p_data->value.value);
    } else {
        jb = sCallbackEnv->NewByteArray(1);
    }

    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onReadDescriptor
        , conn_id, status, SRVC_ID_PARAMS((&p_data->srvc_id))
        , GATT_ID_PARAMS((&p_data->char_id)), GATT_ID_PARAMS((&p_data->descr_id))
        , p_data->value_type, jb);

    sCallbackEnv->DeleteLocalRef(jb);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgattc_write_descriptor_cb(int conn_id, int status, btgatt_write_params_t *p_data)
{
    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onWriteDescriptor
        , conn_id, status, SRVC_ID_PARAMS((&p_data->srvc_id))
        , GATT_ID_PARAMS((&p_data->char_id))
        , GATT_ID_PARAMS((&p_data->descr_id)));
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgattc_remote_rssi_cb(int client_if,bt_bdaddr_t* bda, int rssi, int status)
{
    CHECK_CALLBACK_ENV

    char c_address[32];
    snprintf(c_address, sizeof(c_address),"%02X:%02X:%02X:%02X:%02X:%02X",
        bda->address[0], bda->address[1], bda->address[2],
        bda->address[3], bda->address[4], bda->address[5]);
    jstring address = sCallbackEnv->NewStringUTF(c_address);
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onReadRemoteRssi,
       client_if, address, rssi, status);
    sCallbackEnv->DeleteLocalRef(address);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgattc_advertise_cb(int status, int client_if)
{
    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAdvertiseCallback, status, client_if);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgattc_configure_mtu_cb(int conn_id, int status, int mtu)
{
    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConfigureMTU,
                                 conn_id, status, mtu);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgattc_scan_filter_cfg_cb(int action, int client_if, int status, int filt_type,
                                int avbl_space)
{
    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScanFilterConfig,
                                 action, status, client_if, filt_type, avbl_space);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgattc_scan_filter_param_cb(int action, int client_if, int status, int avbl_space)
{
    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScanFilterParamsConfigured,
            action, status, client_if, avbl_space);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgattc_scan_filter_status_cb(int action, int client_if, int status)
{
    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScanFilterEnableDisabled,
            action, status, client_if);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgattc_multiadv_enable_cb(int client_if, int status)
{
    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onMultiAdvEnable, status,client_if);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgattc_multiadv_update_cb(int client_if, int status)
{
    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onMultiAdvUpdate, status, client_if);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgattc_multiadv_setadv_data_cb(int client_if, int status)
{
    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onMultiAdvSetAdvData, status, client_if);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgattc_multiadv_disable_cb(int client_if, int status)
{
    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onMultiAdvDisable, status, client_if);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgattc_congestion_cb(int conn_id, bool congested)
{
    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientCongestion, conn_id, congested);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgattc_batchscan_cfg_storage_cb(int client_if, int status)
{
    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onBatchScanStorageConfigured, status, client_if);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgattc_batchscan_startstop_cb(int startstop_action, int client_if, int status)
{
    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onBatchScanStartStopped, startstop_action,
                                 status, client_if);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgattc_batchscan_reports_cb(int client_if, int status, int report_format,
                        int num_records, int data_len, uint8_t *p_rep_data)
{
    CHECK_CALLBACK_ENV
    jbyteArray jb = sCallbackEnv->NewByteArray(data_len);
    sCallbackEnv->SetByteArrayRegion(jb, 0, data_len, (jbyte *) p_rep_data);

    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onBatchScanReports, status, client_if,
                                report_format, num_records, jb);
    sCallbackEnv->DeleteLocalRef(jb);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgattc_batchscan_threshold_cb(int client_if)
{
    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onBatchScanThresholdCrossed, client_if);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgattc_track_adv_event_cb(int client_if, int filt_index, int addr_type,
                                        bt_bdaddr_t* bda, int adv_state)
{
    CHECK_CALLBACK_ENV
    char c_address[32];
    snprintf(c_address, sizeof(c_address),"%02X:%02X:%02X:%02X:%02X:%02X",
        bda->address[0], bda->address[1], bda->address[2],
        bda->address[3], bda->address[4], bda->address[5]);
    jstring address = sCallbackEnv->NewStringUTF(c_address);
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onTrackAdvFoundLost,
                                    filt_index, addr_type, address, adv_state, client_if);
    sCallbackEnv->DeleteLocalRef(address);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

static const btgatt_client_callbacks_t sGattClientCallbacks = {
    btgattc_register_app_cb,
    btgattc_scan_result_cb,
    btgattc_open_cb,
    btgattc_close_cb,
    btgattc_search_complete_cb,
    btgattc_search_result_cb,
    btgattc_get_characteristic_cb,
    btgattc_get_descriptor_cb,
    btgattc_get_included_service_cb,
    btgattc_register_for_notification_cb,
    btgattc_notify_cb,
    btgattc_read_characteristic_cb,
    btgattc_write_characteristic_cb,
    btgattc_read_descriptor_cb,
    btgattc_write_descriptor_cb,
    btgattc_execute_write_cb,
    btgattc_remote_rssi_cb,
    btgattc_advertise_cb,
    btgattc_configure_mtu_cb,
    btgattc_scan_filter_cfg_cb,
    btgattc_scan_filter_param_cb,
    btgattc_scan_filter_status_cb,
    btgattc_multiadv_enable_cb,
    btgattc_multiadv_update_cb,
    btgattc_multiadv_setadv_data_cb,
    btgattc_multiadv_disable_cb,
    btgattc_congestion_cb,
    btgattc_batchscan_cfg_storage_cb,
    btgattc_batchscan_startstop_cb,
    btgattc_batchscan_reports_cb,
    btgattc_batchscan_threshold_cb,
    btgattc_track_adv_event_cb
};


/**
 * BTA server callbacks
 */

void btgatts_register_app_cb(int status, int server_if, bt_uuid_t *uuid)
{
    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerRegistered
        , status, server_if, UUID_PARAMS(uuid));
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgatts_connection_cb(int conn_id, int server_if, int connected, bt_bdaddr_t *bda)
{
    CHECK_CALLBACK_ENV

    char c_address[32];
    sprintf(c_address, "%02X:%02X:%02X:%02X:%02X:%02X",
            bda->address[0], bda->address[1], bda->address[2],
            bda->address[3], bda->address[4], bda->address[5]);

    jstring address = sCallbackEnv->NewStringUTF(c_address);
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientConnected,
                                 address, connected, conn_id, server_if);
    sCallbackEnv->DeleteLocalRef(address);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgatts_service_added_cb(int status, int server_if,
                              btgatt_srvc_id_t *srvc_id, int srvc_handle)
{
    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceAdded, status,
                                 server_if, SRVC_ID_PARAMS(srvc_id),
                                 srvc_handle);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgatts_included_service_added_cb(int status, int server_if,
                                   int srvc_handle,
                                   int incl_srvc_handle)
{
    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onIncludedServiceAdded,
                                 status, server_if, srvc_handle, incl_srvc_handle);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgatts_characteristic_added_cb(int status, int server_if, bt_uuid_t *char_id,
                                     int srvc_handle, int char_handle)
{
    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onCharacteristicAdded,
                                 status, server_if, UUID_PARAMS(char_id),
                                 srvc_handle, char_handle);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgatts_descriptor_added_cb(int status, int server_if,
                                 bt_uuid_t *descr_id, int srvc_handle,
                                 int descr_handle)
{
    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onDescriptorAdded,
                                 status, server_if, UUID_PARAMS(descr_id),
                                 srvc_handle, descr_handle);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgatts_service_started_cb(int status, int server_if, int srvc_handle)
{
    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceStarted, status,
                                 server_if, srvc_handle);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgatts_service_stopped_cb(int status, int server_if, int srvc_handle)
{
    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceStopped, status,
                                 server_if, srvc_handle);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgatts_service_deleted_cb(int status, int server_if, int srvc_handle)
{
    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceDeleted, status,
                                 server_if, srvc_handle);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgatts_request_read_cb(int conn_id, int trans_id, bt_bdaddr_t *bda,
                             int attr_handle, int offset, bool is_long)
{
    CHECK_CALLBACK_ENV

    char c_address[32];
    sprintf(c_address, "%02X:%02X:%02X:%02X:%02X:%02X",
            bda->address[0], bda->address[1], bda->address[2],
            bda->address[3], bda->address[4], bda->address[5]);

    jstring address = sCallbackEnv->NewStringUTF(c_address);
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAttributeRead,
                                 address, conn_id, trans_id, attr_handle,
                                 offset, is_long);
    sCallbackEnv->DeleteLocalRef(address);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgatts_request_write_cb(int conn_id, int trans_id,
                              bt_bdaddr_t *bda, int attr_handle,
                              int offset, int length,
                              bool need_rsp, bool is_prep, uint8_t* value)
{
    CHECK_CALLBACK_ENV

    char c_address[32];
    sprintf(c_address, "%02X:%02X:%02X:%02X:%02X:%02X",
            bda->address[0], bda->address[1], bda->address[2],
            bda->address[3], bda->address[4], bda->address[5]);

    jstring address = sCallbackEnv->NewStringUTF(c_address);

    jbyteArray val = sCallbackEnv->NewByteArray(length);
    if (val) sCallbackEnv->SetByteArrayRegion(val, 0, length, (jbyte*)value);
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAttributeWrite,
                                 address, conn_id, trans_id, attr_handle,
                                 offset, length, need_rsp, is_prep, val);
    sCallbackEnv->DeleteLocalRef(address);
    sCallbackEnv->DeleteLocalRef(val);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgatts_request_exec_write_cb(int conn_id, int trans_id,
                                   bt_bdaddr_t *bda, int exec_write)
{
    CHECK_CALLBACK_ENV

    char c_address[32];
    sprintf(c_address, "%02X:%02X:%02X:%02X:%02X:%02X",
            bda->address[0], bda->address[1], bda->address[2],
            bda->address[3], bda->address[4], bda->address[5]);

    jstring address = sCallbackEnv->NewStringUTF(c_address);
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onExecuteWrite,
                                 address, conn_id, trans_id, exec_write);
    sCallbackEnv->DeleteLocalRef(address);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgatts_response_confirmation_cb(int status, int handle)
{
    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onResponseSendCompleted,
                                 status, handle);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgatts_indication_sent_cb(int conn_id, int status)
{
    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNotificationSent,
                                 conn_id, status);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgatts_congestion_cb(int conn_id, bool congested)
{
    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerCongestion, conn_id, congested);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

void btgatts_mtu_changed_cb(int conn_id, int mtu)
{
    CHECK_CALLBACK_ENV
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerMtuChanged, conn_id, mtu);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

static const btgatt_server_callbacks_t sGattServerCallbacks = {
    btgatts_register_app_cb,
    btgatts_connection_cb,
    btgatts_service_added_cb,
    btgatts_included_service_added_cb,
    btgatts_characteristic_added_cb,
    btgatts_descriptor_added_cb,
    btgatts_service_started_cb,
    btgatts_service_stopped_cb,
    btgatts_service_deleted_cb,
    btgatts_request_read_cb,
    btgatts_request_write_cb,
    btgatts_request_exec_write_cb,
    btgatts_response_confirmation_cb,
    btgatts_indication_sent_cb,
    btgatts_congestion_cb,
    btgatts_mtu_changed_cb
};

/**
 * GATT callbacks
 */

static const btgatt_callbacks_t sGattCallbacks = {
    sizeof(btgatt_callbacks_t),
    &sGattClientCallbacks,
    &sGattServerCallbacks
};

/**
 * Native function definitions
 */
static void classInitNative(JNIEnv* env, jclass clazz) {

    // Client callbacks

    method_onClientRegistered = env->GetMethodID(clazz, "onClientRegistered", "(IIJJ)V");
    method_onScanResult = env->GetMethodID(clazz, "onScanResult", "(Ljava/lang/String;I[B)V");
    method_onConnected   = env->GetMethodID(clazz, "onConnected", "(IIILjava/lang/String;)V");
    method_onDisconnected = env->GetMethodID(clazz, "onDisconnected", "(IIILjava/lang/String;)V");
    method_onReadCharacteristic = env->GetMethodID(clazz, "onReadCharacteristic", "(IIIIJJIJJI[B)V");
    method_onWriteCharacteristic = env->GetMethodID(clazz, "onWriteCharacteristic", "(IIIIJJIJJ)V");
    method_onExecuteCompleted = env->GetMethodID(clazz, "onExecuteCompleted",  "(II)V");
    method_onSearchCompleted = env->GetMethodID(clazz, "onSearchCompleted",  "(II)V");
    method_onSearchResult = env->GetMethodID(clazz, "onSearchResult", "(IIIJJ)V");
    method_onReadDescriptor = env->GetMethodID(clazz, "onReadDescriptor", "(IIIIJJIJJIJJI[B)V");
    method_onWriteDescriptor = env->GetMethodID(clazz, "onWriteDescriptor", "(IIIIJJIJJIJJ)V");
    method_onNotify = env->GetMethodID(clazz, "onNotify", "(ILjava/lang/String;IIJJIJJZ[B)V");
    method_onGetCharacteristic = env->GetMethodID(clazz, "onGetCharacteristic", "(IIIIJJIJJI)V");
    method_onGetDescriptor = env->GetMethodID(clazz, "onGetDescriptor", "(IIIIJJIJJIJJ)V");
    method_onGetIncludedService = env->GetMethodID(clazz, "onGetIncludedService", "(IIIIJJIIJJ)V");
    method_onRegisterForNotifications = env->GetMethodID(clazz, "onRegisterForNotifications", "(IIIIIJJIJJ)V");
    method_onReadRemoteRssi = env->GetMethodID(clazz, "onReadRemoteRssi", "(ILjava/lang/String;II)V");
    method_onConfigureMTU = env->GetMethodID(clazz, "onConfigureMTU", "(III)V");
    method_onAdvertiseCallback = env->GetMethodID(clazz, "onAdvertiseCallback", "(II)V");
    method_onScanFilterConfig = env->GetMethodID(clazz, "onScanFilterConfig", "(IIIII)V");
    method_onScanFilterParamsConfigured = env->GetMethodID(clazz, "onScanFilterParamsConfigured", "(IIII)V");
    method_onScanFilterEnableDisabled = env->GetMethodID(clazz, "onScanFilterEnableDisabled", "(III)V");
    method_onMultiAdvEnable = env->GetMethodID(clazz, "onAdvertiseInstanceEnabled", "(II)V");
    method_onMultiAdvUpdate = env->GetMethodID(clazz, "onAdvertiseDataUpdated", "(II)V");
    method_onMultiAdvSetAdvData = env->GetMethodID(clazz, "onAdvertiseDataSet", "(II)V");
    method_onMultiAdvDisable = env->GetMethodID(clazz, "onAdvertiseInstanceDisabled", "(II)V");
    method_onClientCongestion = env->GetMethodID(clazz, "onClientCongestion", "(IZ)V");
    method_onBatchScanStorageConfigured = env->GetMethodID(clazz, "onBatchScanStorageConfigured", "(II)V");
    method_onBatchScanStartStopped = env->GetMethodID(clazz, "onBatchScanStartStopped", "(III)V");
    method_onBatchScanReports = env->GetMethodID(clazz, "onBatchScanReports", "(IIII[B)V");
    method_onBatchScanThresholdCrossed = env->GetMethodID(clazz, "onBatchScanThresholdCrossed", "(I)V");
    method_onTrackAdvFoundLost = env->GetMethodID(clazz, "onTrackAdvFoundLost", "(IILjava/lang/String;II)V");

     // Server callbacks

    method_onServerRegistered = env->GetMethodID(clazz, "onServerRegistered", "(IIJJ)V");
    method_onClientConnected = env->GetMethodID(clazz, "onClientConnected", "(Ljava/lang/String;ZII)V");
    method_onServiceAdded = env->GetMethodID(clazz, "onServiceAdded", "(IIIIJJI)V");
    method_onIncludedServiceAdded = env->GetMethodID(clazz, "onIncludedServiceAdded", "(IIII)V");
    method_onCharacteristicAdded  = env->GetMethodID(clazz, "onCharacteristicAdded", "(IIJJII)V");
    method_onDescriptorAdded = env->GetMethodID(clazz, "onDescriptorAdded", "(IIJJII)V");
    method_onServiceStarted = env->GetMethodID(clazz, "onServiceStarted", "(III)V");
    method_onServiceStopped = env->GetMethodID(clazz, "onServiceStopped", "(III)V");
    method_onServiceDeleted = env->GetMethodID(clazz, "onServiceDeleted", "(III)V");
    method_onResponseSendCompleted = env->GetMethodID(clazz, "onResponseSendCompleted", "(II)V");
    method_onAttributeRead= env->GetMethodID(clazz, "onAttributeRead", "(Ljava/lang/String;IIIIZ)V");
    method_onAttributeWrite= env->GetMethodID(clazz, "onAttributeWrite", "(Ljava/lang/String;IIIIIZZ[B)V");
    method_onExecuteWrite= env->GetMethodID(clazz, "onExecuteWrite", "(Ljava/lang/String;III)V");
    method_onNotificationSent = env->GetMethodID(clazz, "onNotificationSent", "(II)V");
    method_onServerCongestion = env->GetMethodID(clazz, "onServerCongestion", "(IZ)V");
    method_onServerMtuChanged = env->GetMethodID(clazz, "onMtuChanged", "(II)V");

    info("classInitNative: Success!");
}

static const bt_interface_t* btIf;

static void initializeNative(JNIEnv *env, jobject object) {
    if(btIf)
        return;

    if ( (btIf = getBluetoothInterface()) == NULL) {
        error("Bluetooth module is not loaded");
        return;
    }

    if (sGattIf != NULL) {
         ALOGW("Cleaning up Bluetooth GATT Interface before initializing...");
         sGattIf->cleanup();
         sGattIf = NULL;
    }

    if (mCallbacksObj != NULL) {
         ALOGW("Cleaning up Bluetooth GATT callback object");
         env->DeleteGlobalRef(mCallbacksObj);
         mCallbacksObj = NULL;
    }

    if ( (sGattIf = (btgatt_interface_t *)
          btIf->get_profile_interface(BT_PROFILE_GATT_ID)) == NULL) {
        error("Failed to get Bluetooth GATT Interface");
        return;
    }

    bt_status_t status;
    if ( (status = sGattIf->init(&sGattCallbacks)) != BT_STATUS_SUCCESS) {
        error("Failed to initialize Bluetooth GATT, status: %d", status);
        sGattIf = NULL;
        return;
    }

    mCallbacksObj = env->NewGlobalRef(object);
}

static void cleanupNative(JNIEnv *env, jobject object) {
    bt_status_t status;
    if (!btIf) return;

    if (sGattIf != NULL) {
        sGattIf->cleanup();
        sGattIf = NULL;
    }

    if (mCallbacksObj != NULL) {
        env->DeleteGlobalRef(mCallbacksObj);
        mCallbacksObj = NULL;
    }
    btIf = NULL;
}

/**
 * Native Client functions
 */

static int gattClientGetDeviceTypeNative(JNIEnv* env, jobject object, jstring address)
{
    if (!sGattIf) return 0;
    bt_bdaddr_t bda;
    jstr2bdaddr(env, &bda, address);
    return sGattIf->client->get_device_type(&bda);
}

static void gattClientRegisterAppNative(JNIEnv* env, jobject object,
                                        jlong app_uuid_lsb, jlong app_uuid_msb )
{
    bt_uuid_t uuid;

    if (!sGattIf) return;
    set_uuid(uuid.uu, app_uuid_msb, app_uuid_lsb);
    sGattIf->client->register_client(&uuid);
}

static void gattClientUnregisterAppNative(JNIEnv* env, jobject object, jint clientIf)
{
    if (!sGattIf) return;
    sGattIf->client->unregister_client(clientIf);
}

static void gattClientScanNative(JNIEnv* env, jobject object, jboolean start)
{
    if (!sGattIf) return;
    sGattIf->client->scan(start);
}

static void gattClientConnectNative(JNIEnv* env, jobject object, jint clientif,
                                 jstring address, jboolean isDirect, jint transport)
{
    if (!sGattIf) return;

    bt_bdaddr_t bda;
    jstr2bdaddr(env, &bda, address);
    sGattIf->client->connect(clientif, &bda, isDirect, transport);
}

static void gattClientDisconnectNative(JNIEnv* env, jobject object, jint clientIf,
                                  jstring address, jint conn_id)
{
    if (!sGattIf) return;
    bt_bdaddr_t bda;
    jstr2bdaddr(env, &bda, address);
    sGattIf->client->disconnect(clientIf, &bda, conn_id);
}

static void gattClientRefreshNative(JNIEnv* env, jobject object, jint clientIf,
                                    jstring address)
{
    if (!sGattIf) return;

    bt_bdaddr_t bda;
    jstr2bdaddr(env, &bda, address);
    sGattIf->client->refresh(clientIf, &bda);
}

static void gattClientSearchServiceNative(JNIEnv* env, jobject object, jint conn_id,
            jboolean search_all, jlong service_uuid_lsb, jlong service_uuid_msb)
{
    if (!sGattIf) return;

    bt_uuid_t uuid;
    set_uuid(uuid.uu, service_uuid_msb, service_uuid_lsb);
    sGattIf->client->search_service(conn_id, search_all ? 0 : &uuid);
}

static void gattClientGetCharacteristicNative(JNIEnv* env, jobject object,
    jint conn_id,
    jint  service_type, jint  service_id_inst_id,
    jlong service_id_uuid_lsb, jlong service_id_uuid_msb,
    jint  char_id_inst_id,
    jlong char_id_uuid_lsb, jlong char_id_uuid_msb)
{
    if (!sGattIf) return;

    btgatt_srvc_id_t srvc_id;
    srvc_id.id.inst_id = (uint8_t) service_id_inst_id;
    srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);

    set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);

    btgatt_gatt_id_t char_id;
    char_id.inst_id = (uint8_t) char_id_inst_id;
    set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb);

    if (char_id_uuid_lsb == 0)
    {
        sGattIf->client->get_characteristic(conn_id, &srvc_id, 0);
    } else {
        sGattIf->client->get_characteristic(conn_id, &srvc_id, &char_id);
    }
}

static void gattClientGetDescriptorNative(JNIEnv* env, jobject object,
    jint conn_id,
    jint  service_type, jint  service_id_inst_id,
    jlong service_id_uuid_lsb, jlong service_id_uuid_msb,
    jint  char_id_inst_id,
    jlong char_id_uuid_lsb, jlong char_id_uuid_msb,
    jint descr_id_inst_id,
    jlong descr_id_uuid_lsb, jlong descr_id_uuid_msb)
{
    if (!sGattIf) return;

    btgatt_srvc_id_t srvc_id;
    srvc_id.id.inst_id = (uint8_t) service_id_inst_id;
    srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
    set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);

    btgatt_gatt_id_t char_id;
    char_id.inst_id = (uint8_t) char_id_inst_id;
    set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb);

    btgatt_gatt_id_t descr_id;
    descr_id.inst_id = (uint8_t) descr_id_inst_id;
    set_uuid(descr_id.uuid.uu, descr_id_uuid_msb, descr_id_uuid_lsb);

    if (descr_id_uuid_lsb == 0)
    {
        sGattIf->client->get_descriptor(conn_id, &srvc_id, &char_id, 0);
    } else {
        sGattIf->client->get_descriptor(conn_id, &srvc_id, &char_id, &descr_id);
    }
}

static void gattClientGetIncludedServiceNative(JNIEnv* env, jobject object,
    jint conn_id, jint service_type, jint service_id_inst_id,
    jlong service_id_uuid_lsb, jlong service_id_uuid_msb,
    jint incl_service_id_inst_id, jint incl_service_type,
    jlong incl_service_id_uuid_lsb, jlong incl_service_id_uuid_msb)
{
    if (!sGattIf) return;

    btgatt_srvc_id_t srvc_id;
    srvc_id.id.inst_id = (uint8_t) service_id_inst_id;
    srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
    set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);

    btgatt_srvc_id_t  incl_srvc_id;
    incl_srvc_id.id.inst_id = (uint8_t) incl_service_id_inst_id;
    incl_srvc_id.is_primary = (incl_service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
    set_uuid(incl_srvc_id.id.uuid.uu, incl_service_id_uuid_msb, incl_service_id_uuid_lsb);

    if (incl_service_id_uuid_lsb == 0)
    {
        sGattIf->client->get_included_service(conn_id, &srvc_id, 0);
    } else {
        sGattIf->client->get_included_service(conn_id, &srvc_id, &incl_srvc_id);
    }
}

static void gattClientReadCharacteristicNative(JNIEnv* env, jobject object,
    jint conn_id, jint  service_type, jint  service_id_inst_id,
    jlong service_id_uuid_lsb, jlong service_id_uuid_msb,
    jint  char_id_inst_id,
    jlong char_id_uuid_lsb, jlong char_id_uuid_msb,
    jint authReq)
{
    if (!sGattIf) return;

    btgatt_srvc_id_t srvc_id;
    srvc_id.id.inst_id = (uint8_t) service_id_inst_id;
    srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
    set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);

    btgatt_gatt_id_t char_id;
    char_id.inst_id = (uint8_t) char_id_inst_id;
    set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb);

    sGattIf->client->read_characteristic(conn_id, &srvc_id, &char_id, authReq);
}

static void gattClientReadDescriptorNative(JNIEnv* env, jobject object,
    jint conn_id, jint  service_type, jint  service_id_inst_id,
    jlong service_id_uuid_lsb, jlong service_id_uuid_msb,
    jint  char_id_inst_id,
    jlong char_id_uuid_lsb, jlong char_id_uuid_msb,
    jint descr_id_inst_id,
    jlong descr_id_uuid_lsb, jlong descr_id_uuid_msb,
    jint authReq)
{
    if (!sGattIf) return;

    btgatt_srvc_id_t srvc_id;
    srvc_id.id.inst_id = (uint8_t) service_id_inst_id;
    srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
    set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);

    btgatt_gatt_id_t char_id;
    char_id.inst_id = (uint8_t) char_id_inst_id;
    set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb);

    btgatt_gatt_id_t descr_id;
    descr_id.inst_id = (uint8_t) descr_id_inst_id;
    set_uuid(descr_id.uuid.uu, descr_id_uuid_msb, descr_id_uuid_lsb);

    sGattIf->client->read_descriptor(conn_id, &srvc_id, &char_id, &descr_id, authReq);
}

static void gattClientWriteCharacteristicNative(JNIEnv* env, jobject object,
    jint conn_id, jint  service_type, jint  service_id_inst_id,
    jlong service_id_uuid_lsb, jlong service_id_uuid_msb,
    jint  char_id_inst_id,
    jlong char_id_uuid_lsb, jlong char_id_uuid_msb,
    jint write_type, jint auth_req, jbyteArray value)
{
    if (!sGattIf) return;

    btgatt_srvc_id_t srvc_id;
    srvc_id.id.inst_id = (uint8_t) service_id_inst_id;
    srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
    set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);

    btgatt_gatt_id_t char_id;
    char_id.inst_id = (uint8_t) char_id_inst_id;
    set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb);

    uint16_t len = (uint16_t) env->GetArrayLength(value);
    jbyte *p_value = env->GetByteArrayElements(value, NULL);
    if (p_value == NULL) return;

    sGattIf->client->write_characteristic(conn_id, &srvc_id, &char_id,
                                    write_type, len, auth_req, (char*)p_value);
    env->ReleaseByteArrayElements(value, p_value, 0);
}

static void gattClientExecuteWriteNative(JNIEnv* env, jobject object,
    jint conn_id, jboolean execute)
{
    if (!sGattIf) return;
    sGattIf->client->execute_write(conn_id, execute ? 1 : 0);
}

static void gattClientWriteDescriptorNative(JNIEnv* env, jobject object,
    jint conn_id, jint  service_type, jint service_id_inst_id,
    jlong service_id_uuid_lsb, jlong service_id_uuid_msb,
    jint char_id_inst_id,
    jlong char_id_uuid_lsb, jlong char_id_uuid_msb,
    jint descr_id_inst_id,
    jlong descr_id_uuid_lsb, jlong descr_id_uuid_msb,
    jint write_type, jint auth_req, jbyteArray value)
{
    if (!sGattIf) return;

    if (value == NULL) {
        warn("gattClientWriteDescriptorNative() ignoring NULL array");
        return;
    }

    btgatt_srvc_id_t srvc_id;
    srvc_id.id.inst_id = (uint8_t) service_id_inst_id;
    srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
    set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);

    btgatt_gatt_id_t char_id;
    char_id.inst_id = (uint8_t) char_id_inst_id;
    set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb);

    btgatt_gatt_id_t descr_id;
    descr_id.inst_id = (uint8_t) descr_id_inst_id;
    set_uuid(descr_id.uuid.uu, descr_id_uuid_msb, descr_id_uuid_lsb);

    uint16_t len = (uint16_t) env->GetArrayLength(value);
    jbyte *p_value = env->GetByteArrayElements(value, NULL);
    if (p_value == NULL) return;

    sGattIf->client->write_descriptor(conn_id, &srvc_id, &char_id, &descr_id,
                                    write_type, len, auth_req, (char*)p_value);
    env->ReleaseByteArrayElements(value, p_value, 0);
}

static void gattClientRegisterForNotificationsNative(JNIEnv* env, jobject object,
    jint clientIf, jstring address,
    jint  service_type, jint service_id_inst_id,
    jlong service_id_uuid_lsb, jlong service_id_uuid_msb,
    jint char_id_inst_id,
    jlong char_id_uuid_lsb, jlong char_id_uuid_msb,
    jboolean enable)
{
    if (!sGattIf) return;

    btgatt_srvc_id_t srvc_id;
    srvc_id.id.inst_id = (uint8_t) service_id_inst_id;
    srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
    set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);

    btgatt_gatt_id_t char_id;
    char_id.inst_id = (uint8_t) char_id_inst_id;
    set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb);

    bt_bdaddr_t bd_addr;
    const char *c_address = env->GetStringUTFChars(address, NULL);
    bd_addr_str_to_addr(c_address, bd_addr.address);

    if (enable)
        sGattIf->client->register_for_notification(clientIf, &bd_addr, &srvc_id, &char_id);
    else
        sGattIf->client->deregister_for_notification(clientIf, &bd_addr, &srvc_id, &char_id);
}

static void gattClientReadRemoteRssiNative(JNIEnv* env, jobject object, jint clientif,
                                 jstring address)
{
    if (!sGattIf) return;

    bt_bdaddr_t bda;
    jstr2bdaddr(env, &bda, address);

    sGattIf->client->read_remote_rssi(clientif, &bda);
}

static void gattAdvertiseNative(JNIEnv *env, jobject object,
        jint client_if, jboolean start)
{
    if (!sGattIf) return;
    sGattIf->client->listen(client_if, start);
}

static void gattSetAdvDataNative(JNIEnv *env, jobject object, jint client_if,
        jboolean setScanRsp, jboolean inclName, jboolean inclTxPower, jint minInterval,
        jint maxInterval, jint appearance, jbyteArray manufacturerData, jbyteArray serviceData,
        jbyteArray serviceUuid)
{
    if (!sGattIf) return;
    jbyte* arr_data = env->GetByteArrayElements(manufacturerData, NULL);
    uint16_t arr_len = (uint16_t) env->GetArrayLength(manufacturerData);

    jbyte* service_data = env->GetByteArrayElements(serviceData, NULL);
    uint16_t service_data_len = (uint16_t) env->GetArrayLength(serviceData);

    jbyte* service_uuid = env->GetByteArrayElements(serviceUuid, NULL);
    uint16_t service_uuid_len = (uint16_t) env->GetArrayLength(serviceUuid);

    sGattIf->client->set_adv_data(client_if, setScanRsp, inclName, inclTxPower,
        minInterval, maxInterval, appearance, arr_len, (char*)arr_data,
        service_data_len, (char*)service_data, service_uuid_len,
        (char*)service_uuid);

    env->ReleaseByteArrayElements(manufacturerData, arr_data, JNI_ABORT);
    env->ReleaseByteArrayElements(serviceData, service_data, JNI_ABORT);
    env->ReleaseByteArrayElements(serviceUuid, service_uuid, JNI_ABORT);
}

static void gattSetScanParametersNative(JNIEnv* env, jobject object,
                                        jint scan_interval_unit, jint scan_window_unit)
{
    if (!sGattIf) return;
    sGattIf->client->set_scan_parameters(scan_interval_unit, scan_window_unit);
}

static void gattClientScanFilterParamAddNative(JNIEnv* env, jobject object,
        jint client_if, jint filt_index,
        jint feat_seln, jint list_logic_type, jint filt_logic_type,
        jint rssi_high_thres, jint rssi_low_thres,
        jint dely_mode, jint found_timeout, jint lost_timeout, jint found_timeout_cnt)
{
    if (!sGattIf) return;
    const int add_scan_filter_params_action = 0;
    sGattIf->client->scan_filter_param_setup(client_if, add_scan_filter_params_action, filt_index,
            feat_seln, list_logic_type, filt_logic_type,
            rssi_high_thres, rssi_low_thres,
            dely_mode, found_timeout, lost_timeout, found_timeout_cnt);
}

static void gattClientScanFilterParamDeleteNative(JNIEnv* env, jobject object,
        jint client_if, jint filt_index)
{
    if (!sGattIf) return;
    const int delete_scan_filter_params_action = 1;
    sGattIf->client->scan_filter_param_setup(client_if, delete_scan_filter_params_action,
            filt_index, 0, 0, 0, 0, 0, 0, 0, 0, 0);
}

static void gattClientScanFilterParamClearAllNative(JNIEnv* env, jobject object, jint client_if)
{
    if (!sGattIf) return;
    const int clear_scan_filter_params_action = 2;
    sGattIf->client->scan_filter_param_setup(client_if, clear_scan_filter_params_action,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
}

static void gattClientScanFilterAddRemoveNative(JNIEnv* env, jobject object,
        jint client_if, jint action, jint filt_type, jint filt_index, jint company_id,
        jint company_id_mask, jlong uuid_lsb,  jlong uuid_msb, jlong uuid_mask_lsb,
        jlong uuid_mask_msb, jstring name, jstring address, jbyte addr_type,
        jbyteArray data, jbyteArray mask)
{
    switch(filt_type)
    {
        case 0: // BTM_BLE_PF_ADDR_FILTER
        {
            bt_bdaddr_t bda;
            jstr2bdaddr(env, &bda, address);
            sGattIf->client->scan_filter_add_remove(client_if, action, filt_type, filt_index, 0,
                                             0, NULL, NULL, &bda, addr_type,0, NULL,0, NULL);
            break;
        }

        case 1: // BTM_BLE_PF_SRVC_DATA
        {
            jbyte* data_array = env->GetByteArrayElements(data, 0);
            int data_len = env->GetArrayLength(data);
            jbyte* mask_array = env->GetByteArrayElements(mask, NULL);
            uint16_t mask_len = (uint16_t) env->GetArrayLength(mask);
            sGattIf->client->scan_filter_add_remove(client_if, action, filt_type, filt_index,
               0, 0, NULL, NULL, NULL, 0, data_len, (char*)data_array, mask_len,(char*) mask_array);
            env->ReleaseByteArrayElements(data, data_array, JNI_ABORT);
            env->ReleaseByteArrayElements(mask, mask_array, JNI_ABORT);
            break;
        }

        case 2: // BTM_BLE_PF_SRVC_UUID
        case 3: // BTM_BLE_PF_SRVC_SOL_UUID
        {
            bt_uuid_t uuid, uuid_mask;
            set_uuid(uuid.uu, uuid_msb, uuid_lsb);
            set_uuid(uuid_mask.uu, uuid_mask_msb, uuid_mask_lsb);
            if (uuid_mask_lsb != 0 && uuid_mask_msb != 0)
                sGattIf->client->scan_filter_add_remove(client_if, action, filt_type, filt_index,
                                 0, 0, &uuid, &uuid_mask, NULL,0,0, NULL,0, NULL);
            else
                sGattIf->client->scan_filter_add_remove(client_if, action, filt_type, filt_index,
                                 0, 0, &uuid, NULL, NULL, 0,0, NULL,0, NULL);
            break;
        }

        case 4: // BTM_BLE_PF_LOCAL_NAME
        {
            const char* c_name = env->GetStringUTFChars(name, NULL);
            if (c_name != NULL && strlen(c_name) != 0)
            {
                sGattIf->client->scan_filter_add_remove(client_if, action, filt_type,
                                 filt_index, 0, 0, NULL, NULL, NULL, 0, strlen(c_name),
                                 (char*)c_name, 0, NULL);
                env->ReleaseStringUTFChars(name, c_name);
            }
            break;
        }

        case 5: // BTM_BLE_PF_MANU_DATA
        case 6: // BTM_BLE_PF_SRVC_DATA_PATTERN
        {
            jbyte* data_array = env->GetByteArrayElements(data, 0);
            int data_len = env->GetArrayLength(data); // Array contains mask
            jbyte* mask_array = env->GetByteArrayElements(mask, NULL);
            uint16_t mask_len = (uint16_t) env->GetArrayLength(mask);
            sGattIf->client->scan_filter_add_remove(client_if, action, filt_type, filt_index,
                company_id, company_id_mask, NULL, NULL, NULL, 0, data_len, (char*)data_array,
                mask_len, (char*) mask_array);
            env->ReleaseByteArrayElements(data, data_array, JNI_ABORT);
            env->ReleaseByteArrayElements(mask, mask_array, JNI_ABORT);
            break;
        }

        default:
            break;
    }
}

static void gattClientScanFilterAddNative(JNIEnv* env, jobject object, jint client_if,
                jint filt_type, jint filt_index, jint company_id, jint company_id_mask,
                jlong uuid_lsb,  jlong uuid_msb, jlong uuid_mask_lsb, jlong uuid_mask_msb,
                jstring name, jstring address, jbyte addr_type, jbyteArray data, jbyteArray mask)
{
    if (!sGattIf) return;
    int action = 0;
    gattClientScanFilterAddRemoveNative(env, object, client_if, action, filt_type, filt_index,
                    company_id, company_id_mask, uuid_lsb, uuid_msb, uuid_mask_lsb, uuid_mask_msb,
                    name, address, addr_type, data, mask);

}

static void gattClientScanFilterDeleteNative(JNIEnv* env, jobject object, jint client_if,
                jint filt_type, jint filt_index, jint company_id, jint company_id_mask,
                jlong uuid_lsb,  jlong uuid_msb, jlong uuid_mask_lsb, jlong uuid_mask_msb,
                jstring name, jstring address, jbyte addr_type, jbyteArray data, jbyteArray mask)
{
    if (!sGattIf) return;
    int action = 1;
    gattClientScanFilterAddRemoveNative(env, object, client_if, action, filt_type, filt_index,
                    company_id, company_id_mask, uuid_lsb, uuid_msb, uuid_mask_lsb, uuid_mask_msb,
                    name, address, addr_type, data, mask);
}

static void gattClientScanFilterClearNative(JNIEnv* env, jobject object, jint client_if,
                        jint filt_index)
{
    if (!sGattIf) return;
    sGattIf->client->scan_filter_clear(client_if, filt_index);
}

static void gattClientScanFilterEnableNative (JNIEnv* env, jobject object, jint client_if,
                          jboolean enable)
{
    if (!sGattIf) return;
    sGattIf->client->scan_filter_enable(client_if, enable);
}

static void gattClientConfigureMTUNative(JNIEnv *env, jobject object,
        jint conn_id, jint mtu)
{
    if (!sGattIf) return;
    sGattIf->client->configure_mtu(conn_id, mtu);
}

static void gattConnectionParameterUpdateNative(JNIEnv *env, jobject object, jint client_if,
        jstring address, jint min_interval, jint max_interval, jint latency, jint timeout)
{
    if (!sGattIf) return;
    bt_bdaddr_t bda;
    jstr2bdaddr(env, &bda, address);
    sGattIf->client->conn_parameter_update(&bda, min_interval, max_interval, latency, timeout);
}

static void gattClientEnableAdvNative(JNIEnv* env, jobject object, jint client_if,
       jint min_interval, jint max_interval, jint adv_type, jint chnl_map, jint tx_power,
       jint timeout_s)
{
    if (!sGattIf) return;

    sGattIf->client->multi_adv_enable(client_if, min_interval, max_interval, adv_type, chnl_map,
        tx_power, timeout_s);
}

static void gattClientUpdateAdvNative(JNIEnv* env, jobject object, jint client_if,
       jint min_interval, jint max_interval, jint adv_type, jint chnl_map, jint tx_power,
       jint timeout_s)
{
    if (!sGattIf) return;

    sGattIf->client->multi_adv_update(client_if, min_interval, max_interval, adv_type, chnl_map,
        tx_power, timeout_s);
}

static void gattClientSetAdvDataNative(JNIEnv* env, jobject object , jint client_if,
        jboolean set_scan_rsp, jboolean incl_name, jboolean incl_txpower, jint appearance,
        jbyteArray manufacturer_data,jbyteArray service_data, jbyteArray service_uuid)
{
    if (!sGattIf) return;
    jbyte* manu_data = env->GetByteArrayElements(manufacturer_data, NULL);
    uint16_t manu_len = (uint16_t) env->GetArrayLength(manufacturer_data);

    jbyte* serv_data = env->GetByteArrayElements(service_data, NULL);
    uint16_t serv_data_len = (uint16_t) env->GetArrayLength(service_data);

    jbyte* serv_uuid = env->GetByteArrayElements(service_uuid, NULL);
    uint16_t serv_uuid_len = (uint16_t) env->GetArrayLength(service_uuid);

    sGattIf->client->multi_adv_set_inst_data(client_if, set_scan_rsp, incl_name,incl_txpower,
                                             appearance, manu_len, (char*)manu_data,
                                             serv_data_len, (char*)serv_data, serv_uuid_len,
                                             (char*)serv_uuid);

    env->ReleaseByteArrayElements(manufacturer_data, manu_data, JNI_ABORT);
    env->ReleaseByteArrayElements(service_data, serv_data, JNI_ABORT);
    env->ReleaseByteArrayElements(service_uuid, serv_uuid, JNI_ABORT);
}

static void gattClientDisableAdvNative(JNIEnv* env, jobject object, jint client_if)
{
    if (!sGattIf) return;
    sGattIf->client->multi_adv_disable(client_if);
}

static void gattClientConfigBatchScanStorageNative(JNIEnv* env, jobject object, jint client_if,
            jint max_full_reports_percent, jint max_trunc_reports_percent,
            jint notify_threshold_level_percent)
{
    if (!sGattIf) return;
    sGattIf->client->batchscan_cfg_storage(client_if, max_full_reports_percent,
            max_trunc_reports_percent, notify_threshold_level_percent);
}

static void gattClientStartBatchScanNative(JNIEnv* env, jobject object, jint client_if,
            jint scan_mode, jint scan_interval_unit, jint scan_window_unit, jint addr_type,
            jint discard_rule)
{
    if (!sGattIf) return;
    sGattIf->client->batchscan_enb_batch_scan(client_if, scan_mode, scan_interval_unit,
            scan_window_unit, addr_type, discard_rule);
}

static void gattClientStopBatchScanNative(JNIEnv* env, jobject object, jint client_if)
{
    if (!sGattIf) return;
    sGattIf->client->batchscan_dis_batch_scan(client_if);
}

static void gattClientReadScanReportsNative(JNIEnv* env, jobject object, jint client_if,
        jint scan_type)
{
    if (!sGattIf) return;
    sGattIf->client->batchscan_read_reports(client_if, scan_type);
}

/**
 * Native server functions
 */
static void gattServerRegisterAppNative(JNIEnv* env, jobject object,
                                        jlong app_uuid_lsb, jlong app_uuid_msb )
{
    bt_uuid_t uuid;
    if (!sGattIf) return;
    set_uuid(uuid.uu, app_uuid_msb, app_uuid_lsb);
    sGattIf->server->register_server(&uuid);
}

static void gattServerUnregisterAppNative(JNIEnv* env, jobject object, jint serverIf)
{
    if (!sGattIf) return;
    sGattIf->server->unregister_server(serverIf);
}

static void gattServerConnectNative(JNIEnv *env, jobject object,
                                 jint server_if, jstring address, jboolean is_direct, jint transport)
{
    if (!sGattIf) return;

    bt_bdaddr_t bd_addr;
    const char *c_address = env->GetStringUTFChars(address, NULL);
    bd_addr_str_to_addr(c_address, bd_addr.address);

    sGattIf->server->connect(server_if, &bd_addr, is_direct, transport);
}

static void gattServerDisconnectNative(JNIEnv* env, jobject object, jint serverIf,
                                  jstring address, jint conn_id)
{
    if (!sGattIf) return;
    bt_bdaddr_t bda;
    jstr2bdaddr(env, &bda, address);
    sGattIf->server->disconnect(serverIf, &bda, conn_id);
}

static void gattServerAddServiceNative (JNIEnv *env, jobject object,
        jint server_if, jint service_type, jint service_id_inst_id,
        jlong service_id_uuid_lsb, jlong service_id_uuid_msb,
        jint num_handles)
{
    if (!sGattIf) return;

    btgatt_srvc_id_t srvc_id;
    srvc_id.id.inst_id = (uint8_t) service_id_inst_id;
    srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
    set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);

    sGattIf->server->add_service(server_if, &srvc_id, num_handles);
}

static void gattServerAddIncludedServiceNative (JNIEnv *env, jobject object,
        jint server_if, jint svc_handle, jint included_svc_handle)
{
    if (!sGattIf) return;
    sGattIf->server->add_included_service(server_if, svc_handle,
                                          included_svc_handle);
}

static void gattServerAddCharacteristicNative (JNIEnv *env, jobject object,
        jint server_if, jint svc_handle,
        jlong char_uuid_lsb, jlong char_uuid_msb,
        jint properties, jint permissions)
{
    if (!sGattIf) return;

    bt_uuid_t uuid;
    set_uuid(uuid.uu, char_uuid_msb, char_uuid_lsb);

    sGattIf->server->add_characteristic(server_if, svc_handle,
                                        &uuid, properties, permissions);
}

static void gattServerAddDescriptorNative (JNIEnv *env, jobject object,
        jint server_if, jint svc_handle,
        jlong desc_uuid_lsb, jlong desc_uuid_msb,
        jint permissions)
{
    if (!sGattIf) return;

    bt_uuid_t uuid;
    set_uuid(uuid.uu, desc_uuid_msb, desc_uuid_lsb);

    sGattIf->server->add_descriptor(server_if, svc_handle, &uuid, permissions);
}

static void gattServerStartServiceNative (JNIEnv *env, jobject object,
        jint server_if, jint svc_handle, jint transport )
{
    if (!sGattIf) return;
    sGattIf->server->start_service(server_if, svc_handle, transport);
}

static void gattServerStopServiceNative (JNIEnv *env, jobject object,
                                         jint server_if, jint svc_handle)
{
    if (!sGattIf) return;
    sGattIf->server->stop_service(server_if, svc_handle);
}

static void gattServerDeleteServiceNative (JNIEnv *env, jobject object,
                                           jint server_if, jint svc_handle)
{
    if (!sGattIf) return;
    sGattIf->server->delete_service(server_if, svc_handle);
}

static void gattServerSendIndicationNative (JNIEnv *env, jobject object,
        jint server_if, jint attr_handle, jint conn_id, jbyteArray val)
{
    if (!sGattIf) return;

    jbyte* array = env->GetByteArrayElements(val, 0);
    int val_len = env->GetArrayLength(val);

    sGattIf->server->send_indication(server_if, attr_handle, conn_id, val_len,
                                     /*confirm*/ 1, (char*)array);
    env->ReleaseByteArrayElements(val, array, JNI_ABORT);
}

static void gattServerSendNotificationNative (JNIEnv *env, jobject object,
        jint server_if, jint attr_handle, jint conn_id, jbyteArray val)
{
    if (!sGattIf) return;

    jbyte* array = env->GetByteArrayElements(val, 0);
    int val_len = env->GetArrayLength(val);

    sGattIf->server->send_indication(server_if, attr_handle, conn_id, val_len,
                                     /*confirm*/ 0, (char*)array);
    env->ReleaseByteArrayElements(val, array, JNI_ABORT);
}

static void gattServerSendResponseNative (JNIEnv *env, jobject object,
        jint server_if, jint conn_id, jint trans_id, jint status,
        jint handle, jint offset, jbyteArray val, jint auth_req)
{
    if (!sGattIf) return;

    btgatt_response_t response;

    response.attr_value.handle = handle;
    response.attr_value.auth_req = auth_req;
    response.attr_value.offset = offset;
    response.attr_value.len = 0;

    if (val != NULL)
    {
        response.attr_value.len = (uint16_t) env->GetArrayLength(val);
        jbyte* array = env->GetByteArrayElements(val, 0);

        for (int i = 0; i != response.attr_value.len; ++i)
            response.attr_value.value[i] = (uint8_t) array[i];
        env->ReleaseByteArrayElements(val, array, JNI_ABORT);
    }

    sGattIf->server->send_response(conn_id, trans_id, status, &response);
}

static void gattTestNative(JNIEnv *env, jobject object, jint command,
                           jlong uuid1_lsb, jlong uuid1_msb, jstring bda1,
                           jint p1, jint p2, jint p3, jint p4, jint p5 )
{
    if (!sGattIf) return;

    bt_bdaddr_t bt_bda1;
    jstr2bdaddr(env, &bt_bda1, bda1);

    bt_uuid_t uuid1;
    set_uuid(uuid1.uu, uuid1_msb, uuid1_lsb);

    btgatt_test_params_t params;
    params.bda1 = &bt_bda1;
    params.uuid1 = &uuid1;
    params.u1 = p1;
    params.u2 = p2;
    params.u3 = p3;
    params.u4 = p4;
    params.u5 = p5;
    sGattIf->client->test_command(command, &params);
}

/**
 * JNI function definitinos
 */

// JNI functions defined in AdvertiseManager class.
static JNINativeMethod sAdvertiseMethods[] = {
    {"gattClientEnableAdvNative", "(IIIIIII)V", (void *) gattClientEnableAdvNative},
    {"gattClientUpdateAdvNative", "(IIIIIII)V", (void *) gattClientUpdateAdvNative},
    {"gattClientSetAdvDataNative", "(IZZZI[B[B[B)V", (void *) gattClientSetAdvDataNative},
    {"gattClientDisableAdvNative", "(I)V", (void *) gattClientDisableAdvNative},
    {"gattSetAdvDataNative", "(IZZZIII[B[B[B)V", (void *) gattSetAdvDataNative},
    {"gattAdvertiseNative", "(IZ)V", (void *) gattAdvertiseNative},
};

// JNI functions defined in ScanManager class.
static JNINativeMethod sScanMethods[] = {
    {"gattClientScanNative", "(Z)V", (void *) gattClientScanNative},
    // Batch scan JNI functions.
    {"gattClientConfigBatchScanStorageNative", "(IIII)V",(void *) gattClientConfigBatchScanStorageNative},
    {"gattClientStartBatchScanNative", "(IIIIII)V", (void *) gattClientStartBatchScanNative},
    {"gattClientStopBatchScanNative", "(I)V", (void *) gattClientStopBatchScanNative},
    {"gattClientReadScanReportsNative", "(II)V", (void *) gattClientReadScanReportsNative},
    // Scan filter JNI functions.
    {"gattClientScanFilterParamAddNative", "(IIIIIIIIIII)V", (void *) gattClientScanFilterParamAddNative},
    {"gattClientScanFilterParamDeleteNative", "(II)V", (void *) gattClientScanFilterParamDeleteNative},
    {"gattClientScanFilterParamClearAllNative", "(I)V", (void *) gattClientScanFilterParamClearAllNative},
    {"gattClientScanFilterAddNative", "(IIIIIJJJJLjava/lang/String;Ljava/lang/String;B[B[B)V", (void *) gattClientScanFilterAddNative},
    {"gattClientScanFilterDeleteNative", "(IIIIIJJJJLjava/lang/String;Ljava/lang/String;B[B[B)V", (void *) gattClientScanFilterDeleteNative},
    {"gattClientScanFilterClearNative", "(II)V", (void *) gattClientScanFilterClearNative},
    {"gattClientScanFilterEnableNative", "(IZ)V", (void *) gattClientScanFilterEnableNative},
    {"gattSetScanParametersNative", "(II)V", (void *) gattSetScanParametersNative},
};

// JNI functions defined in GattService class.
static JNINativeMethod sMethods[] = {
    {"classInitNative", "()V", (void *) classInitNative},
    {"initializeNative", "()V", (void *) initializeNative},
    {"cleanupNative", "()V", (void *) cleanupNative},
    {"gattClientGetDeviceTypeNative", "(Ljava/lang/String;)I", (void *) gattClientGetDeviceTypeNative},
    {"gattClientRegisterAppNative", "(JJ)V", (void *) gattClientRegisterAppNative},
    {"gattClientUnregisterAppNative", "(I)V", (void *) gattClientUnregisterAppNative},
    {"gattClientConnectNative", "(ILjava/lang/String;ZI)V", (void *) gattClientConnectNative},
    {"gattClientDisconnectNative", "(ILjava/lang/String;I)V", (void *) gattClientDisconnectNative},
    {"gattClientRefreshNative", "(ILjava/lang/String;)V", (void *) gattClientRefreshNative},
    {"gattClientSearchServiceNative", "(IZJJ)V", (void *) gattClientSearchServiceNative},
    {"gattClientGetCharacteristicNative", "(IIIJJIJJ)V", (void *) gattClientGetCharacteristicNative},
    {"gattClientGetDescriptorNative", "(IIIJJIJJIJJ)V", (void *) gattClientGetDescriptorNative},
    {"gattClientGetIncludedServiceNative", "(IIIJJIIJJ)V", (void *) gattClientGetIncludedServiceNative},
    {"gattClientReadCharacteristicNative", "(IIIJJIJJI)V", (void *) gattClientReadCharacteristicNative},
    {"gattClientReadDescriptorNative", "(IIIJJIJJIJJI)V", (void *) gattClientReadDescriptorNative},
    {"gattClientWriteCharacteristicNative", "(IIIJJIJJII[B)V", (void *) gattClientWriteCharacteristicNative},
    {"gattClientWriteDescriptorNative", "(IIIJJIJJIJJII[B)V", (void *) gattClientWriteDescriptorNative},
    {"gattClientExecuteWriteNative", "(IZ)V", (void *) gattClientExecuteWriteNative},
    {"gattClientRegisterForNotificationsNative", "(ILjava/lang/String;IIJJIJJZ)V", (void *) gattClientRegisterForNotificationsNative},
    {"gattClientReadRemoteRssiNative", "(ILjava/lang/String;)V", (void *) gattClientReadRemoteRssiNative},
    {"gattClientConfigureMTUNative", "(II)V", (void *) gattClientConfigureMTUNative},
    {"gattConnectionParameterUpdateNative", "(ILjava/lang/String;IIII)V", (void *) gattConnectionParameterUpdateNative},
    {"gattServerRegisterAppNative", "(JJ)V", (void *) gattServerRegisterAppNative},
    {"gattServerUnregisterAppNative", "(I)V", (void *) gattServerUnregisterAppNative},
    {"gattServerConnectNative", "(ILjava/lang/String;ZI)V", (void *) gattServerConnectNative},
    {"gattServerDisconnectNative", "(ILjava/lang/String;I)V", (void *) gattServerDisconnectNative},
    {"gattServerAddServiceNative", "(IIIJJI)V", (void *) gattServerAddServiceNative},
    {"gattServerAddIncludedServiceNative", "(III)V", (void *) gattServerAddIncludedServiceNative},
    {"gattServerAddCharacteristicNative", "(IIJJII)V", (void *) gattServerAddCharacteristicNative},
    {"gattServerAddDescriptorNative", "(IIJJI)V", (void *) gattServerAddDescriptorNative},
    {"gattServerStartServiceNative", "(III)V", (void *) gattServerStartServiceNative},
    {"gattServerStopServiceNative", "(II)V", (void *) gattServerStopServiceNative},
    {"gattServerDeleteServiceNative", "(II)V", (void *) gattServerDeleteServiceNative},
    {"gattServerSendIndicationNative", "(III[B)V", (void *) gattServerSendIndicationNative},
    {"gattServerSendNotificationNative", "(III[B)V", (void *) gattServerSendNotificationNative},
    {"gattServerSendResponseNative", "(IIIIII[BI)V", (void *) gattServerSendResponseNative},

    {"gattTestNative", "(IJJLjava/lang/String;IIIII)V", (void *) gattTestNative},
};

int register_com_android_bluetooth_gatt(JNIEnv* env)
{
    int register_success =
        jniRegisterNativeMethods(env, "com/android/bluetooth/gatt/ScanManager$ScanNative",
                sScanMethods, NELEM(sScanMethods));
    register_success &=
        jniRegisterNativeMethods(env, "com/android/bluetooth/gatt/AdvertiseManager$AdvertiseNative",
                sAdvertiseMethods, NELEM(sAdvertiseMethods));
    return register_success &
        jniRegisterNativeMethods(env, "com/android/bluetooth/gatt/GattService",
                sMethods, NELEM(sMethods));
}
}
