Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  bluetooth_hci.cc

  Sprache: C
 

//
// Copyright 2017 The Android Open Source Project
//
// 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 "android.hardware.bluetooth@1.1.sim"

#include "bluetooth_hci.h"

#include <cutils/properties.h>
#include <log/log.h>
#include <netdb.h>
#include <netinet/in.h>
#include <string.h>

#include "hci_internals.h"
#include "model/devices/hci_device.h"
#include "model/devices/link_layer_socket_device.h"
#include "model/hci/hci_socket_transport.h"

namespace android {
namespace hardware {
namespace bluetooth {
namespace V1_1 {
namespace sim {

using android::hardware::hidl_vec;
using ::bluetooth::hci::Address;
using rootcanal::AsyncTaskId;
using rootcanal::DualModeController;
using rootcanal::HciDevice;
using rootcanal::HciSocketTransport;
using rootcanal::LinkLayerSocketDevice;
using rootcanal::TaskCallback;

namespace {

bool BtTestConsoleEnabled() {
  // Assume enabled by default.
  return property_get_bool("vendor.bt.rootcanal_test_console"true);
}

}  // namespace

BluetoothHci::BluetoothHci() : death_recipient_(new BluetoothDeathRecipient(this)) {}

Return<void> BluetoothHci::initialize(const sp<V1_0::IBluetoothHciCallbacks>& cb) {
  return initialize_impl(cb, nullptr);
}

Return<void> BluetoothHci::initialize_1_1(const sp<V1_1::IBluetoothHciCallbacks>& cb) {
  return initialize_impl(cb, cb);
}

Return<void> BluetoothHci::initialize_impl(const sp<V1_0::IBluetoothHciCallbacks>& cb,
                                           const sp<V1_1::IBluetoothHciCallbacks>& cb_1_1) {
  ALOGI("%s", __func__);
  if (cb == nullptr) {
    ALOGE("cb == nullptr! -> Unable to call initializationComplete(ERR)");
    return Void();
  }

  death_recipient_->setHasDied(false);
  auto link_ret = cb->linkToDeath(death_recipient_, 0);
  ALOG_ASSERT(link_ret.isOk(), "Error calling linkToDeath.");

  test_channel_transport_.RegisterCommandHandler([this](const std::string& name,
                                                        const std::vector<std::string>& args) {
    async_manager_.ExecAsync(user_id_, std::chrono::milliseconds(0),
                             [this, name, args]() { test_channel_.HandleCommand(name, args); });
  });

  controller_ = std::make_shared<DualModeController>();

  char mac_property[PROPERTY_VALUE_MAX] = "";
  property_get("vendor.bt.rootcanal_mac_address", mac_property, "3C:5A:B4:01:02:03");
  auto addr = Address::FromString(std::string(mac_property));
  if (addr) {
    controller_->SetAddress(*addr);
  } else {
    LOG_ALWAYS_FATAL("Invalid address: %s", mac_property);
  }

  controller_->RegisterEventChannel([this, cb](std::shared_ptr<std::vector<uint8_t>> packet) {
    hidl_vec<uint8_t> hci_event(packet->begin(), packet->end());
    auto ret = cb->hciEventReceived(hci_event);
    if (!ret.isOk()) {
      ALOGE("Error sending event callback");
      if (!death_recipient_->getHasDied()) {
        ALOGE("Closing");
        close();
      }
    }
  });

  controller_->RegisterAclChannel([this, cb](std::shared_ptr<std::vector<uint8_t>> packet) {
    hidl_vec<uint8_t> acl_packet(packet->begin(), packet->end());
    auto ret = cb->aclDataReceived(acl_packet);
    if (!ret.isOk()) {
      ALOGE("Error sending acl callback");
      if (!death_recipient_->getHasDied()) {
        ALOGE("Closing");
        close();
      }
    }
  });

  controller_->RegisterScoChannel([this, cb](std::shared_ptr<std::vector<uint8_t>> packet) {
    hidl_vec<uint8_t> sco_packet(packet->begin(), packet->end());
    auto ret = cb->scoDataReceived(sco_packet);
    if (!ret.isOk()) {
      ALOGE("Error sending sco callback");
      if (!death_recipient_->getHasDied()) {
        ALOGE("Closing");
        close();
      }
    }
  });

  if (cb_1_1 != nullptr) {
    controller_->RegisterIsoChannel([this, cb_1_1](std::shared_ptr<std::vector<uint8_t>> packet) {
      hidl_vec<uint8_t> iso_packet(packet->begin(), packet->end());
      auto ret = cb_1_1->isoDataReceived(iso_packet);
      if (!ret.isOk()) {
        ALOGE("Error sending iso callback");
        if (!death_recipient_->getHasDied()) {
          ALOGE("Closing");
          close();
        }
      }
    });
  }

  // Add the controller as a device in the model.
  size_t controller_index = test_model_.AddDevice(controller_);
  size_t low_energy_phy_index = test_model_.AddPhy(rootcanal::Phy::Type::LOW_ENERGY);
  size_t classic_phy_index = test_model_.AddPhy(rootcanal::Phy::Type::BR_EDR);
  test_model_.AddDeviceToPhy(controller_index, low_energy_phy_index);
  test_model_.AddDeviceToPhy(controller_index, classic_phy_index);
  test_model_.SetTimerPeriod(std::chrono::milliseconds(10));
  test_model_.StartTimer();

  // Send responses to logcat if the test channel is not configured.
  test_channel_.RegisterSendResponse(
          [](const std::string& response) { ALOGI("No test channel yet: %s", response.c_str()); });

  if (BtTestConsoleEnabled()) {
    test_socket_server_ = std::make_shared<net::PosixAsyncSocketServer>(6111, &async_manager_);
    hci_socket_server_ = std::make_shared<net::PosixAsyncSocketServer>(6211, &async_manager_);
    link_socket_server_ = std::make_shared<net::PosixAsyncSocketServer>(6311, &async_manager_);
    connector_ = std::make_shared<net::PosixAsyncSocketConnector>(&async_manager_);
    SetUpTestChannel();
    SetUpHciServer([this](std::shared_ptr<AsyncDataChannel> socket, AsyncDataChannelServer* srv) {
      auto transport = HciSocketTransport::Create(socket);
      test_model_.AddHciConnection(HciDevice::Create(transport, rootcanal::ControllerProperties()));
      srv->StartListening();
    });
    SetUpLinkLayerServer([this](std::shared_ptr<AsyncDataChannel> socket,
                                AsyncDataChannelServer* srv) {
      auto phy_type = Phy::Type::BR_EDR;
      test_model_.AddLinkLayerConnection(LinkLayerSocketDevice::Create(socket, phy_type), phy_type);
      srv->StartListening();
    });
  } else {
    // This should be configurable in the future.
    ALOGI("Adding Beacons so the scan list is not empty.");
    test_channel_.AddDevice({"beacon""be:ac:10:00:00:01""1000"});
    test_model_.AddDeviceToPhy(controller_index + 1, low_energy_phy_index);
    test_channel_.AddDevice({"beacon""be:ac:10:00:00:02""1000"});
    test_model_.AddDeviceToPhy(controller_index + 2, low_energy_phy_index);
    test_channel_.AddDevice({"scripted_beacon""5b:ea:c1:00:00:03",
                             "/data/vendor/bluetooth/bluetooth_sim_ble_playback_file",
                             "/data/vendor/bluetooth/bluetooth_sim_ble_playback_events"});
    test_model_.AddDeviceToPhy(controller_index + 3, low_energy_phy_index);
    test_channel_.List({});
  }

  unlink_cb_ = [cb](sp<BluetoothDeathRecipient>& death_recipient) {
    if (death_recipient->getHasDied()) {
      ALOGI("Skipping unlink call, service died.");
    } else {
      auto ret = cb->unlinkToDeath(death_recipient);
      if (!ret.isOk()) {
        ALOG_ASSERT(death_recipient_->getHasDied(),
                    "Error calling unlink, but no death notification.");
      }
    }
  };

  auto init_ret = cb->initializationComplete(V1_0::Status::SUCCESS);
  if (!init_ret.isOk()) {
    ALOG_ASSERT(death_recipient_->getHasDied(),
                "Error sending init callback, but no death notification.");
  }
  return Void();
}

Return<void> BluetoothHci::close() {
  ALOGI("%s", __func__);
  test_model_.Reset();
  return Void();
}

Return<void> BluetoothHci::sendHciCommand(const hidl_vec<uint8_t>& packet) {
  async_manager_.ExecAsync(user_id_, std::chrono::milliseconds(0), [this, packet]() {
    std::shared_ptr<std::vector<uint8_t>> packet_copy =
            std::shared_ptr<std::vector<uint8_t>>(new std::vector<uint8_t>(packet));
    controller_->HandleCommand(packet_copy);
  });
  return Void();
}

Return<void> BluetoothHci::sendAclData(const hidl_vec<uint8_t>& packet) {
  async_manager_.ExecAsync(user_id_, std::chrono::milliseconds(0), [this, packet]() {
    std::shared_ptr<std::vector<uint8_t>> packet_copy =
            std::shared_ptr<std::vector<uint8_t>>(new std::vector<uint8_t>(packet));
    controller_->HandleAcl(packet_copy);
  });
  return Void();
}

Return<void> BluetoothHci::sendScoData(const hidl_vec<uint8_t>& packet) {
  async_manager_.ExecAsync(user_id_, std::chrono::milliseconds(0), [this, packet]() {
    std::shared_ptr<std::vector<uint8_t>> packet_copy =
            std::shared_ptr<std::vector<uint8_t>>(new std::vector<uint8_t>(packet));
    controller_->HandleSco(packet_copy);
  });
  return Void();
}

Return<void> BluetoothHci::sendIsoData(const hidl_vec<uint8_t>& packet) {
  async_manager_.ExecAsync(user_id_, std::chrono::milliseconds(0), [this, packet]() {
    std::shared_ptr<std::vector<uint8_t>> packet_copy =
            std::shared_ptr<std::vector<uint8_t>>(new std::vector<uint8_t>(packet));
    controller_->HandleIso(packet_copy);
  });
  return Void();
}

void BluetoothHci::SetUpHciServer(ConnectCallback connection_callback) {
  test_channel_.RegisterSendResponse([](const std::string& response) {
    ALOGI("No HCI Response channel: %s", response.c_str());
  });

  if (!remote_hci_transport_.SetUp(hci_socket_server_, connection_callback)) {
    ALOGE("Remote HCI channel SetUp failed.");
    return;
  }
}

void BluetoothHci::SetUpLinkLayerServer(ConnectCallback connection_callback) {
  remote_link_layer_transport_.SetUp(link_socket_server_, connection_callback);

  test_channel_.RegisterSendResponse([](const std::string& response) {
    ALOGI("No LinkLayer Response channel: %s", response.c_str());
  });
}

std::shared_ptr<Device> BluetoothHci::ConnectToRemoteServer(const std::string& server, int port,
                                                            Phy::Type phy_type) {
  auto socket = connector_->ConnectToRemoteServer(server, port);
  if (!socket->Connected()) {
    return nullptr;
  }
  return LinkLayerSocketDevice::Create(socket, phy_type);
}

void BluetoothHci::SetUpTestChannel() {
  bool transport_configured = test_channel_transport_.SetUp(
          test_socket_server_,
          [this](std::shared_ptr<AsyncDataChannel> conn_fd, AsyncDataChannelServer*) {
            ALOGI("Test channel connection accepted.");
            test_channel_.RegisterSendResponse([this, conn_fd](const std::string& response) {
              test_channel_transport_.SendResponse(conn_fd, response);
            });

            conn_fd->WatchForNonBlockingRead([this](AsyncDataChannel* conn_fd) {
              test_channel_transport_.OnCommandReady(conn_fd, []() {});
            });
            return false;
          });
  test_channel_.RegisterSendResponse(
          [](const std::string& response) { ALOGI("No test channel: %s", response.c_str()); });

  if (!transport_configured) {
    ALOGE("Test channel SetUp failed.");
    return;
  }

  ALOGI("Test channel SetUp() successful");
}

/* Fallback to shared library if there is no service. */
IBluetoothHci* HIDL_FETCH_IBluetoothHci(const char/* name */) { return new BluetoothHci(); }

}  // namespace sim
}  // namespace V1_1
}  // namespace bluetooth
}  // namespace hardware
}  // namespace android

Messung V0.5 in Prozent
C=98 H=89 G=93

¤ Dauer der Verarbeitung: 0.25 Sekunden  (vorverarbeitet am  2026-06-27) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik