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