/*
** Copyright 2006, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/

#define LOG_TAG "BT HSHFP"

#include "android_bluetooth_common.h"
#include "android_runtime/AndroidRuntime.h"
#include "JNIHelp.h"
#include "jni.h"
#include "utils/Log.h"
#include "utils/misc.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <sys/poll.h>

#ifdef HAVE_BLUETOOTH
#include <bluetooth/bluetooth.h>
#include <bluetooth/rfcomm.h>
#include <bluetooth/sco.h>
#endif

namespace android {

#ifdef HAVE_BLUETOOTH
static jfieldID field_mNativeData;
static jfieldID field_mAddress;
static jfieldID field_mRfcommChannel;
static jfieldID field_mTimeoutRemainingMs;

typedef struct {
    jstring address;
    const char *c_address;
    int rfcomm_channel;
    int last_read_err;
    int rfcomm_sock;
    int rfcomm_connected; // -1 in progress, 0 not connected, 1 connected
    int rfcomm_sock_flags;
} native_data_t;

static inline native_data_t * get_native_data(JNIEnv *env, jobject object) {
    return (native_data_t *)(env->GetIntField(object, field_mNativeData));
}

static const char CRLF[] = "\xd\xa";
static const int CRLF_LEN = 2;

static inline int write_error_check(int fd, const char* line, int len) {
    int ret;
    errno = 0;
    ret = write(fd, line, len);
    if (ret < 0) {
        LOGE("%s: write() failed: %s (%d)", __FUNCTION__, strerror(errno),
             errno);
        return -1;
    }
    if (ret != len) {
        LOGE("%s: write() only wrote %d of %d bytes", __FUNCTION__, ret, len);
        return -1;
    }
    return 0;
}

static int send_line(int fd, const char* line) {
    int nw;
    int len = strlen(line);
    int llen = len + CRLF_LEN * 2 + 1;
    char *buffer = (char *)calloc(llen, sizeof(char));

    snprintf(buffer, llen, "%s%s%s", CRLF, line, CRLF);

    if (write_error_check(fd, buffer, llen - 1)) {
        free(buffer);
        return -1;
    }
    free(buffer);
    return 0;
}

static const char* get_line(int fd, char *buf, int len, int timeout_ms,
                            int *err) {
    char *bufit=buf;
    int fd_flags = fcntl(fd, F_GETFL, 0);
    struct pollfd pfd;

again:
    *bufit = 0;
    pfd.fd = fd;
    pfd.events = POLLIN;
    *err = errno = 0;
    int ret = poll(&pfd, 1, timeout_ms);
    if (ret < 0) {
        LOGE("poll() error\n");
        *err = errno;
        return NULL;
    }
    if (ret == 0) {
        return NULL;
    }

    if (pfd.revents & (POLLHUP | POLLERR | POLLNVAL)) {
        LOGW("RFCOMM poll() returned  success (%d), "
             "but with an unexpected revents bitmask: %#x\n", ret, pfd.revents);
        errno = EIO;
        *err = errno;
        return NULL;
    }

    while ((int)(bufit - buf) < len)
    {
        errno = 0;
        int rc = read(fd, bufit, 1);

        if (!rc)
            break;

        if (rc < 0) {
            if (errno == EBUSY) {
                LOGI("read() error %s (%d): repeating read()...",
                     strerror(errno), errno);
                goto again;
            }
            *err = errno;
            LOGE("read() error %s (%d)", strerror(errno), errno);
            return NULL;
        }


        if (*bufit=='\xd') {
            break;
        }

        if (*bufit=='\xa')
            bufit = buf;
        else
            bufit++;
    }

    *bufit = '\x0';
    LOG(LOG_INFO, "Bluetooth AT recv", buf);

    return buf;
}
#endif

static void classInitNative(JNIEnv* env, jclass clazz) {
    LOGV(__FUNCTION__);
#ifdef HAVE_BLUETOOTH
    field_mNativeData = get_field(env, clazz, "mNativeData", "I");
    field_mAddress = get_field(env, clazz, "mAddress", "Ljava/lang/String;");
    field_mTimeoutRemainingMs = get_field(env, clazz, "mTimeoutRemainingMs", "I");
    field_mRfcommChannel = get_field(env, clazz, "mRfcommChannel", "I");
#endif
}

static void initializeNativeDataNative(JNIEnv* env, jobject object,
                                       jint socketFd) {
    LOGV(__FUNCTION__);
#ifdef HAVE_BLUETOOTH
    native_data_t *nat = (native_data_t *)calloc(1, sizeof(native_data_t));
    if (NULL == nat) {
        LOGE("%s: out of memory!", __FUNCTION__);
        return;
    }

    env->SetIntField(object, field_mNativeData, (jint)nat);
    nat->address =
        (jstring)env->NewGlobalRef(env->GetObjectField(object,
                                                       field_mAddress));
    nat->c_address = env->GetStringUTFChars(nat->address, NULL);
    nat->rfcomm_channel = env->GetIntField(object, field_mRfcommChannel);
    nat->rfcomm_sock = socketFd;
    nat->rfcomm_connected = socketFd >= 0;
    if (nat->rfcomm_connected)
        LOGI("%s: ALREADY CONNECTED!", __FUNCTION__);
#endif
}

static void cleanupNativeDataNative(JNIEnv* env, jobject object) {
    LOGV(__FUNCTION__);
#ifdef HAVE_BLUETOOTH
    native_data_t *nat =
        (native_data_t *)env->GetIntField(object, field_mNativeData);
    env->ReleaseStringUTFChars(nat->address, nat->c_address);
    env->DeleteGlobalRef(nat->address);
    if (nat)
        free(nat);
#endif
}

static jboolean connectNative(JNIEnv *env, jobject obj)
{
    LOGV(__FUNCTION__);
#ifdef HAVE_BLUETOOTH
    int lm;
    struct sockaddr_rc addr;
    native_data_t *nat = get_native_data(env, obj);

    nat->rfcomm_sock = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);

    if (nat->rfcomm_sock < 0) {
        LOGE("%s: Could not create RFCOMM socket: %s\n", __FUNCTION__,
             strerror(errno));
        return JNI_FALSE;
    }

    if (debug_no_encrypt()) {
        lm = RFCOMM_LM_AUTH;
    } else {
        lm = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT;
    }

    if (lm && setsockopt(nat->rfcomm_sock, SOL_RFCOMM, RFCOMM_LM, &lm,
                sizeof(lm)) < 0) {
        LOGE("%s: Can't set RFCOMM link mode", __FUNCTION__);
        close(nat->rfcomm_sock);
        return JNI_FALSE;
    }

    memset(&addr, 0, sizeof(struct sockaddr_rc));
    get_bdaddr(nat->c_address, &addr.rc_bdaddr);
    addr.rc_channel = nat->rfcomm_channel;
    addr.rc_family = AF_BLUETOOTH;
    nat->rfcomm_connected = 0;
    while (nat->rfcomm_connected == 0) {
        if (connect(nat->rfcomm_sock, (struct sockaddr *)&addr,
                      sizeof(addr)) < 0) {
            if (errno == EINTR) continue;
            LOGE("%s: connect() failed: %s\n", __FUNCTION__, strerror(errno));
            close(nat->rfcomm_sock);
            nat->rfcomm_sock = -1;
            return JNI_FALSE;
        } else {
            nat->rfcomm_connected = 1;
        }
    }

    return JNI_TRUE;
#else
    return JNI_FALSE;
#endif
}

static jint connectAsyncNative(JNIEnv *env, jobject obj) {
    LOGV(__FUNCTION__);
#ifdef HAVE_BLUETOOTH
    struct sockaddr_rc addr;
    native_data_t *nat = get_native_data(env, obj);

    if (nat->rfcomm_connected) {
        LOGV("RFCOMM socket is already connected or connection is in progress.");
        return 0;
    }

    if (nat->rfcomm_sock < 0) {
        int lm;

        nat->rfcomm_sock = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
        if (nat->rfcomm_sock < 0) {
            LOGE("%s: Could not create RFCOMM socket: %s\n", __FUNCTION__,
                 strerror(errno));
            return -1;
        }

        if (debug_no_encrypt()) {
            lm = RFCOMM_LM_AUTH;
        } else {
            lm = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT;
        }

        if (lm && setsockopt(nat->rfcomm_sock, SOL_RFCOMM, RFCOMM_LM, &lm,
                    sizeof(lm)) < 0) {
            LOGE("%s: Can't set RFCOMM link mode", __FUNCTION__);
            close(nat->rfcomm_sock);
            return -1;
        }
        LOGI("Created RFCOMM socket fd %d.", nat->rfcomm_sock);
    }

    memset(&addr, 0, sizeof(struct sockaddr_rc));
    get_bdaddr(nat->c_address, &addr.rc_bdaddr);
    addr.rc_channel = nat->rfcomm_channel;
    addr.rc_family = AF_BLUETOOTH;
    if (nat->rfcomm_sock_flags >= 0) {
        nat->rfcomm_sock_flags = fcntl(nat->rfcomm_sock, F_GETFL, 0);
        if (fcntl(nat->rfcomm_sock,
                  F_SETFL, nat->rfcomm_sock_flags | O_NONBLOCK) >= 0) {
            int rc;
            nat->rfcomm_connected = 0;
            errno = 0;
            rc = connect(nat->rfcomm_sock,
                        (struct sockaddr *)&addr,
                         sizeof(addr));

            if (rc >= 0) {
                nat->rfcomm_connected = 1;
                LOGI("async connect successful");
                return 0;
            }
            else if (rc < 0) {
                if (errno == EINPROGRESS || errno == EAGAIN)
                {
                    LOGI("async connect is in progress (%s)",
                         strerror(errno));
                    nat->rfcomm_connected = -1;
                    return 0;
                }
                else
                {
                    LOGE("async connect error: %s (%d)", strerror(errno), errno);
                    close(nat->rfcomm_sock);
                    nat->rfcomm_sock = -1;
                    return -errno;
                }
            }
        } // fcntl(nat->rfcomm_sock ...)
    } // if (nat->rfcomm_sock_flags >= 0)
#endif
    return -1;
}

static jint waitForAsyncConnectNative(JNIEnv *env, jobject obj,
                                           jint timeout_ms) {
    LOGV(__FUNCTION__);
#ifdef HAVE_BLUETOOTH
    struct sockaddr_rc addr;
    native_data_t *nat = get_native_data(env, obj);

    env->SetIntField(obj, field_mTimeoutRemainingMs, timeout_ms);

    if (nat->rfcomm_connected > 0) {
        LOGI("RFCOMM is already connected!");
        return 1;
    }

    if (nat->rfcomm_sock >= 0 && nat->rfcomm_connected == 0) {
        LOGI("Re-opening RFCOMM socket.");
        close(nat->rfcomm_sock);
        nat->rfcomm_sock = -1;
    }
    int ret = connectAsyncNative(env, obj);

    if (ret < 0) {
        LOGI("Failed to re-open RFCOMM socket!");
        return ret;
    }

    if (nat->rfcomm_sock >= 0) {
        /* Do an asynchronous select() */
        int n;
        fd_set rset, wset;
        struct timeval to;

        FD_ZERO(&rset);
        FD_ZERO(&wset);
        FD_SET(nat->rfcomm_sock, &rset);
        FD_SET(nat->rfcomm_sock, &wset);
        if (timeout_ms >= 0) {
            to.tv_sec = timeout_ms / 1000;
            to.tv_usec = 1000 * (timeout_ms % 1000);
        }
        n = select(nat->rfcomm_sock + 1,
                   &rset,
                   &wset,
                   NULL,
                   (timeout_ms < 0 ? NULL : &to));

        if (timeout_ms > 0) {
            jint remaining = to.tv_sec*1000 + to.tv_usec/1000;
            LOGV("Remaining time %ldms", (long)remaining);
            env->SetIntField(obj, field_mTimeoutRemainingMs,
                             remaining);
        }

        if (n <= 0) {
            if (n < 0)  {
                LOGE("select() on RFCOMM socket: %s (%d)",
                     strerror(errno),
                     errno);
                return -errno;
            }
            return 0;
        }
        /* n must be equal to 1 and either rset or wset must have the
           file descriptor set. */
        LOGV("select() returned %d.", n);
        if (FD_ISSET(nat->rfcomm_sock, &rset) ||
            FD_ISSET(nat->rfcomm_sock, &wset))
        {
            /* A trial async read() will tell us if everything is OK. */
            {
                char ch;
                errno = 0;
                int nr = read(nat->rfcomm_sock, &ch, 1);
                /* It should be that nr != 1 because we just opened a socket
                   and we haven't sent anything over it for the other side to
                   respond... but one can't be paranoid enough.
                */
                if (nr >= 0 || errno != EAGAIN) {
                    LOGE("RFCOMM async connect() error: %s (%d), nr = %d\n",
                         strerror(errno),
                         errno,
                         nr);
                    /* Clear the rfcomm_connected flag to cause this function
                       to re-create the socket and re-attempt the connect()
                       the next time it is called.
                    */
                    nat->rfcomm_connected = 0;
                    /* Restore the blocking properties of the socket. */
                    fcntl(nat->rfcomm_sock, F_SETFL, nat->rfcomm_sock_flags);
                    close(nat->rfcomm_sock);
                    nat->rfcomm_sock = -1;
                    return -errno;
                }
            }
            /* Restore the blocking properties of the socket. */
            fcntl(nat->rfcomm_sock, F_SETFL, nat->rfcomm_sock_flags);
            LOGI("Successful RFCOMM socket connect.");
            nat->rfcomm_connected = 1;
            return 1;
        }
    }
    else LOGE("RFCOMM socket file descriptor %d is bad!",
              nat->rfcomm_sock);
