Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4ca973fa authored by Dennis Cheng's avatar Dennis Cheng Committed by Andre Eisenbach
Browse files

test_vendor_lib: Initial commit

Basic vendor library for a test Bluetooth controller. Currently consists
of mostly stub functions and objects and can only handle the reset
command (by immediately responding with a command complete event).
Implemented through a global EventDispatcher object which waits for data
from the HCI and directly returns the appropriate response.

Eventually, the dispatcher will manage a fake controller object that
will provide callbacks to be executed whenever events are processed by
the dispatcher. Unit tests are still in progress and will be in the next
upload.

Bug: 21586676
Change-Id: I1c6746f8b0f1732b89a1da13facecdd49b5ac1b6
parent 5c44522e
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

group("vendor-libs") {
  deps = [
    "linux:bt-vendor-linux"
    "linux:bt-vendor-linux",
    "test_vendor_lib:test_vendor_lib",
  ]
}
+33 −0
Original line number Diff line number Diff line
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

BT_DIR := $(TOP_DIR)packages/modules/Bluetooth/system

LOCAL_SRC_FILES := \
    src/bredr_controller.cc \
    src/bt_vendor.cc \
    src/command_packet.cc \
    src/event_packet.cc \
    src/hci_handler.cc \
    src/hci_transport.cc \
    src/packet.cc \
    src/packet_stream.cc \

LOCAL_C_INCLUDES := \
    $(LOCAL_PATH)/include \
    $(BT_DIR) \
    $(BT_DIR)/hci/include \
    $(BT_DIR)/osi/include \
    $(BT_DIR)/stack/include \

LOCAL_SHARED_LIBRARIES := \
    liblog \
    libchrome

LOCAL_CPP_EXTENSION := .cc
LOCAL_MODULE := test-vendor
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := SHARED_LIBRARIES

include $(BUILD_SHARED_LIBRARY)
+25 −0
Original line number Diff line number Diff line
shared_library("test_vendor_lib") {
  sources = [
    "src/bredr_controller.cc",
    "src/bt_vendor.cc",
    "src/command_packet.cc",
    "src/event_packet.cc",
    "src/hci_handler.cc",
    "src/hci_transport.cc",
    "src/packet.cc",
    "src/packet_stream.cc",
  ]

  include_dirs = [
    "include",
    "//",
    # TODO(dennischeng): Ideally we should need to have the lines below for
    # indirect includes.
    "//osi/include",
    "//stack/include",
  ]

  # TODO(dennischeng): Add libchrome as a dependency.
}

# TODO(dennischeng): Add a unit test target.
+86 −0
Original line number Diff line number Diff line
//
// Copyright 2015 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.
//

#pragma once

#include <cstdint>
#include <vector>
#include <unordered_map>

#include <base/macros.h>

namespace test_vendor_lib {

// Emulates a BR/EDR controller by maintaining the link layer state machine
// detailed in the Bluetooth Core Specification Version 4.2, Volume 2, Part B,
// Section 8 (page 159). Provides actions corresponding to commands sent by the
// HCI. These actions will be registered from a single global controller
// instance as callbacks and called from the HciHandler.
// TODO(dennischeng): Should the controller implement an interface provided by
// the HciHandler and be used as a delegate (i.e. the HciHandler would hold a
// controller object) instead of registering its methods as callbacks?
class BREDRController {
 public:
  // Functions that operate on the global controller instance. Initialize()
  // is called by the vendor library's Init() function to create the global
  // controller and must be called before Get() and CleanUp().
  // CleanUp() should be called when a call to TestVendorCleanUp() is made
  // since the global controller should live throughout the entire time the test
  // vendor library is in use.
  static BREDRController* Get();

  static void Initialize();

  static void CleanUp();

  // Controller commands. For error codes, see the Bluetooth Core Specification,
  // Version 4.2, Volume 2, Part D (page 370).

  // Resets the controller. For now, this just generates and sends a command
  // complete event back to the HCI.
  // Command parameters: none.
  // Command response:
  //   Status (1 octet)
  //     0x00: Success.
  //     0x01-0xFF: Failed. Check error codes.
  void HciReset(const std::vector<std::uint8_t>& args);

 private:
  // There will only be a single global instance of this class.
  BREDRController();

  // The destructor can only be indirectly accessed through the static
  // CleanUp() method that destructs the global controller.
  ~BREDRController() = default;

  // Registers command callbacks with the HciHandler instance so that they are
  // fired when the corresponding opcode is received from the HCI. For now, each
  // command must be individually registered. This allows for some flexibility
  // in which commands are made available by which controller.
  void RegisterHandlerCallbacks();

  // Maintains the commands to be registered and used in the HciHandler object.
  // Keys are command opcodes and values are the callbacks to handle each
  // command.
  std::unordered_map<std::uint16_t,
                     std::function<void(const std::vector<std::uint8_t>&)>>
      active_commands_;

  // Disallow any copies of the singleton to be made.
  DISALLOW_COPY_AND_ASSIGN(BREDRController);
};

}  // namespace test_vendor_lib
+81 −0
Original line number Diff line number Diff line
//
// Copyright 2015 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.
//

#pragma once

#include "vendor_libs/test_vendor_lib/include/packet.h"

#include <cstdint>
#include <vector>

#include <base/macros.h>

namespace test_vendor_lib {

// The following is specified in the Bluetooth Core Specification Version 4.2,
// Volume 2, Part E, Section 5.4.1 (page 470). Command Packets begin with a 3
// octet header formatted as follows:
// - Opcode: 2 octets
//   - Opcode Group Field (OGF): Upper bits 10-15
//   - Opcode Command Field (OCF): Lower bits 0-9
// - Payload size (in octets): 1 octet
// The header is followed by the payload, which contains command specific
// parameters and has a maximum size of 255 octets. Valid command opcodes are
// defined in stack/include/hcidefs.h. The OGF ranges from 0x00 to 0x3F, with
// 0x3F reserved for vendor-specific debug functions. The OCF ranges from
// 0x0000 to 0x03FF. Note that the payload size is the size in octets of the
// command parameters and not the number of parameters. Finally, although the
// parameters contained in the payload are command specific (including the size
// and number of parameters), each parameter will be an integer number of octets
// in size.
class CommandPacket : public Packet {
 public:
  CommandPacket();

  ~CommandPacket() override = default;

  // Returns the command opcode as defined in stack/include/hcidefs.h.
  // See the Bluetooth Core Specification Version 4.2, Volume 2, Part E,
  // Section 7 for more information about each HCI commands and for a listing
  // of their specific opcodes/OGF and OCF values.
  std::uint16_t GetOpcode() const;

  // Returns the 6 bit opcode group field that specifies the general category of
  // the command. The OGF can be one of seven values:
  // - 0x01: Link control commands
  // - 0x02: Link policy commands
  // - 0x03: Controller and baseband commands
  // - 0x04: Informational parameters commands
  // - 0x05: Status parameters commands
  // - 0x06: Testing commands
  // - 0x08: Low energy controller commands
  // The upper 2 bits will be zero filled.
  std::uint8_t GetOGF() const;

  // Returns the 10 bit opcode command field that specifies an exact command
  // within an opcode group field. The upper 6 bits will be zero filled.
  std::uint16_t GetOCF() const;

  // Size in octets of a command packet header, which consists of a 2 octet
  // opcode and a 1 octet payload size.
  static const size_t kCommandHeaderSize = 3;

 private:
  // Disallow any copies of the singleton to be made.
  DISALLOW_COPY_AND_ASSIGN(CommandPacket);
};

}  // namespace test_vendor_lib
Loading