//
//  Copyright (C) 2015 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_gatts"

#include "gatt_server_old.h"

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <algorithm>
#include <array>
#include <condition_variable>
#include <map>
#include <memory>
#include <mutex>
#include <set>
#include <string>
#include <unordered_map>
#include <vector>

#include <hardware/bluetooth.h>
#include <hardware/bt_gatt.h>

#include "service/hal/bluetooth_interface.h"
#include "service/logging_helpers.h"

extern "C" {
#include "osi/include/log.h"
#include "osi/include/osi.h"
}  // extern "C"

namespace {

const size_t kMaxGattAttributeSize = 512;
// TODO(icoolidge): Difficult to generalize without knowing how many attributes.
const int kNumBlueDroidHandles = 60;

// TODO(icoolidge): Support multiple instances
// TODO(armansito): Remove this variable. No point of having this if
// each bluetooth::gatt::Server instance already keeps a pointer to the
// ServerInternals that is associated with it (which is much cleaner). It looks
// like this variable exists because the btif callbacks don't allow the
// upper-layer to pass user data to them. We could:
//
//    1. Fix the btif callbacks so that some sort of continuation can be
//    attached to a callback. This might be a long shot since the callback
//    interface doesn't allow more than one caller to register its own callbacks
//    (which might be what we want though, since this would make the API more
//    flexible).
//
//    2. Allow creation of Server objects using a factory method that returns
//    the result asynchronously in a base::Callback. The RegisterServerCallback
//    provides an |app_uuid|, which can be used to store callback structures in
//    a map and lazily instantiate the Server and invoke the correct callback.
//    This is a general pattern that we should use throughout the daemon, since
//    all operations can timeout or fail and this is best reported in an
//    asynchronous base::Callback.
//
static bluetooth::gatt::ServerInternals *g_internal = nullptr;

enum { kPipeReadEnd = 0, kPipeWriteEnd = 1, kPipeNumEnds = 2 };

}  // namespace

namespace bluetooth {
namespace gatt {

struct Characteristic {
  UUID uuid;
  int blob_section;
  std::vector<uint8_t> blob;

  // Support synchronized blob updates by latching under mutex.
  std::vector<uint8_t> next_blob;
  bool next_blob_pending;
  bool notify;
};

struct ServerInternals {
  ServerInternals();
  ~ServerInternals();
  int Initialize();
  bt_status_t AddCharacteristic(
      const UUID& uuid,
      int properties,
      int permissions);

  // This maps API attribute UUIDs to BlueDroid handles.
  std::map<UUID, int> uuid_to_attribute;

  // The attribute cache, indexed by BlueDroid handles.
  std::unordered_map<int, Characteristic> characteristics;

  // Associate a control attribute with its value attribute.
  std::unordered_map<int, int> controlled_blobs;

  ScanResults scan_results;

  UUID last_write;
  const btgatt_interface_t *gatt;
  int server_if;
  int client_if;
  int service_handle;
  btgatt_srvc_id_t service_id;
  std::set<int> connections;

  std::mutex lock;
  std::condition_variable api_synchronize;
  int pipefd[kPipeNumEnds];
};

}  // namespace gatt
}  // namespace bluetooth

