1 | --- a/hostapd/ctrl_iface.c |
2 | +++ b/hostapd/ctrl_iface.c |
3 | @@ -35,6 +35,7 @@ |
4 | #include "ap/wps_hostapd.h" |
5 | #include "ap/ctrl_iface_ap.h" |
6 | #include "ctrl_iface.h" |
7 | +#include "config_file.h" |
8 | |
9 | |
10 | struct wpa_ctrl_dst { |
11 | @@ -45,6 +46,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 | @@ -315,6 +317,66 @@ static int hostapd_ctrl_iface_wps_oob(st |
20 | #endif /* CONFIG_WPS_OOB */ |
21 | #endif /* CONFIG_WPS */ |
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, "hwmode="))) |
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_reload(struct hostapd_data *hapd, char *txt) |
73 | +{ |
74 | + struct hostapd_iface *iface = hapd->iface; |
75 | + |
76 | + iface->config_read_cb = hostapd_ctrl_iface_config_read; |
77 | + reload_opts = txt; |
78 | + |
79 | + hostapd_reload_config(iface); |
80 | + |
81 | + iface->config_read_cb = hostapd_config_read; |
82 | +} |
83 | |
84 | static void hostapd_ctrl_iface_receive(int sock, void *eloop_ctx, |
85 | void *sock_ctx) |
86 | @@ -379,6 +441,10 @@ static void hostapd_ctrl_iface_receive(i |
87 | reply_len += res; |
88 | } |
89 | #endif /* CONFIG_NO_RADIUS */ |
90 | + } else if (os_strcmp(buf, "DOWN") == 0) { |
91 | + hostapd_ctrl_iface_set_down(hapd); |
92 | + } else if (os_strncmp(buf, "RELOAD ", 7) == 0) { |
93 | + hostapd_ctrl_iface_reload(hapd, buf + 7); |
94 | } else if (os_strcmp(buf, "STA-FIRST") == 0) { |
95 | reply_len = hostapd_ctrl_iface_sta_first(hapd, reply, |
96 | reply_size); |
97 | |