diff options
author | Felix Fietkau <nbd@nbd.name> | 2021-06-09 13:57:23 +0200 |
---|---|---|
committer | Felix Fietkau <nbd@nbd.name> | 2021-06-09 13:57:26 +0200 |
commit | aa0e3c4bbe12f02ddb3a0a2e69b3b4f0b30b9b79 (patch) | |
tree | 34943e6d8d97203ff7cc824292c56eae28cb53e1 /iwinfo_nl80211.c | |
parent | c45f0b584b4b86f8250f90ea19afca271c114fa2 (diff) | |
download | iwinfo-aa0e3c4bbe12f02ddb3a0a2e69b3b4f0b30b9b79.tar.gz |
iwinfo: nl80211: add support for printing the device path for a phy
Will be used to replace the shell code from mac80211.sh
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Diffstat (limited to 'iwinfo_nl80211.c')
-rw-r--r-- | iwinfo_nl80211.c | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/iwinfo_nl80211.c b/iwinfo_nl80211.c index eea521e..be90824 100644 --- a/iwinfo_nl80211.c +++ b/iwinfo_nl80211.c @@ -233,6 +233,66 @@ static struct nl80211_msg_conveyor * nl80211_ctl(int cmd, int flags) return nl80211_new(nls->nlctrl, cmd, flags); } +static const char *nl80211_phy_path_str(const char *phyname) +{ + static char path[PATH_MAX]; + const char *prefix = "/sys/devices/"; + int prefix_len = strlen(prefix); + int buf_len, offset; + struct dirent *e; + char buf[128], *link; + int phy_id; + int seq = 0; + DIR *d; + + if (strncmp(phyname, "phy", 3) != 0) + return NULL; + + phy_id = atoi(phyname + 3); + buf_len = snprintf(buf, sizeof(buf), "/sys/class/ieee80211/%s/device", phyname); + link = realpath(buf, path); + if (!link) + return NULL; + + if (strncmp(link, prefix, prefix_len) != 0) + return NULL; + + link += prefix_len; + + prefix = "platform/"; + prefix_len = strlen(prefix); + if (!strncmp(link, prefix, prefix_len) && strstr(link, "/pci")) + link += prefix_len; + + snprintf(buf + buf_len, sizeof(buf) - buf_len, "/ieee80211"); + d = opendir(buf); + if (!d) + return link; + + while ((e = readdir(d)) != NULL) { + int cur_id; + + if (strncmp(e->d_name, "phy", 3) != 0) + continue; + + cur_id = atoi(e->d_name + 3); + if (cur_id >= phy_id) + continue; + + seq++; + } + + closedir(d); + + if (!seq) + return link; + + offset = link - path + strlen(link); + snprintf(path + offset, sizeof(path) - offset, "+%d", seq); + + return link; +} + static int nl80211_phy_idx_from_uci_path(struct uci_section *s) { size_t linklen, pathlen; @@ -3429,6 +3489,21 @@ static int nl80211_lookup_phyname(const char *section, char *buf) return 0; } +static int nl80211_phy_path(const char *phyname, const char **path) +{ + if (strncmp(phyname, "phy", 3) != 0) + return -1; + + if (strchr(phyname, '/')) + return -1; + + *path = nl80211_phy_path_str(phyname); + if (!*path) + return -1; + + return 0; +} + const struct iwinfo_ops nl80211_ops = { .name = "nl80211", .probe = nl80211_probe, @@ -3463,5 +3538,6 @@ const struct iwinfo_ops nl80211_ops = { .countrylist = nl80211_get_countrylist, .survey = nl80211_get_survey, .lookup_phy = nl80211_lookup_phyname, + .phy_path = nl80211_phy_path, .close = nl80211_close }; |