namespace {

/** Callback invoked in response to register_server */
void RegisterServerCallback(int status, int server_if, bt_uuid_t *app_uuid) {
  LOG_INFO(LOG_TAG, "%s: status:%d server_if:%d app_uuid:%p", __func__, status,
           server_if, app_uuid);

  g_internal->server_if = server_if;

  btgatt_srvc_id_t service_id;
  service_id.id.uuid = *app_uuid;
  service_id.id.inst_id = 0;
  service_id.is_primary = true;

  g_internal->gatt->server->add_service(
      server_if, &service_id, kNumBlueDroidHandles);
}

void ServiceAddedCallback(int status, int server_if, btgatt_srvc_id_t *srvc_id,
                          int srvc_handle) {
  LOG_INFO(LOG_TAG, "%s: status:%d server_if:%d gatt_srvc_id:%u srvc_handle:%d",
           __func__, status, server_if, srvc_id->id.inst_id, srvc_handle);

  std::lock_guard<std::mutex> lock(g_internal->lock);
  g_internal->server_if = server_if;
  g_internal->service_handle = srvc_handle;
  g_internal->service_id = *srvc_id;
  // This finishes the Initialize call.
  g_internal->api_synchronize.notify_one();
}

void RequestReadCallback(int conn_id, int trans_id, bt_bdaddr_t *bda,
                         int attr_handle, int attribute_offset_octets,
                         bool is_long) {
  std::lock_guard<std::mutex> lock(g_internal->lock);

  bluetooth::gatt::Characteristic &ch = g_internal->characteristics[attr_handle];

  // Latch next_blob to blob on a 'fresh' read.
  if (ch.next_blob_pending && attribute_offset_octets == 0 &&
      ch.blob_section == 0) {
    std::swap(ch.blob, ch.next_blob);
    ch.next_blob_pending = false;
  }

  const size_t blob_offset_octets =
      std::min(ch.blob.size(), ch.blob_section * kMaxGattAttributeSize);
  const size_t blob_remaining = ch.blob.size() - blob_offset_octets;
  const size_t attribute_size = std::min(kMaxGattAttributeSize, blob_remaining);

  std::string addr(BtAddrString(bda));
  LOG_INFO(LOG_TAG,
      "%s: connection:%d (%s) reading attr:%d attribute_offset_octets:%d "
      "blob_section:%u (is_long:%u)",
      __func__, conn_id, addr.c_str(), attr_handle, attribute_offset_octets,
      ch.blob_section, is_long);

  btgatt_response_t response;
  response.attr_value.len = 0;

  if (attribute_offset_octets < static_cast<int>(attribute_size)) {
    std::copy(ch.blob.begin() + blob_offset_octets + attribute_offset_octets,
              ch.blob.begin() + blob_offset_octets + attribute_size,
              response.attr_value.value);
    response.attr_value.len = attribute_size - attribute_offset_octets;
  }

  response.attr_value.handle = attr_handle;
  response.attr_value.offset = attribute_offset_octets;
  response.attr_value.auth_req = 0;
  g_internal->gatt->server->send_response(conn_id, trans_id, 0, &response);
}

void RequestWriteCallback(int conn_id, int trans_id, bt_bdaddr_t *bda,
                          int attr_handle, int attribute_offset, int length,
                          bool need_rsp, bool is_prep, uint8_t *value) {
  std::string addr(BtAddrString(bda));
  LOG_INFO(LOG_TAG,
      "%s: connection:%d (%s:trans:%d) write attr:%d attribute_offset:%d "
      "length:%d "
      "need_resp:%u is_prep:%u",
      __func__, conn_id, addr.c_str(), trans_id, attr_handle, attribute_offset,
      length, need_rsp, is_prep);

  std::lock_guard<std::mutex> lock(g_internal->lock);

  bluetooth::gatt::Characteristic &ch =
      g_internal->characteristics[attr_handle];

  ch.blob.resize(attribute_offset + length);

  std::copy(value, value + length, ch.blob.begin() + attribute_offset);

  auto target_blob = g_internal->controlled_blobs.find(attr_handle);
  // If this is a control attribute, adjust offset of the target blob.
  if (target_blob != g_internal->controlled_blobs.end() &&
      ch.blob.size() == 1u) {
    g_internal->characteristics[target_blob->second].blob_section = ch.blob[0];
    LOG_INFO(LOG_TAG, "%s: updating attribute %d blob_section to %u", __func__,
        target_blob->second, ch.blob[0]);
  } else if (!is_prep) {
    // This is a single frame characteristic write.
    // Notify upwards because we're done now.
    const bluetooth::UUID::UUID128Bit &attr_uuid = ch.uuid.GetFullBigEndian();
    ssize_t status;
    OSI_NO_INTR(status = write(g_internal->pipefd[kPipeWriteEnd],
                               attr_uuid.data(), attr_uuid.size()));
    if (-1 == status)
      LOG_ERROR(LOG_TAG, "%s: write failed: %s", __func__, strerror(errno));
  } else {
    // This is a multi-frame characteristic write.
    // Wait for an 'RequestExecWriteCallback' to notify completion.
    g_internal->last_write = ch.uuid;
  }

  // Respond only if needed.
  if (!need_rsp) return;

  btgatt_response_t response;
  response.attr_value.handle = attr_handle;
  response.attr_value.offset = attribute_offset;
  response.attr_value.len = length;
  response.attr_value.auth_req = 0;
  // Provide written data back to sender for the response.
  // Remote stacks use this to validate the success of the write.
  std::copy(value, value + length, response.attr_value.value);
  g_internal->gatt->server->send_response(conn_id, trans_id, 0, &response);
}

void RequestExecWriteCallback(int conn_id, int trans_id, bt_bdaddr_t *bda,
                              int exec_write) {
  std::string addr(BtAddrString(bda));
  LOG_INFO(LOG_TAG, "%s: connection:%d (%s:trans:%d) exec_write:%d", __func__,
      conn_id, addr.c_str(), trans_id, exec_write);

  // This 'response' data is unused for ExecWriteResponses.
  // It is only used to pass BlueDroid argument validation.
  btgatt_response_t response = {};
  g_internal->gatt->server->send_response(conn_id, trans_id, 0, &response);

  if (!exec_write)
    return;

  std::lock_guard<std::mutex> lock(g_internal->lock);
  // Communicate the attribute UUID as notification of a write update.
  const bluetooth::UUID::UUID128Bit uuid =
      g_internal->last_write.GetFullBigEndian();
  ssize_t status;
  OSI_NO_INTR(status = write(g_internal->pipefd[kPipeWriteEnd], uuid.data(),
                             uuid.size()));
  if (-1 == status)
    LOG_ERROR(LOG_TAG, "%s: write failed: %s", __func__, strerror(errno));
}

void ConnectionCallback(int conn_id, int server_if, int connected,
                        bt_bdaddr_t *bda) {
  std::string addr(BtAddrString(bda));
  LOG_INFO(LOG_TAG, "%s: connection:%d server_if:%d connected:%d addr:%s",
      __func__, conn_id, server_if, connected, addr.c_str());
  if (connected == 1) {
    g_internal->connections.insert(conn_id);
  } else if (connected == 0) {
    g_internal->connections.erase(conn_id);
  }
}

void CharacteristicAddedCallback(int status, int server_if, bt_uuid_t *uuid,
                                 int srvc_handle, int char_handle) {
  LOG_INFO(LOG_TAG,
      "%s: status:%d server_if:%d service_handle:%d char_handle:%d", __func__,
      status, server_if, srvc_handle, char_handle);

  bluetooth::UUID id(*uuid);

  std::lock_guard<std::mutex> lock(g_internal->lock);

  g_internal->uuid_to_attribute[id] = char_handle;
  g_internal->characteristics[char_handle].uuid = id;
  g_internal->characteristics[char_handle].blob_section = 0;

  // This terminates an AddCharacteristic.
  g_internal->api_synchronize.notify_one();
}

void DescriptorAddedCallback(int status, int server_if, bt_uuid_t *uuid,
                             int srvc_handle, int descr_handle) {
  LOG_INFO(LOG_TAG,
      "%s: status:%d server_if:%d service_handle:%d uuid[0]:%u "
      "descr_handle:%d",
      __func__, status, server_if, srvc_handle, uuid->uu[0], descr_handle);
}

void ServiceStartedCallback(int status, int server_if, int srvc_handle) {
  LOG_INFO(LOG_TAG, "%s: status:%d server_if:%d srvc_handle:%d", __func__,
      status, server_if, srvc_handle);

  // The UUID provided here is unimportant, and is only used to satisfy
  // BlueDroid.
  // It must be different than any other registered UUID.
  bt_uuid_t client_id = g_internal->service_id.id.uuid;
  ++client_id.uu[15];

  bt_status_t btstat = g_internal->gatt->client->register_client(&client_id);
  if (btstat != BT_STATUS_SUCCESS) {
    LOG_ERROR(LOG_TAG, "%s: Failed to register client", __func__);
  }
}

void RegisterClientCallback(int status, int client_if, bt_uuid_t *app_uuid) {
  LOG_INFO(LOG_TAG, "%s: status:%d client_if:%d uuid[0]:%u", __func__, status,
      client_if, app_uuid->uu[0]);
  g_internal->client_if = client_if;

  // Setup our advertisement. This has no callback.
  bt_status_t btstat = g_internal->gatt->client->set_adv_data(
      client_if, false, /* beacon, not scan response */
      false,            /* name */
      false,            /* no txpower */
      2, 2,             /* interval */
      0,                /* appearance */
      0, nullptr,       /* no mfg data */
      0, nullptr,       /* no service data */
      0, nullptr /* no service id yet */);
  if (btstat != BT_STATUS_SUCCESS) {
    LOG_ERROR(LOG_TAG, "Failed to set advertising data");
    return;
  }

  // TODO(icoolidge): Deprecated, use multi-adv interface.
  // This calls back to ListenCallback.
  btstat = g_internal->gatt->client->listen(client_if, true);
  if (btstat != BT_STATUS_SUCCESS) {
    LOG_ERROR(LOG_TAG, "Failed to start listening");
  }
}

void ListenCallback(int status, int client_if) {
  LOG_INFO(LOG_TAG, "%s: status:%d client_if:%d", __func__, status, client_if);
  // This terminates a Start call.
  std::lock_guard<std::mutex> lock(g_internal->lock);
  g_internal->api_synchronize.notify_one();
}

void ServiceStoppedCallback(int status, int server_if, int srvc_handle) {
  LOG_INFO(LOG_TAG, "%s: status:%d server_if:%d srvc_handle:%d", __func__,
      status, server_if, srvc_handle);
  // This terminates a Stop call.
  // TODO(icoolidge): make this symmetric with start
  std::lock_guard<std::mutex> lock(g_internal->lock);
  g_internal->api_synchronize.notify_one();
}

void ScanResultCallback(bt_bdaddr_t *bda, int rssi, uint8_t *adv_data) {
  std::string addr(BtAddrString(bda));
  (void)adv_data;
  std::lock_guard<std::mutex> lock(g_internal->lock);
  g_internal->scan_results[addr] = rssi;
}

void ClientConnectCallback(int conn_id, int status, int client_if,
                           bt_bdaddr_t *bda) {
  std::string addr(BtAddrString(bda));
  LOG_INFO(LOG_TAG, "%s: conn_id:%d status:%d client_if:%d %s", __func__,
      conn_id, status, client_if, addr.c_str());
}

void ClientDisconnectCallback(int conn_id, int status, int client_if,
                              bt_bdaddr_t *bda) {
  std::string addr(BtAddrString(bda));
  LOG_INFO(LOG_TAG, "%s: conn_id:%d status:%d client_if:%d %s", __func__,
      conn_id, status, client_if, addr.c_str());
}

void IndicationSentCallback(UNUSED_ATTR int conn_id,
                            UNUSED_ATTR int status) {
  // TODO(icoolidge): what to do
}

void ResponseConfirmationCallback(UNUSED_ATTR int status,
                                  UNUSED_ATTR int handle) {
  // TODO(icoolidge): what to do
}

const btgatt_server_callbacks_t gatt_server_callbacks = {
    RegisterServerCallback,
    ConnectionCallback,
    ServiceAddedCallback,
    nullptr, /* included_service_added_cb */
    CharacteristicAddedCallback,
    DescriptorAddedCallback,
    ServiceStartedCallback,
    ServiceStoppedCallback,
    nullptr, /* service_deleted_cb */
    RequestReadCallback,
    RequestWriteCallback,
    RequestExecWriteCallback,
    ResponseConfirmationCallback,
    IndicationSentCallback,
    nullptr, /* congestion_cb*/
    nullptr, /* mtu_changed_cb */
};

// TODO(eisenbach): Refactor GATT interface to not require servers
// to refer to the client interface.
const btgatt_client_callbacks_t gatt_client_callbacks = {
    RegisterClientCallback,
    ScanResultCallback,
    ClientConnectCallback,
    ClientDisconnectCallback,
    nullptr, /* search_complete_cb; */
    nullptr, /* register_for_notification_cb; */
    nullptr, /* notify_cb; */
    nullptr, /* read_characteristic_cb; */
    nullptr, /* write_characteristic_cb; */
    nullptr, /* read_descriptor_cb; */
    nullptr, /* write_descriptor_cb; */
    nullptr, /* execute_write_cb; */
    nullptr, /* read_remote_rssi_cb; */
    ListenCallback,
    nullptr, /* configure_mtu_cb; */
    nullptr, /* scan_filter_cfg_cb; */
    nullptr, /* scan_filter_param_cb; */
    nullptr, /* scan_filter_status_cb; */
    nullptr, /* multi_adv_enable_cb */
    nullptr, /* multi_adv_update_cb; */
    nullptr, /* multi_adv_data_cb*/
    nullptr, /* multi_adv_disable_cb; */
    nullptr, /* congestion_cb; */
    nullptr, /* batchscan_cfg_storage_cb; */
    nullptr, /* batchscan_enb_disable_cb; */
    nullptr, /* batchscan_reports_cb; */
    nullptr, /* batchscan_threshold_cb; */
    nullptr, /* track_adv_event_cb; */
    nullptr, /* scan_parameter_setup_completed_cb; */
    nullptr, /* get_gatt_db_cb; */
    nullptr, /* services_removed_cb */
    nullptr, /* services_added_cb */
};

const btgatt_callbacks_t gatt_callbacks = {
    /** Set to sizeof(btgatt_callbacks_t) */
    sizeof(btgatt_callbacks_t),

    /** GATT Client callbacks */
    &gatt_client_callbacks,

    /** GATT Server callbacks */
    &gatt_server_callbacks};

}  // namespace