#endif
    return -1;
}

static void disconnectNative(JNIEnv *env, jobject obj) {
    LOGV(__FUNCTION__);
#ifdef HAVE_BLUETOOTH
    native_data_t *nat = get_native_data(env, obj);
    if (nat->rfcomm_sock >= 0) {
        close(nat->rfcomm_sock);
        nat->rfcomm_sock = -1;
        nat->rfcomm_connected = 0;
    }
#endif
}

static void pretty_log_urc(const char *urc) {
    size_t i;
    bool in_line_break = false;
    char *buf = (char *)calloc(strlen(urc) + 1, sizeof(char));

    strcpy(buf, urc);
    for (i = 0; i < strlen(buf); i++) {
        switch(buf[i]) {
        case '\r':
        case '\n':
            in_line_break = true;
            buf[i] = ' ';
            break;
        default:
            if (in_line_break) {
                in_line_break = false;
                buf[i-1] = '\n';
            }
        }
    }
    LOG(LOG_INFO, "Bluetooth AT sent", buf);

    free(buf);
}

static jboolean sendURCNative(JNIEnv *env, jobject obj, jstring urc) {
#ifdef HAVE_BLUETOOTH
    native_data_t *nat = get_native_data(env, obj);
    if (nat->rfcomm_connected) {
        const char *c_urc = env->GetStringUTFChars(urc, NULL);
        jboolean ret = send_line(nat->rfcomm_sock, c_urc) == 0 ? JNI_TRUE : JNI_FALSE;
        if (ret == JNI_TRUE) pretty_log_urc(c_urc);
        env->ReleaseStringUTFChars(urc, c_urc);
        return ret;
    }
#endif
    return JNI_FALSE;
}

