HCI Event Masks: Find the Missing Controller Event Before Blaming the Radio

Before blaming the radio for a missing controller event, establish that the event is supported, enabled, required by the attempted procedure and visible at the HCI receive boundary. An application callback is the last observation in that chain, not the first.

Applicability: Bluetooth Core 6.1 HCI event-selection commands and Linux v6.12 initialization source. The worked event is LE PHY Update Complete. Mask experiments are proposed for an isolated, exclusively owned test controller; no mask, connection or radio setting was changed here.

The general LE Meta bit 61 and LE PHY completion bit 11 gate a supported event before HCI receipt and host/application dispatch.
Original two-mask evidence diagram. Bit contributions are illustrative and are not recommended complete masks; no controller configuration or event experiment was executed.

1. Name the exact event and procedure version

Record event code, LE subevent code if applicable, command that should trigger it, relevant handle and required controller features. Distinguish command acceptance from the later procedure event. A successful Command Status can coexist with a deliberately masked completion event.

Use the specification for the selected controller/host combination. Event revisions can occupy different LE mask bits. Enabling an older version’s bit is not automatically equivalent to requesting every newer version.

For the fixture, LE PHY Update Complete is an LE Meta subevent. Its HCI event code is 0x3E, its subevent code is 0x0C and its LE event-mask bit is 11. Those are three different numbers with different jobs.

Do not compute a mask by shifting one by the event code or assume the subevent code is the zero-based bit number. Read the exact mask table, then preserve the byte-level encoding sent to the controller.

2. Check both LE event gates

Core section 7.3.1 assigns bit 61 of the general Event_Mask to LE Meta events. Section 7.8.1 additionally requires the corresponding bit in LE_Event_Mask. The general gate can suppress all LE Meta events even when their individual LE bits are enabled.

For PHY Update Complete, the general mask needs bit 61 and the LE mask needs bit 11, alongside all other bits required by the owning host. In an eight-octet little-endian mask representation, these individual contributions are general byte 7 bit 5, and LE byte 1 bit 3.

Expressed as isolated contributions, they are 00 00 00 00 00 00 00 20 and 00 08 00 00 00 00 00 00 respectively. These are not complete recommended production masks. Preserve the host’s other required events instead of replacing its masks with these examples.

Set Event Mask Page 2 is another command for other specified events; it does not replace the LE Set Event Mask requirement. Put the command identity beside every stored mask so equal-looking byte arrays cannot be applied to the wrong register-like state.

3. Separate supported from merely enabled

The mask commands ignore unsupported and reserved event bits as specified. A successful mask command therefore does not prove that every requested event exists on that controller.

Build a capability record from supported-command and feature responses, controller firmware identity and the procedure’s prerequisites. Keep the mask request and successful completion as separate records. “Requested bit=1” and “feature supported” answer different questions.

The Linux v6.12 hci_le_set_event_mask_sync constructs its LE mask conditionally. For PHY Update Complete, it enables events[1] bit 0x08 when the supported-command bitmap indicates LE Set Default PHY or LE Set PHY support.

This illustrates why copying a mask from another adapter is weak evidence. Different command/feature results, host versions and initialization paths can produce different masks. Inspect the exact transmitted command and result on the failing build.

Assign configuration ownership to the host stack. Do not let a debugging application issue raw mask writes behind its back; it can suppress events that the stack needs to finish unrelated procedures.

4. Confirm that the trigger requires an event

Core section 7.8.49 states that an accepted LE Set PHY procedure generates PHY Update Complete either when a PHY changes or when the controller determines neither PHY will change immediately, subject to event masking.

A no-change outcome can therefore still be successful. Do not use “the PHY stayed at 1M” as proof that no completion should have occurred, or use a completion as proof that the requested PHY was actually selected. Read the returned status and TX/RX PHY values.

First verify command parameters and initial Command Status. If the controller rejects the request, follow that rejection’s contract rather than waiting for the success-path event.

For other events, inspect their own generation conditions. A threshold-crossing event requires its reporting setup and crossing condition; an advertising report also depends on scanning and filtering. Turning on a mask does not manufacture the underlying event.

5. Follow the event through three observation boundaries

Capture controller-to-host HCI delivery where supported, the host’s decoded event handling and the application’s callback or state update. Preserve timestamps and the active connection generation at each boundary.

If the event is present in the HCI trace but absent from the application, the controller mask did not suppress that observed event. Investigate host dispatch, feature exposure, callback registration, queue loss and application filtering.

If the trace lacks the event, check capture completeness before concluding it was never transmitted. Dropped monitor records, late capture startup or transport framing failure can create missing evidence.

Keep the last successfully applied mask ledger for the current controller generation. Defaults or reinitialization can replace previously applied state. A configuration file from the previous boot is not proof of the current effective mask.

6. Run a controlled two-mask experiment

General LE Meta bit PHY LE bit Expected selection result
1 1 Eligible PHY completion can be delivered
1 0 PHY completion is masked
0 1 All LE Meta events are masked, including this one

Use a dedicated test host that owns the controller and can safely restore its baseline. Retain every unrelated required mask bit except the intentionally changed gate. Disabling the general LE gate is especially disruptive and belongs only in this controlled experiment.

  1. Record capabilities and baseline masks, then verify their successful command completions.
  2. Establish the intended lab connection and issue a supported, valid LE Set PHY request.
  3. Capture Command Status and the later event, including an accepted no-change case.
  4. Repeat with one gate deliberately disabled and a fresh trigger for each run.
  5. Restore both required bits and repeat; do not assume old masked events will be replayed.
  6. Keep masks unchanged while deliberately dropping an application callback in a harness; verify HCI evidence distinguishes this downstream fault.

Acceptance requires a ledger linking capability, applied mask, valid trigger and received event to the application outcome. A missing event then has a named unresolved boundary, rather than becoming an unsupported claim about radio reliability.

Similar Posts