Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,079 changes: 1,039 additions & 1,040 deletions model/controller/dual_mode_controller.cc

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions model/controller/dual_mode_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -598,14 +598,16 @@ class DualModeController : public Device {

// Map command opcodes to the corresponding bit index in the
// supported command mask.
static const std::unordered_map<OpCode, OpCodeIndex> hci_command_op_code_to_index_;
static const std::unordered_map<OpCode, OpCodeIndex>& GetOpCodeToIndex();

// Map all implemented opcodes to the function implementing the handler
// for the associated command. The map should be a subset of the
// supported_command field in the properties_ object. Commands
// that are supported but not implemented will raise a fatal assert.
using CommandHandler = std::function<void(DualModeController*, bluetooth::hci::CommandView)>;
static const std::unordered_map<OpCode, CommandHandler> hci_command_handlers_;

// Getter for the command handlers map
static const std::unordered_map<OpCode, CommandHandler>& GetHciCommandHandlers();
};

} // namespace rootcanal
27 changes: 20 additions & 7 deletions model/controller/ffi.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,28 +38,41 @@ enum Idc {
extern "C" {

__attribute__((visibility("default"))) void* ffi_controller_new(
uint8_t const address[6], void (*send_hci)(int idc, uint8_t const* data, size_t data_len),
void (*send_ll)(uint8_t const* data, size_t data_len, int phy, int tx_power)) {
uint8_t const address[6],
void (*send_hci)(void* cookie, int idc, uint8_t const* data, size_t data_len),
void (*send_ll)(void* cookie, uint8_t const* data, size_t data_len, int phy, int tx_power),
void (*invalid_packet_handler)(void* cookie, int reason, char const* message,
uint8_t const* data, size_t data_len),
void* cookie) {
DualModeController* controller = new DualModeController();
controller->SetAddress(
Address({address[0], address[1], address[2], address[3], address[4], address[5]}));
controller->RegisterEventChannel([=](std::shared_ptr<std::vector<uint8_t>> data) {
send_hci(hci::Idc::EVT, data->data(), data->size());
send_hci(cookie, hci::Idc::EVT, data->data(), data->size());
});
controller->RegisterAclChannel([=](std::shared_ptr<std::vector<uint8_t>> data) {
send_hci(hci::Idc::ACL, data->data(), data->size());
send_hci(cookie, hci::Idc::ACL, data->data(), data->size());
});
controller->RegisterScoChannel([=](std::shared_ptr<std::vector<uint8_t>> data) {
send_hci(hci::Idc::SCO, data->data(), data->size());
send_hci(cookie, hci::Idc::SCO, data->data(), data->size());
});
controller->RegisterIsoChannel([=](std::shared_ptr<std::vector<uint8_t>> data) {
send_hci(hci::Idc::ISO, data->data(), data->size());
send_hci(cookie, hci::Idc::ISO, data->data(), data->size());
});
controller->RegisterLinkLayerChannel(
[=](std::vector<uint8_t> const& data, Phy::Type phy, int8_t tx_power) {
send_ll(data.data(), data.size(), static_cast<int>(phy), tx_power);
send_ll(cookie, data.data(), data.size(), static_cast<int>(phy), tx_power);
});

if (invalid_packet_handler) {
controller->RegisterInvalidPacketHandler([=](uint32_t /*id*/, InvalidPacketReason reason,
std::string message,
std::vector<uint8_t> const& packet) {
invalid_packet_handler(cookie, static_cast<int>(reason), message.c_str(), packet.data(),
packet.size());
});
}

return controller;
}

Expand Down
11 changes: 7 additions & 4 deletions model/controller/ffi.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,13 @@

extern "C" {

void* ffi_controller_new(uint8_t const address[6],
void (*send_hci)(int idc, uint8_t const* data, size_t data_len),
void (*send_ll)(uint8_t const* data, size_t data_len, int phy,
int tx_power));
void* ffi_controller_new(
uint8_t const address[6],
void (*send_hci)(void* cookie, int idc, uint8_t const* data, size_t data_len),
void (*send_ll)(void* cookie, uint8_t const* data, size_t data_len, int phy, int tx_power),
void (*invalid_packet_handler)(void* cookie, int reason, char const* message,
uint8_t const* data, size_t data_len),
void* cookie);
void ffi_controller_delete(void* controller);
void ffi_controller_receive_hci(void* controller, int idc, uint8_t const* data, size_t data_len);
void ffi_controller_receive_ll(void* controller, uint8_t const* data, size_t data_len, int phy,
Expand Down
2 changes: 1 addition & 1 deletion model/controller/le_advertiser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ using duration = std::chrono::steady_clock::duration;
using time_point = std::chrono::steady_clock::time_point;
}; // namespace chrono

slots operator"" _slots(unsigned long long count) { return slots(count); }
slots operator""_slots(unsigned long long count) { return slots(count); }

// =============================================================================
// Constants
Expand Down
2 changes: 1 addition & 1 deletion model/controller/le_advertiser.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ namespace rootcanal {
using slots = std::chrono::duration<unsigned long long, std::ratio<625, 1000000>>;

// User defined literal for slots, e.g. `0x800_slots`
slots operator"" _slots(unsigned long long count);
slots operator""_slots(unsigned long long count);

using namespace bluetooth::hci;

Expand Down
206 changes: 3 additions & 203 deletions packets/hci_packets.pdl
Original file line number Diff line number Diff line change
Expand Up @@ -384,12 +384,13 @@ enum OpCode : 16 {
LE_CS_READ_REMOTE_FAE_TABLE = 0x208E,
LE_CS_WRITE_CACHED_REMOTE_FAE_TABLE = 0x208F,
LE_CS_CREATE_CONFIG = 0x2090,
LE_CS_REMOVE_CONFIG = 0x0291,
LE_CS_REMOVE_CONFIG = 0x2091,
LE_CS_SET_CHANNEL_CLASSIFICATION = 0x2092,
LE_CS_SET_PROCEDURE_PARAMETERS = 0x2093,
LE_CS_PROCEDURE_ENABLE = 0x2094,
LE_CS_TEST = 0x2095,
LE_CS_TEST_END = 0x2096,
LE_SET_HOST_FEATURE_V2 = 0x2097,
LE_ADD_DEVICE_TO_MONITORED_ADVERTISERS_LIST = 0x2098,
LE_REMOVE_DEVICE_FROM_MONITORED_ADVERTISERS_LIST = 0x2099,
LE_CLEAR_MONITORED_ADVERTISERS_LIST = 0x209A,
Expand Down Expand Up @@ -4029,18 +4030,6 @@ struct EnabledSet {
max_extended_advertising_events : 8,
}

struct DisabledSet {
advertising_handle : 8,
_fixed_ = 0x00 : 16, // duration
_fixed_ = 0x00 : 8, // max_extended_advertising_events
}

packet LeSetExtendedAdvertisingDisable : Command (op_code = LE_SET_EXTENDED_ADVERTISING_ENABLE) {
_fixed_ = 0x00 : 8, // Enable::DISABLED
_count_(disabled_sets) : 8,
disabled_sets : DisabledSet[],
}

packet LeSetExtendedAdvertisingEnable : Command (op_code = LE_SET_EXTENDED_ADVERTISING_ENABLE) {
enable : Enable,
_count_(enabled_sets) : 8,
Expand All @@ -4051,7 +4040,7 @@ test LeSetExtendedAdvertisingEnable {
"\x39\x20\x06\x01\x01\x01\x00\x00\x00",
}

test LeSetExtendedAdvertisingDisable {
test LeSetExtendedAdvertisingEnable {
"\x39\x20\x06\x00\x01\x01\x00\x00\x00",
}

Expand Down Expand Up @@ -6530,12 +6519,6 @@ packet LeBatchScanReadResultParameters : LeBatchScan (batch_scan_opcode = READ_R
batch_scan_data_read : BatchScanDataRead,
}

packet LeBatchScanReadResultParametersCompleteRaw : LeBatchScanComplete (batch_scan_opcode = READ_RESULT_PARAMETERS) {
batch_scan_data_read : BatchScanDataRead,
num_of_records : 8,
raw_data : 8[],
}

packet LeBatchScanReadResultParametersComplete : LeBatchScanComplete (batch_scan_opcode = READ_RESULT_PARAMETERS) {
batch_scan_data_read : BatchScanDataRead,
_body_,
Expand Down Expand Up @@ -6888,186 +6871,3 @@ packet ControllerDebugInfoEvent : VendorSpecificEvent (subevent_code = CONTROLLE
_size_(debug_data) : 16,
debug_data : 8[],
}

// -----------------------------------------------------------------------------
// Microsoft Commands
// https://learn.microsoft.com/en-us/windows-hardware/drivers/bluetooth/microsoft-defined-bluetooth-hci-commands-and-events
// -----------------------------------------------------------------------------

enum MsftSubcommandOpcode : 8 {
MSFT_READ_SUPPORTED_FEATURES = 0x00,
MSFT_MONITOR_RSSI = 0x01,
MSFT_CANCEL_MONITOR_RSSI = 0x02,
MSFT_LE_MONITOR_ADV = 0x03,
MSFT_LE_CANCEL_MONITOR_ADV = 0x04,
MSFT_LE_SET_ADV_FILTER_ENABLE = 0x05,
MSFT_READ_ABSOLUTE_RSSI = 0x06,
}

// MSFT Commands do not have a constant opcode, so leave `op_code` undefined.
packet MsftCommand : Command {
subcommand_opcode: MsftSubcommandOpcode,
_payload_,
}

packet MsftReadSupportedFeatures : MsftCommand (subcommand_opcode = MSFT_READ_SUPPORTED_FEATURES) {}

enum MsftLeMonitorAdvConditionType : 8 {
MSFT_CONDITION_TYPE_PATTERNS = 0x01,
MSFT_CONDITION_TYPE_UUID = 0x02,
MSFT_CONDITION_TYPE_IRK_RESOLUTION = 0x03,
MSFT_CONDITION_TYPE_ADDRESS = 0x04,
}

enum MsftLeMonitorAdvConditionUuidType : 8 {
MSFT_CONDITION_UUID_TYPE_16_BIT = 0x01,
MSFT_CONDITION_UUID_TYPE_32_BIT = 0x02,
MSFT_CONDITION_UUID_TYPE_128_BIT = 0x03,
}

packet MsftLeMonitorAdv : MsftCommand (subcommand_opcode = MSFT_LE_MONITOR_ADV) {
rssi_threshold_high : 8,
rssi_threshold_low : 8,
rssi_threshold_low_time_interval : 8,
rssi_sampling_period : 8,
condition_type: MsftLeMonitorAdvConditionType,
_payload_,
}

struct MsftLeMonitorAdvConditionPattern {
_size_(pattern) : 8, // including one byte for ad_type and one byte for start_of_pattern
ad_type: 8,
start_of_pattern: 8,
pattern: 8[+2],
}

packet MsftLeMonitorAdvConditionPatterns : MsftLeMonitorAdv (condition_type = MSFT_CONDITION_TYPE_PATTERNS) {
_count_(patterns): 8,
patterns: MsftLeMonitorAdvConditionPattern[],
}

test MsftLeMonitorAdvConditionPatterns {
"\x1e\xfc\x0e\x03\x10\x05\x04\xaa\x01\x01\x06\x03\x00\x80\x81\x82\x83", // 1 pattern
"\x70\xfd\x13\x03\x15\x04\x02\xbb\x01\x02\x04\x03\x00\x80\x81\x06\x0f\x00\x90\x91\x92\x93", // 2 patterns
}

packet MsftLeMonitorAdvConditionUuid : MsftLeMonitorAdv (condition_type = MSFT_CONDITION_TYPE_UUID) {
uuid_type: MsftLeMonitorAdvConditionUuidType,
_payload_,
}

packet MsftLeMonitorAdvConditionUuid2 : MsftLeMonitorAdvConditionUuid (uuid_type = MSFT_CONDITION_UUID_TYPE_16_BIT) {
uuid2: 8[2],
}

test MsftLeMonitorAdvConditionUuid2 {
"\x1e\xfc\x09\x03\x10\x11\x12\x13\x02\x01\x70\x71", // opcode = fc1e for Intel
"\x70\xfd\x09\x03\x10\x11\x12\x13\x02\x01\x70\x71", // opcode = fd70 for Qualcomm
}

packet MsftLeMonitorAdvConditionUuid4 : MsftLeMonitorAdvConditionUuid (uuid_type = MSFT_CONDITION_UUID_TYPE_32_BIT) {
uuid4: 8[4],
}

test MsftLeMonitorAdvConditionUuid4 {
"\x1e\xfc\x0b\x03\x10\x11\x12\x13\x02\x02\x70\x71\x72\x73",
"\x70\xfd\x0b\x03\x10\x11\x12\x13\x02\x02\x70\x71\x72\x73",
}

packet MsftLeMonitorAdvConditionUuid16 : MsftLeMonitorAdvConditionUuid (uuid_type = MSFT_CONDITION_UUID_TYPE_128_BIT) {
uuid16: 8[16],
}

test MsftLeMonitorAdvConditionUuid16 {
"\x1e\xfc\x17\x03\x10\x11\x12\x13\x02\x03\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f",
"\x70\xfd\x17\x03\x10\x11\x12\x13\x02\x03\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f",
}

packet MsftLeCancelMonitorAdv: MsftCommand (subcommand_opcode = MSFT_LE_CANCEL_MONITOR_ADV) {
monitor_handle: 8,
}

test MsftLeCancelMonitorAdv {
"\x1e\xfc\x02\x04\x01", // cancel handle 0x01
}

packet MsftLeSetAdvFilterEnable : MsftCommand (subcommand_opcode = MSFT_LE_SET_ADV_FILTER_ENABLE) {
enable: 8,
}

test MsftLeSetAdvFilterEnable {
"\x1e\xfc\x02\x05\x01", // disable
"\x70\xfd\x02\x05\x01", // enable
}

packet MsftCommandComplete : CommandComplete {
status: ErrorCode,
subcommand_opcode: MsftSubcommandOpcode,
_payload_,
}

packet MsftReadSupportedFeaturesCommandComplete : MsftCommandComplete (subcommand_opcode = MSFT_READ_SUPPORTED_FEATURES) {
supported_features: 64,
_size_(prefix) : 8,
prefix: 8[],
}

test MsftReadSupportedFeaturesCommandComplete {
"\x0e\x10\x01\x1e\xfc\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x02\x87\x80", // Msft opcode by Intel
"\x0e\x12\x01\x70\xfd\x00\x00\x1f\x00\x00\x00\x00\x00\x00\x00\x04\x4d\x53\x46\x54", // Msft opcode by Qualcomm
}

packet MsftLeMonitorAdvCommandComplete : MsftCommandComplete (subcommand_opcode = MSFT_LE_MONITOR_ADV) {
monitor_handle: 8,
}

test MsftLeMonitorAdvCommandComplete {
"\x0e\x06\x01\x1e\xfc\x00\x03\x05", // succeeded
"\x0e\x06\x01\x70\xfd\x01\x03\x06", // failed
}

packet MsftLeCancelMonitorAdvCommandComplete : MsftCommandComplete (subcommand_opcode = MSFT_LE_CANCEL_MONITOR_ADV) {}

packet MsftLeSetAdvFilterEnableCommandComplete : MsftCommandComplete (subcommand_opcode = MSFT_LE_SET_ADV_FILTER_ENABLE) {}

enum MsftEventCode : 8 {
MSFT_RSSI_EVENT = 0x01,
MSFT_LE_MONITOR_DEVICE_EVENT = 0x02,
}

enum MsftEventStatus : 8 {
MSFT_EVENT_STATUS_SUCCESS = 0x00,
MSFT_EVENT_STATUS_FAILURE = 0x01,
}

// It is not possible to define MSFT Event packet by deriving `Event` packet
// because it starts with variable-length event prefix which can only be determined
// at run-time (after receiving return of MSFT Read Supported Features).
// Therefore we only define the payload which is located after the event prefix.
packet MsftEventPayload {
msft_event_code : MsftEventCode,
_payload_,
}

packet MsftRssiEventPayload : MsftEventPayload (msft_event_code = MSFT_RSSI_EVENT) {
status: MsftEventStatus,
connection_handle: 16,
rssi: 8,
}

test MsftRssiEventPayload {
"\x01\x00\x01\x10\xf0", // MSFT_RSSI_EVENT succeeded
"\x01\x01\x02\x02\x08", // MSFT_RSSI_EVENT failed
}

packet MsftLeMonitorDeviceEventPayload : MsftEventPayload (msft_event_code = MSFT_LE_MONITOR_DEVICE_EVENT) {
address_type: 8,
bd_addr: Address,
monitor_handle: 8,
monitor_state: 8,
}

test MsftLeMonitorDeviceEventPayload {
"\x02\x01\x00\x01\x02\x03\x04\x05\x10\x00",
"\x02\x02\xf0\xf1\xf2\xf3\xf4\xf5\xaa\x02",
}
10 changes: 7 additions & 3 deletions rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,24 @@ version = "0.1.0"
edition = "2018"
build="build.rs"

[features]
serde = []

[dependencies]
bytes = "1.0.1"
num-bigint = "0.4.3"
num-derive = "0.3.3"
num-integer = "0.1.45"
num-traits = "0.2.14"
paste = "1.0.4"
pdl-runtime = "0.3.0"
pdl-derive = "0.4.2"
pdl-runtime = "0.4.2"
pin-utils = "0.1.0"
rand = "0.9.1"
rand = "0.8.3"
thiserror = "1.0.23"

[build-dependencies]
pdl-compiler = "0.3.2"
pdl-compiler = "0.4.2"

[lib]
path="src/lib.rs"
Expand Down
6 changes: 2 additions & 4 deletions rust/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@ fn generate_module(in_file: &Path) {
)
.expect("PDL parse failed");
let analyzed_file = pdl_compiler::analyzer::analyze(&parsed_file).expect("PDL analysis failed");
let rust_source = pdl_compiler::backends::rust_legacy::generate(&sources, &analyzed_file);
out_file
.write_all(rust_source.as_bytes())
.expect("Could not write to output file");
let rust_source = pdl_compiler::backends::rust::generate(&sources, &analyzed_file, &[]);
out_file.write_all(rust_source.as_bytes()).expect("Could not write to output file");
}
Loading