/******************************************************************************
 *
 *  Copyright 2014 Google, Inc.
 *
 *  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_btif_sock_sco"

#include <sys/socket.h>
#include <sys/types.h>

#include <cstdint>
#include <mutex>

#include "device/include/esco_parameters.h"
#include "include/hardware/bt_sock.h"
#include "osi/include/allocator.h"
#include "osi/include/list.h"
#include "osi/include/log.h"
#include "osi/include/osi.h"  // UNUSED_ATTR
#include "osi/include/socket.h"
#include "osi/include/thread.h"
#include "stack/include/btm_api.h"
#include "types/raw_address.h"

// This module provides a socket abstraction for SCO connections to a higher
// layer. It returns file descriptors representing two types of sockets:
// listening (server) and connected (client) sockets. No SCO data is
// transferred across these sockets; instead, they are used to manage SCO
// connection lifecycles while the data routing takes place over the I2S bus.
//
// This code bridges the gap between the BTM layer, which implements SCO
// connections, and the Android HAL. It adapts the BTM representation of SCO
// connections (integer handles) to a file descriptor representation usable by
// Android's LocalSocket implementation.
//
// Sample flow for an incoming connection:
//   btsock_sco_listen()       - listen for incoming connections
//   connection_request_cb()   - incoming connection request from remote host
//   connect_completed_cb()    - connection successfully established
//   socket_read_ready_cb()    - local host closed SCO socket
//   disconnect_completed_cb() - connection terminated

typedef struct {
  uint16_t sco_handle;
  socket_t* socket;
  bool connect_completed;
} sco_socket_t;

static sco_socket_t* sco_socket_establish_locked(bool is_listening,
                                                 const RawAddress* bd_addr,
                                                 int* sock_fd);
static sco_socket_t* sco_socket_new(void);
static void sco_socket_free_locked(sco_socket_t* socket);
static sco_socket_t* sco_socket_find_locked(uint16_t sco_handle);
static void connection_request_cb(tBTM_ESCO_EVT event,
                                  tBTM_ESCO_EVT_DATA* data);
static void connect_completed_cb(uint16_t sco_handle);
static void disconnect_completed_cb(uint16_t sco_handle);
static void socket_read_ready_cb(socket_t* socket, void* context);

// |sco_lock| protects all of the static variables below and
// calls into the BTM layer.
static std::mutex sco_lock;
static list_t* sco_sockets;  // Owns a collection of sco_socket_t objects.
static sco_socket_t* listen_sco_socket;  // Not owned, do not free.
static thread_t* thread;                 // Not owned, do not free.

bt_status_t btsock_sco_init(thread_t* thread_) {
  CHECK(thread_ != NULL);

  sco_sockets = list_new((list_free_cb)sco_socket_free_locked);
  if (!sco_sockets) return BT_STATUS_FAIL;

  thread = thread_;
  enh_esco_params_t params = esco_parameters_for_codec(SCO_CODEC_CVSD_D1);
  BTM_SetEScoMode(&params);

  return BT_STATUS_SUCCESS;
}

bt_status_t btsock_sco_cleanup(void) {
  list_free(sco_sockets);
  sco_sockets = NULL;
  return BT_STATUS_SUCCESS;
}

bt_status_t btsock_sco_listen(int* sock_fd, UNUSED_ATTR int flags) {
  CHECK(sock_fd != NULL);

  std::unique_lock<std::mutex> lock(sco_lock);

  sco_socket_t* sco_socket = sco_socket_establish_locked(true, NULL, sock_fd);
  if (!sco_socket) return BT_STATUS_FAIL;

  BTM_RegForEScoEvts(sco_socket->sco_handle, connection_request_cb);
  listen_sco_socket = sco_socket;

  return BT_STATUS_SUCCESS;
}

bt_status_t btsock_sco_connect(const RawAddress* bd_addr, int* sock_fd,
                               UNUSED_ATTR int flags) {
  CHECK(bd_addr != NULL);
  CHECK(sock_fd != NULL);

  std::unique_lock<std::mutex> lock(sco_lock);
  sco_socket_t* sco_socket =
      sco_socket_establish_locked(false, bd_addr, sock_fd);

  return (sco_socket != NULL) ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
}

// Must be called with |lock| held.
static sco_socket_t* sco_socket_establish_locked(bool is_listening,
                                                 const RawAddress* bd_addr,
                                                 int* sock_fd) {
  int pair[2] = {INVALID_FD, INVALID_FD};
  sco_socket_t* sco_socket = NULL;
  socket_t* socket = NULL;
  tBTM_STATUS status;
  enh_esco_params_t params;
  if (socketpair(AF_LOCAL, SOCK_STREAM, 0, pair) == -1) {
    LOG_ERROR("%s unable to allocate socket pair: %s", __func__,
              strerror(errno));
    goto error;
  }

  sco_socket = sco_socket_new();
  if (!sco_socket) {
    LOG_ERROR("%s unable to allocate new SCO socket.", __func__);
    goto error;
  }

  params = esco_parameters_for_codec(SCO_CODEC_CVSD_D1);
  status = BTM_CreateSco(bd_addr, !is_listening, params.packet_types,
                         &sco_socket->sco_handle, connect_completed_cb,
                         disconnect_completed_cb);
  if (status != BTM_CMD_STARTED) {
    LOG_ERROR("%s unable to create SCO socket: %d", __func__, status);
    goto error;
  }

  socket = socket_new_from_fd(pair[1]);
  if (!socket) {
    LOG_ERROR("%s unable to allocate socket from file descriptor %d.", __func__,
              pair[1]);
    goto error;
  }

  *sock_fd = pair[0];           // Transfer ownership of one end to caller.
  sco_socket->socket = socket;  // Hang on to the other end.
  list_append(sco_sockets, sco_socket);

  socket_register(socket, thread_get_reactor(thread), sco_socket,
                  socket_read_ready_cb, NULL);
  return sco_socket;

error:;
  if (pair[0] != INVALID_FD) close(pair[0]);
  if (pair[1] != INVALID_FD) close(pair[1]);

  sco_socket_free_locked(sco_socket);
  return NULL;
}

static sco_socket_t* sco_socket_new(void) {
  sco_socket_t* sco_socket = (sco_socket_t*)osi_calloc(sizeof(sco_socket_t));
  sco_socket->sco_handle = BTM_INVALID_SCO_INDEX;
  return sco_socket;
}

// Must be called with |lock| held except during teardown when we know the
// socket thread
// is no longer alive.
static void sco_socket_free_locked(sco_socket_t* sco_socket) {
  if (!sco_socket) return;

  if (sco_socket->sco_handle != BTM_INVALID_SCO_INDEX)
    BTM_RemoveSco(sco_socket->sco_handle);
  socket_free(sco_socket->socket);
  osi_free(sco_socket);
}

// Must be called with |lock| held.
static sco_socket_t* sco_socket_find_locked(uint16_t sco_handle) {
  for (const list_node_t* node = list_begin(sco_sockets);
       node != list_end(sco_sockets); node = list_next(node)) {
    sco_socket_t* sco_socket = (sco_socket_t*)list_node(node);
    if (sco_socket->sco_handle == sco_handle) return sco_socket;
  }
  return NULL;
}

static void connection_request_cb(tBTM_ESCO_EVT event,
                                  tBTM_ESCO_EVT_DATA* data) {
  CHECK(data != NULL);

  // Don't care about change of link parameters, only connection requests.
  if (event != BTM_ESCO_CONN_REQ_EVT) return;

  std::unique_lock<std::mutex> lock(sco_lock);

  const tBTM_ESCO_CONN_REQ_EVT_DATA* conn_data = &data->conn_evt;
  sco_socket_t* sco_socket = sco_socket_find_locked(conn_data->sco_inx);
  int client_fd = INVALID_FD;

  uint16_t temp;
  sco_socket_t* new_sco_socket;

  if (!sco_socket) {
    LOG_ERROR("%s unable to find sco_socket for handle: %hu", __func__,
              conn_data->sco_inx);
    goto error;
  }

  if (sco_socket != listen_sco_socket) {
    LOG_ERROR(

        "%s received connection request on non-listening socket handle: %hu",
        __func__, conn_data->sco_inx);
    goto error;
  }

  new_sco_socket = sco_socket_establish_locked(true, NULL, &client_fd);
  if (!new_sco_socket) {
    LOG_ERROR("%s unable to allocate new sco_socket.", __func__);
    goto error;
  }

  // Swap socket->sco_handle and new_socket->sco_handle
  temp = sco_socket->sco_handle;
  sco_socket->sco_handle = new_sco_socket->sco_handle;
  new_sco_socket->sco_handle = temp;

  sock_connect_signal_t connect_signal;
  connect_signal.size = sizeof(connect_signal);
  connect_signal.bd_addr = conn_data->bd_addr;
  connect_signal.channel = 0;
  connect_signal.status = 0;

  if (socket_write_and_transfer_fd(sco_socket->socket, &connect_signal,
                                   sizeof(connect_signal),
                                   client_fd) != sizeof(connect_signal)) {
    LOG_ERROR("%s unable to send new file descriptor to listening socket.",
              __func__);
    goto error;
  }

  BTM_RegForEScoEvts(listen_sco_socket->sco_handle, connection_request_cb);
  BTM_EScoConnRsp(conn_data->sco_inx, HCI_SUCCESS, NULL);

  return;

error:;
  if (client_fd != INVALID_FD) close(client_fd);
  BTM_EScoConnRsp(conn_data->sco_inx, HCI_ERR_HOST_REJECT_RESOURCES, NULL);
}

static void connect_completed_cb(uint16_t sco_handle) {
  std::unique_lock<std::mutex> lock(sco_lock);

  sco_socket_t* sco_socket = sco_socket_find_locked(sco_handle);
  if (!sco_socket) {
    LOG_ERROR("%s SCO socket not found on connect for handle: %hu", __func__,
              sco_handle);
    return;
  }

  // If sco_socket->socket was closed, we should tear down because there is no
  // app-level
  // interest in the SCO socket.
  if (!sco_socket->socket) {
    BTM_RemoveSco(sco_socket->sco_handle);
    list_remove(sco_sockets, sco_socket);
    return;
  }

  sco_socket->connect_completed = true;
}

static void disconnect_completed_cb(uint16_t sco_handle) {
  std::unique_lock<std::mutex> lock(sco_lock);

  sco_socket_t* sco_socket = sco_socket_find_locked(sco_handle);
  if (!sco_socket) {
    LOG_ERROR("%s SCO socket not found on disconnect for handle: %hu", __func__,
              sco_handle);
    return;
  }

  list_remove(sco_sockets, sco_socket);
}

static void socket_read_ready_cb(UNUSED_ATTR socket_t* socket, void* context) {
  std::unique_lock<std::mutex> lock(sco_lock);

  sco_socket_t* sco_socket = (sco_socket_t*)context;
  socket_free(sco_socket->socket);
  sco_socket->socket = NULL;

  // Defer the underlying disconnect until the connection completes
  // since the BTM code doesn't behave correctly when a disconnect
  // request is issued while a connect is in progress. The fact that
  // sco_socket->socket == NULL indicates to the connect callback
  // routine that the socket is no longer desired and should be torn
  // down.
  if (sco_socket->connect_completed || sco_socket == listen_sco_socket) {
    if (BTM_RemoveSco(sco_socket->sco_handle) == BTM_SUCCESS)
      list_remove(sco_sockets, sco_socket);
    if (sco_socket == listen_sco_socket) listen_sco_socket = NULL;
  }
}
