OAI’s Link Adaptation Algorithm#
The original OpenAirInterface link adaptation algorithm (OAI-LA) implements a sampling-based approach for the MCS selection. This baseline implementation serves as a foundation for more advanced algorithms and demonstrates the basic principles of link adaptation. OAI-LA samples different MCS configurations, performing single-step adjustments of the MCS index based on observed BLER statistics. It uses CQI reports to determine the maximum MCS index that can be used to achieve the target BLER.
Algorithm Overview#
The OAI-LA algorithm operates on a simple threshold-based principle:
BLER Monitoring: Tracks the block error rate over a sliding window
Threshold Comparison: Compares current BLER against upper and lower thresholds
MCS Adjustment:
Increments MCS if BLER < lower threshold (requires at least 4 DL transmissions since the last update)
Decrements MCS if BLER > upper threshold, with a floor at MCS 6
Decrements MCS if fewer than 4 DL transmissions were scheduled (inactivity guard, with a floor at MCS 9)
Stability Constraints: Updates the MCS at most every
BLER_UPDATE_FRAMEframes (10 by default) to avoid reacting to transient statisticsChannel Quality Indicator (CQI) Feedback: Uses CQI reports from CSI-RS to determine the maximum allowable MCS, enabling rapid MCS reduction when channel conditions degrade
The algorithm estimates the average BLER via an exponentially weighted moving average:
where \(\text{BLER}_{window}\) is the recent BLER, which is computed from
the changes of the scheduling statistics since the last link adaptation update
(by default, every 10 frames), and \(\alpha = 0.9\) is the smoothing factor.
This is implemented in link_adaptation_log.c:
// last update is longer than x frames ago
const int num_dl_sched = (int)(stats->rounds[0] - bler_stats->rounds[0]);
const int num_dl_retx = (int)(stats->rounds[1] - bler_stats->rounds[1]);
const float bler_window = num_dl_sched > 0 ? (float) num_dl_retx / num_dl_sched : bler_stats->bler;
bler_stats->bler = BLER_FILTER * bler_stats->bler + (1 - BLER_FILTER) * bler_window;
The main MCS selection logic is implemented in the link_adaptation_get_mcs_from_bler function:
if (bler_stats->bler < bler_options->lower && old_mcs < max_mcs && num_dl_sched > 3)
new_mcs += 1;
else if ((bler_stats->bler > bler_options->upper && old_mcs > 6) // above threshold
|| (num_dl_sched <= 3 && old_mcs > 9)) // no activity
new_mcs -= 1;
// else we are within threshold boundaries
MAC Plugin Infrastructure#
We leverage OAI’s dynamic library loading mechanism to support multiple algorithm variants and incremental builds. This enables runtime selection of different link adaptation algorithms without recompilation.
Plugin Interface#
The plugin system defines a standard interface for link adaptation modules in link_adaptation_extern.h:
/**
* @brief Link adaptation interface structure
*
* Defines the interface for dynamic library loading of link adaptation modules.
* This structure contains function pointers to the core link adaptation functions
* and is used by the plugin system to load different link adaptation algorithms
* (OLLA, etc.) at runtime.
*/
typedef struct link_adaptation_interface_s {
link_adaptation_initfunc_t *init; // Initialization function
link_adaptation_shutdownfunc_t *shutdown; // Shutdown function
link_adaptation_mcsfunc_t *get_mcs_from_bler; // Main MCS selection function
} link_adaptation_interface_t;
// Global access point for the plugin interface
extern link_adaptation_interface_t link_adaptation_interface;
/**
* @brief Load link adaptation library
*
* Dynamically loads a link adaptation library based on the specified version.
* The library should export the required functions (init, shutdown, get_mcs_from_bler)
* and populate the interface structure with the appropriate function pointers.
*
* @param version Version string identifying which link adaptation algorithm to load
* @param interface Pointer to interface structure to populate with function pointers
* @return 0 on success, negative value on error
*/
int load_link_adaptation_lib(char *version, link_adaptation_interface_t *interface);
/**
* @brief Free link adaptation library
*
* Unloads the currently loaded link adaptation library and cleans up
* any associated resources. Should be called before loading a different
* library or when shutting down the system.
*
* @param interface Pointer to interface structure to clean up
* @return 0 on success, negative value on error
*/
int free_link_adaptation_lib(link_adaptation_interface_t *interface);
// Function declarations that will be loaded from the library
/**
* @brief Initialize link adaptation module
*
* Initializes the currently loaded link adaptation module and prepares
* it for operation. This function pointer is populated by the library
* loading mechanism.
*
* @return 0 on success, negative value on error
*/
link_adaptation_initfunc_t link_adaptation_init;
/**
* @brief Shutdown link adaptation module
*
* Cleans up resources and performs any necessary cleanup operations
* for the currently loaded link adaptation module.
*
* @return 0 on success
*/
link_adaptation_shutdownfunc_t link_adaptation_shutdown;
/**
* @brief Get MCS from BLER statistics
*
* Main link adaptation function that selects the optimal MCS based on
* current channel conditions, historical performance, and ACK/NACK feedback.
* This function pointer is populated by the library loading mechanism.
*
* @param bler_options BLER configuration options
* @param stats MAC layer statistics
* @param bler_stats BLER statistics structure
* @param max_mcs Maximum allowed MCS
* @param frame Current frame number
* @return Selected MCS value
*/
link_adaptation_mcsfunc_t link_adaptation_get_mcs_from_bler;
Plugin Loading and Unloading#
The MAC plugin infrastructure automatically loads the appropriate link adaptation library in mac_plugins.c:
link_adaptation_interface_t link_adaptation_interface = {0};
void init_mac_plugins(void)
{
load_link_adaptation_lib(NULL, &link_adaptation_interface);
}
void free_mac_plugins(void)
{
free_link_adaptation_lib(&link_adaptation_interface);
}
See the Configuration and Usage section for available plugin variants and configuration details.