hostapd: fix more AP+STA issues
When STA is disconnected, ensure that the interface is in a cleanly stopped state: - if in regular enable/disable state, stop beacons if necessary - in any other state, disable the interface When the STA is up, ignore repeated start commands for the same channel, in order to avoid unnecessary AP restarts Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
parent
a63e118f77
commit
4acbe4e336
2 changed files with 34 additions and 14 deletions
|
@ -688,7 +688,6 @@ let main_obj = {
|
||||||
freq_info.csa_count = req.args.csa_count ?? 10;
|
freq_info.csa_count = req.args.csa_count ?? 10;
|
||||||
ret = iface.switch_channel(freq_info);
|
ret = iface.switch_channel(freq_info);
|
||||||
} else {
|
} else {
|
||||||
iface.stop();
|
|
||||||
ret = iface.start(freq_info);
|
ret = iface.start(freq_info);
|
||||||
}
|
}
|
||||||
if (!ret)
|
if (!ret)
|
||||||
|
|
|
@ -382,13 +382,23 @@ uc_hostapd_iface_stop(uc_vm_t *vm, size_t nargs)
|
||||||
struct hostapd_iface *iface = uc_fn_thisval("hostapd.iface");
|
struct hostapd_iface *iface = uc_fn_thisval("hostapd.iface");
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
switch (iface->state) {
|
||||||
|
case HAPD_IFACE_ENABLED:
|
||||||
|
case HAPD_IFACE_DISABLED:
|
||||||
|
break;
|
||||||
#ifdef CONFIG_ACS
|
#ifdef CONFIG_ACS
|
||||||
if (iface->state == HAPD_IFACE_ACS) {
|
case HAPD_IFACE_ACS:
|
||||||
acs_cleanup(iface);
|
acs_cleanup(iface);
|
||||||
iface->scan_cb = NULL;
|
iface->scan_cb = NULL;
|
||||||
hostapd_disable_iface(iface);
|
/* fallthrough */
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
default:
|
||||||
|
hostapd_disable_iface(iface);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iface->state != HAPD_IFACE_ENABLED)
|
||||||
|
hostapd_disable_iface(iface);
|
||||||
|
|
||||||
for (i = 0; i < iface->num_bss; i++) {
|
for (i = 0; i < iface->num_bss; i++) {
|
||||||
struct hostapd_data *hapd = iface->bss[i];
|
struct hostapd_data *hapd = iface->bss[i];
|
||||||
|
@ -406,28 +416,37 @@ uc_hostapd_iface_start(uc_vm_t *vm, size_t nargs)
|
||||||
struct hostapd_iface *iface = uc_fn_thisval("hostapd.iface");
|
struct hostapd_iface *iface = uc_fn_thisval("hostapd.iface");
|
||||||
uc_value_t *info = uc_fn_arg(0);
|
uc_value_t *info = uc_fn_arg(0);
|
||||||
struct hostapd_config *conf;
|
struct hostapd_config *conf;
|
||||||
|
bool changed = false;
|
||||||
uint64_t intval;
|
uint64_t intval;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!iface)
|
if (!iface)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
iface->freq = 0;
|
if (!info) {
|
||||||
if (!info)
|
iface->freq = 0;
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (ucv_type(info) != UC_OBJECT)
|
if (ucv_type(info) != UC_OBJECT)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
#define UPDATE_VAL(field, name) \
|
||||||
|
if ((intval = ucv_int64_get(ucv_object_get(info, name, NULL))) && \
|
||||||
|
!errno && intval != conf->field) do { \
|
||||||
|
conf->field = intval; \
|
||||||
|
changed = true; \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
conf = iface->conf;
|
conf = iface->conf;
|
||||||
if ((intval = ucv_int64_get(ucv_object_get(info, "op_class", NULL))) && !errno)
|
UPDATE_VAL(op_class, "op_class");
|
||||||
conf->op_class = intval;
|
UPDATE_VAL(hw_mode, "hw_mode");
|
||||||
if ((intval = ucv_int64_get(ucv_object_get(info, "hw_mode", NULL))) && !errno)
|
UPDATE_VAL(channel, "channel");
|
||||||
conf->hw_mode = intval;
|
UPDATE_VAL(secondary_channel, "sec_channel");
|
||||||
if ((intval = ucv_int64_get(ucv_object_get(info, "channel", NULL))) && !errno)
|
if (!changed &&
|
||||||
conf->channel = intval;
|
(iface->bss[0]->beacon_set_done ||
|
||||||
if ((intval = ucv_int64_get(ucv_object_get(info, "sec_channel", NULL))) && !errno)
|
iface->state == HAPD_IFACE_DFS))
|
||||||
conf->secondary_channel = intval;
|
return ucv_boolean_new(true);
|
||||||
|
|
||||||
intval = ucv_int64_get(ucv_object_get(info, "center_seg0_idx", NULL));
|
intval = ucv_int64_get(ucv_object_get(info, "center_seg0_idx", NULL));
|
||||||
if (!errno)
|
if (!errno)
|
||||||
|
@ -444,6 +463,8 @@ uc_hostapd_iface_start(uc_vm_t *vm, size_t nargs)
|
||||||
intval = ucv_int64_get(ucv_object_get(info, "frequency", NULL));
|
intval = ucv_int64_get(ucv_object_get(info, "frequency", NULL));
|
||||||
if (!errno)
|
if (!errno)
|
||||||
iface->freq = intval;
|
iface->freq = intval;
|
||||||
|
else
|
||||||
|
iface->freq = 0;
|
||||||
conf->acs = 0;
|
conf->acs = 0;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
|
Loading…
Reference in a new issue