rename script_data to node_info
[project/usteer.git] / parse.c
1 /*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
14 *
15 * Copyright (C) 2020 embedd.ch
16 * Copyright (C) 2020 Felix Fietkau <nbd@nbd.name>
17 * Copyright (C) 2020 John Crispin <john@phrozen.org>
18 */
19
20 #include "usteer.h"
21 #include "remote.h"
22
23 bool parse_apmsg(struct apmsg *msg, struct blob_attr *data)
24 {
25 static const struct blob_attr_info policy[__APMSG_MAX] = {
26 [APMSG_ID] = { .type = BLOB_ATTR_INT32 },
27 [APMSG_SEQ] = { .type = BLOB_ATTR_INT32 },
28 [APMSG_NODES] = { .type = BLOB_ATTR_NESTED },
29 };
30 struct blob_attr *tb[__APMSG_MAX];
31
32 blob_parse(data, tb, policy, __APMSG_MAX);
33 if (!tb[APMSG_ID] || !tb[APMSG_SEQ] || !tb[APMSG_NODES])
34 return false;
35
36 msg->id = blob_get_int32(tb[APMSG_ID]);
37 msg->seq = blob_get_int32(tb[APMSG_SEQ]);
38 msg->nodes = tb[APMSG_NODES];
39
40 return true;
41 }
42
43 static int
44 get_int32(struct blob_attr *attr)
45 {
46 if (!attr)
47 return 0;
48
49 return blob_get_int32(attr);
50 }
51
52 bool parse_apmsg_node(struct apmsg_node *msg, struct blob_attr *data)
53 {
54 static const struct blob_attr_info policy[__APMSG_NODE_MAX] = {
55 [APMSG_NODE_NAME] = { .type = BLOB_ATTR_STRING },
56 [APMSG_NODE_FREQ] = { .type = BLOB_ATTR_INT32 },
57 [APMSG_NODE_N_ASSOC] = { .type = BLOB_ATTR_INT32 },
58 [APMSG_NODE_MAX_ASSOC] = { .type = BLOB_ATTR_INT32 },
59 [APMSG_NODE_STATIONS] = { .type = BLOB_ATTR_NESTED },
60 [APMSG_NODE_NOISE] = { .type = BLOB_ATTR_INT32 },
61 [APMSG_NODE_LOAD] = { .type = BLOB_ATTR_INT32 },
62 [APMSG_NODE_RRM_NR] = { .type = BLOB_ATTR_NESTED },
63 [APMSG_NODE_NODE_INFO] = { .type = BLOB_ATTR_NESTED },
64 };
65 struct blob_attr *tb[__APMSG_NODE_MAX];
66 struct blob_attr *cur;
67
68 blob_parse(data, tb, policy, __APMSG_NODE_MAX);
69 if (!tb[APMSG_NODE_NAME] ||
70 !tb[APMSG_NODE_FREQ] ||
71 !tb[APMSG_NODE_N_ASSOC] ||
72 !tb[APMSG_NODE_STATIONS] ||
73 !tb[APMSG_NODE_SSID])
74 return false;
75
76 msg->name = blob_data(tb[APMSG_NODE_NAME]);
77 msg->n_assoc = blob_get_int32(tb[APMSG_NODE_N_ASSOC]);
78 msg->freq = blob_get_int32(tb[APMSG_NODE_FREQ]);
79 msg->stations = tb[APMSG_NODE_STATIONS];
80 msg->ssid = blob_data(tb[APMSG_NODE_SSID]);
81
82 msg->noise = get_int32(tb[APMSG_NODE_NOISE]);
83 msg->load = get_int32(tb[APMSG_NODE_LOAD]);
84 msg->max_assoc = get_int32(tb[APMSG_NODE_MAX_ASSOC]);
85 msg->rrm_nr = NULL;
86
87 cur = tb[APMSG_NODE_RRM_NR];
88 if (cur && blob_len(cur) >= sizeof(struct blob_attr) &&
89 blob_len(cur) >= blob_pad_len(blob_data(cur))) {
90 int rem;
91
92 msg->rrm_nr = blob_data(cur);
93
94 blobmsg_for_each_attr(cur, msg->rrm_nr, rem) {
95 if (blobmsg_check_attr(cur, false))
96 continue;
97 if (blobmsg_type(cur) == BLOBMSG_TYPE_STRING)
98 continue;
99 msg->rrm_nr = NULL;
100 break;
101 }
102
103 if (msg->rrm_nr &&
104 blobmsg_type(msg->rrm_nr) != BLOBMSG_TYPE_ARRAY)
105 msg->rrm_nr = NULL;
106 }
107
108 msg->node_info = tb[APMSG_NODE_NODE_INFO];
109
110 return true;
111 }
112
113 bool parse_apmsg_sta(struct apmsg_sta *msg, struct blob_attr *data)
114 {
115 static const struct blob_attr_info policy[__APMSG_STA_MAX] = {
116 [APMSG_STA_ADDR] = { .type = BLOB_ATTR_BINARY },
117 [APMSG_STA_SIGNAL] = { .type = BLOB_ATTR_INT32 },
118 [APMSG_STA_SEEN] = { .type = BLOB_ATTR_INT32 },
119 [APMSG_STA_TIMEOUT] = { .type = BLOB_ATTR_INT32 },
120 [APMSG_STA_CONNECTED] = { .type = BLOB_ATTR_INT8 },
121 };
122 struct blob_attr *tb[__APMSG_STA_MAX];
123
124 blob_parse(data, tb, policy, __APMSG_STA_MAX);
125 if (!tb[APMSG_STA_ADDR] ||
126 !tb[APMSG_STA_SIGNAL] ||
127 !tb[APMSG_STA_SEEN] ||
128 !tb[APMSG_STA_TIMEOUT] ||
129 !tb[APMSG_STA_CONNECTED])
130 return false;
131
132 if (blob_len(tb[APMSG_STA_ADDR]) != sizeof(msg->addr))
133 return false;
134
135 memcpy(msg->addr, blob_data(tb[APMSG_STA_ADDR]), sizeof(msg->addr));
136 msg->signal = blob_get_int32(tb[APMSG_STA_SIGNAL]);
137 msg->seen = blob_get_int32(tb[APMSG_STA_SEEN]);
138 msg->timeout = blob_get_int32(tb[APMSG_STA_TIMEOUT]);
139 msg->connected = blob_get_int8(tb[APMSG_STA_CONNECTED]);
140
141 return true;
142 }