#ifndef NR_ANTENNA_STATE_H #define NR_ANTENNA_STATE_H #include #include #include #ifdef __cplusplus extern "C" { #endif /// Maximum number of physical antennas supported #define NR_MAX_ANTENNAS 8 /// O-RAN compliant antenna state for TX/RX arrays /// Mirrors o-ran-uplane-conf.yang: tx-array-antenna-mask-config typedef struct { /// Antenna bitmask per O-RAN WG4 spec: bit N = 1 means antenna N is active /// Corresponds to o-ran-uplane-conf:antenna-bitmask uint8_t tx_antenna_bitmask; uint8_t rx_antenna_bitmask; /// Total number of configured antennas uint8_t num_tx_antennas; uint8_t num_rx_antennas; /// Thread safety for runtime updates pthread_mutex_t lock; /// Energy saving statistics (for research/monitoring) struct { uint64_t tx_mute_events; ///< Number of TX mute operations uint64_t rx_mute_events; ///< Number of RX mute operations uint64_t total_muted_slots; ///< Total slots with at least one antenna muted uint64_t energy_saved_estimate; ///< Estimated energy saved (arbitrary units) uint64_t last_update_timestamp; ///< Last update time (for O1 notifications) } stats; /// O-RAN compliance: array name for NETCONF identification char tx_array_name[64]; char rx_array_name[64]; /// Recovery mode: after unmuting, allow CSI to update before using full capacity struct { bool in_recovery; ///< Currently in recovery mode uint64_t recovery_start_ts; ///< Timestamp when recovery started (us) uint32_t recovery_duration_ms; ///< Recovery duration in milliseconds (default 500ms) } recovery; /// Configuration flags struct { bool protect_antenna0; ///< Never mute antenna 0 (needed for SSB) } config; } nr_antenna_state_t; /** * @brief Initialize antenna state with all antennas active * @param state Pointer to antenna state structure * @param num_tx Number of TX antennas * @param num_rx Number of RX antennas * @param tx_array_name O-RAN array name for TX (e.g., "tx-array-0") * @param rx_array_name O-RAN array name for RX (e.g., "rx-array-0") */ void nr_init_antenna_state(nr_antenna_state_t *state, uint8_t num_tx, uint8_t num_rx, const char *tx_array_name, const char *rx_array_name); /** * @brief Free antenna state resources * @param state Pointer to antenna state structure */ void nr_free_antenna_state(nr_antenna_state_t *state); /** * @brief Set TX antenna bitmask (O-RAN O1 interface equivalent) * * This function implements the O-RAN WG4 MPLANE-TRX-CONTROL feature. * Corresponds to NETCONF edit-config on tx-array-antenna-mask-config. * * @param state Pointer to antenna state structure * @param bitmask Antenna bitmask (bit N = 1 means antenna N active) * @return Previous bitmask value */ uint8_t nr_set_tx_antenna_bitmask(nr_antenna_state_t *state, uint8_t bitmask); /** * @brief Set RX antenna bitmask (O-RAN O1 interface equivalent) * @param state Pointer to antenna state structure * @param bitmask Antenna bitmask (bit N = 1 means antenna N active) * @return Previous bitmask value */ uint8_t nr_set_rx_antenna_bitmask(nr_antenna_state_t *state, uint8_t bitmask); /** * @brief Get current TX antenna bitmask * @param state Pointer to antenna state structure * @return Current TX antenna bitmask */ uint8_t nr_get_tx_antenna_bitmask(const nr_antenna_state_t *state); /** * @brief Get current RX antenna bitmask * @param state Pointer to antenna state structure * @return Current RX antenna bitmask */ uint8_t nr_get_rx_antenna_bitmask(const nr_antenna_state_t *state); /** * @brief Check if a specific TX antenna is active * @param state Pointer to antenna state structure * @param ant_id Antenna index (0-based) * @return true if antenna is active, false if muted */ bool nr_is_tx_antenna_active(const nr_antenna_state_t *state, uint8_t ant_id); /** * @brief Check if a specific RX antenna is active * @param state Pointer to antenna state structure * @param ant_id Antenna index (0-based) * @return true if antenna is active, false if muted */ bool nr_is_rx_antenna_active(const nr_antenna_state_t *state, uint8_t ant_id); /** * @brief Get count of currently active TX antennas * @param state Pointer to antenna state structure * @return Number of active TX antennas */ int nr_get_active_tx_antenna_count(const nr_antenna_state_t *state); /** * @brief Get count of currently active RX antennas * @param state Pointer to antenna state structure * @return Number of active RX antennas */ int nr_get_active_rx_antenna_count(const nr_antenna_state_t *state); /** * @brief Mute a specific TX antenna * @param state Pointer to antenna state structure * @param ant_id Antenna index to mute (0-based) */ void nr_mute_tx_antenna(nr_antenna_state_t *state, uint8_t ant_id); /** * @brief Unmute a specific TX antenna * @param state Pointer to antenna state structure * @param ant_id Antenna index to unmute (0-based) */ void nr_unmute_tx_antenna(nr_antenna_state_t *state, uint8_t ant_id); /** * @brief Mute a specific RX antenna * @param state Pointer to antenna state structure * @param ant_id Antenna index to mute (0-based) */ void nr_mute_rx_antenna(nr_antenna_state_t *state, uint8_t ant_id); /** * @brief Unmute a specific RX antenna * @param state Pointer to antenna state structure * @param ant_id Antenna index to unmute (0-based) */ void nr_unmute_rx_antenna(nr_antenna_state_t *state, uint8_t ant_id); /** * @brief Get effective number of MIMO layers based on active antennas * * For MIMO, the number of layers is limited by active antennas. * This function returns min(requested_layers, active_antennas). * * @param state Pointer to antenna state structure * @param requested_layers Originally requested number of layers * @return Effective number of layers that can be used */ int nr_get_effective_mimo_layers(const nr_antenna_state_t *state, int requested_layers); /** * @brief Log antenna state for debugging * @param state Pointer to antenna state structure */ void nr_log_antenna_state(const nr_antenna_state_t *state); /** * @brief Get energy saving statistics * @param state Pointer to antenna state structure * @param tx_mute_events Output: number of TX mute events * @param rx_mute_events Output: number of RX mute events * @param total_muted_slots Output: total slots with muting */ void nr_get_antenna_stats(const nr_antenna_state_t *state, uint64_t *tx_mute_events, uint64_t *rx_mute_events, uint64_t *total_muted_slots); /** * @brief Reset energy saving statistics * @param state Pointer to antenna state structure */ void nr_reset_antenna_stats(nr_antenna_state_t *state); /** * @brief Unmute all TX antennas and enter recovery mode * @param state Pointer to antenna state structure * * This initiates a recovery period during which the scheduler * uses conservative settings to allow UE CSI reports to update. */ void nr_unmute_all_tx_antennas(nr_antenna_state_t *state); /** * @brief Unmute all RX antennas * @param state Pointer to antenna state structure */ void nr_unmute_all_rx_antennas(nr_antenna_state_t *state); /** * @brief Check if system is in recovery mode after unmuting * @param state Pointer to antenna state structure * @return true if in recovery mode */ bool nr_is_in_recovery_mode(const nr_antenna_state_t *state); /** * @brief Set antenna 0 protection (SSB antenna) * @param state Pointer to antenna state structure * @param protect true to prevent muting antenna 0 */ void nr_set_antenna0_protection(nr_antenna_state_t *state, bool protect); #ifdef __cplusplus } #endif #endif /* NR_ANTENNA_STATE_H */