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

Commit b309d99f authored by Archie Pusaka's avatar Archie Pusaka Committed by Archie Pusaka
Browse files

Hcidoc: Use hci_packets.pdl in rootcanal

The hci_packets.pdl in system/pdl doesn't seem to be fully compatible
with the pdl-compiler. Therefore, use the one in rootcanal instead.

Since they have different structure, some adjustments needs to be made.
In particular, this one doesn't have nested HCI structure, and doesn't
have GAP Data implementation.

Bug: 289858128
Test: m -j
Test: Manual verification
Flag: EXEMPT, floss only changes
Change-Id: I0ede46f80cc0e371bc69ccdbd9f2b60e9be6ccd8
parent d86585a6
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -44,7 +44,7 @@ fn generate_packets() {
    );

    let out_file = File::create(out_dir.join("hci_packets.rs")).unwrap();
    let in_file = PathBuf::from("../../../system/pdl/hci/hci_packets.pdl");
    let in_file = PathBuf::from("../../../tools/rootcanal/packets/hci_packets.pdl");

    println!("cargo:rerun-if-changed={}", in_file.display());
    let output = Command::new("pdlc")
+42 −0
Original line number Diff line number Diff line
@@ -36,4 +36,46 @@ pub mod hci {
            bytes[0..6].try_into().unwrap()
        }
    }

    pub struct GapData {
        pub data_type: GapDataType,
        pub data: Vec<u8>,
    }

    impl GapData {
        pub fn parse(bytes: &[u8]) -> std::result::Result<Self, String> {
            // In case of parsing EIR, we can get normal data, or all zeroes. Normal data always
            // have at least 2 bytes: one for the length, and another for the type. Therefore we
            // can terminate early if the data has less than 2 bytes.
            if (bytes.len() == 0) {
                return Err("no data to parse".to_string());
            } else if (bytes.len() == 1) {
                if (bytes[0] != 0) {
                    return Err(format!("can't parse 1 byte of data: {}", bytes[0]));
                }
                return Ok(GapData { data_type: GapDataType::Invalid, data: vec![] });
            }

            let mut data_size = bytes[0] as usize;
            if (data_size == 0) {
                // Data size already include the data_type, so size = 0 is possible only when
                // parsing EIR, where all data are zeroes. Here we just assume that assumption is
                // correct, and don't really check all the elements.
                return Ok(GapData { data_type: GapDataType::Invalid, data: bytes[2..].to_vec() });
            }

            if (data_size > bytes.len() - 1) {
                return Err(format!(
                    "size {} is bigger than remaining length {}",
                    data_size,
                    bytes.len() - 1
                ));
            }
            let data_type = match GapDataType::try_from(bytes[1]) {
                Ok(data_type) => Ok(data_type),
                Err(_) => Err(format!("can't parse data type {}", bytes[1])),
            }?;
            return Ok(GapData { data_type, data: bytes[2..(data_size + 1)].to_vec() });
        }
    }
}
+95 −137
Original line number Diff line number Diff line
@@ -8,11 +8,9 @@ use std::slice::Iter;
use crate::engine::{Rule, RuleGroup, Signal};
use crate::parser::{Packet, PacketChild};
use hcidoc_packets::hci::{
    Acl, AclCommandChild, Address, AuthenticatedPayloadTimeoutExpired, CommandChild,
    ConnectionManagementCommandChild, DisconnectReason, Enable, ErrorCode, EventChild,
    InitiatorFilterPolicy, LeConnectionManagementCommandChild, LeMetaEventChild,
    LeSecurityCommandChild, NumberOfCompletedPackets, OpCode, ScoConnectionCommandChild,
    SecurityCommandChild,
    Acl, Address, AuthenticatedPayloadTimeoutExpired, CommandChild, DisconnectReason, Enable,
    ErrorCode, EventChild, InitiatorFilterPolicy, LeMetaEventChild, NumberOfCompletedPackets,
    OpCode,
};