static jstring readNative(JNIEnv *env, jobject obj, jint timeout_ms) {
#ifdef HAVE_BLUETOOTH
    {
        native_data_t *nat = get_native_data(env, obj);
        if (nat->rfcomm_connected) {
            char buf[128];
            const char *ret = get_line(nat->rfcomm_sock,
                                       buf, sizeof(buf),
                                       timeout_ms,
                                       &nat->last_read_err);
            return ret ? env->NewStringUTF(ret) : NULL;
        }
        return NULL;
    }
#else
    return NULL;
#endif
}

static jint getLastReadStatusNative(JNIEnv *env, jobject obj) {
#ifdef HAVE_BLUETOOTH
    {
        native_data_t *nat = get_native_data(env, obj);
        if (nat->rfcomm_connected)
            return (jint)nat->last_read_err;
        return 0;
    }
#else
    return 0;
#endif
}

static JNINativeMethod sMethods[] = {
     /* name, signature, funcPtr */
    {"classInitNative", "()V", (void*)classInitNative},
    {"initializeNativeDataNative", "(I)V", (void *)initializeNativeDataNative},
    {"cleanupNativeDataNative", "()V", (void *)cleanupNativeDataNative},
    {"connectNative", "()Z", (void *)connectNative},
    {"connectAsyncNative", "()I", (void *)connectAsyncNative},
    {"waitForAsyncConnectNative", "(I)I", (void *)waitForAsyncConnectNative},
    {"disconnectNative", "()V", (void *)disconnectNative},
    {"sendURCNative", "(Ljava/lang/String;)Z", (void *)sendURCNative},
    {"readNative", "(I)Ljava/lang/String;", (void *)readNative},
    {"getLastReadStatusNative", "()I", (void *)getLastReadStatusNative},
};

int register_android_bluetooth_HeadsetBase(JNIEnv *env) {
    return AndroidRuntime::registerNativeMethods(env,
            "android/bluetooth/HeadsetBase", sMethods, NELEM(sMethods));
}

} /* namespace android */
