diff --git a/README.md b/README.md
index e1204001a65ecfdc0e62d244514f859c7db5cd9a..afa1c4339e31944a78489beb85be46f6bceacab7 100644
--- a/README.md
+++ b/README.md
@@ -135,6 +135,7 @@ Next change the version in the following places:
 # Release Notes
 
 * 0.22.0 Migrate execution environment to nomad
+* 0.21.3 Added DigitalBeam.Antenna_Usage_Mask_R to expose antennas used in beamforming
 * 0.21.2 Removed deprecated "Boot" device (use StationManager now)
 * 0.21.1 Implement multi project integration downstream pipeline
 * 0.21.0 Use radians instead of degrees when interpreting pointings
@@ -143,38 +144,38 @@ Next change the version in the following places:
 * 0.20.3 Fix application of Field_Attenuation_R
 * 0.20.2 Support only one parent in hierarchies
 * 0.20.1 Create an abstract AntennaMapper class which implements behavior of both AntennaToSdpMapper
-  and AntennaToRecvMapper
+         and AntennaToRecvMapper
 * 0.20.0 Complete implementation of station-state transitions in StationManager device.
-  Unified power management under power_hardware_on/off(), dropping prepare_hardware(),
-  disable_hardware().
-  Replaced device.warm_boot() by device.boot().
+         Unified power management under power_hardware_on/off(), dropping prepare_hardware(),
+         disable_hardware().
+         Replaced device.warm_boot() by device.boot().
 * 0.19.0 Ensure requirements.txt are installed when using pip install
 * 0.18.3 Many configuration fixes in tango device configs, Fixed APS & EC device port mapping,
-  fixed variable initialization in several devices, Fixed XST device going into
-  fault state, prevent UDP packet loss and verify UDP buffer size for XSTs,
-  Fixed several tests due to use of numpy.array in properties, Implement control hierarchy,
-  Version pin PyASN, Fix code coverage for PyTango devices, Fix beam tracker not starting again
-  after being stopped.
+         fixed variable initialization in several devices, Fixed XST device going into
+         fault state, prevent UDP packet loss and verify UDP buffer size for XSTs,
+         Fixed several tests due to use of numpy.array in properties, Implement control hierarchy,
+         Version pin PyASN, Fix code coverage for PyTango devices, Fix beam tracker not starting again
+         after being stopped.
 * 0.18.2 Fix documentation links in README
 * 0.18.1 Various improvements including: better error handling for commands and
-  resolving a configuration issue related to beamlets
+         resolving a configuration issue related to beamlets
 * 0.18.0 Expose attribute related to SDP rings such as `FPGA_bf_ring_nof_transport_hops_RW_default` and
-  `FPGA_ring_use_cable_to_next_rn_RW_default`
+         `FPGA_ring_use_cable_to_next_rn_RW_default`
 * 0.17.1 Ensure OPCUA devices reconnect automatically if the connection is lost
 * 0.17.0 Add Power Hierarchy state transition
 * 0.16.2 Add Power_Parent and Parent_Children properties in LOFAR devices
 * 0.16.1 AntennaField: Do not put device in FAULT if an attribute cannot be read/written.
-  AntennaField: Avoid archiving HBA-specific attributes for LBA fields.
+         AntennaField: Avoid archiving HBA-specific attributes for LBA fields.
 * 0.16.0 Observation: Removed antenna mask from specification
-  DigitalBeam: Removed beamlet and antenna selection
+         DigitalBeam: Removed beamlet and antenna selection
 * 0.15.0 Split `recv` device into `rcu2h` and `rcu2l` and
-  split `recv-sim` translator into `rcu2h-sim` and `rcu2l-sim`
+         split `recv-sim` translator into `rcu2h-sim` and `rcu2l-sim`
 * 0.14.0 Create async device base and make tilebeam and digitalbeam async device servers,
-  allowing for cooperative multitasking and preventing issues with beamtracking.
+         allowing for cooperative multitasking and preventing issues with beamtracking.
 * 0.13.1 Upgrade PyTango to 9.4.x and ensure it is installed through requirements.txt
 * 0.13.0 Remove all `archiver-timescale`, `hdbppts-cm`, `hdbppts-es` functionalities
 * 0.12.1 Add `AbstractHierarchy` and `AbstractHierarchyDevice` classes and