namespace bluetooth {
namespace gatt {

int ServerInternals::Initialize() {
  // Get the interface to the GATT profile.
  const bt_interface_t* bt_iface =
      hal::BluetoothInterface::Get()->GetHALInterface();
  gatt = reinterpret_cast<const btgatt_interface_t *>(
      bt_iface->get_profile_interface(BT_PROFILE_GATT_ID));
  if (!gatt) {
    LOG_ERROR(LOG_TAG, "Error getting GATT interface");
    return -1;
  }

  bt_status_t btstat = gatt->init(&gatt_callbacks);
  if (btstat != BT_STATUS_SUCCESS) {
    LOG_ERROR(LOG_TAG, "Failed to initialize gatt interface");
    return -1;
  }

  int status = pipe(pipefd);
  if (status == -1) {
    LOG_ERROR(LOG_TAG, "pipe creation failed: %s", strerror(errno));
    return -1;
  }

  return 0;
}

bt_status_t ServerInternals::AddCharacteristic(
    const UUID& uuid,
    int properties,
    int permissions) {
  bt_uuid_t c_uuid = uuid.GetBlueDroid();
  return gatt->server->add_characteristic(
      server_if, service_handle, &c_uuid, properties, permissions);
}

ServerInternals::ServerInternals()
    : gatt(nullptr),
      server_if(0),
      client_if(0),
      service_handle(0),
      pipefd{INVALID_FD, INVALID_FD} {}

ServerInternals::~ServerInternals() {
  if (pipefd[0] != INVALID_FD)
    close(pipefd[0]);
  if (pipefd[1] != INVALID_FD)
    close(pipefd[1]);

  gatt->server->delete_service(server_if, service_handle);
  gatt->server->unregister_server(server_if);
  gatt->client->unregister_client(client_if);
}

Server::Server() : internal_(nullptr) {}

Server::~Server() {}

bool Server::Initialize(const UUID& service_id, int* gatt_pipe) {
  internal_.reset(new ServerInternals);
  if (!internal_) {
    LOG_ERROR(LOG_TAG, "Error creating internals");
    return false;
  }
  g_internal = internal_.get();

  std::unique_lock<std::mutex> lock(internal_->lock);
  int status = internal_->Initialize();
  if (status) {
    LOG_ERROR(LOG_TAG, "Error initializing internals");
    return false;
  }

  bt_uuid_t uuid = service_id.GetBlueDroid();

  bt_status_t btstat = internal_->gatt->server->register_server(&uuid);
  if (btstat != BT_STATUS_SUCCESS) {
    LOG_ERROR(LOG_TAG, "Failed to register server");
    return false;
  }

  internal_->api_synchronize.wait(lock);
  // TODO(icoolidge): Better error handling.
  if (internal_->server_if == 0) {
    LOG_ERROR(LOG_TAG, "Initialization of server failed");
    return false;
  }

  *gatt_pipe = internal_->pipefd[kPipeReadEnd];
  LOG_INFO(LOG_TAG, "Server Initialize succeeded");
  return true;
}

bool Server::SetAdvertisement(const std::vector<UUID>& ids,
                              const std::vector<uint8_t>& service_data,
                              const std::vector<uint8_t>& manufacturer_data,
                              bool transmit_name) {
  std::vector<uint8_t> id_data;
  auto mutable_manufacturer_data = manufacturer_data;
  auto mutable_service_data = service_data;

  for (const UUID &id : ids) {
    const auto le_id = id.GetFullLittleEndian();
    id_data.insert(id_data.end(), le_id.begin(), le_id.end());
  }

  std::lock_guard<std::mutex> lock(internal_->lock);

  // Setup our advertisement. This has no callback.
  bt_status_t btstat = internal_->gatt->client->set_adv_data(
      internal_->client_if, false, /* beacon, not scan response */
      transmit_name,               /* name */
      false,                       /* no txpower */
      2, 2,                        /* interval */
      0,                           /* appearance */
      mutable_manufacturer_data.size(),
      reinterpret_cast<char *>(mutable_manufacturer_data.data()),
      mutable_service_data.size(),
      reinterpret_cast<char *>(mutable_service_data.data()), id_data.size(),
      reinterpret_cast<char *>(id_data.data()));
  if (btstat != BT_STATUS_SUCCESS) {
    LOG_ERROR(LOG_TAG, "Failed to set advertising data");
    return false;
  }
  return true;
}

bool Server::SetScanResponse(const std::vector<UUID>& ids,
                             const std::vector<uint8_t>& service_data,
                             const std::vector<uint8_t>& manufacturer_data,
                             bool transmit_name) {
  std::vector<uint8_t> id_data;
  auto mutable_manufacturer_data = manufacturer_data;
  auto mutable_service_data = service_data;

  for (const UUID &id : ids) {
    const auto le_id = id.GetFullLittleEndian();
    id_data.insert(id_data.end(), le_id.begin(), le_id.end());
  }

  std::lock_guard<std::mutex> lock(internal_->lock);

  // Setup our advertisement. This has no callback.
  bt_status_t btstat = internal_->gatt->client->set_adv_data(
      internal_->client_if, true, /* scan response */
      transmit_name,              /* name */
      false,                      /* no txpower */
      2, 2,                       /* interval */
      0,                          /* appearance */
      mutable_manufacturer_data.size(),
      reinterpret_cast<char *>(mutable_manufacturer_data.data()),
      mutable_service_data.size(),
      reinterpret_cast<char *>(mutable_service_data.data()), id_data.size(),
      reinterpret_cast<char *>(id_data.data()));
  if (btstat != BT_STATUS_SUCCESS) {
    LOG_ERROR(LOG_TAG, "Failed to set scan response data");
    return false;
  }
  return true;
}

bool Server::AddCharacteristic(
    const UUID &id, int properties, int permissions) {
  std::unique_lock<std::mutex> lock(internal_->lock);
  bt_status_t btstat = internal_->AddCharacteristic(
      id, properties, permissions);
  if (btstat != BT_STATUS_SUCCESS) {
    LOG_ERROR(LOG_TAG, "Failed to add characteristic to service: 0x%04x",
              internal_->service_handle);
    return false;
  }
  internal_->api_synchronize.wait(lock);
  const int handle = internal_->uuid_to_attribute[id];
  internal_->characteristics[handle].notify = properties & kPropertyNotify;
  return true;
}

bool Server::AddBlob(const UUID &id, const UUID &control_id, int properties,
                    int permissions) {
  std::unique_lock<std::mutex> lock(internal_->lock);

  // First, add the primary attribute (characteristic value)
  bt_status_t btstat = internal_->AddCharacteristic(
      id, properties, permissions);
  if (btstat != BT_STATUS_SUCCESS) {
    LOG_ERROR(LOG_TAG, "Failed to set scan response data");
    return false;
  }

  internal_->api_synchronize.wait(lock);

  // Next, add the secondary attribute (blob control).
  // Control attributes have fixed permissions/properties.
  btstat = internal_->AddCharacteristic(
      control_id,
      kPropertyRead | kPropertyWrite,
      kPermissionRead | kPermissionWrite);
  internal_->api_synchronize.wait(lock);

  // Finally, associate the control attribute with the value attribute.
  // Also, initialize the control attribute to a readable zero.
  const int control_attribute = internal_->uuid_to_attribute[control_id];
  const int blob_attribute = internal_->uuid_to_attribute[id];
  internal_->controlled_blobs[control_attribute] = blob_attribute;
  internal_->characteristics[blob_attribute].notify =
      properties & kPropertyNotify;

  Characteristic &ctrl = internal_->characteristics[control_attribute];
  ctrl.next_blob.clear();
  ctrl.next_blob.push_back(0);
  ctrl.next_blob_pending = true;
  ctrl.blob_section = 0;
  ctrl.notify = false;
  return true;
}

bool Server::Start() {
  std::unique_lock<std::mutex> lock(internal_->lock);
  bt_status_t btstat = internal_->gatt->server->start_service(
      internal_->server_if, internal_->service_handle, GATT_TRANSPORT_LE);
  if (btstat != BT_STATUS_SUCCESS) {
    LOG_ERROR(LOG_TAG, "Failed to start service with handle: 0x%04x",
              internal_->service_handle);
    return false;
  }
  internal_->api_synchronize.wait(lock);
  return true;
}

bool Server::Stop() {
  std::unique_lock<std::mutex> lock(internal_->lock);
  bt_status_t btstat = internal_->gatt->server->stop_service(
      internal_->server_if, internal_->service_handle);
  if (btstat != BT_STATUS_SUCCESS) {
    LOG_ERROR(LOG_TAG, "Failed to stop service with handle: 0x%04x",
              internal_->service_handle);
    return false;
  }
  internal_->api_synchronize.wait(lock);
  return true;
}

bool Server::ScanEnable() {
  bt_status_t btstat = internal_->gatt->client->scan(true);
  if (btstat) {
    LOG_ERROR(LOG_TAG, "Enable scan failed: %d", btstat);
    return false;
  }
  return true;
}

bool Server::ScanDisable() {
  bt_status_t btstat = internal_->gatt->client->scan(false);
  if (btstat) {
    LOG_ERROR(LOG_TAG, "Disable scan failed: %d", btstat);
    return false;
  }
  return true;
}

bool Server::GetScanResults(ScanResults *results) {
  std::lock_guard<std::mutex> lock(internal_->lock);
  *results = internal_->scan_results;
  return true;
}

bool Server::SetCharacteristicValue(const UUID &id,
                              const std::vector<uint8_t> &value) {
  std::lock_guard<std::mutex> lock(internal_->lock);
  const int attribute_id = internal_->uuid_to_attribute[id];
  Characteristic &ch = internal_->characteristics[attribute_id];
  ch.next_blob = value;
  ch.next_blob_pending = true;

  if (!ch.notify)
    return true;

  for (auto connection : internal_->connections) {
    char dummy = 0;
    internal_->gatt->server->send_indication(internal_->server_if,
                                             attribute_id,
                                             connection,
                                             sizeof(dummy),
                                             true,
                                             &dummy);
  }
  return true;
}

bool Server::GetCharacteristicValue(const UUID &id, std::vector<uint8_t> *value) {
  std::lock_guard<std::mutex> lock(internal_->lock);
  const int attribute_id = internal_->uuid_to_attribute[id];
  *value = internal_->characteristics[attribute_id].blob;
  return true;
}

}  // namespace gatt
}  // namespace bluetooth
