diff options
Diffstat (limited to 'package/network/services')
-rw-r--r-- | package/network/services/hostapd/patches/600-ubus_support.patch | 84 |
1 files changed, 83 insertions, 1 deletions
diff --git a/package/network/services/hostapd/patches/600-ubus_support.patch b/package/network/services/hostapd/patches/600-ubus_support.patch index 41792a6dd5..98acf19b5b 100644 --- a/package/network/services/hostapd/patches/600-ubus_support.patch +++ b/package/network/services/hostapd/patches/600-ubus_support.patch @@ -41,7 +41,7 @@ HAPD_IFACE_DISABLED, --- /dev/null +++ b/src/ap/ubus.c -@@ -0,0 +1,408 @@ +@@ -0,0 +1,490 @@ +/* + * hostapd / ubus support + * Copyright (c) 2013, Felix Fietkau <nbd@openwrt.org> @@ -63,6 +63,12 @@ +static struct blob_buf b; +static int ctx_ref; + ++static inline struct hostapd_data *get_hapd_from_object(struct ubus_object *obj) ++{ ++ return container_of(obj, struct hostapd_data, ubus.obj); ++} ++ ++ +struct ubus_banned_client { + struct avl_node avl; + u8 addr[ETH_ALEN]; @@ -337,12 +343,88 @@ + return 0; +} + ++enum { ++ CSA_FREQ, ++ CSA_BCN_COUNT, ++ __CSA_MAX ++}; ++ ++static const struct blobmsg_policy csa_policy[__CSA_MAX] = { ++ /* ++ * for now, frequency and beacon count are enough, add more ++ * parameters on demand ++ */ ++ [CSA_FREQ] = { "freq", BLOBMSG_TYPE_INT32 }, ++ [CSA_BCN_COUNT] = { "bcn_count", BLOBMSG_TYPE_INT32 }, ++}; ++ ++static int ++hostapd_switch_chan(struct ubus_context *ctx, struct ubus_object *obj, ++ struct ubus_request_data *req, const char *method, ++ struct blob_attr *msg) ++{ ++ struct blob_attr *tb[__CSA_MAX]; ++ struct hostapd_data *hapd = get_hapd_from_object(obj); ++ struct csa_settings css; ++ ++ blobmsg_parse(csa_policy, __CSA_MAX, tb, blob_data(msg), blob_len(msg)); ++ ++ if (!tb[CSA_FREQ]) ++ return UBUS_STATUS_INVALID_ARGUMENT; ++ ++ memset(&css, 0, sizeof(css)); ++ css.freq_params.freq = blobmsg_get_u32(tb[CSA_FREQ]); ++ if (tb[CSA_BCN_COUNT]) ++ css.cs_count = blobmsg_get_u32(tb[CSA_BCN_COUNT]); ++ ++ if (hostapd_switch_channel(hapd, &css) != 0) ++ return UBUS_STATUS_NOT_SUPPORTED; ++ return UBUS_STATUS_OK; ++} ++ ++enum { ++ VENDOR_ELEMENTS, ++ __VENDOR_ELEMENTS_MAX ++}; ++ ++static const struct blobmsg_policy ve_policy[__VENDOR_ELEMENTS_MAX] = { ++ /* vendor elements are provided as hex-string */ ++ [VENDOR_ELEMENTS] = { "vendor_elements", BLOBMSG_TYPE_STRING }, ++}; ++ ++static int ++hostapd_vendor_elements(struct ubus_context *ctx, struct ubus_object *obj, ++ struct ubus_request_data *req, const char *method, ++ struct blob_attr *msg) ++{ ++ struct blob_attr *tb[__VENDOR_ELEMENTS_MAX]; ++ struct hostapd_data *hapd = get_hapd_from_object(obj); ++ ++ blobmsg_parse(ve_policy, __VENDOR_ELEMENTS_MAX, tb, ++ blob_data(msg), blob_len(msg)); ++ ++ if (!tb[VENDOR_ELEMENTS]) ++ return UBUS_STATUS_INVALID_ARGUMENT; ++ ++ const char *vendor_elements = blobmsg_data(tb[VENDOR_ELEMENTS]); ++ if (hostapd_set_iface(hapd->iconf, hapd->conf, "vendor_elements", ++ vendor_elements) != 0) ++ return UBUS_STATUS_NOT_SUPPORTED; ++ ++ /* update beacons if vendor elements were set successfully */ ++ if (ieee802_11_update_beacons(hapd->iface) != 0) ++ return UBUS_STATUS_NOT_SUPPORTED; ++ return UBUS_STATUS_OK; ++} ++ +static const struct ubus_method bss_methods[] = { + UBUS_METHOD_NOARG("get_clients", hostapd_bss_get_clients), + UBUS_METHOD("del_client", hostapd_bss_del_client, del_policy), + UBUS_METHOD_NOARG("list_bans", hostapd_bss_list_bans), + UBUS_METHOD_NOARG("wps_start", hostapd_bss_wps_start), + UBUS_METHOD_NOARG("wps_cancel", hostapd_bss_wps_cancel), ++ UBUS_METHOD("switch_chan", hostapd_switch_chan, csa_policy), ++ UBUS_METHOD("set_vendor_elements", hostapd_vendor_elements, ve_policy), +}; + +static struct ubus_object_type bss_object_type = |