139 | | Here, {{{token_ap_res_mult_factor}}} is the top-level variable we just added. If we make no other changes, then this value will be fixed at {{{TOKEN_RES_MULT_FACTOR_MIN}}}. |
| 139 | Here, {{{token_ap_res_mult_factor}}} is the top-level variable we just added. If we make no other changes, then this value will be fixed at {{{TOKEN_RES_MULT_FACTOR_MIN}}}. Next, find the same {{{ipc_payload.res_duration = DEFAULT_RESERVATION_DURATION_USEC;}}} line in the {{{else}}} clause and replace it with |
| 140 | |
| 141 | {{{ |
| 142 | #!c |
| 143 | |
| 144 | ipc_payload.res_duration = DEFAULT_RESERVATION_DURATION_USEC * curr_station_info->token_res_mult_factor; |
| 145 | }}} |
| 146 | |
| 147 | {{{token_res_mult_factor}}} is the element we added to the {{{station_info}}} struct definition and set to {{{TOKEN_RES_MULT_FACTOR_MIN}}} whenever a station_info gets created. |
| 148 | |
| 149 | ---- |
| 150 | Next, we need to actually make the {{{token_res_mult_factor}}} of {{{station_info}}} as well as the {{{token_ap_res_mult_factor}}} factors adapt with perceived usage of the token reservation periods. To do this, we will keep track of how many bytes were received in each token reservation from each STA as well as how many bytes were sent by the AP during its token reservation. First, we will deal with the AP case. Find the {{{mpdu_transmit_done()}}} function and add the following line at the top of the function: |
| 151 | |
| 152 | {{{ |
| 153 | #!c |
| 154 | |
| 155 | token_ap_num_tx_bytes += (tx_mpdu->length); |
| 156 | }}} |
| 157 | |
| 158 | This line ensures that every time we get confirmation from CPU_LOW that we have transmitted a frame, we increment {{{token_ap_num_tx_bytes}}} with the number of bytes in that frame. For each STA, we are already tracking the cumulative number of received bytes in each station's statistics struct. Next, we need to create a function that will be called whenever we receive the {{{IPC_MBOX_TOKEN_NEW_RESERVATION}}} message from CPU_LOW. Add the following function to the AP code: |
| 159 | |
| 160 | {{{ |
| 161 | #!c |
| 162 | |
| 163 | void token_stats_start( u8* addr, u16 res_duration ){ |
| 164 | dl_entry* station_info_entry = NULL; |
| 165 | station_info* station = NULL; |
| 166 | |
| 167 | memcpy(token_addr, addr, 6); |
| 168 | |
| 169 | if(wlan_addr_eq(token_addr, my_bss_info->bssid)){ |
| 170 | //This is the start of the AP's reservation |
| 171 | token_ap_num_tx_bytes = 0; |
| 172 | } else { |
| 173 | //This is the start of the a STA's reservation |
| 174 | station_info_entry = wlan_mac_high_find_station_info_ADDR(&my_bss_info->associated_stations, token_addr); |
| 175 | |
| 176 | if(station_info_entry != NULL){ |
| 177 | station = (station_info*)(station_info_entry->data); |
| 178 | token_sta_num_rx_bytes_start = station->stats->data.rx_num_bytes; |
| 179 | } |
| 180 | } |
| 181 | } |
| 182 | }}} |
| 183 | |
| 184 | |
| 185 | If the address provided as the argument to this function matches the AP's address (stored in {{{my_bss_info->bssid}}}), then we will reset {{{token_ap_num_tx_bytes}}}. Once this reservation period is over, {{{token_ap_num_tx_bytes}}} will only represent the total number of bytes sent during the reservation period. If the address does not match the AP, we will find the {{{station_info}}} struct that matches the address from the doubly-linked list of associated stations. From that struct, we will record the current value of the cumulative number of received bytes and store it in the {{{token_sta_num_rx_bytes_start}}} global variable. When the reservation period is over, we will calculate the difference between this value and the new cumulative number of received bytes from the same struct. |
| 186 | |
| 187 | Finally, we need to attach this new function to the callback we created in the MAC High Framework. In the {{{main()}}} function of the AP, add the following line: |
| 188 | |
| 189 | {{{ |
| 190 | #!c |
| 191 | |
| 192 | wlan_mac_high_set_token_stats_start_callback((function_ptr_t)token_stats_start); |
| 193 | }}} |
| 194 | |
| 195 | ---- |
| 196 | |
| 197 | Finally, the last change we need to make to the AP is to write a function that actually performs the performance audit at the end of every reservation period. Add the following function to the AP: |
| 198 | |
| 199 | {{{ |
| 200 | #!c |
| 201 | |
| 202 | void token_stats_end(){ |
| 203 | u64 efficiency_metric; |
| 204 | u32 token_sta_num_rx_bytes_end; |
| 205 | dl_entry* station_info_entry = NULL; |
| 206 | station_info* station = NULL; |
| 207 | |
| 208 | if(wlan_addr_eq(token_addr, my_bss_info->bssid)){ |
| 209 | //This is the start of the AP's reservation |
| 210 | efficiency_metric = token_ap_num_tx_bytes * token_ap_res_mult_factor; |
| 211 | |
| 212 | if(efficiency_metric > TOKEN_RES_BYTES_EFFICIENCY_THRESH){ |
| 213 | //Set the mult factor to max |
| 214 | token_ap_res_mult_factor = TOKEN_RES_MULT_FACTOR_MAX; |
| 215 | } else { |
| 216 | //Set the mult factor to min |
| 217 | token_ap_res_mult_factor = TOKEN_RES_MULT_FACTOR_MIN; |
| 218 | } |
| 219 | |
| 220 | } else { |
| 221 | //This is the start of the a STA's reservation |
| 222 | station_info_entry = wlan_mac_high_find_station_info_ADDR(&my_bss_info->associated_stations, token_addr); |
| 223 | |
| 224 | if(station_info_entry != NULL){ |
| 225 | station = (station_info*)(station_info_entry->data); |
| 226 | token_sta_num_rx_bytes_end = station->stats->data.rx_num_bytes; |
| 227 | |
| 228 | efficiency_metric = (token_sta_num_rx_bytes_end - token_sta_num_rx_bytes_start) * station->token_res_mult_factor; |
| 229 | |
| 230 | if(efficiency_metric > TOKEN_RES_BYTES_EFFICIENCY_THRESH){ |
| 231 | //Set the mult factor to max |
| 232 | station->token_res_mult_factor = TOKEN_RES_MULT_FACTOR_MAX; |
| 233 | } else { |
| 234 | //Set the mult factor to min |
| 235 | station->token_res_mult_factor = TOKEN_RES_MULT_FACTOR_MIN; |
| 236 | } |
| 237 | |
| 238 | } |
| 239 | } |
| 240 | } |
| 241 | }}} |
| 242 | |
| 243 | In the above function, we normalize the number of transmitted or received bytes by the device's associated {{{res_mult_factor}}}. We compare this normalize "efficiency metric" against the {{{TOKEN_RES_BYTES_EFFICIENCY_THRESH}}} value we defined earlier. If we exceed this value, we'll set the multiplication factor for the next reservation period to be {{{TOKEN_RES_MULT_FACTOR_MAX}}}. Otherwise, we will set it to be {{{TOKEN_RES_MULT_FACTOR_MIN}}}. |