//
//  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,
                            const 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, const RawAddress& 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, const RawAddress& 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, const RawAddress& 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,
                        const RawAddress& 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,
                            const 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,
                        RawAddress* 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,
                           const RawAddress& 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,
                              const RawAddress& 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