-  functionality
+         functionality
 * 0.12.0 Add `Calibration_SDP_Subband_Weights_<XXX>MHz_R` attributes to implement HDF5 calibration tables
 * 0.11.2 Fix sleep duration in archiver test
 * 0.11.1 Fix event unsubscription in TemperatureManager
@@ -182,8 +183,8 @@ Next change the version in the following places:
 * 0.10.0 Add `AntennaToSdpMapper` and fpga_sdp_info_* mapped attributes in `Antennafield` device
 * 0.9.0 Statistics writer: moved the whole functionality to lofar-station-client repository
 * 0.8.0 Statistics writer: HDF5 format overhaul (removed `values`, added and moved attributes),
-  Statistics writer: Added `--field` parameter to record statistics of a specific AntennaField,
-  AntennaField: Added `RCU_DTH_on_R`, `RCU_DTH_freq_R(W)`, `RCU_band_select_R`, `RCU_attenuator_dB_R`.
+        Statistics writer: Added `--field` parameter to record statistics of a specific AntennaField,
+        AntennaField: Added `RCU_DTH_on_R`, `RCU_DTH_freq_R(W)`, `RCU_band_select_R`, `RCU_attenuator_dB_R`.
 * 0.7.2 Added `sdp.subband_frequency_R`, `antennafield.Frequency_Band_RW`, and support for spectral inversion
 * 0.7.1 Add restore backup configuration for `Configuration` device
 * 0.7.0 Raised required Python version to 3.10
diff --git a/tangostationcontrol/tangostationcontrol/beam/managers/_digitalbeam.py b/tangostationcontrol/tangostationcontrol/beam/managers/_digitalbeam.py
index 1bca73797bcd39ee55065f1fe3353987a26a9007..16e38a6f2804065ecce05b01350cc7b2fe45005f 100644
--- a/tangostationcontrol/tangostationcontrol/beam/managers/_digitalbeam.py
+++ b/tangostationcontrol/tangostationcontrol/beam/managers/_digitalbeam.py
@@ -26,6 +26,35 @@ class DigitalBeamManager(AbstractBeamManager):
         self.relative_antenna_positions = None
         super().__init__()
 