enum ConnectionSignal {
@@ -626,100 +624,77 @@ impl Rule for OddDisconnectionsRule {
    fn process(&mut self, packet: &Packet) {
        match &packet.inner {
            PacketChild::HciCommand(cmd) => match cmd.specialize() {
                CommandChild::AclCommand(aclpkt) => match aclpkt.specialize() {
                    AclCommandChild::ConnectionManagementCommand(conn) => match conn.specialize() {
                        ConnectionManagementCommandChild::CreateConnection(cc) => {
                CommandChild::CreateConnection(cc) => {
                    self.process_classic_connection(cc.get_bd_addr(), packet);
                }
                        ConnectionManagementCommandChild::AcceptConnectionRequest(ac) => {
                CommandChild::AcceptConnectionRequest(ac) => {
                    self.process_classic_connection(ac.get_bd_addr(), packet);
                }
                        ConnectionManagementCommandChild::ReadRemoteSupportedFeatures(rrsf) => {
                CommandChild::ReadRemoteSupportedFeatures(rrsf) => {
                    self.process_remote_feat_cmd(
                        PendingRemoteFeature::Supported,
                        &rrsf.get_connection_handle(),
                        packet,
                    );
                }
                        ConnectionManagementCommandChild::ReadRemoteExtendedFeatures(rref) => {
                CommandChild::ReadRemoteExtendedFeatures(rref) => {
                    self.process_remote_feat_cmd(
                        PendingRemoteFeature::Extended,
                        &rref.get_connection_handle(),
                        packet,
                    );
                }
                        // End ConnectionManagementCommand.specialize()
                        _ => {}
                    },
                    AclCommandChild::ScoConnectionCommand(sco_con) => match sco_con.specialize() {
                        ScoConnectionCommandChild::SetupSynchronousConnection(ssc) => {
                            let address =
                                self.convert_sco_handle_to_address(ssc.get_connection_handle());
                CommandChild::SetupSynchronousConnection(ssc) => {
                    let address = self.convert_sco_handle_to_address(ssc.get_connection_handle());
                    self.process_sync_connection(address, packet);
                }
                        ScoConnectionCommandChild::EnhancedSetupSynchronousConnection(esc) => {
                            let address =
                                self.convert_sco_handle_to_address(esc.get_connection_handle());
                CommandChild::EnhancedSetupSynchronousConnection(esc) => {
                    let address = self.convert_sco_handle_to_address(esc.get_connection_handle());
                    self.process_sync_connection(address, packet);
                }
                        ScoConnectionCommandChild::AcceptSynchronousConnection(asc) => {
                CommandChild::AcceptSynchronousConnection(asc) => {
                    self.process_sync_connection(asc.get_bd_addr(), packet);
                }
                        ScoConnectionCommandChild::EnhancedAcceptSynchronousConnection(easc) => {
                CommandChild::EnhancedAcceptSynchronousConnection(easc) => {
                    self.process_sync_connection(easc.get_bd_addr(), packet);
                }
                        // End ScoConnectionCommand.specialize()
                        _ => {}
                    },
                    AclCommandChild::LeConnectionManagementCommand(le_conn) => match le_conn
                        .specialize()
                    {
                        LeConnectionManagementCommandChild::LeCreateConnection(lcc) => {
                CommandChild::LeCreateConnection(lcc) => {
                    self.process_le_create_connection(
                        lcc.get_peer_address(),
                        lcc.get_initiator_filter_policy(),
                        packet,
                    );
                }
                        LeConnectionManagementCommandChild::LeExtendedCreateConnection(lecc) => {
                CommandChild::LeExtendedCreateConnection(lecc) => {
                    self.process_le_create_connection(
                        lecc.get_peer_address(),
                        lecc.get_initiator_filter_policy(),
                        packet,
                    );
                }
                        LeConnectionManagementCommandChild::LeAddDeviceToFilterAcceptList(laac) => {
                CommandChild::LeAddDeviceToFilterAcceptList(laac) => {
                    self.process_add_accept_list(laac.get_address(), packet);
                }
                        LeConnectionManagementCommandChild::LeRemoveDeviceFromFilterAcceptList(
                            lrac,
                        ) => {
                CommandChild::LeRemoveDeviceFromFilterAcceptList(lrac) => {
                    self.process_remove_accept_list(lrac.get_address(), packet);
                }
                        LeConnectionManagementCommandChild::LeClearFilterAcceptList(_lcac) => {
                CommandChild::LeClearFilterAcceptList(_lcac) => {
                    self.process_clear_accept_list(packet);
                }
                        LeConnectionManagementCommandChild::LeReadRemoteFeatures(lrrf) => {
                CommandChild::LeReadRemoteFeatures(lrrf) => {
                    self.process_remote_feat_cmd(
                        PendingRemoteFeature::Le,
                        &lrrf.get_connection_handle(),
                        packet,
                    );
                }
                        // End LeConnectionManagementCommand.specialize()
                        _ => {}
                    },
                    AclCommandChild::Disconnect(dc_conn) => {
                CommandChild::Disconnect(dc_conn) => {
                    self.process_disconnect_cmd(
                        dc_conn.get_reason(),
                        dc_conn.get_connection_handle(),
                        packet,
                    );
                }

                    // End AclCommand.specialize()
                    _ => (),
                },
                CommandChild::Reset(_) => {
                    self.process_reset();
                }
@@ -754,6 +729,7 @@ impl Rule for OddDisconnectionsRule {
                EventChild::NumberOfCompletedPackets(nocp) => {
                    self.process_nocp(&nocp, packet);
                }

                EventChild::AuthenticatedPayloadTimeoutExpired(apte) => {
                    self.process_apte(&apte, packet);
                }
@@ -1008,11 +984,10 @@ impl Rule for LinkKeyMismatchRule {
            },

            PacketChild::HciCommand(cmd) => match cmd.specialize() {
                CommandChild::AclCommand(cmd) => match cmd.specialize() {
                // Have an arm for Disconnect since sometimes we don't receive disconnect
                // event when powering off. However, no need to actually match the reason
                // since we just clean the handle in both cases.
                    AclCommandChild::Disconnect(cmd) => {
                CommandChild::Disconnect(cmd) => {
                    self.process_handle_auth(
                        ErrorCode::Success,
                        cmd.get_connection_handle(),
@@ -1020,32 +995,15 @@ impl Rule for LinkKeyMismatchRule {
                    );
                    self.handles.remove(&cmd.get_connection_handle());
                }

                    // CommandChild::AclCommand(cmd).specialize()
                    _ => {}
                },

                CommandChild::SecurityCommand(cmd) => match cmd.specialize() {
                    SecurityCommandChild::LinkKeyRequestReply(cmd) => {
                CommandChild::LinkKeyRequestReply(cmd) => {
                    self.process_reply_link_key(cmd.get_bd_addr(), true);
                }
                    SecurityCommandChild::LinkKeyRequestNegativeReply(cmd) => {
                CommandChild::LinkKeyRequestNegativeReply(cmd) => {
                    self.process_reply_link_key(cmd.get_bd_addr(), false);
                }

                    // CommandChild::SecurityCommand(cmd).specialize()
                    _ => {}
                },

                CommandChild::LeSecurityCommand(cmd) => match cmd.specialize() {
                    LeSecurityCommandChild::LeStartEncryption(cmd) => {
                CommandChild::LeStartEncryption(cmd) => {
                    self.pending_le_encrypt.insert(cmd.get_connection_handle());
                }

                    // CommandChild::LeSecurityCommand(cmd).specialize()
                    _ => {}
                },

                CommandChild::Reset(_) => {
                    self.process_reset();
                }
+37 −49
Original line number Diff line number Diff line
@@ -10,8 +10,8 @@ use std::io::Write;
use crate::engine::{Rule, RuleGroup, Signal};
use crate::parser::{get_acl_content, AclContent, Packet, PacketChild};
use hcidoc_packets::hci::{
    AclCommandChild, Address, CommandChild, ConnectionManagementCommandChild, DisconnectReason,
    ErrorCode, EventChild, GapData, GapDataType, LeMetaEventChild,
    Address, CommandChild, DisconnectReason, ErrorCode, EventChild, GapData, GapDataType,
    LeMetaEventChild,
};
use hcidoc_packets::l2cap::{ConnectionResponseResult, ControlChild};

@@ -706,18 +706,20 @@ impl InformationalRule {
    fn process_raw_gap_data(&mut self, address: &Address, data: &[u8]) {
        let mut offset = 0;
        while offset < data.len() {
            let chunk_size = usize::from(data[offset]);
            let chunk_end = offset + chunk_size + 1;

            // Prevent out-of-bounds index
            if chunk_end > data.len() {
                return;
            match GapData::parse(&data[offset..]) {
                Ok(gap_data) => {
                    self.process_gap_data(&address, &gap_data);
                    // advance data len + 2 (size = 1, type = 1)
                    offset += gap_data.data.len() + 2;
                }
                Err(err) => {
                    eprintln!("[{}] GAP data is not parsed correctly: {}", address, err);
                    break;
                }
            }
            match GapData::parse(&data[offset..chunk_end]) {
                Ok(gap_data) => self.process_gap_data(&address, &gap_data),
                Err(_err) => {}
            if offset >= data.len() {
                break;
            }
            offset = chunk_end;
        }
    }

@@ -804,9 +806,10 @@ impl Rule for InformationalRule {
                }

                EventChild::ExtendedInquiryResult(ev) => {
                    for data in ev.get_extended_inquiry_response() {
                        self.process_gap_data(&ev.get_address(), data);
                    }
                    self.process_raw_gap_data(
                        &ev.get_address(),
                        ev.get_extended_inquiry_response(),
                    );
                    self.report_address_type(&ev.get_address(), AddressType::BREDR);
                }

@@ -851,16 +854,14 @@ impl Rule for InformationalRule {
                        self.report_address_type(&ev.get_peer_address(), AddressType::LE);
                    }

                    // Use the Raw version because somehow LeAdvertisingReport doesn't work
                    LeMetaEventChild::LeAdvertisingReportRaw(ev) => {
                    LeMetaEventChild::LeAdvertisingReport(ev) => {
                        for resp in ev.get_responses() {
                            self.process_raw_gap_data(&resp.address, &resp.advertising_data);
                            self.report_address_type(&resp.address, AddressType::LE);
                        }
                    }

                    // Use the Raw version because somehow LeExtendedAdvertisingReport doesn't work
                    LeMetaEventChild::LeExtendedAdvertisingReportRaw(ev) => {
                    LeMetaEventChild::LeExtendedAdvertisingReport(ev) => {
                        for resp in ev.get_responses() {
                            self.process_raw_gap_data(&resp.address, &resp.advertising_data);
                            self.report_address_type(&resp.address, AddressType::LE);
@@ -879,24 +880,15 @@ impl Rule for InformationalRule {
                CommandChild::Reset(_cmd) => {
                    self.report_reset(packet.ts);
                }

                CommandChild::AclCommand(cmd) => match cmd.specialize() {
                    AclCommandChild::ConnectionManagementCommand(cmd) => match cmd.specialize() {
                        ConnectionManagementCommandChild::CreateConnection(cmd) => {
                CommandChild::CreateConnection(cmd) => {
                    self.report_acl_state(&cmd.get_bd_addr(), AclState::Initiating);
                    self.report_address_type(&cmd.get_bd_addr(), AddressType::BREDR);
                }

                        ConnectionManagementCommandChild::AcceptConnectionRequest(cmd) => {
                CommandChild::AcceptConnectionRequest(cmd) => {
                    self.report_acl_state(&cmd.get_bd_addr(), AclState::Accepting);
                    self.report_address_type(&cmd.get_bd_addr(), AddressType::BREDR);
                }

                        // AclCommandChild::ConnectionManagementCommand(cmd).specialize()
                        _ => {}
                    },

                    AclCommandChild::Disconnect(cmd) => {
                CommandChild::Disconnect(cmd) => {
                    // If reason is power off, the host might not wait for connection complete event
                    let is_power_off = cmd.get_reason()
                        == DisconnectReason::RemoteDeviceTerminatedConnectionPowerOff;
@@ -907,10 +899,6 @@ impl Rule for InformationalRule {
                    }
                }

                    // CommandChild::AclCommand(cmd).specialize()
                    _ => {}
                },

                // PacketChild::HciCommand(cmd).specialize()
                _ => {}
            },