#include "proto.h"
#include "wireless.h"
#include "config.h"
+#include "ubus.h"
bool config_init = false;
if (!vif)
return;
- vif->vlan_idx = vif->sta_idx = 0;
- vlist_update(&vif->vlans);
- vlist_update(&vif->stations);
-
if (s->anonymous)
goto out;
vlist_flush(&vif->stations);
}
+static void
+config_init_procd_wireless_interface(const char *wdev_name, const char *vif_name,
+ struct blob_attr *config,
+ struct blob_attr *vlans,
+ struct blob_attr *stations)
+{
+ struct wireless_interface *vif;
+ struct wireless_device *wdev;
+ struct blob_attr *cur;
+ char name[16];
+ int idx = 0;
+ int rem;
+
+ wdev = vlist_find(&wireless_devices, wdev_name, wdev, node);
+ if (!wdev) {
+ D(WIRELESS, "device %s not found!", wdev_name);
+ return;
+ }
+
+ vif = wireless_interface_create(wdev, config, vif_name);
+ if (!vif)
+ return;
+
+ blobmsg_for_each_attr(cur, vlans, rem) {
+ snprintf(name, sizeof(name), "%d", ++idx);
+ wireless_vlan_create(vif, cur, name);
+ }
+
+ blobmsg_for_each_attr(cur, stations, rem) {
+ snprintf(name, sizeof(name), "%d", ++idx);
+ wireless_station_create(vif, cur, name);
+ }
+
+ vlist_flush(&vif->vlans);
+ vlist_flush(&vif->stations);
+}
+
+static void
+config_procd_wireless_interface_cb(struct blob_attr *data)
+{
+ enum {
+ UDATA_ATTR_DEVICE,
+ UDATA_ATTR_CONFIG,
+ UDATA_ATTR_STATIONS,
+ UDATA_ATTR_VLANS,
+ __UDATA_ATTR_MAX,
+ };
+ static const struct blobmsg_policy policy[__UDATA_ATTR_MAX] = {
+ [UDATA_ATTR_DEVICE] = { "device", BLOBMSG_TYPE_STRING },
+ [UDATA_ATTR_CONFIG] = { "config", BLOBMSG_TYPE_TABLE },
+ [UDATA_ATTR_STATIONS] = { "stations", BLOBMSG_TYPE_ARRAY },
+ [UDATA_ATTR_VLANS] = { "vlans", BLOBMSG_TYPE_ARRAY },
+ };
+ struct blob_attr *tb[__UDATA_ATTR_MAX];
+ const char *dev;
+
+ blobmsg_parse_attr(policy, __UDATA_ATTR_MAX, tb, data);
+ if (!tb[UDATA_ATTR_DEVICE] || !tb[UDATA_ATTR_CONFIG])
+ return;
+
+ dev = blobmsg_get_string(tb[UDATA_ATTR_DEVICE]);
+ config_init_procd_wireless_interface(dev, blobmsg_name(data),
+ tb[UDATA_ATTR_CONFIG],
+ tb[UDATA_ATTR_VLANS],
+ tb[UDATA_ATTR_STATIONS]);
+}
+
static void
config_init_wireless(void)
{
config_parse_wireless_interface(wdev, s);
}
+ netifd_ubus_get_procd_data("wifi-iface", config_procd_wireless_interface_cb);
+
vlist_for_each_element(&wireless_devices, wdev, node)
vlist_flush(&wdev->interfaces);
}
ubus_remove_object(ubus_ctx, &iface->ubus);
free((void *) iface->ubus.name);
}
+
+static void
+netifd_ubus_data_cb(struct ubus_request *req, int type, struct blob_attr *msg)
+{
+ struct blob_attr *srv, *in, *t, *data;
+ procd_data_cb cb = req->priv;
+ int rem, rem2, rem3, rem4;
+
+ blobmsg_for_each_attr(srv, msg, rem) {
+ if (!blobmsg_check_attr(srv, true) ||
+ blobmsg_type(srv) != BLOBMSG_TYPE_TABLE)
+ continue;
+ blobmsg_for_each_attr(in, srv, rem2) {
+ if (!blobmsg_check_attr(in , true) ||
+ blobmsg_type(in) != BLOBMSG_TYPE_TABLE)
+ continue;
+ blobmsg_for_each_attr(t, in, rem3) {
+ if (!blobmsg_check_attr(t, true) ||
+ blobmsg_type(t) != BLOBMSG_TYPE_TABLE)
+ continue;
+ blobmsg_for_each_attr(data, t, rem4) {
+ if (!blobmsg_check_attr(t, true) ||
+ blobmsg_type(t) != BLOBMSG_TYPE_TABLE)
+ continue;
+ cb(data);
+ }
+ }
+ }
+ }
+}
+
+void netifd_ubus_get_procd_data(const char *type, procd_data_cb cb)
+{
+ uint32_t id;
+
+ if (ubus_lookup_id(ubus_ctx, "service", &id))
+ return;
+
+ blob_buf_init(&b, 0);
+ blobmsg_add_string(&b, "type", type);
+ ubus_invoke(ubus_ctx, id, "get_data", b.head, netifd_ubus_data_cb, cb, 30000);
+}
#ifndef __NETIFD_UBUS_H
#define __NETIFD_UBUS_H
+typedef void (*procd_data_cb)(struct blob_attr *data);
+
extern struct ubus_context *ubus_ctx;
int netifd_ubus_init(const char *path);
void netifd_ubus_interface_event(struct interface *iface, bool up);
void netifd_ubus_interface_notify(struct interface *iface, bool up);
void netifd_ubus_device_notify(const char *event, struct blob_attr *data, int timeout);
+void netifd_ubus_get_procd_data(const char *type, procd_data_cb cb);
#endif
put_container(struct blob_buf *buf, struct blob_attr *attr, const char *name)
{
void *c = blobmsg_open_table(buf, name);
- blob_put_raw(buf, blob_data(attr), blob_len(attr));
+ blob_put_raw(buf, blobmsg_data(attr), blobmsg_len(attr));
blobmsg_close_table(buf, c);
}
vlist_add(&wdev->interfaces, &vif->node, vif->name);
- return vlist_find(&wdev->interfaces, name, vif, node);
+ vif = vlist_find(&wdev->interfaces, name, vif, node);
+ if (!vif)
+ return NULL;
+
+ vif->vlan_idx = vif->sta_idx = 0;
+ vlist_update(&vif->vlans);
+ vlist_update(&vif->stations);
+
+ return vif;
}
/* ubus callback network.wireless.status, runs for every interface */