+    def antennas_used(self) -> list[bool]:
+        """
+        Return the set of antennas actually used in the beamforming, after
+        all masks and selectionis have been applied.
+        """
+
+        # Use zero weights for antennas that we should not use:
+        #  - if the antenna has no input mapped on the SDP
+        #  - if the antenna is bad (False in Antenna_Usage_Mask_R)
+        #  - if the antenna is not in the antenna set (False in Antenna_Mask_RW)
+        antenna_usage_mask = self._device.control.read_parent_attribute(
+            "Antenna_Usage_Mask_R"
+        )
+        antenna_mask = self._device.read_Antenna_Mask_R()
+        antenna_to_sdp_mapping = self._device.control.read_parent_attribute(
+            "Antenna_to_SDP_Mapping_R"
+        )
+
+        antennas_used = [False] * len(antenna_mask)
+
+        for antenna_nr, (_fpga_nr, input_nr) in enumerate(antenna_to_sdp_mapping):
+            antennas_used[antenna_nr] = (
+                input_nr >= 0
+                and antenna_usage_mask[antenna_nr]
+                and antenna_mask[antenna_nr]
+            )
+
+        return antennas_used
+
     @TimeIt()
     def delays(self, pointing_direction: numpy.array, timestamp: datetime.datetime):
         """
@@ -74,24 +103,14 @@ class DigitalBeamManager(AbstractBeamManager):
         beam_weights = self._device.beamlet.calculate_bf_weights(beam_delays.flatten())
         beam_weights = beam_weights.reshape(N_pn, A_pn, N_beamlets_ctrl)
 
-        # Use zero weights for antennas that we should not use:
-        #  - if the antenna has no input mapped on the SDP
-        #  - if the antenna is bad (False in Antenna_Usage_Mask_R)
-        #  - if the antenna is not in the antenna set (False in Antenna_Mask_RW)
-        antenna_usage_mask = self._device.control.read_parent_attribute(
-            "Antenna_Usage_Mask_R"
-        )
-        antenna_mask = self._device.read_Antenna_Mask_R()
+        # Use zero weights for antennas that we should not use
+        antennas_used = self.antennas_used()
         zeroes_for_all_beamlets = numpy.array([0] * N_beamlets_ctrl, dtype=numpy.uint32)
 
         for antenna_nr, (fpga_nr, input_nr) in enumerate(
             self._device.control.read_parent_attribute("Antenna_to_SDP_Mapping_R")
         ):
-            if (
-                input_nr < 0
-                or not antenna_usage_mask[antenna_nr]
-                or not antenna_mask[antenna_nr]
-            ):
+            if not antennas_used[antenna_nr]:
                 beam_weights[fpga_nr, input_nr, :] = zeroes_for_all_beamlets
 
         return beam_weights
diff --git a/tangostationcontrol/tangostationcontrol/clients/udp_receiver.py b/tangostationcontrol/tangostationcontrol/clients/udp_receiver.py
index c8d364c7bd2ea50b46dce5327cccf021082a851a..52170d5431d5b90394fd1b8cf647d9e5ebd07c5a 100644
--- a/tangostationcontrol/tangostationcontrol/clients/udp_receiver.py
+++ b/tangostationcontrol/tangostationcontrol/clients/udp_receiver.py
@@ -83,11 +83,15 @@ class UDPReceiver(Thread, StatisticsClientThread):
         )
 
         if self.parameters["recv_buffer_size"] < self.options["recv_buffer_size"]:
+            # Typically this is the host OS not allowing us to allocate buffers
+            # of this size. Try increasing it using (as root):
+            #     sysctl -w net.core.rmem_max=$((16*1024*1024))
             logger.error(
                 f"OS does not allow requested buffer size. "
                 f"This could result in UDP packet loss. "
                 f'Requested {self.options["recv_buffer_size"]} bytes, '
-                f'got {self.parameters["recv_buffer_size"]}.'
+                f'got {self.parameters["recv_buffer_size"]}. Verify '
+                f'if "sysctl net.core.rmem_max" is sufficiently large.'
             )
 
         # specify what host and port to listen on
diff --git a/tangostationcontrol/tangostationcontrol/devices/sdp/digitalbeam.py b/tangostationcontrol/tangostationcontrol/devices/sdp/digitalbeam.py
index 1d2d8f77ba0c911e3aaa832e4de328207e0cd27d..022263aab3eeeac20823a37a1b50e1368deab4f9 100644
--- a/tangostationcontrol/tangostationcontrol/devices/sdp/digitalbeam.py
+++ b/tangostationcontrol/tangostationcontrol/devices/sdp/digitalbeam.py
@@ -72,9 +72,19 @@ class DigitalBeam(BeamDevice):
         max_dim_x=MAX_ANTENNA,
     )
 
+    Antenna_Usage_Mask_R = attribute(
+        doc="Antennas used for beam forming. Excludes antennas outside "
+        "the antenna set, broken antennas, unconnected antennas, etc.",
+        dtype=(bool,),
+        max_dim_x=MAX_ANTENNA,
+        fisallowed="is_attribute_access_allowed",
+        fget=lambda self: self._beam_manager.antennas_used(),
+    )
+
     Duration_delays_R = attribute(
         access=AttrWriteType.READ,
         dtype=numpy.float64,
+        fisallowed="is_attribute_access_allowed",
         fget=lambda self: self._beam_manager.delays.get_statistic(self)["last"] or 0,
     )
 
diff --git a/tangostationcontrol/tangostationcontrol/devices/sdp/statistics.py b/tangostationcontrol/tangostationcontrol/devices/sdp/statistics.py
index 1c8f0de551c3d387c7abb1fe7a680541ec6a7bb6..fe1f1093256253ab7757cfe8f40f8a81986c9a61 100644
--- a/tangostationcontrol/tangostationcontrol/devices/sdp/statistics.py
+++ b/tangostationcontrol/tangostationcontrol/devices/sdp/statistics.py
@@ -58,6 +58,7 @@ class Statistics(OPCUADevice):
     )
     # size of UDP receive buffer
     udp_recv_buffer_size_R = AttributeWrapper(
+        doc="Buffer size for receiving UDP packets.",
         comms_id=StatisticsClient,
         comms_annotation={"type": "udp", "parameter": "recv_buffer_size"},
         datatype=numpy.uint64,
diff --git a/tangostationcontrol/test/beam/managers/test_digitalbeam_manager.py b/tangostationcontrol/test/beam/managers/test_digitalbeam_manager.py
index bbb360bf46e7fd9218266621093d7915c042579d..cda32bb678eb023665a85051f99d9fa43ea3fa23 100644
--- a/tangostationcontrol/test/beam/managers/test_digitalbeam_manager.py
+++ b/tangostationcontrol/test/beam/managers/test_digitalbeam_manager.py
@@ -116,3 +116,76 @@ class TestDigitalBeamManager(base.TestCase):
         numpy.testing.assert_array_equal(
             sut.current_pointing_error, numpy.full(1, 1.05)
         )
+
+
+class TestDigitalBeamManagerAntennasUsed(base.TestCase):
+    def _test_antennas_used(
+        self,
+        antenna_to_sdp_mapping: list[list[int]],
+        antenna_usage_mask: list[bool],
+        antenna_mask: list[bool],
+        expected_antennas_used: list[bool],
+    ):
+        """Generic test function."""
+
+        def read_parent_attribute(attr):
+            match attr:
+                case "Antenna_to_SDP_Mapping_R":
+                    return antenna_to_sdp_mapping
+                case "Antenna_Usage_Mask_R":
+                    return antenna_usage_mask
+
+        device_mock = MagicMock()
+        device_mock.read_Antenna_Mask_R = MagicMock(return_value=antenna_mask)
+
+        device_mock.control = MagicMock()
+        device_mock.control.read_parent_attribute = MagicMock()
+        device_mock.control.read_parent_attribute.side_effect = read_parent_attribute
+
+        sut = DigitalBeamManager(device_mock)
+        self.assertListEqual(sut.antennas_used(), expected_antennas_used)
+
+    def test_antennas_used_single_antenna(self):
+        # Test simple case: single antenna
+        self._test_antennas_used(
+            antenna_to_sdp_mapping=[[0, 0]],
+            antenna_usage_mask=[True],
+            antenna_mask=[True],
+            expected_antennas_used=[True],
+        )
+
+    def test_antennas_used_unconnected_antenna(self):
+        # Exclude antenna because it is not connected
+        self._test_antennas_used(
+            antenna_to_sdp_mapping=[[0, -1]],
+            antenna_usage_mask=[True],
+            antenna_mask=[True],
+            expected_antennas_used=[False],
+        )
+
+    def test_antennas_used_unusable_antenna(self):
+        # Exclude antenna because it is not to be used
+        self._test_antennas_used(
+            antenna_to_sdp_mapping=[[0, 0]],
+            antenna_usage_mask=[False],
+            antenna_mask=[True],
+            expected_antennas_used=[False],
+        )
+
+    def test_antennas_used_unselected_antenna(self):
+        # Exclude antenna because it is not in the selected antenna set
+        self._test_antennas_used(
+            antenna_to_sdp_mapping=[[0, 0]],
+            antenna_usage_mask=[True],
+            antenna_mask=[False],
+            expected_antennas_used=[False],
+        )
+
+    def test_antennas_used_multiple_antennas(self):
+        # All combinations in one go to test multiple antennas
+        self._test_antennas_used(
+            antenna_to_sdp_mapping=[[0, 0], [0, 1], [0, 2], [0, -1]],
+            antenna_usage_mask=[True, False, True, True],
+            antenna_mask=[True, True, False, True],
+            expected_antennas_used=[True, False, False, False],
+        )