diff --git a/agent.wireless.cfg b/agent.wireless.cfg new file mode 100644 index 0000000000000000000000000000000000000000..1ee93881fd44d65d0eeddc1edb25d380dde0f99c --- /dev/null +++ b/agent.wireless.cfg @@ -0,0 +1,42 @@ +config wifi-device 'wlan0' + option type 'mac80211' + option channel '11' + option hwmode '11g' + option country 'DE' + option path 'pci0000:00/0000:00:00.0/0000:01:00.0' + option htmode 'HT20' + +config wifi-iface 'default_wlan0' + option device 'wlan0' + option network 'lan' + option ifname 'wlan0' + option mode 'sta' + option encryption 'psk2' + option wps '1' + option wps_pushbutton '1' + option bss_transition '1' + option multi_ap '1' + option multi_ap_backhaul_sta '1' + option ssid 'dummy' + option key 'dummy12345' + +config wifi-device 'wlan1' + option type 'mac80211' + option channel '36' + option hwmode '11a' + option country 'DE' + option path 'pci0000:00/0000:00:01.0/0000:02:00.0' + option htmode 'VHT80' + +config wifi-iface 'default_wlan1' + option device 'wlan1' + option network 'lan' + option ifname 'wlan1' + option mode 'sta' + option encryption 'psk2' + option wps '1' + option wps_pushbutton '1' + option multi_ap '1' + option multi_ap_backhaul_sta '1' + option ssid 'dummy' + option key 'dummy12345' \ No newline at end of file diff --git a/controller.wireless.cfg b/controller.wireless.cfg new file mode 100644 index 0000000000000000000000000000000000000000..753dcff06b5ace1edaef97d0f6fd28bc3296d77e --- /dev/null +++ b/controller.wireless.cfg @@ -0,0 +1,75 @@ +config wifi-device 'wlan0' + option type 'mac80211' + option channel '11' + option hwmode '11g' + option country 'DE' + option path 'pci0000:00/0000:00:00.0/0000:01:00.0' + option htmode 'HT20' + +config wifi-iface 'default_wlan0' + option device 'wlan0' + option network 'lan' + option ifname 'wlan0' + option mode 'ap' + option ssid 'iopsysWrt-0022077E9CD6' + option encryption 'psk2' + option key '2TBJG6DKTKIC75' + option wps '1' + option wps_pushbutton '1' + option ieee80211k '1' + option ieee80211v '1' + option bss_transition '1' + option multi_ap '2' + option multi_ap_backhaul_ssid 'MultiAP-0022077E9CD6' + option multi_ap_backhaul_key 'multiap_key123' + +config wifi-iface 'default_wlan0_1' + option device 'wlan0' + option network 'lan' + option ifname 'wlan0_1' + option mode 'ap' + option ssid 'MultiAP-0022077E9CD6' + option encryption 'psk2' + option key 'multiap_key123' + option ieee80211k '1' + option ieee80211v '1' + option bss_transition '1' + option multi_ap '1' + +config wifi-device 'wlan1' + option type 'mac80211' + option channel '36' + option hwmode '11a' + option country 'DE' + option path 'pci0000:00/0000:00:01.0/0000:02:00.0' + option htmode 'VHT80' + +config wifi-iface 'default_wlan1' + option device 'wlan1' + option network 'lan' + option ifname 'wlan1' + option mode 'ap' + option ssid 'iopsysWrt-0022077E9CD6' + option encryption 'psk2' + option key '2TBJG6DKTKIC75' + option wps '1' + option wps_pushbutton '1' + option ieee80211k '1' + option ieee80211v '1' + option bss_transition '1' + option multi_ap '2' + option multi_ap_backhaul_ssid 'MultiAP-0022077E9CD6' + option multi_ap_backhaul_key 'multiap_key123' + +config wifi-iface 'default_wlan1_1' + option device 'wlan1' + option network 'lan' + option ifname 'wlan1_1' + option mode 'ap' + option ssid 'MultiAP-0022077E9CD6' + option encryption 'psk2' + option key 'multiap_key123' + option ieee80211k '1' + option ieee80211v '1' + option bss_transition '1' + option multi_ap '1' diff --git a/src/core/agent.c b/src/core/agent.c index 1f88ff04cbd4a0a06c22dc16520536eb43f3e99e..30ed622ee8579beacb5ece32d6d5664d6028ed51 100644 --- a/src/core/agent.c +++ b/src/core/agent.c @@ -1707,10 +1707,36 @@ static void wifi_radio_event_handler(void *c, struct blob_attr *msg) dbg("%s: Unhandled!!! TODO\n", __func__); } +static void wifi_wps_creds_event_handler(void *c, struct blob_attr *msg) +{ + struct agent *a = (struct agent *)c; + struct netif_fh *fh; + char encryption[32] = {0}, ifname[16] = {0}, ssid[33] = {0}, + key[64] = {0}; + struct blob_attr *tb[4]; + static const struct blobmsg_policy ap_attr[4] = { + [0] = { .name = "ifname", .type = BLOBMSG_TYPE_STRING }, + [1] = { .name = "encryption", .type = BLOBMSG_TYPE_STRING }, + [2] = { .name = "ssid", .type = BLOBMSG_TYPE_STRING }, + [3] = { .name = "key", .type = BLOBMSG_TYPE_STRING }, + }; + + blobmsg_parse(ap_attr, 4, tb, blob_data(msg), blob_len(msg)); + + if (!tb[0] || !tb[1] || !tb[2] || !tb[3]) + return; + + strncpy(ifname, blobmsg_data(tb[0]), sizeof(ifname)); + strncpy(encryption, blobmsg_data(tb[1]), sizeof(encryption)); + strncpy(ssid, blobmsg_data(tb[2]), sizeof(ssid)); + strncpy(key, blobmsg_data(tb[3]), sizeof(key)); + + wifi_apply_iface_cfg(ifname, encryption, ssid, key); +} + static void ubus_wifi_event_handler(struct ubus_context *ctx, - struct ubus_event_handler *ev, - const char *type, - struct blob_attr *msg) + struct ubus_event_handler *ev, + const char *type, struct blob_attr *msg) { int i; char *str; @@ -1718,11 +1744,14 @@ static void ubus_wifi_event_handler(struct ubus_context *ctx, struct wifi_ev_handler { const char *ev_type; void (*handler)(void *ctx, struct blob_attr *ev_data); - } evs[] = { {"wifi.sta", wifi_sta_event_handler}, - {"wifi.channel", wifi_channel_event_handler}, - {"wifi.dfs", wifi_dfs_event_handler}, - {"wifi.radio", wifi_radio_event_handler}, - {"wifi.iface", wifi_iface_event_handler} }; + } evs[] = { + { "wifi.sta", wifi_sta_event_handler }, + { "wifi.channel", wifi_channel_event_handler }, + { "wifi.dfs", wifi_dfs_event_handler }, + { "wifi.radio", wifi_radio_event_handler }, + { "wifi.iface", wifi_iface_event_handler }, + { "wps_credentials", wifi_wps_creds_event_handler }, + }; str = blobmsg_format_json(msg, true); if (!str) @@ -2870,6 +2899,7 @@ int start_agent(void) agent_init_interfaces(w); ubus_register_event_handler(ctx, &w->wifi_evh, "wifi.*"); + ubus_register_event_handler(ctx, &w->wifi_evh, "wps_credentials"); ubus_register_event_handler(ctx, &w->ieee1905_evh, "ieee1905.*"); w->heartbeat.cb = agent_periodic_run; @@ -3777,8 +3807,8 @@ int wifiagent_get_status(struct ubus_context *ctx, } int wifiagent_process_cmd_async(struct ubus_context *ctx, - struct ubus_request_data *req, - int cmd_id, char *cmd_data, int len) + struct ubus_request_data *req, + int cmd_id, char *cmd_data, int len) { struct agent *a = this_agent; int ret = 0; diff --git a/src/core/config.c b/src/core/config.c index 2d7045b25e6a78d9e3d3ba55c34753deefb590cf..f5c3668741b9f32044c5d5fea9275907a7b0c15f 100644 --- a/src/core/config.c +++ b/src/core/config.c @@ -34,6 +34,85 @@ int verbose; +static int set_value(struct uci_context *ctx, struct uci_package *pkg, + struct uci_section *section, const char *key, + const char *value, enum uci_option_type type) +{ + struct uci_ptr ptr = {0}; + + ptr.p = pkg; + ptr.s = section; + ptr.option = key; + ptr.value = value; + + if (type == UCI_TYPE_STRING) + return uci_set(ctx, &ptr); + + if (type == UCI_TYPE_LIST) + return uci_add_list(ctx, &ptr); + + return -1; +} + +static struct uci_section *wifi_get_iface_section(struct uci_context *ctx, + struct uci_package *pkg, char *ifname) +{ + + struct uci_element *e; + struct uci_section *section; + + /* get the wet iface section */ + uci_foreach_element(&pkg->sections, e) { + const char *c_ifname; + + section = uci_to_section(e); + if (strcmp(section->type, "wifi-iface")) + continue; + + c_ifname = uci_lookup_option_string(ctx, section, "ifname"); + if (c_ifname && !strcmp(c_ifname, ifname)) + return section; + } + + return NULL; +} + +int wifi_apply_iface_cfg(const char *ifname, const char *encryption, + const char *ssid, const char *key) +{ + struct uci_context *ctx; + struct uci_package *pkg; + struct uci_element *e; + struct uci_section *section; + int rv = -1; + + ctx = uci_alloc_context(); + if (!ctx) + goto out; + + if (uci_load(ctx, "wireless", &pkg) != UCI_OK) { + dbg("config file 'wireless' not found!\n"); + goto out_uci; + } + + section = wifi_get_iface_section(ctx, pkg, ifname); + if (!section) + goto out_pkg; + + set_value(ctx, pkg, section, "encryption", encryption, UCI_TYPE_STRING); + set_value(ctx, pkg, section, "ssid", ssid, UCI_TYPE_STRING); + set_value(ctx, pkg, section, "key", key, UCI_TYPE_STRING); + + uci_commit(ctx, &pkg, false); + +out_pkg: + uci_unload(ctx, pkg); +out_uci: + uci_free_context(ctx); +out: + return rv; +} + static struct netif_bkcfg *get_netif_bkcfg_by_name(struct agent_config *c, const char *name) { diff --git a/src/core/config.h b/src/core/config.h index 7b5e346dfb9d54a4da76dd85d03d8c90e3008eee..d8856bc84f34264de88db356631011654abda925 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -125,14 +125,17 @@ int agent_config_defaults(struct agent *a, struct agent_config *cfg); void agent_config_dump(struct agent_config *cfg); int config_update(const char *confname, struct agent_config *cfg, - const char *section, const char *option, int add, - void *value, int len); + const char *section, const char *option, int add, + void *value, int len); int config_update2(const char *confname, struct agent_config *cfg, - const char *section_type, - const char *match_option, - const char *match_option_value, - const char *option, int add, void *value, int len); + const char *section_type, + const char *match_option, + const char *match_option_value, + const char *option, int add, void *value, int len); + +int wifi_apply_iface_cfg(const char *ifname, const char *encryption, + const char *ssid, const char *key); #endif