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.
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.
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.
15 * Copyright (C) 2020 embedd.ch
16 * Copyright (C) 2020 Felix Fietkau <nbd@nbd.name>
17 * Copyright (C) 2020 John Crispin <john@phrozen.org>
23 static struct blob_buf b
;
26 netifd_parse_interface_config(struct usteer_local_node
*ln
, struct blob_attr
*msg
)
28 static const struct blobmsg_policy policy
= {
30 .type
= BLOBMSG_TYPE_INT32
,
32 struct blob_attr
*cur
;
35 blobmsg_parse(&policy
, 1, &cur
, blobmsg_data(msg
), blobmsg_data_len(msg
));
37 val
= blobmsg_get_u32(cur
);
39 ln
->node
.max_assoc
= val
;
40 ln
->netifd
.status_complete
= true;
44 netifd_parse_interface(struct usteer_local_node
*ln
, struct blob_attr
*msg
)
51 static const struct blobmsg_policy policy
[__N_IF_MAX
] = {
52 [N_IF_CONFIG
] = { .name
= "config", .type
= BLOBMSG_TYPE_TABLE
},
53 [N_IF_NAME
] = { .name
= "ifname", .type
= BLOBMSG_TYPE_STRING
},
55 struct blob_attr
*tb
[__N_IF_MAX
];
57 if (blobmsg_type(msg
) != BLOBMSG_TYPE_TABLE
)
60 blobmsg_parse(policy
, __N_IF_MAX
, tb
, blobmsg_data(msg
), blobmsg_data_len(msg
));
61 if (!tb
[N_IF_CONFIG
] || !tb
[N_IF_NAME
])
64 if (strcmp(blobmsg_get_string(tb
[N_IF_NAME
]), ln
->iface
) != 0)
67 netifd_parse_interface_config(ln
, tb
[N_IF_CONFIG
]);
71 netifd_parse_radio(struct usteer_local_node
*ln
, struct blob_attr
*msg
)
73 static const struct blobmsg_policy policy
= {
75 .type
= BLOBMSG_TYPE_ARRAY
,
77 struct blob_attr
*cur
, *iface
;
80 if (blobmsg_type(msg
) != BLOBMSG_TYPE_TABLE
)
83 blobmsg_parse(&policy
, 1, &iface
, blobmsg_data(msg
), blobmsg_data_len(msg
));
87 blobmsg_for_each_attr(cur
, iface
, rem
)
88 netifd_parse_interface(ln
, cur
);
92 netifd_status_cb(struct ubus_request
*req
, int type
, struct blob_attr
*msg
)
94 struct usteer_local_node
*ln
;
95 struct blob_attr
*cur
;
98 ln
= container_of(req
, struct usteer_local_node
, netifd
.req
);
99 ln
->netifd
.req_pending
= false;
101 blobmsg_for_each_attr(cur
, msg
, rem
)
102 netifd_parse_radio(ln
, cur
);
105 static void netifd_update_node(struct usteer_node
*node
)
107 struct usteer_local_node
*ln
;
110 ln
= container_of(node
, struct usteer_local_node
, node
);
111 if (ln
->netifd
.status_complete
)
114 if (ln
->netifd
.req_pending
)
115 ubus_abort_request(ubus_ctx
, &ln
->netifd
.req
);
117 if (ubus_lookup_id(ubus_ctx
, "network.wireless", &id
))
120 blob_buf_init(&b
, 0);
121 ubus_invoke_async(ubus_ctx
, id
, "status", b
.head
, &ln
->netifd
.req
);
122 ln
->netifd
.req
.data_cb
= netifd_status_cb
;
123 ubus_complete_request_async(ubus_ctx
, &ln
->netifd
.req
);
124 ln
->netifd
.req_pending
= true;
127 static void netifd_init_node(struct usteer_node
*node
)
129 struct usteer_local_node
*ln
;
131 ln
= container_of(node
, struct usteer_local_node
, node
);
132 ln
->netifd
.status_complete
= false;
133 netifd_update_node(node
);
136 static void netifd_free_node(struct usteer_node
*node
)
138 struct usteer_local_node
*ln
;
140 ln
= container_of(node
, struct usteer_local_node
, node
);
141 if (ln
->netifd
.req_pending
)
142 ubus_abort_request(ubus_ctx
, &ln
->netifd
.req
);
145 static struct usteer_node_handler netifd_handler
= {
146 .init_node
= netifd_init_node
,
147 .update_node
= netifd_update_node
,
148 .free_node
= netifd_free_node
,
151 static void __usteer_init
usteer_netifd_init(void)
153 list_add(&netifd_handler
.list
, &node_handlers
);