int ap_list_reconfig(struct hostapd_iface *iface, struct hostapd_config *oldconf) { time_t now; struct ap_info *ap; if (iface->conf->ap_table_max_size == oldconf->ap_table_max_size && iface->conf->ap_table_expiration_time == oldconf->ap_table_expiration_time) return 0; time(&now); while (iface->ap_list) { ap = iface->ap_list->prev; if (iface->num_ap <= iface->conf->ap_table_max_size && ap->last_beacon + iface->conf->ap_table_expiration_time >= now) break; if (iface->conf->passive_scan_interval > 0) ap_list_expired_ap(iface, iface->ap_list->prev); ap_free_ap(iface, iface->ap_list->prev); } return 0; }
static struct ap_info * ap_ap_add(struct hostapd_iface *iface, u8 *addr) { struct ap_info *ap; ap = os_zalloc(sizeof(struct ap_info)); if (ap == NULL) return NULL; /* initialize AP info data */ os_memcpy(ap->addr, addr, ETH_ALEN); ap_ap_list_add(iface, ap); iface->num_ap++; ap_ap_hash_add(iface, ap); ap_ap_iter_list_add(iface, ap); if (iface->num_ap > iface->conf->ap_table_max_size && ap != ap->prev) { wpa_printf(MSG_DEBUG, "Removing the least recently used AP " MACSTR " from AP table", MAC2STR(ap->prev->addr)); if (iface->conf->passive_scan_interval > 0) ap_list_expired_ap(iface, ap->prev); ap_free_ap(iface, ap->prev); } return ap; }
static void ap_list_timer(void *eloop_ctx, void *timeout_ctx) { struct hostapd_iface *iface = eloop_ctx; struct os_reltime now; struct ap_info *ap; int set_beacon = 0; eloop_register_timeout(10, 0, ap_list_timer, iface, NULL); if (!iface->ap_list) { return; } os_get_reltime(&now); while (iface->ap_list) { ap = iface->ap_list->prev; if (!os_reltime_expired(&now, &ap->last_beacon, iface->conf->ap_table_expiration_time)) { break; } ap_free_ap(iface, ap); } if (iface->olbc || iface->olbc_ht) { int olbc = 0; int olbc_ht = 0; ap = iface->ap_list; while (ap && (olbc == 0 || olbc_ht == 0)) { if (ap_list_beacon_olbc(iface, ap)) { olbc = 1; } if (!ap->ht_support) { olbc_ht = 1; } ap = ap->next; } if (!olbc && iface->olbc) { wpa_printf(MSG_DEBUG, "OLBC not detected anymore"); iface->olbc = 0; set_beacon++; } #ifdef CONFIG_IEEE80211N if (!olbc_ht && iface->olbc_ht) { wpa_printf(MSG_DEBUG, "OLBC HT not detected anymore"); iface->olbc_ht = 0; hostapd_ht_operation_update(iface); set_beacon++; } #endif /* CONFIG_IEEE80211N */ } if (set_beacon) { ieee802_11_update_beacons(iface); } }
static void hostapd_free_aps(struct hostapd_iface *iface) { struct ap_info *ap, *prev; ap = iface->ap_list; while (ap) { prev = ap; ap = ap->next; ap_free_ap(iface, prev); } iface->ap_list = NULL; }
static void ap_list_timer(void *eloop_ctx, void *timeout_ctx) { struct hostapd_iface *iface = eloop_ctx; time_t now; struct ap_info *ap; eloop_register_timeout(10, 0, ap_list_timer, iface, NULL); if (!iface->ap_list) return; time(&now); /* FIX: it looks like jkm-Purina ended up in busy loop in this * function. Apparently, something can still cause a loop in the AP * list.. */ while (iface->ap_list) { ap = iface->ap_list->prev; if (ap->last_beacon + iface->conf->ap_table_expiration_time >= now) break; if (iface->conf->passive_scan_interval > 0) ap_list_expired_ap(iface, ap); ap_free_ap(iface, ap); } if (iface->olbc) { int olbc = 0; ap = iface->ap_list; while (ap) { if (ap_list_beacon_olbc(iface, ap)) { olbc = 1; break; } ap = ap->next; } if (!olbc) { struct hostapd_data *hapd = iface->bss[0]; HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "OLBC not detected anymore\n"); iface->olbc = 0; ieee802_11_set_beacons(hapd->iface); } } }
static void ap_list_timer(void *eloop_ctx, void *timeout_ctx) { struct hostapd_iface *iface = eloop_ctx; time_t now; struct ap_info *ap; int set_beacon = 0; eloop_register_timeout(10, 0, ap_list_timer, iface, NULL); if (!iface->ap_list) return; time(&now); /* FIX: it looks like jkm-Purina ended up in busy loop in this * function. Apparently, something can still cause a loop in the AP * list.. */ while (iface->ap_list) { ap = iface->ap_list->prev; if (ap->last_beacon + iface->conf->ap_table_expiration_time >= now) break; if (iface->conf->passive_scan_interval > 0) ap_list_expired_ap(iface, ap); ap_free_ap(iface, ap); } if (iface->olbc || iface->olbc_ht) { int olbc = 0; int olbc_ht = 0; ap = iface->ap_list; while (ap && (olbc == 0 || olbc_ht == 0)) { if (ap_list_beacon_olbc(iface, ap)) olbc = 1; #ifdef CONFIG_IEEE80211N if (ap_list_beacon_olbc_ht(iface, ap)) olbc_ht = 1; #endif /* CONFIG_IEEE80211N */ ap = ap->next; } if (!olbc && iface->olbc) { wpa_printf(MSG_DEBUG, "OLBC not detected anymore"); iface->olbc = 0; set_beacon++; } #ifdef CONFIG_IEEE80211N if (!olbc_ht && iface->olbc_ht) { wpa_printf(MSG_DEBUG, "OLBC HT not detected anymore"); iface->olbc_ht = 0; hostapd_ht_operation_update(iface); set_beacon++; } #endif /* CONFIG_IEEE80211N */ } if (set_beacon) ieee802_11_set_beacons(iface); }