2019-11-23 20:32:15 +00:00
|
|
|
/*
|
|
|
|
Copyright (c) 2016-2019, Matthias Schiffer <mschiffer@universe-factory.net>
|
|
|
|
All rights reserved.
|
|
|
|
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
|
|
modification, are permitted provided that the following conditions are met:
|
|
|
|
|
|
|
|
1. Redistributions of source code must retain the above copyright notice,
|
|
|
|
this list of conditions and the following disclaimer.
|
|
|
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
|
|
this list of conditions and the following disclaimer in the documentation
|
|
|
|
and/or other materials provided with the distribution.
|
|
|
|
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
|
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
|
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
|
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
|
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
|
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
|
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
|
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "respondd-common.h"
|
|
|
|
|
|
|
|
#include <libgluonutil.h>
|
|
|
|
|
|
|
|
#include <iwinfo.h>
|
|
|
|
#include <json-c/json.h>
|
|
|
|
|
|
|
|
|
|
|
|
static struct json_object * get_wifi_neighbours(const char *ifname) {
|
|
|
|
const struct iwinfo_ops *iw = iwinfo_backend(ifname);
|
|
|
|
if (!iw)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
int len;
|
|
|
|
char buf[IWINFO_BUFSIZE];
|
|
|
|
if (iw->assoclist(ifname, buf, &len) < 0)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
struct json_object *neighbours = json_object_new_object();
|
|
|
|
|
|
|
|
struct iwinfo_assoclist_entry *entry;
|
|
|
|
for (entry = (struct iwinfo_assoclist_entry *)buf; (char*)(entry+1) <= buf + len; entry++) {
|
|
|
|
if (entry->inactive > MAX_INACTIVITY)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
struct json_object *obj = json_object_new_object();
|
|
|
|
|
|
|
|
json_object_object_add(obj, "signal", json_object_new_int(entry->signal));
|
|
|
|
json_object_object_add(obj, "noise", json_object_new_int(entry->noise));
|
|
|
|
json_object_object_add(obj, "inactive", json_object_new_int(entry->inactive));
|
|
|
|
|
|
|
|
char mac[18];
|
|
|
|
snprintf(mac, sizeof(mac), "%02x:%02x:%02x:%02x:%02x:%02x",
|
|
|
|
entry->mac[0], entry->mac[1], entry->mac[2],
|
|
|
|
entry->mac[3], entry->mac[4], entry->mac[5]);
|
|
|
|
|
|
|
|
json_object_object_add(neighbours, mac, obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct json_object *ret = json_object_new_object();
|
|
|
|
|
|
|
|
if (json_object_object_length(neighbours))
|
|
|
|
json_object_object_add(ret, "neighbours", neighbours);
|
|
|
|
else
|
|
|
|
json_object_put(neighbours);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct json_object * get_wifi(void) {
|
|
|
|
struct uci_context *ctx = uci_alloc_context();
|
|
|
|
if (!ctx)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
ctx->flags &= ~UCI_FLAG_STRICT;
|
|
|
|
|
|
|
|
struct json_object *ret = json_object_new_object();
|
|
|
|
|
|
|
|
struct uci_package *p;
|
gluon-respondd: fix missing section "wifi" for request type "neighbours" (#2599)
The below mentioned commit introduced a regression, that the "wifi"
section of the request type "neighbours" was empty:
~# gluon-neighbour-info -d ::1 -r neighbours | ffh_pretty_json
{
"wifi": [
],
...
}
After this commit, the section (correctly) looks like this:
root@UFU-FWH-A272-Tresckowstr-GemR-vorne:~# gluon-neighbour-info -d ::1 -r neighbours | ffh_pretty_json
{
"wifi": {
"ca:38:7e:42:5f:21": {
"neighbours": {
"fe:9f:4d:01:ea:e1": {
"noise": -102,
"inactive": 50,
"signal": -84
},
"fe:df:b9:84:37:51": {
"noise": -102,
"inactive": 20,
"signal": -73
}
}
}
},
...
}
The issue was due to the fact, that the iteration over the (mesh) wifi interfaces
was broken. The code was assuming, that the section
config interface 'mesh_radio0'
option proto 'gluon_mesh'
in /etc/config/network contains an option "ifname", which it does not.
The ifname property is only stored in the corresponding section in
/etc/config/wireless:
config wifi-iface 'mesh_radio0'
option ifname 'mesh0'
option network 'mesh_radio0'
option mode 'mesh'
...
Therefore, we now iterate over wifi-ifaces in /etc/config/wireless, that
have the mode 'mesh' instead. This resolves the issue.
Fixes 0f1fa243f781ee5eef9ed4bc1b3c5397136ac2da
2022-08-09 20:24:44 +00:00
|
|
|
if (uci_load(ctx, "wireless", &p))
|
2019-11-23 20:32:15 +00:00
|
|
|
goto end;
|
|
|
|
|
|
|
|
|
|
|
|
struct uci_element *e;
|
|
|
|
uci_foreach_element(&p->sections, e) {
|
|
|
|
struct uci_section *s = uci_to_section(e);
|
gluon-respondd: fix missing section "wifi" for request type "neighbours" (#2599)
The below mentioned commit introduced a regression, that the "wifi"
section of the request type "neighbours" was empty:
~# gluon-neighbour-info -d ::1 -r neighbours | ffh_pretty_json
{
"wifi": [
],
...
}
After this commit, the section (correctly) looks like this:
root@UFU-FWH-A272-Tresckowstr-GemR-vorne:~# gluon-neighbour-info -d ::1 -r neighbours | ffh_pretty_json
{
"wifi": {
"ca:38:7e:42:5f:21": {
"neighbours": {
"fe:9f:4d:01:ea:e1": {
"noise": -102,
"inactive": 50,
"signal": -84
},
"fe:df:b9:84:37:51": {
"noise": -102,
"inactive": 20,
"signal": -73
}
}
}
},
...
}
The issue was due to the fact, that the iteration over the (mesh) wifi interfaces
was broken. The code was assuming, that the section
config interface 'mesh_radio0'
option proto 'gluon_mesh'
in /etc/config/network contains an option "ifname", which it does not.
The ifname property is only stored in the corresponding section in
/etc/config/wireless:
config wifi-iface 'mesh_radio0'
option ifname 'mesh0'
option network 'mesh_radio0'
option mode 'mesh'
...
Therefore, we now iterate over wifi-ifaces in /etc/config/wireless, that
have the mode 'mesh' instead. This resolves the issue.
Fixes 0f1fa243f781ee5eef9ed4bc1b3c5397136ac2da
2022-08-09 20:24:44 +00:00
|
|
|
if (strcmp(s->type, "wifi-iface"))
|
2019-11-23 20:32:15 +00:00
|
|
|
continue;
|
|
|
|
|
gluon-respondd: fix missing section "wifi" for request type "neighbours" (#2599)
The below mentioned commit introduced a regression, that the "wifi"
section of the request type "neighbours" was empty:
~# gluon-neighbour-info -d ::1 -r neighbours | ffh_pretty_json
{
"wifi": [
],
...
}
After this commit, the section (correctly) looks like this:
root@UFU-FWH-A272-Tresckowstr-GemR-vorne:~# gluon-neighbour-info -d ::1 -r neighbours | ffh_pretty_json
{
"wifi": {
"ca:38:7e:42:5f:21": {
"neighbours": {
"fe:9f:4d:01:ea:e1": {
"noise": -102,
"inactive": 50,
"signal": -84
},
"fe:df:b9:84:37:51": {
"noise": -102,
"inactive": 20,
"signal": -73
}
}
}
},
...
}
The issue was due to the fact, that the iteration over the (mesh) wifi interfaces
was broken. The code was assuming, that the section
config interface 'mesh_radio0'
option proto 'gluon_mesh'
in /etc/config/network contains an option "ifname", which it does not.
The ifname property is only stored in the corresponding section in
/etc/config/wireless:
config wifi-iface 'mesh_radio0'
option ifname 'mesh0'
option network 'mesh_radio0'
option mode 'mesh'
...
Therefore, we now iterate over wifi-ifaces in /etc/config/wireless, that
have the mode 'mesh' instead. This resolves the issue.
Fixes 0f1fa243f781ee5eef9ed4bc1b3c5397136ac2da
2022-08-09 20:24:44 +00:00
|
|
|
const char *proto = uci_lookup_option_string(ctx, s, "mode");
|
|
|
|
if (!proto || strcmp(proto, "mesh"))
|
2019-11-23 20:32:15 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
const char *ifname = uci_lookup_option_string(ctx, s, "ifname");
|
|
|
|
if (!ifname)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
char *ifaddr = gluonutil_get_interface_address(ifname);
|
|
|
|
if (!ifaddr)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
struct json_object *neighbours = get_wifi_neighbours(ifname);
|
|
|
|
if (neighbours)
|
|
|
|
json_object_object_add(ret, ifaddr, neighbours);
|
|
|
|
|
|
|
|
free(ifaddr);
|
|
|
|
}
|
|
|
|
|
|
|
|
end:
|
|
|
|
uci_free_context(ctx);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct json_object * respondd_provider_neighbours(void) {
|
|
|
|
struct json_object *ret = json_object_new_object();
|
|
|
|
|
|
|
|
json_object_object_add(ret, "node_id", gluonutil_wrap_and_free_string(gluonutil_get_node_id()));
|
|
|
|
|
|
|
|
struct json_object *wifi = get_wifi();
|
|
|
|
if (wifi)
|
|
|
|
json_object_object_add(ret, "wifi", wifi);
|
|
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|