//
//  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 <base/bind.h>
#include <algorithm>
#include <array>
#include <condition_variable>
#include <map>
#include <memory>
#include <mutex>
#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

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

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

#include "osi/include/log.h"
#include "osi/include/osi.h"

namespace {

const size_t kMaxGattAttributeSize = 512;
std::vector<btgatt_db_element_t> pending_svc_decl;
std::unordered_set<int> blob_index;

// 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

void DoNothing(uint8_t p) {}

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, uint8_t properties,
                                uint16_t 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;
  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;
  pending_svc_decl.push_back(
      {.type = BTGATT_DB_PRIMARY_SERVICE, .uuid = *app_uuid});
}

void ServiceAddedCallback(int status, int server_if,
                          std::vector<btgatt_db_element_t> service) {
  LOG_INFO(LOG_TAG, "%s: status:%d server_if:%d count:%zu svc_handle:%d",
           __func__, status, server_if, service.size(),
           service[0].attribute_handle);

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

  g_internal->service_handle = service[0].attribute_handle;

  uint16_t prev_char_handle = 0;
  uint16_t prev_char_properties = 0;
  for (size_t i = 1; i < service.size(); i++) {
    const btgatt_db_element_t& el = service[i];
    if (el.type == BTGATT_DB_DESCRIPTOR) {
      LOG_INFO(LOG_TAG, "%s: descr_handle:%d", __func__, el.attribute_handle);
    } else if (el.type == BTGATT_DB_CHARACTERISTIC) {
      bluetooth::UUID id(el.uuid);
      uint16_t char_handle = el.attribute_handle;

      LOG_INFO(LOG_TAG, "%s: char_handle:%d", __func__, char_handle);

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

      // If the added characteristic is blob
      if (blob_index.find(i) != blob_index.end()) {
        // Finally, associate the control attribute with the value attribute.
        // Also, initialize the control attribute to a readable zero.
        const uint16_t control_attribute = char_handle;
        const uint16_t blob_attribute = prev_char_handle;
        g_internal->controlled_blobs[control_attribute] = blob_attribute;
        g_internal->characteristics[blob_attribute].notify =
            prev_char_properties & bluetooth::gatt::kPropertyNotify;

        bluetooth::gatt::Characteristic& ctrl =
            g_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;
      }
      prev_char_handle = char_handle;
      prev_char_properties = el.properties;
    }
  }

  pending_svc_decl.clear();
  blob_index.clear();

  // 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 = service[0].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 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, bool need_rsp,
                          bool is_prep, std::vector<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:%zu "
           "need_resp:%u is_prep:%u",
           __func__, conn_id, addr.c_str(), trans_id, attr_handle,
           attribute_offset, value.size(), 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 + value.size());

  std::copy(value.begin(), value.end(), 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 = value.size();
  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.begin(), value.end(), 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 EnableAdvertisingCallback(uint8_t status) {
  LOG_INFO(LOG_TAG, "%s: status:%d", __func__, status);
  // This terminates a Start call.
  std::lock_guard<std::mutex> lock(g_internal->lock);
  g_internal->api_synchronize.notify_one();
}

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.
  g_internal->gatt->advertiser->SetData(0 /* std_inst */, false,
                                        {/*TODO: put inverval 2,2 here*/},
                                        base::Bind(&DoNothing));

  g_internal->gatt->advertiser->Enable(
      0 /* std_inst */, true, base::Bind(&EnableAdvertisingCallback),
      0 /* no duration */, 0 /* no maxExtAdvEvent*/, base::Bind(&DoNothing));
}

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(uint16_t ble_evt_type, uint8_t addr_type,
                        bt_bdaddr_t* bda, uint8_t ble_primary_phy,
                        uint8_t ble_secondary_phy, uint8_t ble_advertising_sid,
                        int8_t ble_tx_power, int8_t rssi,
                        uint16_t ble_periodic_adv_int,
                        std::vector<uint8_t> adv_data) {
  std::string addr(BtAddrString(bda));
  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,
    ServiceStoppedCallback,
    nullptr, /* service_deleted_cb */
    RequestReadCallback,
    RequestReadCallback,
    RequestWriteCallback,
    RequestWriteCallback,
    RequestExecWriteCallback,
    ResponseConfirmationCallback,
    IndicationSentCallback,
    nullptr, /* congestion_cb*/
    nullptr, /* mtu_changed_cb */
    nullptr, /* phy_update_cb */
    nullptr, /* conn_update_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,
    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; */
    nullptr, /* configure_mtu_cb; */
    nullptr, /* congestion_cb; */
    nullptr, /* get_gatt_db_cb; */
    nullptr, /* services_removed_cb */
    nullptr, /* services_added_cb */
    nullptr, /* phy_update_cb */
    nullptr, /* conn_update_cb */
};

const btgatt_scanner_callbacks_t gatt_scanner_callbacks = {
    ScanResultCallback,
    nullptr, /* batchscan_reports_cb; */
    nullptr, /* batchscan_threshold_cb; */
    nullptr, /* track_adv_event_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,

    /** GATT Server callbacks */
    &gatt_scanner_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,
                                               uint8_t properties,
                                               uint16_t permissions) {
  bt_uuid_t c_uuid = uuid.GetBlueDroid();

  pending_svc_decl.push_back({.type = BTGATT_DB_CHARACTERISTIC,
                              .uuid = c_uuid,
                              .properties = properties,
                              .permissions = permissions});
  return BT_STATUS_SUCCESS;
}

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;
  // const auto& mutable_manufacturer_data = manufacturer_data;
  // const 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.
  internal_->gatt->advertiser->SetData(0, false, /* beacon, not scan response */
                                       {}, base::Bind(&DoNothing));
  // transmit_name,               /* name */
  // 2, 2,                         interval
  // mutable_manufacturer_data,
  // mutable_service_data,
  // id_data);
  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;
  // const auto& mutable_manufacturer_data = manufacturer_data;
  // const 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.
  internal_->gatt->advertiser->SetData(0, true, /* scan response */
                                       {}, base::Bind(&DoNothing));
  // transmit_name,              /* name */
  // false,                      /* no txpower */
  // 2, 2,                        interval
  // 0,                          /* appearance */
  // mutable_manufacturer_data,
  // mutable_service_data,
  // id_data);
  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;
  }

  // Next, add the secondary attribute (blob control).
  // Control attributes have fixed permissions/properties.
  // Remember position at which blob was added.
  blob_index.insert(pending_svc_decl.size());
  btstat =
      internal_->AddCharacteristic(control_id, kPropertyRead | kPropertyWrite,
                                   kPermissionRead | kPermissionWrite);

  return true;
}

bool Server::Start() {
  std::unique_lock<std::mutex> lock(internal_->lock);
  bt_status_t btstat = internal_->gatt->server->add_service(
      internal_->server_if, pending_svc_decl);
  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() {
  internal_->gatt->scanner->Scan(true);
  return true;
}

bool Server::ScanDisable() {
  internal_->gatt->scanner->Scan(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) {
    internal_->gatt->server->send_indication(internal_->server_if, attribute_id,
                                             connection, true, {0});
  }
  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
