/******************************************************************************
 *
 *  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 "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;
  }
}
