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 [APMSG_HOST_INFO] = { .type = BLOB_ATTR_NESTED }, 30 }; 31 struct blob_attr *tb[__APMSG_MAX]; 32 33 blob_parse(data, tb, policy, __APMSG_MAX); 34 if (!tb[APMSG_ID] || !tb[APMSG_SEQ] || !tb[APMSG_NODES]) 35 return false; 36 37 msg->id = blob_get_int32(tb[APMSG_ID]); 38 msg->seq = blob_get_int32(tb[APMSG_SEQ]); 39 msg->nodes = tb[APMSG_NODES]; 40 msg->host_info = tb[APMSG_HOST_INFO]; 41 42 return true; 43 } 44 45 static int 46 get_int32(struct blob_attr *attr) 47 { 48 if (!attr) 49 return 0; 50 51 return blob_get_int32(attr); 52 } 53 54 bool parse_apmsg_node(struct apmsg_node *msg, struct blob_attr *data) 55 { 56 static const struct blob_attr_info policy[__APMSG_NODE_MAX] = { 57 [APMSG_NODE_NAME] = { .type = BLOB_ATTR_STRING }, 58 [APMSG_NODE_BSSID] = { .type = BLOB_ATTR_BINARY }, 59 [APMSG_NODE_FREQ] = { .type = BLOB_ATTR_INT32 }, 60 [APMSG_NODE_N_ASSOC] = { .type = BLOB_ATTR_INT32 }, 61 [APMSG_NODE_MAX_ASSOC] = { .type = BLOB_ATTR_INT32 }, 62 [APMSG_NODE_STATIONS] = { .type = BLOB_ATTR_NESTED }, 63 [APMSG_NODE_NOISE] = { .type = BLOB_ATTR_INT32 }, 64 [APMSG_NODE_LOAD] = { .type = BLOB_ATTR_INT32 }, 65 [APMSG_NODE_RRM_NR] = { .type = BLOB_ATTR_NESTED }, 66 [APMSG_NODE_NODE_INFO] = { .type = BLOB_ATTR_NESTED }, 67 [APMSG_NODE_CHANNEL] = { .type = BLOB_ATTR_INT32 }, 68 [APMSG_NODE_OP_CLASS] = { .type = BLOB_ATTR_INT32 }, 69 }; 70 struct blob_attr *tb[__APMSG_NODE_MAX]; 71 struct blob_attr *cur; 72 73 blob_parse(data, tb, policy, __APMSG_NODE_MAX); 74 if (!tb[APMSG_NODE_NAME] || 75 !tb[APMSG_NODE_BSSID] || 76 blob_len(tb[APMSG_NODE_BSSID]) != 6 || 77 !tb[APMSG_NODE_FREQ] || 78 !tb[APMSG_NODE_N_ASSOC] || 79 !tb[APMSG_NODE_STATIONS] || 80 !tb[APMSG_NODE_SSID]) 81 return false; 82 83 msg->name = blob_data(tb[APMSG_NODE_NAME]); 84 msg->n_assoc = blob_get_int32(tb[APMSG_NODE_N_ASSOC]); 85 msg->freq = blob_get_int32(tb[APMSG_NODE_FREQ]); 86 msg->stations = tb[APMSG_NODE_STATIONS]; 87 msg->ssid = blob_data(tb[APMSG_NODE_SSID]); 88 msg->bssid = blob_data(tb[APMSG_NODE_BSSID]); 89 90 msg->noise = get_int32(tb[APMSG_NODE_NOISE]); 91 msg->load = get_int32(tb[APMSG_NODE_LOAD]); 92 msg->max_assoc = get_int32(tb[APMSG_NODE_MAX_ASSOC]); 93 msg->rrm_nr = NULL; 94 95 if (tb[APMSG_NODE_CHANNEL] && tb[APMSG_NODE_OP_CLASS]) { 96 msg->channel = blob_get_int32(tb[APMSG_NODE_CHANNEL]); 97 msg->op_class = blob_get_int32(tb[APMSG_NODE_OP_CLASS]); 98 } 99 100 cur = tb[APMSG_NODE_RRM_NR]; 101 if (cur && blob_len(cur) >= sizeof(struct blob_attr) && 102 blob_len(cur) >= blob_pad_len(blob_data(cur))) { 103 int rem; 104 105 msg->rrm_nr = blob_data(cur); 106 107 blobmsg_for_each_attr(cur, msg->rrm_nr, rem) { 108 if (blobmsg_check_attr(cur, false)) 109 continue; 110 if (blobmsg_type(cur) == BLOBMSG_TYPE_STRING) 111 continue; 112 msg->rrm_nr = NULL; 113 break; 114 } 115 116 if (msg->rrm_nr && 117 blobmsg_type(msg->rrm_nr) != BLOBMSG_TYPE_ARRAY) 118 msg->rrm_nr = NULL; 119 } 120 121 msg->node_info = tb[APMSG_NODE_NODE_INFO]; 122 123 return true; 124 } 125 126 bool parse_apmsg_sta(struct apmsg_sta *msg, struct blob_attr *data) 127 { 128 static const struct blob_attr_info policy[__APMSG_STA_MAX] = { 129 [APMSG_STA_ADDR] = { .type = BLOB_ATTR_BINARY }, 130 [APMSG_STA_SIGNAL] = { .type = BLOB_ATTR_INT32 }, 131 [APMSG_STA_SEEN] = { .type = BLOB_ATTR_INT32 }, 132 [APMSG_STA_TIMEOUT] = { .type = BLOB_ATTR_INT32 }, 133 [APMSG_STA_CONNECTED] = { .type = BLOB_ATTR_INT8 }, 134 [APMSG_STA_LAST_CONNECTED] = { .type = BLOB_ATTR_INT32 }, 135 }; 136 struct blob_attr *tb[__APMSG_STA_MAX]; 137 138 blob_parse(data, tb, policy, __APMSG_STA_MAX); 139 if (!tb[APMSG_STA_ADDR] || 140 !tb[APMSG_STA_SIGNAL] || 141 !tb[APMSG_STA_SEEN] || 142 !tb[APMSG_STA_TIMEOUT] || 143 !tb[APMSG_STA_CONNECTED] || 144 !tb[APMSG_STA_LAST_CONNECTED]) 145 return false; 146 147 if (blob_len(tb[APMSG_STA_ADDR]) != sizeof(msg->addr)) 148 return false; 149 150 memcpy(msg->addr, blob_data(tb[APMSG_STA_ADDR]), sizeof(msg->addr)); 151 msg->signal = blob_get_int32(tb[APMSG_STA_SIGNAL]); 152 msg->seen = blob_get_int32(tb[APMSG_STA_SEEN]); 153 msg->timeout = blob_get_int32(tb[APMSG_STA_TIMEOUT]); 154 msg->connected = blob_get_int8(tb[APMSG_STA_CONNECTED]); 155 msg->last_connected = blob_get_int32(tb[APMSG_STA_LAST_CONNECTED]); 156 157 return true; 158 } 159
This page was automatically generated by LXR 0.3.1. • OpenWrt