Newer
Older
/*
* config.c - configurations handling
*
* Copyright (C) 2019 IOPSYS Software Solutions AB. All rights reserved.
*
* Author: anjan.chanda@iopsys.eu
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#ifndef IFNAMSIZ
#define IFNAMSIZ 16
#endif
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <json-c/json.h>
#include <libubox/blobmsg.h>
#include <libubox/blobmsg_json.h>
#include <libubox/uloop.h>
#include <libubox/ustream.h>
#include <libubox/utils.h>
#include <libubus.h>
#include <uci.h>
#include "debug.h"
#include "utils.h"
#include "config.h"
#include "steer_rules.h"
#include "comm.h"
#include "msgqueue.h"
#include "worker.h"
// UCI sections
#define UCI_BK_AGENT "bk-iface"
#define UCI_FH_AGENT "fh-iface"
#define UCI_WLAN_IFACE "wifi-iface"
#define UCI_WL_DEVICE "wifi-device"
#define UCI_WIRELESS "wireless"
#define UCI_IEEE1905 "ieee1905"
Jakob Olsson
committed
#define UCI_AGENT "mapagent"
char *replace_char(char *str, char find, char replace)
{
char *current_pos = strchr(str, find);
while (current_pos) {
*current_pos = replace;
current_pos = strchr(current_pos, find);
}
return str;
}
int set_value(struct uci_context *ctx, struct uci_package *pkg,
struct uci_section *section, const char *key,
const char *value, enum uci_option_type type)
{
struct uci_ptr ptr = {0};
ptr.p = pkg;
ptr.s = section;
ptr.option = key;
ptr.value = value;
if (type == UCI_TYPE_STRING)
return uci_set(ctx, &ptr);
if (type == UCI_TYPE_LIST)
return uci_add_list(ctx, &ptr);
return -1;
}
Jakob Olsson
committed
int set_value_by_string(const char *package, const char *section,
const char *key, const char *value, enum uci_option_type type)
{
struct uci_ptr ptr = {0};
struct uci_context *ctx;
int rv;
ctx = uci_alloc_context();
if (!ctx)
return -1;
ptr.package = package;
ptr.section = section;
ptr.option = key;
ptr.value = value;
if (type == UCI_TYPE_STRING)
rv = uci_set(ctx, &ptr);
if (type == UCI_TYPE_LIST)
rv = uci_add_list(ctx, &ptr);
uci_commit(ctx, &ptr.p, false);
uci_free_context(ctx);
return rv;
Jakob Olsson
committed
}
struct uci_section *config_get_section(struct uci_context *ctx,
struct uci_package *pkg, const char *type, const char *key,
const char *value)
{
struct uci_element *e;
struct uci_section *section;
/* get the wet iface section */
uci_foreach_element(&pkg->sections, e) {
const char *c_value;
section = uci_to_section(e);
c_value = uci_lookup_option_string(ctx, section, key);
if (c_value && !strcmp(c_value, value))
return section;
}
return NULL;
}
struct uci_package *uci_load_pkg(struct uci_context **ctx, const char *config)
{
struct uci_package *pkg;
if (!*ctx) {
*ctx = uci_alloc_context();
if (!*ctx)
return NULL;
}
Jakob Olsson
committed
if (uci_load(*ctx, config, &pkg) != UCI_OK) {
free(*ctx);
return NULL;
}
return pkg;
}
Jakob Olsson
committed
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
/* TODO: causes segfault in disc? */
char *uci_get_bridge(char *ifname, char *bridge)
{
struct uci_context *ctx;
struct uci_package *pkg;
struct uci_element *e;
strncpy(bridge, "lan", 15);
return bridge;
pkg = uci_load_pkg(&ctx, UCI_WIRELESS);
if (!pkg)
return NULL;
uci_foreach_element(&pkg->sections, e) {
struct uci_section *s = uci_to_section(e);
struct uci_option *opt;
if (strcmp(s->type, UCI_WLAN_IFACE))
continue;
opt = uci_lookup_option(ctx, s, "ifname");
if (!opt || opt->type != UCI_TYPE_STRING)
continue;
if (!strncmp(opt->v.string, ifname, 16))
continue;
opt = uci_lookup_option(ctx, s, "network");
if (!opt || opt->type != UCI_TYPE_STRING)
continue;
strncpy(bridge, opt->v.string, 16);
break;
}
uci_unload(ctx, pkg);
uci_free_context(ctx);
return bridge;
}
/* TODO: can it be generalized? */
int wifi_set_iface_bssid(const char *ifname, uint8_t *bssid)
{
struct uci_context *ctx = NULL;
struct uci_package *pkg;
struct uci_section *section;
char bssid_str[18] = {0};
int ret = -1;
pkg = uci_load_pkg(&ctx, "wireless");
if (!pkg)
return ret;
section = config_get_section(ctx, pkg, "wifi-iface", "ifname", ifname);
if (!section)
goto out_pkg;
if (bssid && !hwaddr_ntoa(bssid, bssid_str))
goto out_pkg;
ret = set_value(ctx, pkg, section, "bssid", bssid_str, UCI_TYPE_STRING);
uci_commit(ctx, &pkg, false);
uci_reload_services("wireless");
out_pkg:
uci_unload(ctx, pkg);
uci_free_context(ctx);
return ret;
}
int config_del_iface(const char *config, const char *type, const char *ifname)
{
struct uci_context *ctx;
struct uci_package *pkg;
struct uci_section *section;
struct uci_ptr ptr = {0};
int rv = -1;
ctx = uci_alloc_context();
if (!ctx)
goto out;
if (uci_load(ctx, config, &pkg) != UCI_OK) {
dbg("config file 'wireless' not found!\n");
goto out_uci;
}
section = config_get_section(ctx, pkg, type, "ifname", ifname);
if (!section)
goto out_pkg;
ptr.p = pkg;
ptr.s = section;
uci_delete(ctx, &ptr);
uci_commit(ctx, &pkg, false);
out_pkg:
uci_unload(ctx, pkg);
out_uci:
uci_free_context(ctx);
out:
return rv;
}
int wifi_apply_iface_cfg(const char *ifname, const char *encryption,
const char *ssid, const char *key)
{
struct uci_context *ctx;
struct uci_package *pkg;
struct uci_section *section;
int rv = -1;
ctx = uci_alloc_context();
if (!ctx)
goto out;
if (uci_load(ctx, "wireless", &pkg) != UCI_OK) {
dbg("config file 'wireless' not found!\n");
goto out_uci;
}
section = config_get_section(ctx, pkg, "wifi-iface", "ifname", ifname);
if (!section)
goto out_pkg;
set_value(ctx, pkg, section, "encryption", encryption, UCI_TYPE_STRING);
set_value(ctx, pkg, section, "ssid", ssid, UCI_TYPE_STRING);
set_value(ctx, pkg, section, "key", key, UCI_TYPE_STRING);
Jakob Olsson
committed
set_value(ctx, pkg, section, "wds", "1", UCI_TYPE_STRING);
uci_commit(ctx, &pkg, false);
out_pkg:
uci_unload(ctx, pkg);
out_uci:
uci_free_context(ctx);
out:
return rv;
}
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
char *agent_config_get_ethwan(char *ifname)
{
struct uci_context *ctx;
struct uci_ptr ptr = {0};
ctx = uci_alloc_context();
if (!ctx)
return NULL;
//ptr.value = value;
ptr.package = "ports";
ptr.section = "WAN";
ptr.option = "ifname";
ptr.target = UCI_TYPE_OPTION;
if (uci_lookup_ptr(ctx, &ptr, NULL, false)) {
uci_free_context(ctx);
return NULL;
}
strncpy(ifname, ptr.o->v.string, 15);
uci_free_context(ctx);
return ifname;
}
struct uci_section *config_add_section(struct uci_context *ctx,
struct uci_package *pkg, const char *config, const char *type,
const char *key, const char *value)
struct uci_section *section = NULL;
struct uci_ptr ptr = {0};
int rv = -1;
section = config_get_section(ctx, pkg, type, key, value);
if (!section) {
rv = uci_add_section(ctx, pkg, type, §ion);
if (rv)
goto out_pkg;
rv = uci_save(ctx, pkg);
if (rv)
goto out_pkg;
ptr.value = value;
ptr.package = config;
ptr.section = section->e.name;
ptr.option = key;
ptr.target = UCI_TYPE_OPTION;
uci_lookup_ptr(ctx, &ptr, NULL, false);
uci_set(ctx, &ptr);
uci_save(ctx, ptr.p);
return section;
}
int config_add_default_wifi_iface(const char *config, const char *type,
const char *ifname, const char *device, const char *network,
const char *mode)
{
struct uci_context *ctx;
struct uci_package *pkg;
struct uci_section *section;
int rv = -1;
ctx = uci_alloc_context();
if (!ctx)
goto out;
if (uci_load(ctx, config, &pkg) != UCI_OK) {
dbg("config file 'wireless' not found!\n");
goto out_uci;
}
section = config_add_section(ctx, pkg, config, type, "ifname", ifname);
set_value(ctx, pkg, section, "device", device, UCI_TYPE_STRING);
set_value(ctx, pkg, section, "network", network, UCI_TYPE_STRING);
//set_value(ctx, pkg, section, "mode", mode, UCI_TYPE_STRING);
uci_commit(ctx, &pkg, false);
out_pkg:
uci_unload(ctx, pkg);
out_uci:
uci_free_context(ctx);
out:
}
int config_add_default_agent_iface(const char *config, const char *type,
const char *ifname, enum wifi_band band)
{
struct uci_context *ctx;
struct uci_package *pkg;
struct uci_section *section;
int rv = -1;
ctx = uci_alloc_context();
if (!ctx)
goto out;
if (uci_load(ctx, config, &pkg) != UCI_OK) {
dbg("config file 'wireless' not found!\n");
goto out_uci;
}
section = config_add_section(ctx, pkg, config, type, "ifname", ifname);
trace("band = %d\n", band);
if (band == BAND_5)
set_value(ctx, pkg, section, "band", "5", UCI_TYPE_STRING);
if (band == BAND_2)
set_value(ctx, pkg, section, "band", "2", UCI_TYPE_STRING);
uci_commit(ctx, &pkg, false);
out_pkg:
uci_unload(ctx, pkg);
out_uci:
uci_free_context(ctx);
out:
}
/* below functions are mostly taken from ieee1905d */
Jakob Olsson
committed
bool uci_check_wifi_iface(char *package_name, char *ifname,
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
char *section)
{
bool ret;
struct uci_context *ctx;
struct uci_package *pkg;
struct uci_element *e;
if (!package_name || !ifname)
return false;
ctx = uci_alloc_context();
if (!ctx)
return false;
if (uci_load(ctx, package_name, &pkg)) {
uci_free_context(ctx);
return false;
}
ret = false;
uci_foreach_element(&pkg->sections, e) {
struct uci_section *s = uci_to_section(e);
if (!strcmp(s->type, section)) {
struct uci_option *opt = uci_lookup_option(ctx, s,
"ifname");
if (!opt || opt->type != UCI_TYPE_STRING)
continue;
if (strcmp(opt->v.string, ifname) == 0) {
ret = true;
break;
}
}
}
uci_unload(ctx, pkg);
uci_free_context(ctx);
return ret;
}
Jakob Olsson
committed
bool uci_set_wireless_interface_option(char *package_name,
char *section_type, char *search_key, char *search_val,
char *option, char *value)
{
struct uci_context *ctx;
struct uci_package *pkg;
struct uci_element *e;
if (!package_name || !search_val || !option || !value)
return false;
ctx = uci_alloc_context();
if (!ctx)
return false;
if (uci_load(ctx, package_name, &pkg)) {
uci_free_context(ctx);
return false;
}
uci_foreach_element(&pkg->sections, e) {
struct uci_section *s = uci_to_section(e);
if (!strcmp(s->type, section_type)) {
struct uci_option *opt = uci_lookup_option(ctx, s,
if (!opt || opt->type != UCI_TYPE_STRING)
continue;
if (strcmp(opt->v.string, search_val) == 0) {
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
struct uci_ptr ptr = {0};
ptr.value = value;
ptr.package = package_name;
ptr.section = s->e.name;
ptr.option = option;
ptr.target = UCI_TYPE_OPTION;
if (uci_lookup_ptr(ctx, &ptr, NULL, false) ||
!UCI_LOOKUP_COMPLETE)
break;
if (uci_set(ctx, &ptr) == UCI_OK)
uci_save(ctx, ptr.p);
break;
}
}
}
uci_commit(ctx, &pkg, false);
uci_unload(ctx, pkg);
uci_free_context(ctx);
return false;
}
static bool get_encryption_value(uint16_t auth_type, uint16_t encryption_type,
char *encrypt_val, size_t elen)
{
if (!encrypt_val)
return false;
if ((auth_type & WPS_AUTH_WPAPSK) && (auth_type & WPS_AUTH_WPA2PSK))
strncat(encrypt_val, "psk-mixed", elen);
else if ((auth_type & WPS_AUTH_WPA) && (auth_type & WPS_AUTH_WPA2))
strncat(encrypt_val, "wpa-mixed", elen);
else if (auth_type & WPS_AUTH_WPAPSK)
strncat(encrypt_val, "psk", elen);
else if (auth_type & WPS_AUTH_WPA2PSK)
strncat(encrypt_val, "psk2", elen);
else if (auth_type & WPS_AUTH_WPA)
strncat(encrypt_val, "wpa", elen);
else if (auth_type & WPS_AUTH_WPA2)
strncat(encrypt_val, "wpa2", elen);
else if (auth_type & WPS_AUTH_OPEN)
strncat(encrypt_val, "none", elen);
else
return false;
//Check for the encryption type
if ((encryption_type & WPS_ENCR_TKIP) &&
(encryption_type & WPS_ENCR_AES))
strncat(encrypt_val, "+tkip+aes", elen);
else if (encryption_type & WPS_ENCR_TKIP)
strncat(encrypt_val, "+tkip", elen);
else if (encryption_type & WPS_ENCR_AES)
strncat(encrypt_val, "+aes", elen);
return true;
}
Jakob Olsson
committed
bool uci_add_wireless_iface_sec(char *package_name, char *interface_name,
char *section_type, char *section_name)
{
struct uci_context *ctx;
struct uci_package *pkg;
struct uci_section *s;
struct uci_ptr ptr = {0};
bool ret = false;
if (!interface_name || !package_name)
return false;
ctx = uci_alloc_context();
if (!ctx)
return false;
if (uci_load(ctx, package_name, &pkg))
goto out_ctx;
ptr.p = pkg;
if (section_name) {
ptr.section = section_name;
ptr.value = section_type;
ptr.option = NULL;
uci_set(ctx, &ptr);
if (uci_save(ctx, ptr.p) != UCI_OK)
goto out_unload;
} else {
if (uci_add_section(ctx, pkg, section_type, &s) != UCI_OK)
goto out_unload;
ptr.value = interface_name;
ptr.option = "ifname";
ptr.target = UCI_TYPE_OPTION;
uci_lookup_ptr(ctx, &ptr, NULL, false);
uci_set(ctx, &ptr);
uci_save(ctx, ptr.p);
uci_commit(ctx, &pkg, false);
ret = true;
out_unload:
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
}
static int ubus_call(const char *object, const char *method,
struct blob_buf *data, void *callback, void *cb_arg)
{
uint32_t id;
struct ubus_context *ctx = ubus_connect(NULL);
if (!ctx) {
err("ubus_connect failed\n");
return UBUS_STATUS_UNKNOWN_ERROR;
}
if (ubus_lookup_id(ctx, object, &id)) {
err("(%s) not present\n", object);
ubus_free(ctx);
return UBUS_STATUS_UNKNOWN_ERROR;
}
// Invoke Ubus to get data from uspd
if (ubus_invoke(ctx, id, method, data->head, callback, cb_arg, 1000)) {
err("ubus call failed\n");
ubus_free(ctx);
return UBUS_STATUS_UNKNOWN_ERROR;
}
ubus_free(ctx);
return UBUS_STATUS_OK;
}
bool uci_reload_services(char *services)
int rv = 0;
memset(&bb, 0, sizeof(struct blob_buf));
blob_buf_init(&bb, 0);
blobmsg_add_string(&bb, "config", services);
rv = ubus_call("uci", "commit", &bb, NULL, NULL);
info("## Reloading uci config %d\n", rv);
//if (!ubus_call("uci", "reload_config", &bb, NULL, NULL))
// return true;
//ubus_call("uci", "reload_config", &bb, NULL, NULL);
blob_buf_free(&bb);
return false;
}
#if 0 /* Deprecated for 6.1 - Possibly bring back in 6.2 with modifications */
Jakob Olsson
committed
/* TODO: introduce option and vendor extension to make this logic redundant */
int uci_apply_wps_credentials(struct agent_config *cfg, enum wifi_band band)
{
struct netif_bkcfg *bk;
struct netif_fhcfg *fh;
list_for_each_entry(bk, &cfg->bklist, list) {
if (bk->band != band)
continue;
list_for_each_entry(fh, &cfg->fhlist, list) {
if (fh->band != band)
continue;
dbg("Applying bBSS credentials to %s:\n", fh->name);
dbg(" - SSID : %s\n", bk->ssid);
dbg(" - NETWORK_KEY : %s\n", bk->key);
uci_set_wireless_interface_option(UCI_WIRELESS,
UCI_WLAN_IFACE,
Jakob Olsson
committed
fh->name,
"multi_ap_backhaul_ssid",
bk->ssid);
uci_set_wireless_interface_option(UCI_WIRELESS,
UCI_WLAN_IFACE,
Jakob Olsson
committed
fh->name,
"multi_ap_backhaul_key",
bk->key);
uci_set_wireless_interface_option(UCI_WIRELESS,
UCI_WLAN_IFACE, "ifname", fh->name, "wps", "1");
Jakob Olsson
committed
uci_set_wireless_interface_option(UCI_WIRELESS,
UCI_WLAN_IFACE, "ifname", fh->name,
Jakob Olsson
committed
"wps_pushbutton", "1");
}
break;
}
return 0;
}
Jakob Olsson
committed
/* TODO: batch the changes arther than commit oneby one */
int uci_apply_m2(struct agent_config *cfg, char *interface_name, char *device,
struct wps_credential *out, bool onboarded)
{
bool ret;
char auth_type_str[20] = {0};
char multiap_str[2] = {0};
uint8_t multi_ap = 0;
char band_str[2] = {0};
Jakob Olsson
committed
char agent_section[16] = {0};
char ipaddr_str[INET_ADDRSTRLEN] = {0};
char ssid[33] = {0}, network_key[65] = {0}, bridge_buf[16] = {0}, *bridge;
/* step past br- prefix if present*/
if (!strncmp("br-", bridge, 3))
bridge += 3;
dbg("%s %d band = %d\n", __func__, __LINE__, out->band);
if (out->band == BAND_5)
strncpy(band_str, "5", 1);
else if (out->band == BAND_2)
strncpy(band_str, "2", 1);
else /* TODO: 60 */
return M2_PROCESS_ERROR;
memcpy(ssid, out->ssid, out->ssidlen);
memcpy(network_key, out->key, out->keylen);
memcpy(bridge, out->bridge, 15);
inet_ntop(AF_INET, &out->br_ip, ipaddr_str, INET_ADDRSTRLEN);
dbg("Applying WSC configuration (%s):\n", interface_name);
dbg(" - SSID : %s\n", ssid);
dbg(" - AUTH_TYPE : 0x%04x\n", out->auth_type);
dbg(" - ENCRYPTION_TYPE : 0x%04x\n", out->enc_type);
dbg(" - MAPIE_EXTENSION : 0x%02x\n", out->mapie);
dbg(" - BRIDGE : %s\n", bridge);
dbg(" - PROTO : %s\n", out->proto);
dbg(" - VID : 0x%02x\n", out->vid);
dbg(" - BR_IP : %s\n", ipaddr_str);
dbg(" - BK_SSID : %s\n", out->bk_ssid);
dbg(" - BK_KEY : %s\n", out->bk_key);
dbg(" - BAND : %s\n", band_str);
multi_ap |= (BIT(5, out->mapie) << 1);
multi_ap |= BIT(6, out->mapie);
snprintf(multiap_str, sizeof(multiap_str), "%d", multi_ap);
//snprintf(ipaddr_str, sizeof(ipaddr_str), "%d.%d.%d.%d", br_ip[0],
// br_ip[1], br_ip[2], br_ip[3]);
if (!get_encryption_value(out->auth_type, out->enc_type,
auth_type_str, 20)) {
info("Unsupported encryption or cipher received!!\n");
return M2_PROCESS_ERROR;
}
ret = uci_set_bridge("network", bridge, out->proto, ipaddr_str);
if (ret) {
info("Error seting up bridge from M2!\n");
return M2_PROCESS_ERROR;
}
strncpy(agent_section, UCI_FH_AGENT, sizeof(agent_section));
Jakob Olsson
committed
// Set uci in agent
ret = uci_check_wifi_iface(UCI_AGENT, interface_name,
Jakob Olsson
committed
agent_section);
if (!ret) {
ret = uci_add_wireless_iface_sec(UCI_AGENT, interface_name,
if (!ret)
return M2_PROCESS_ERROR;
}
uci_set_wireless_interface_option(UCI_AGENT, agent_section, "ifname",
Jakob Olsson
committed
interface_name, "band", band_str);
uci_set_wireless_interface_option(UCI_AGENT, agent_section, "ifname",
Jakob Olsson
committed
interface_name, "device", device);
uci_set_wireless_interface_option(UCI_AGENT, agent_section, "ifname",
Jakob Olsson
committed
interface_name, "ssid", ssid);
uci_set_wireless_interface_option(UCI_AGENT, agent_section, "ifname",
Jakob Olsson
committed
interface_name, "key", network_key);
uci_set_wireless_interface_option(UCI_AGENT, agent_section, "ifname",
Jakob Olsson
committed
interface_name, "encryption", auth_type_str);
if (multi_ap & 0x01) {
char disallow_str[2] = {0};
snprintf(disallow_str, sizeof(disallow_str), "%d",
uci_set_wireless_interface_option(UCI_AGENT,
agent_section, "ifname",
interface_name,
"disallow_bsta", disallow_str);
}
// Set uci in wireless
ret = uci_check_wifi_iface(UCI_WIRELESS, interface_name,
UCI_WLAN_IFACE);
if (!ret) {
char name[32] = {0};
snprintf(name, sizeof(name), "%s_ap", interface_name);
replace_char(name, '.', '_');
ret = uci_add_wireless_iface_sec(UCI_WIRELESS, interface_name,
if (!ret)
return M2_PROCESS_ERROR;
}
uci_set_wireless_interface_option(UCI_WIRELESS, UCI_WLAN_IFACE, "ifname",
interface_name, "network", bridge);
uci_set_wireless_interface_option(UCI_WIRELESS, UCI_WLAN_IFACE, "ifname",
uci_set_wireless_interface_option(UCI_WIRELESS, UCI_WLAN_IFACE, "ifname",
interface_name, "key", (char *) network_key);
uci_set_wireless_interface_option(UCI_WIRELESS, UCI_WLAN_IFACE, "ifname",
interface_name, "encryption", auth_type_str);
uci_set_wireless_interface_option(UCI_WIRELESS, UCI_WLAN_IFACE, "ifname",
Jakob Olsson
committed
interface_name, "mode", "ap");
uci_set_wireless_interface_option(UCI_WIRELESS, UCI_WLAN_IFACE, "ifname",
Jakob Olsson
committed
interface_name, "device", device);
uci_set_wireless_interface_option(UCI_WIRELESS, UCI_WLAN_IFACE, "ifname",
Jakob Olsson
committed
interface_name, "multi_ap", multiap_str);
uci_set_wireless_interface_option(UCI_WIRELESS, UCI_WLAN_IFACE, "ifname",
interface_name, "multi_ap_backhaul_key", out->bk_key);
uci_set_wireless_interface_option(UCI_WIRELESS, UCI_WLAN_IFACE, "ifname",
interface_name, "multi_ap_backhaul_ssid", out->bk_ssid);
uci_set_wireless_interface_option(UCI_WIRELESS, UCI_WLAN_IFACE, "ifname",
interface_name, "ieee80211k", "1");
uci_set_wireless_interface_option(UCI_WIRELESS, UCI_WLAN_IFACE, "ifname",
interface_name, "ieee80211v", "1");
do {
char buf[512] = {0};
char basemacstr[18] = {0};
uint8_t basemac[6] = {0};
//uint8_t uuid[16] = {0};
chrCmd(buf, sizeof(buf), "db -q get hw.board.basemac");
if (buf[0] != '\0' && strlen(buf) == 17)
strncpy(basemacstr, buf, 17);
hwaddr_aton(buf, basemac);
memset(buf, 0, sizeof(buf));
chrCmd(buf, sizeof(buf),
"uuidgen -s --namespace @dns --name www.iopsys.eu");
if (buf[0] == '\0' || strlen(buf) != 36) {
//TODO
}
snprintf(buf + 24, 13, "%02x%02x%02x%02x%02x%02x", MAC2STR(basemac));
uci_set_wireless_interface_option(UCI_WIRELESS, UCI_WLAN_IFACE, "ifname",
interface_name, "uuid", buf);
} while(0);
if (multi_ap == 0x01) {
Jakob Olsson
committed
uci_set_wireless_interface_option(UCI_WIRELESS, UCI_WLAN_IFACE,
"ifname", interface_name, "hidden", "1");
} else {
uci_set_wireless_interface_option(UCI_WIRELESS,
UCI_WLAN_IFACE, "ifname", interface_name, "wps", "1");
uci_set_wireless_interface_option(UCI_WIRELESS,
UCI_WLAN_IFACE, "ifname", interface_name,
"wps_pushbutton", "1");
Jakob Olsson
committed
}
/* TODO: don't support guest network for the moment */
//uci_add_dhcp(bridge);
//uci_add_fw(cfg, bridge);
return M2_PROCESS_OK;
}
/* end of functions taken from ieee1905d */
static struct netif_bkcfg *get_netif_bkcfg_by_name(struct agent_config *c,
{
struct netif_bkcfg *p;
list_for_each_entry(p, &c->bklist, list) {
if (!strcmp(name, p->name))
return p;
}
return NULL;
}
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
static struct netif_fhcfg *get_netif_fhcfg_by_name(struct agent_config *c,
const char *name)
{
struct netif_fhcfg *p;
list_for_each_entry(p, &c->fhlist, list) {
if (!strcmp(name, p->name))
return p;
}
return NULL;
}
static struct steer_policy *get_steer_policy_by_name(struct netif_fhcfg *c,
const char *name)
{
struct steer_policy *p;
if (!c)
return NULL;
list_for_each_entry(p, &c->steer_policylist, list) {
if (!strcmp(name, p->name))
return p;
}
return NULL;
}
static struct agent_config_radio *get_agent_config_radio(struct agent_config *c,
const char *ifname)
{
struct agent_config_radio *p;
list_for_each_entry(p, &c->radiolist, list) {
if (!strcmp(ifname, p->name))
return p;
}
return NULL;
}
void stax_add_entry(struct list_head *h, char *sta_macstr)
{
struct stax *n;
n = calloc(1, sizeof(struct stax));
if (n) {
snprintf(n->macstring, 18, "%s", sta_macstr);
list_add(&n->list, h);
}
}
void stax_del_entry(struct list_head *h, char *sta_macstr)
{
struct stax *s, *tmp;
list_for_each_entry_safe(s, tmp, h, list) {
if (!strncmp(s->macstring, sta_macstr, sizeof(s->macstring))) {
list_del(&s->list);
free(s);
return;
}
}
}
static int clean_steer_btm_excl(struct agent_config *p)
{
struct stax *n, *tmp;
list_for_each_entry_safe(n, tmp, &p->steer_btm_excludelist, list) {
list_del(&n->list);
free(n);
}
return 0;
}
static int clean_steer_excl(struct agent_config *p)