142
parse.c
Normal file
142
parse.c
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Copyright (C) 2020 embedd.ch
|
||||
* Copyright (C) 2020 Felix Fietkau <nbd@nbd.name>
|
||||
* Copyright (C) 2020 John Crispin <john@phrozen.org>
|
||||
*/
|
||||
|
||||
#include "usteer.h"
|
||||
#include "remote.h"
|
||||
|
||||
bool parse_apmsg(struct apmsg *msg, struct blob_attr *data)
|
||||
{
|
||||
static const struct blob_attr_info policy[__APMSG_MAX] = {
|
||||
[APMSG_ID] = { .type = BLOB_ATTR_INT32 },
|
||||
[APMSG_SEQ] = { .type = BLOB_ATTR_INT32 },
|
||||
[APMSG_NODES] = { .type = BLOB_ATTR_NESTED },
|
||||
};
|
||||
struct blob_attr *tb[__APMSG_MAX];
|
||||
|
||||
blob_parse(data, tb, policy, __APMSG_MAX);
|
||||
if (!tb[APMSG_ID] || !tb[APMSG_SEQ] || !tb[APMSG_NODES])
|
||||
return false;
|
||||
|
||||
msg->id = blob_get_int32(tb[APMSG_ID]);
|
||||
msg->seq = blob_get_int32(tb[APMSG_SEQ]);
|
||||
msg->nodes = tb[APMSG_NODES];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int
|
||||
get_int32(struct blob_attr *attr)
|
||||
{
|
||||
if (!attr)
|
||||
return 0;
|
||||
|
||||
return blob_get_int32(attr);
|
||||
}
|
||||
|
||||
bool parse_apmsg_node(struct apmsg_node *msg, struct blob_attr *data)
|
||||
{
|
||||
static const struct blob_attr_info policy[__APMSG_NODE_MAX] = {
|
||||
[APMSG_NODE_NAME] = { .type = BLOB_ATTR_STRING },
|
||||
[APMSG_NODE_FREQ] = { .type = BLOB_ATTR_INT32 },
|
||||
[APMSG_NODE_N_ASSOC] = { .type = BLOB_ATTR_INT32 },
|
||||
[APMSG_NODE_MAX_ASSOC] = { .type = BLOB_ATTR_INT32 },
|
||||
[APMSG_NODE_STATIONS] = { .type = BLOB_ATTR_NESTED },
|
||||
[APMSG_NODE_NOISE] = { .type = BLOB_ATTR_INT32 },
|
||||
[APMSG_NODE_LOAD] = { .type = BLOB_ATTR_INT32 },
|
||||
[APMSG_NODE_RRM_NR] = { .type = BLOB_ATTR_NESTED },
|
||||
[APMSG_NODE_SCRIPT_DATA] = { .type = BLOB_ATTR_NESTED },
|
||||
};
|
||||
struct blob_attr *tb[__APMSG_NODE_MAX];
|
||||
struct blob_attr *cur;
|
||||
|
||||
blob_parse(data, tb, policy, __APMSG_NODE_MAX);
|
||||
if (!tb[APMSG_NODE_NAME] ||
|
||||
!tb[APMSG_NODE_FREQ] ||
|
||||
!tb[APMSG_NODE_N_ASSOC] ||
|
||||
!tb[APMSG_NODE_STATIONS] ||
|
||||
!tb[APMSG_NODE_SSID])
|
||||
return false;
|
||||
|
||||
msg->name = blob_data(tb[APMSG_NODE_NAME]);
|
||||
msg->n_assoc = blob_get_int32(tb[APMSG_NODE_N_ASSOC]);
|
||||
msg->freq = blob_get_int32(tb[APMSG_NODE_FREQ]);
|
||||
msg->stations = tb[APMSG_NODE_STATIONS];
|
||||
msg->ssid = blob_data(tb[APMSG_NODE_SSID]);
|
||||
|
||||
msg->noise = get_int32(tb[APMSG_NODE_NOISE]);
|
||||
msg->load = get_int32(tb[APMSG_NODE_LOAD]);
|
||||
msg->max_assoc = get_int32(tb[APMSG_NODE_MAX_ASSOC]);
|
||||
msg->rrm_nr = NULL;
|
||||
|
||||
cur = tb[APMSG_NODE_RRM_NR];
|
||||
if (cur && blob_len(cur) >= sizeof(struct blob_attr) &&
|
||||
blob_len(cur) >= blob_pad_len(blob_data(cur))) {
|
||||
int rem;
|
||||
|
||||
msg->rrm_nr = blob_data(cur);
|
||||
|
||||
blobmsg_for_each_attr(cur, msg->rrm_nr, rem) {
|
||||
if (blobmsg_check_attr(cur, false))
|
||||
continue;
|
||||
if (blobmsg_type(cur) == BLOBMSG_TYPE_STRING)
|
||||
continue;
|
||||
msg->rrm_nr = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (msg->rrm_nr &&
|
||||
blobmsg_type(msg->rrm_nr) != BLOBMSG_TYPE_ARRAY)
|
||||
msg->rrm_nr = NULL;
|
||||
}
|
||||
|
||||
msg->script_data = tb[APMSG_NODE_SCRIPT_DATA];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool parse_apmsg_sta(struct apmsg_sta *msg, struct blob_attr *data)
|
||||
{
|
||||
static const struct blob_attr_info policy[__APMSG_STA_MAX] = {
|
||||
[APMSG_STA_ADDR] = { .type = BLOB_ATTR_BINARY },
|
||||
[APMSG_STA_SIGNAL] = { .type = BLOB_ATTR_INT32 },
|
||||
[APMSG_STA_SEEN] = { .type = BLOB_ATTR_INT32 },
|
||||
[APMSG_STA_TIMEOUT] = { .type = BLOB_ATTR_INT32 },
|
||||
[APMSG_STA_CONNECTED] = { .type = BLOB_ATTR_INT8 },
|
||||
};
|
||||
struct blob_attr *tb[__APMSG_STA_MAX];
|
||||
|
||||
blob_parse(data, tb, policy, __APMSG_STA_MAX);
|
||||
if (!tb[APMSG_STA_ADDR] ||
|
||||
!tb[APMSG_STA_SIGNAL] ||
|
||||
!tb[APMSG_STA_SEEN] ||
|
||||
!tb[APMSG_STA_TIMEOUT] ||
|
||||
!tb[APMSG_STA_CONNECTED])
|
||||
return false;
|
||||
|
||||
if (blob_len(tb[APMSG_STA_ADDR]) != sizeof(msg->addr))
|
||||
return false;
|
||||
|
||||
memcpy(msg->addr, blob_data(tb[APMSG_STA_ADDR]), sizeof(msg->addr));
|
||||
msg->signal = blob_get_int32(tb[APMSG_STA_SIGNAL]);
|
||||
msg->seen = blob_get_int32(tb[APMSG_STA_SEEN]);
|
||||
msg->timeout = blob_get_int32(tb[APMSG_STA_TIMEOUT]);
|
||||
msg->connected = blob_get_int8(tb[APMSG_STA_CONNECTED]);
|
||||
|
||||
return true;
|
||||
}
|
Reference in New Issue
Block a user