| 1 | --- a/hostapd/ctrl_iface.c |
| 2 | +++ b/hostapd/ctrl_iface.c |
| 3 | @@ -33,6 +33,7 @@ |
| 4 | #include "wps/wps.h" |
| 5 | #include "config_file.h" |
| 6 | #include "ctrl_iface.h" |
| 7 | +#include "config_file.h" |
| 8 | |
| 9 | |
| 10 | struct wpa_ctrl_dst { |
| 11 | @@ -43,6 +44,7 @@ struct wpa_ctrl_dst { |
| 12 | int errors; |
| 13 | }; |
| 14 | |
| 15 | +static char *reload_opts = NULL; |
| 16 | |
| 17 | static void hostapd_ctrl_iface_send(struct hostapd_data *hapd, int level, |
| 18 | const char *buf, size_t len); |
| 19 | @@ -152,6 +154,68 @@ static int hostapd_ctrl_iface_new_sta(st |
| 20 | return 0; |
| 21 | } |
| 22 | |
| 23 | +static int hostapd_ctrl_iface_set_down(struct hostapd_data *hapd) |
| 24 | +{ |
| 25 | + if (hapd->driver->stop_ap) |
| 26 | + hapd->driver->stop_ap(hapd->drv_priv); |
| 27 | + return 0; |
| 28 | +} |
| 29 | + |
| 30 | +static char *get_option(char *opt, char *str) |
| 31 | +{ |
| 32 | + int len = strlen(str); |
| 33 | + |
| 34 | + if (!strncmp(opt, str, len)) |
| 35 | + return opt + len; |
| 36 | + else |
| 37 | + return NULL; |
| 38 | +} |
| 39 | + |
| 40 | +static struct hostapd_config *hostapd_ctrl_iface_config_read(const char *fname) |
| 41 | +{ |
| 42 | + struct hostapd_config *conf; |
| 43 | + char *opt, *val; |
| 44 | + |
| 45 | + conf = hostapd_config_read(fname); |
| 46 | + if (!conf) |
| 47 | + return NULL; |
| 48 | + |
| 49 | + for (opt = strtok(reload_opts, " "); |
| 50 | + opt; |
| 51 | + opt = strtok(NULL, " ")) { |
| 52 | + |
| 53 | + if ((val = get_option(opt, "channel="))) |
| 54 | + conf->channel = atoi(val); |
| 55 | + else if ((val = get_option(opt, "ht_capab="))) |
| 56 | + conf->ht_capab = atoi(val); |
| 57 | + else if ((val = get_option(opt, "ht_capab_mask="))) |
| 58 | + conf->ht_capab &= atoi(val); |
| 59 | + else if ((val = get_option(opt, "sec_chan="))) |
| 60 | + conf->secondary_channel = atoi(val); |
| 61 | + else if ((val = get_option(opt, "hw_mode="))) |
| 62 | + conf->hw_mode = atoi(val); |
| 63 | + else if ((val = get_option(opt, "ieee80211n="))) |
| 64 | + conf->ieee80211n = atoi(val); |
| 65 | + else |
| 66 | + break; |
| 67 | + } |
| 68 | + |
| 69 | + return conf; |
| 70 | +} |
| 71 | + |
| 72 | +static int hostapd_ctrl_iface_update(struct hostapd_data *hapd, char *txt) |
| 73 | +{ |
| 74 | + struct hostapd_config * (*config_read_cb)(const char *config_fname); |
| 75 | + struct hostapd_iface *iface = hapd->iface; |
| 76 | + |
| 77 | + config_read_cb = iface->interfaces->config_read_cb; |
| 78 | + iface->interfaces->config_read_cb = hostapd_ctrl_iface_config_read; |
| 79 | + reload_opts = txt; |
| 80 | + |
| 81 | + hostapd_reload_config(iface); |
| 82 | + |
| 83 | + iface->interfaces->config_read_cb = config_read_cb; |
| 84 | +} |
| 85 | |
| 86 | #ifdef CONFIG_IEEE80211W |
| 87 | #ifdef NEED_AP_MLME |
| 88 | @@ -864,6 +928,10 @@ static void hostapd_ctrl_iface_receive(i |
| 89 | reply_len += res; |
| 90 | } |
| 91 | #endif /* CONFIG_NO_RADIUS */ |
| 92 | + } else if (os_strcmp(buf, "DOWN") == 0) { |
| 93 | + hostapd_ctrl_iface_set_down(hapd); |
| 94 | + } else if (os_strncmp(buf, "UPDATE ", 7) == 0) { |
| 95 | + hostapd_ctrl_iface_update(hapd, buf + 7); |
| 96 | } else if (os_strcmp(buf, "STA-FIRST") == 0) { |
| 97 | reply_len = hostapd_ctrl_iface_sta_first(hapd, reply, |
| 98 | reply_size); |
| 99 | |