From 4b09108f720dfdabc50ca16fe6b8dcf0d4393df4 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Fri, 10 Jan 2025 09:46:18 +0100 Subject: [PATCH] iwinfo: use new ucode based code for wifi-7 Signed-off-by: John Crispin --- feeds/qca/hostapd/Makefile | 1 + .../hostapd/files-iwinfo/usr/bin/iwinfo.uc | 156 -- .../files-iwinfo/usr/share/iso3166.json | 249 --- .../files-iwinfo/usr/share/ucode/iwinfo.uc | 606 -------- .../files-iwinfo/usr/share/wifi_devices.json | 258 ---- .../files/lib/netifd/wireless/mac80211.sh | 6 +- ...o-add-ucode-based-version-for-wifi-7.patch | 1337 +++++++++++++++++ 7 files changed, 1341 insertions(+), 1272 deletions(-) delete mode 100755 feeds/qca/hostapd/files-iwinfo/usr/bin/iwinfo.uc delete mode 100644 feeds/qca/hostapd/files-iwinfo/usr/share/iso3166.json delete mode 100644 feeds/qca/hostapd/files-iwinfo/usr/share/ucode/iwinfo.uc delete mode 100644 feeds/qca/hostapd/files-iwinfo/usr/share/wifi_devices.json create mode 100644 patches/0084-iwinfo-add-ucode-based-version-for-wifi-7.patch diff --git a/feeds/qca/hostapd/Makefile b/feeds/qca/hostapd/Makefile index c94dfcbba..6c3072770 100644 --- a/feeds/qca/hostapd/Makefile +++ b/feeds/qca/hostapd/Makefile @@ -731,6 +731,7 @@ define Package/hostapd-common/install $(INSTALL_DATA) ./files/*.uc $(1)/usr/share/hostap/ $(INSTALL_BIN) ./files/mpskd $(1)/usr/share/hostap/ $(INSTALL_BIN) ./files/mpskd.init $(1)/etc/init.d/mpskd +# $(CP) ./files-iwinfo/* $(1)/ endef define Package/hostapd/install diff --git a/feeds/qca/hostapd/files-iwinfo/usr/bin/iwinfo.uc b/feeds/qca/hostapd/files-iwinfo/usr/bin/iwinfo.uc deleted file mode 100755 index 01285eb38..000000000 --- a/feeds/qca/hostapd/files-iwinfo/usr/bin/iwinfo.uc +++ /dev/null @@ -1,156 +0,0 @@ -#!/usr/bin/ucode - -'use strict'; - -import * as iwinfo from 'iwinfo'; - -function print_assoclist(stations) { - for (let mac, station in stations) { - printf(`${station.mac} ${station.signal} dBm / ${station.noise} dBm (SNR ${station.snr}) ${station.inactive_time} ms ago\n`); - for (let k in [ 'rx', 'tx' ]) { - let bitrate = station[k]; - let flags = join(', ', bitrate.flags); - - printf(`\t${uc(k)}: ${bitrate.bitrate} MBit/s`); - if (length(bitrate.flags)) - printf(', %s', flags); - printf('%10d Pkts.\n', bitrate.packets); - } - printf(`\texpected throughput: ${station.expected_throughput}\n\n`); - } -} - -function print_countrylist(list) { - for (let k, v in list.countries) - printf(`${k == list.active ? '*' : ' '} ${k} "${v}"\n`); -} - -function print_freqlist(channels) { - for (let channel in channels) { - printf(`${channel.active ? '*' : ' '} ${channel.freq} GHz (Band: ${channel.band} GHz, Channel ${channel.channel})`); - if (length(channel.flags)) - printf(` [${join(', ', channel.flags)}]`); - printf('\n'); - } -} - -function print_htmodelist(htmode) { - printf('%s\n', join(' ', htmode)); -} - -function print_info(list) { - let padding = ' '; - - for (let bss in list) { - printf(`${bss.iface} ESSID: "${bss.ssid}"\n`); - printf(`${padding}Access Point: ${bss.mac}\n`); - printf(`${padding}Mode: ${bss.mode} Channel: ${bss.channel} (${bss.freq} GHz) HT Mode: ${bss.htmode}\n`); - printf(`${padding}Center Channel 1: ${bss.center_freq1} 2: ${bss.center_freq2}\n`); - printf(`${padding}Tx-Power: ${bss.txpower} dBm Link Quality: ${bss.quality}/70\n`); - printf(`${padding}Signal: ${bss.signal} Noise: ${bss.noise}\n`); - printf(`${padding}Bit Rate: ${bss.bitrate ?? 'unknown'} MBit/s\n`); - printf(`${padding}Encryption: ${bss.encryption}\n`); - printf(`${padding}Type: nl80211 HW Mode(s): 802.11${bss.hwmode}\n`); - printf(`${padding}Hardware: ${bss.hw_type} [${bss.hw_id}]\n`); - printf(`${padding}TX power offset: ${bss.power_offset}\n`); - printf(`${padding}Channel offset: ${bss.channel_offset}\n`); - printf(`${padding}Supports VAPs: ${bss.vaps} PHY name: ${bss.phy}\n`); - if (bss.owe_transition_ifname) - printf(`${padding}OWE partner: ${bss.owe_transition_ifname}\n`); - printf('\n'); - } - return 0; -} - -function print_scan(cells) { - let idx = 1; - - for (let cell in cells) { - printf('Cell %02d - Address: %s\n', idx++, cell.bssid); - printf('\t Mode: %s Frequency: %s GHz Band: %s GHz Channel: %d\n', cell.mode, cell.frequency, cell.band, cell.channel); - printf('\t Signal: %d dBm Quality: %2d/70\n', cell.dbm, cell.quality); - - if (!length(cell.crypto.key_mgmt)) - printf('\t Encryption: NONE\n'); - else - printf('\t Encryption: %s (%s)\n', join(' / ', cell.crypto.key_mgmt), join(' / ', cell.crypto.pair)); - - if (cell.ht) { - printf('\t HT Operation:\n'); - printf('\t\tPrimary Channel: %d\n', cell.ht.primary_channel); - printf('\t\tSecondary Channel Offset: %s\n', cell.ht.secondary_chan_off); - printf('\t\tChannel Width: %s\n', cell.ht.chan_width); - } - - if (cell.vht) { - printf('\t VHT Operation:\n'); - printf('\t\tCenter Frequency 1: %d\n', cell.vht.center_chan_1); - printf('\t\tCenter Frequency 2: %s\n', cell.vht.center_chan_2); - printf('\t\tChannel Width: %s\n', cell.vht.chan_width); - } - - printf('\n'); - } -} - -function print_txpowerlist(list) { - for (let power in list) - printf('%s %2d dbm (%4d mW)\n', power.active ? '*' : ' ', power.dbm, power.mw); -} - -let pretty = true; -if (ARGV[0] == '-j') { - pretty = false; - shift(ARGV); -} - -if (!length(ARGV)) { - let info = iwinfo.info(); - if (pretty) - print_info(info); - else - printf('%.J\n', info); - return 0; -} - -const commands = { - assoclist: [ iwinfo.assoclist, print_assoclist ], - countrylist: [ iwinfo.countrylist, print_countrylist ], - freqlist: [ iwinfo.freqlist, print_freqlist ], - htmodelist: [ iwinfo.htmodelist, print_htmodelist ], - info: [ iwinfo.info, print_info ], - scan: [ iwinfo.scan, print_scan ], - txpowerlist: [ iwinfo.txpowerlist, print_txpowerlist ], -}; - -if (length(ARGV) == 2 && iwinfo.ifaces[ARGV[0]]) - for (let cmd, cb in commands) - if (substr(cmd, 0, length(ARGV[1])) == ARGV[1]) { - let ret = cb[0](ARGV[0]); - - if (pretty) - cb[1](ret); - else - printf('%.J\n', ret); - return 0; - } - -switch(ARGV[0]) { -case 'phy': - printf('%.J\n', iwinfo.phys); - return 0; - -case 'iface': - printf('%.J\n', iwinfo.ifaces); - return 0; -} - -printf('Usage:\n' + - '\tiwinfo info\n' + - '\tiwinfo scan\n' + - '\tiwinfo txpowerlist\n' + - '\tiwinfo freqlist\n' + - '\tiwinfo assoclist\n' + - '\tiwinfo countrylist\n' + - '\tiwinfo htmodelist\n' + - '\tiwinfo phyname
\n'); diff --git a/feeds/qca/hostapd/files-iwinfo/usr/share/iso3166.json b/feeds/qca/hostapd/files-iwinfo/usr/share/iso3166.json deleted file mode 100644 index ecd0b6538..000000000 --- a/feeds/qca/hostapd/files-iwinfo/usr/share/iso3166.json +++ /dev/null @@ -1,249 +0,0 @@ -{ - "00": "World", - "AD": "Andorra", - "AE": "United Arab Emirates", - "AF": "Afghanistan", - "AG": "Antigua and Barbuda", - "AI": "Anguilla", - "AL": "Albania", - "AM": "Armenia", - "AN": "Netherlands Antilles", - "AO": "Angola", - "AQ": "Antarctica", - "AR": "Argentina", - "AS": "American Samoa", - "AT": "Austria", - "AU": "Australia", - "AW": "Aruba", - "AX": "Aland Islands", - "AZ": "Azerbaijan", - "BA": "Bosnia and Herzegovina", - "BB": "Barbados", - "BD": "Bangladesh", - "BE": "Belgium", - "BF": "Burkina Faso", - "BG": "Bulgaria", - "BH": "Bahrain", - "BI": "Burundi", - "BJ": "Benin", - "BL": "Saint Barthelemy", - "BM": "Bermuda", - "BN": "Brunei Darussalam", - "BO": "Bolivia", - "BR": "Brazil", - "BS": "Bahamas", - "BT": "Bhutan", - "BV": "Bouvet Island", - "BW": "Botswana", - "BY": "Belarus", - "BZ": "Belize", - "CA": "Canada", - "CC": "Cocos (Keeling) Islands", - "CD": "Congo", - "CF": "Central African Republic", - "CG": "Congo", - "CH": "Switzerland", - "CI": "Cote d'Ivoire", - "CK": "Cook Islands", - "CL": "Chile", - "CM": "Cameroon", - "CN": "China", - "CO": "Colombia", - "CR": "Costa Rica", - "CU": "Cuba", - "CV": "Cape Verde", - "CX": "Christmas Island", - "CY": "Cyprus", - "CZ": "Czech Republic", - "DE": "Germany", - "DJ": "Djibouti", - "DK": "Denmark", - "DM": "Dominica", - "DO": "Dominican Republic", - "DZ": "Algeria", - "EC": "Ecuador", - "EE": "Estonia", - "EG": "Egypt", - "EH": "Western Sahara", - "ER": "Eritrea", - "ES": "Spain", - "ET": "Ethiopia", - "FI": "Finland", - "FJ": "Fiji", - "FK": "Falkland Islands", - "FM": "Micronesia", - "FO": "Faroe Islands", - "FR": "France", - "GA": "Gabon", - "GB": "United Kingdom", - "GD": "Grenada", - "GE": "Georgia", - "GF": "French Guiana", - "GG": "Guernsey", - "GH": "Ghana", - "GI": "Gibraltar", - "GL": "Greenland", - "GM": "Gambia", - "GN": "Guinea", - "GP": "Guadeloupe", - "GQ": "Equatorial Guinea", - "GR": "Greece", - "GS": "South Georgia", - "GT": "Guatemala", - "GU": "Guam", - "GW": "Guinea-Bissau", - "GY": "Guyana", - "HK": "Hong Kong", - "HM": "Heard and McDonald Islands", - "HN": "Honduras", - "HR": "Croatia", - "HT": "Haiti", - "HU": "Hungary", - "ID": "Indonesia", - "IE": "Ireland", - "IL": "Israel", - "IM": "Isle of Man", - "IN": "India", - "IO": "Chagos Islands", - "IQ": "Iraq", - "IR": "Iran", - "IS": "Iceland", - "IT": "Italy", - "JE": "Jersey", - "JM": "Jamaica", - "JO": "Jordan", - "JP": "Japan", - "KE": "Kenya", - "KG": "Kyrgyzstan", - "KH": "Cambodia", - "KI": "Kiribati", - "KM": "Comoros", - "KN": "Saint Kitts and Nevis", - "KP": "North Korea", - "KR": "South Korea", - "KW": "Kuwait", - "KY": "Cayman Islands", - "KZ": "Kazakhstan", - "LA": "Laos", - "LB": "Lebanon", - "LC": "Saint Lucia", - "LI": "Liechtenstein", - "LK": "Sri Lanka", - "LR": "Liberia", - "LS": "Lesotho", - "LT": "Lithuania", - "LU": "Luxembourg", - "LV": "Latvia", - "LY": "Libyan Arab Jamahiriya", - "MA": "Morocco", - "MC": "Monaco", - "MD": "Moldova", - "ME": "Montenegro", - "MF": "Saint Martin (French part)", - "MG": "Madagascar", - "MH": "Marshall Islands", - "MK": "Macedonia", - "ML": "Mali", - "MM": "Myanmar", - "MN": "Mongolia", - "MO": "Macao", - "MP": "Northern Mariana Islands", - "MQ": "Martinique", - "MR": "Mauritania", - "MS": "Montserrat", - "MT": "Malta", - "MU": "Mauritius", - "MV": "Maldives", - "MW": "Malawi", - "MX": "Mexico", - "MY": "Malaysia", - "MZ": "Mozambique", - "NA": "Namibia", - "NC": "New Caledonia", - "NE": "Niger", - "NF": "Norfolk Island", - "NG": "Nigeria", - "NI": "Nicaragua", - "NL": "Netherlands", - "NO": "Norway", - "NP": "Nepal", - "NR": "Nauru", - "NU": "Niue", - "NZ": "New Zealand", - "OM": "Oman", - "PA": "Panama", - "PE": "Peru", - "PF": "French Polynesia", - "PG": "Papua New Guinea", - "PH": "Philippines", - "PK": "Pakistan", - "PL": "Poland", - "PM": "Saint Pierre and Miquelon", - "PN": "Pitcairn", - "PR": "Puerto Rico", - "PS": "Palestinian Territory", - "PT": "Portugal", - "PW": "Palau", - "PY": "Paraguay", - "QA": "Qatar", - "RE": "Reunion", - "RO": "Romania", - "RS": "Serbia", - "RU": "Russian Federation", - "RW": "Rwanda", - "SA": "Saudi Arabia", - "SB": "Solomon Islands", - "SC": "Seychelles", - "SD": "Sudan", - "SE": "Sweden", - "SG": "Singapore", - "SH": "St. Helena and Dependencies", - "SI": "Slovenia", - "SJ": "Svalbard and Jan Mayen", - "SK": "Slovakia", - "SL": "Sierra Leone", - "SM": "San Marino", - "SN": "Senegal", - "SO": "Somalia", - "SR": "Suriname", - "ST": "Sao Tome and Principe", - "SV": "El Salvador", - "SY": "Syrian Arab Republic", - "SZ": "Swaziland", - "TC": "Turks and Caicos Islands", - "TD": "Chad", - "TF": "French Southern Territories", - "TG": "Togo", - "TH": "Thailand", - "TJ": "Tajikistan", - "TK": "Tokelau", - "TL": "Timor-Leste", - "TM": "Turkmenistan", - "TN": "Tunisia", - "TO": "Tonga", - "TR": "Turkey", - "TT": "Trinidad and Tobago", - "TV": "Tuvalu", - "TW": "Taiwan", - "TZ": "Tanzania", - "UA": "Ukraine", - "UG": "Uganda", - "UM": "U.S. Minor Outlying Islands", - "US": "United States", - "UY": "Uruguay", - "UZ": "Uzbekistan", - "VA": "Vatican City State", - "VC": "St. Vincent and Grenadines", - "VE": "Venezuela", - "VG": "Virgin Islands, British", - "VI": "Virgin Islands, U.S.", - "VN": "Viet Nam", - "VU": "Vanuatu", - "WF": "Wallis and Futuna", - "WS": "Samoa", - "YE": "Yemen", - "YT": "Mayotte", - "ZA": "South Africa", - "ZM": "Zambia", - "ZW": "Zimbabwe" -} diff --git a/feeds/qca/hostapd/files-iwinfo/usr/share/ucode/iwinfo.uc b/feeds/qca/hostapd/files-iwinfo/usr/share/ucode/iwinfo.uc deleted file mode 100644 index 84615adb5..000000000 --- a/feeds/qca/hostapd/files-iwinfo/usr/share/ucode/iwinfo.uc +++ /dev/null @@ -1,606 +0,0 @@ -'use strict'; - -import * as nl80211 from 'nl80211'; -import * as libubus from 'ubus'; -import { readfile, stat } from "fs"; - -let wifi_devices = json(readfile('/usr/share/wifi_devices.json')); -let countries = json(readfile('/usr/share/iso3166.json')); -let board_data = json(readfile('/etc/board.json')); - -export let phys = nl80211.request(nl80211.const.NL80211_CMD_GET_WIPHY, nl80211.const.NLM_F_DUMP, { split_wiphy_dump: true }); -let interfaces = nl80211.request(nl80211.const.NL80211_CMD_GET_INTERFACE, nl80211.const.NLM_F_DUMP); - -let ubus = libubus.connect(); -let wireless_status = ubus.call('network.wireless', 'status'); - -function find_phy(wiphy) { - for (let k, phy in phys) - if (phy.wiphy == wiphy) - return phy; - return null; -} - -function get_noise(iface) { - for (let phy in phys) { - let channels = nl80211.request(nl80211.const.NL80211_CMD_GET_SURVEY, nl80211.const.NLM_F_DUMP, { dev: iface.ifname }); - for (let k, channel in channels) - if (channel.survey_info.frequency == iface.wiphy_freq) - return channel.survey_info.noise; - } - - return -100; -} - -function get_country(iface) { - let reg = nl80211.request(nl80211.const.NL80211_CMD_GET_REG, 0, { dev: iface.ifname }); - - return reg.reg_alpha2 ?? ''; -} - -function get_max_power(iface) { - let phy = find_phy(iface.wiphy); - - for (let k, band in phy.wiphy_bands) - if (band) - for (let freq in band.freqs) - if (freq.freq == iface.wiphy_freq) - return freq.max_tx_power;; - return 0; -} - -function get_hardware_id(iface) { - let hw = { - type: 'nl80211', - id: 'Generic MAC80211', - power_offset: 0, - channel_offset: 0, - }; - - let path = `/sys/class/ieee80211/phy${iface.wiphy}/device/`; - if (stat(path) + 'vendor') { - let data = []; - for (let lookup in [ 'vendor', 'device', 'subsystem_vendor', 'subsystem_device' ]) - push(data, trim(readfile(path + lookup), '\n')); - - for (let device in wifi_devices.pci) { - let match = 0; - for (let i = 0; i < 4; i++) - if (lc(data[i]) == lc(device[i])) - match++; - if (match == 4) { - hw.type = `${data[0]}:${data[1]} ${data[2]}:${data[3]}`; - hw.power_offset = device[4]; - hw.channel_offset = device[5]; - hw.id = `${device[6]} ${device[7]}`; - } - } - } - - let compatible = trim(readfile(`/sys/class/net/${iface.ifname}/device/of_node/compatible`), '\n'); - if (compatible && wifi_devices.compatible[compatible]) { - hw.id = wifi_devices.compatible[compatible][0] + ' ' + wifi_devices.compatible[compatible][1]; - hw.compatible = compatible; - hw.type = 'embedded'; - } - - return hw; -} - -const iftypes = [ - 'Unknown', 'Ad-Hoc', 'Client', 'Master', 'Master (VLAN)', - 'WDS', 'Monitor', 'Mesh Point', 'P2P Client', 'P2P Go', -]; - -export let ifaces = {}; -for (let k, v in interfaces) { - let iface = ifaces[v.ifname] = v; - - iface.mode = iftypes[iface.iftype] ?? 'unknonw', - iface.noise = get_noise(iface); - iface.country = get_country(iface); - iface.max_power = get_max_power(iface); - iface.assoclist = nl80211.request(nl80211.const.NL80211_CMD_GET_STATION, nl80211.const.NLM_F_DUMP, { dev: v.ifname }) ?? []; - iface.hardware = get_hardware_id(iface); - - iface.bss_info = ubus.call('hostapd', 'bss_info', { iface: v.ifname }); - if (!iface.bss_info) - iface.bss_info = ubus.call('wpa_supplicant', 'bss_info', { iface: v.ifname }); -} - -for (let radio, data in wireless_status) - for (let k, v in data.interfaces) { - if (!v.ifname || !ifaces[v.ifname]) - continue; - - ifaces[v.ifname].ssid = v.config.ssid; - ifaces[v.ifname].radio = data.config; - - let bss_info = ifaces[v.ifname].bss_info; - let owe_transition_ifname = bss_info?.owe_transition_ifname; - - if (v.config.owe_transition && ifaces[owe_transition_ifname]) { - ifaces[v.ifname].owe_transition_ifname = owe_transition_ifname; - ifaces[owe_transition_ifname].ssid = v.config.ssid; - ifaces[owe_transition_ifname].radio = data.config; - ifaces[owe_transition_ifname].owe_transition_ifname = v.ifname - } - } - -function format_channel(freq) { - if (freq < 1000) - return 0; - if (freq == 2484) - return 14; - if (freq == 5935) - return 2; - if (freq < 2484) - return (freq - 2407) / 5; - if (freq >= 4910 && freq <= 4980) - return (freq - 4000) / 5; - if (freq < 5950) - return (freq - 5000) / 5; - if (freq <= 45000) - return (freq - 5950) / 5; - if (freq >= 58320 && freq <= 70200) - return (freq - 56160) / 2160; - - return 'unknown'; -} - -function format_band(freq) { - if (freq == 5935) - return '6'; - if (freq < 2484) - return '2.4'; - if (freq < 5950) - return '5'; - if (freq <= 45000) - return '6'; - - return '60'; -} - -function format_frequency(freq) { - if (!freq) - return 'unknown'; - freq = '' + freq; - return substr(freq, 0, 1) + '.' + substr(freq, 1); -} - -function format_rate(rate) { - if (!rate) - return 'unknown'; - return '' + (rate / 10) + '.' + (rate % 10); -} - -function format_mgmt_key(key) { - switch(+key) { - case 1: - case 11: - case 12: - case 13: - case 14: - case 15: - case 16: - case 17: - return '802.1x'; - - case 2: - return 'WPA PSK'; - - case 4: - return 'FT PSK'; - - case 6: - return 'WPA PSK2'; - - case 8: - return 'SAE'; - - case 18: - return 'OWE'; - } - - return null; -} - -function assoc_flags(data) { - const assoc_mhz = { - width_40: 40, - width_80: 80, - width_80p80: '80+80', - width_160: 160, - width_320: 320, - width_10: 10, - width_5: 5 - }; - - let mhz = 'unknown'; - for (let k, v in assoc_mhz) - if (data[k]) - mhz = v; - - const assoc_flags = { - mcs: { - mcs: 'MCS', - }, - vht_mcs: { - vht_mcs: 'VHT-MCS', - vht_nss: 'VHT-NSS', - }, - he_mcs: { - he_mcs: 'HE-MCS', - he_nss: 'HE-NSS', - he_gi: 'HE-GI', - he_dcm: 'HE-DCM', - }, - eht_mcs: { - eht_mcs: 'EHT-MCS', - eht_nss: 'EHT-NSS', - eht_gi: 'EHT-GI', - }, - }; - - let flags = []; - for (let k, v in assoc_flags) { - if (!data[k]) - continue; - - let first = 0; - for (let name, flag in v) { - if (data[name] == null) - continue; - push(flags, `${flag} ${data[name]}`); - if (!first++) - push(flags, `${mhz}MHz`); - } - } - - return flags; -} - -function dbm2mw(dbm) { - const LOG10_MAGIC = 1.25892541179; - let res = 1.0; - let ip = dbm / 10; - let fp = dbm % 10; - - for (let k = 0; k < ip; k++) - res *= 10; - for (let k = 0; k < fp; k++) - res *= 1.25892541179; - - return int(res); -} - -function dbm2quality(dbm) { - let quality = dbm; - - if (quality < -110) - quality = -110; - else if (quality > -40) - quality = -40; - quality += 110; - - return quality; -} - -function hwmodelist(name) { - const mode = { 'HT*': 'n', 'VHT*': 'ac', 'HE*': 'ax' }; - let iface = ifaces[name]; - let phy = board_data.wlan?.['phy' + iface.wiphy]; - if (!phy) - return ''; - let htmodes = phy.info.bands[uc(iface.radio.band)].modes; - let list = []; - if (iface.radio.band == '2g' && 'NOHT' in htmodes) - push(list, 'g/b'); - for (let k, v in mode) - for (let htmode in htmodes) - if (wildcard(htmode, k)) - push(list, v); - - return join('/', reverse(uniq(list))); -} - -export function assoclist(dev) { - let stations = ifaces[dev].assoclist; - let ret = {}; - - for (let station in stations) { - let sta = { - mac: uc(station.mac), - signal: station.sta_info.signal_avg, - noise: ifaces[dev].noise, - snr: station.sta_info.signal_avg - ifaces[dev].noise, - inactive_time: station.sta_info.inactive_time, - rx: { - bitrate: format_rate(station.sta_info.rx_bitrate.bitrate), - bitrate_raw: station.sta_info.rx_bitrate.bitrate, - packets: station.sta_info.rx_packets, - flags: assoc_flags(station.sta_info.rx_bitrate), - }, - tx: { - bitrate: format_rate(station.sta_info.tx_bitrate.bitrate), - bitrate_raw: station.sta_info.tx_bitrate.bitrate, - packets: station.sta_info.tx_packets, - flags: assoc_flags(station.sta_info.tx_bitrate), - }, - expected_throughput: station.sta_info.expected_throughput ?? 'unknown', - }; - ret[sta.mac] = sta; - } - - return ret; -}; - -export function freqlist(name) { - const freq_flags = { - no_10mhz: 'NO_10MHZ', - no_20mhz: 'NO_20MHZ', - no_ht40_minus: 'NO_HT40-', - no_ht40_plus: 'NO_HT40+', - no_80mhz: 'NO_80MHZ', - no_160mhz: 'NO_160MHZ', - indoor_only: 'INDOOR_ONLY', - no_ir: 'NO_IR', - no_he: 'NO_HE', - }; - - let iface = ifaces[name]; - let phy = find_phy(iface.wiphy); - let channels = []; - - for (let k, band in phy.wiphy_bands) { - if (!band) - continue; - - let band_name = format_band(band.freqs[0].freq); - for (let freq in band.freqs) { - if (freq.disabled) - continue; - - let channel = { - freq: format_frequency(freq.freq), - band: band_name, - channel: format_channel(freq.freq), - flags: [], - active: iface.wiphy_freq == freq.freq, - }; - - for (let k, v in freq_flags) - if (freq[k]) - push(channel.flags, v); - - push(channels, channel); - } - } - - return channels; -}; - -export function info(name) { - let order = []; - for (let iface, data in ifaces) - push(order, iface); - - let list = []; - for (let iface in sort(order)) { - if (name && iface != name) - continue; - let data = ifaces[iface]; - let dev = { - iface, - ssid: data.ssid, - mac: data.mac, - mode: data.mode, - channel: format_channel(data.wiphy_freq), - freq: format_frequency(data.wiphy_freq), - htmode: data.radio.htmode, - center_freq1: format_channel(data.center_freq1) || 'unknown', - center_freq2: format_channel(data.center_freq2) || 'unknown', - txpower: data.wiphy_tx_power_level / 100, - noise: data.noise, - signal: 0, - bitrate: 0, - encryption: 'unknown', - hwmode: hwmodelist(iface), - phy: 'phy' + data.wiphy, - vaps: 'no', - hw_type: data.hardware.type, - hw_id: data.hardware.id, - power_offset: data.hardware.power_offset || 'none', - channel_offset: data.hardware.channel_offset || 'none', - }; - - let phy = find_phy(data.wiphy); - for (let limit in phy.interface_combinations[0]?.limits) - if (limit.types?.ap && limit.max > 1) - dev.vaps = 'yes'; - - if (data.bss_info) { - if (data.bss_info.wpa_key_mgmt && data.bss_info.wpa_pairwise) - dev.encryption = `${replace(data.bss_info.wpa_key_mgmt, ' ', ' / ')} (${data.bss_info.wpa_pairwise})`; - else if (data.owe_transition_ifname) - dev.encryption = 'none (OWE transition)'; - else - dev.encryption = 'none'; - } - - let stations = assoclist(iface); - for (let k, station in stations) { - dev.signal += station.signal; - dev.bitrate += station.tx.bitrate_raw; - } - dev.signal /= length(data.assoclist) || 1; - dev.bitrate /= length(data.assoclist) || 1; - dev.bitrate = format_rate(dev.bitrate); - dev.quality = dbm2quality(dev.signal); - - if (data.owe_transition_ifname) - dev.owe_transition_ifname = data.owe_transition_ifname; - - push(list, dev); - } - - return list; -}; - -export function htmodelist(name) { - let iface = ifaces[name]; - let phy = board_data.wlan?.['phy' + iface.wiphy]; - if (!phy) - return []; - - return filter(phy.info.bands[uc(iface.radio.band)].modes, (v) => v != 'NOHT'); -}; - -export function txpowerlist(name) { - let iface = ifaces[name]; - let max_power = iface.max_power / 100; - let match = iface.wiphy_tx_power_level / 100; - let list = []; - - for (let power = 0; power <= max_power; power++) { - let txpower = { - dbm: power, - mw: dbm2mw(power), - active: power == match, - }; - push(list, txpower); - } - - return list; -}; - -export function countrylist(dev) { - let iface = ifaces[dev]; - - let list = { - active: iface.country, - countries, - }; - - return list; -}; - -export function scan(dev) { - const rsn_cipher = [ 'NONE', 'WEP-40', 'TKIP', 'WRAP', 'CCMP', 'WEP-104', 'AES-OCB', 'CKIP', 'GCMP', 'GCMP-256', 'CCMP-256' ]; - const ht_chan_offset = [ 'no secondary', 'above', '[reserved]', 'below' ]; - const vht_chan_width = [ '20 or 40 MHz', '80 MHz', '80+80 MHz', '160 MHz' ]; - const ht_chan_width = [ '20 MHz', '40 MHz or higher' ]; - const SCAN_FLAG_AP = (1<<2); - - let params = { - dev, - scan_flags: SCAN_FLAG_AP, - scan_ssids: [ '' ], - }; - - let res = nl80211.request(nl80211.const.NL80211_CMD_TRIGGER_SCAN, 0, params); - if (res === false) { - printf("Unable to trigger scan: " + nl80211.error() + "\n"); - exit(1); - } - - res = nl80211.waitfor([ - nl80211.const.NL80211_CMD_NEW_SCAN_RESULTS, - nl80211.const.NL80211_CMD_SCAN_ABORTED - ], 5000); - - if (!res) { - printf("Netlink error while awaiting scan results: " + nl80211.error() + "\n"); - exit(1); - } else if (res.cmd == nl80211.const.NL80211_CMD_SCAN_ABORTED) { - printf("Scan aborted by kernel\n"); - exit(1); - } - - let scan = nl80211.request(nl80211.const.NL80211_CMD_GET_SCAN, nl80211.const.NLM_F_DUMP, { dev }); - - let cells = []; - for (let k, bss in scan) { - bss = bss.bss; - let cell = { - bssid: uc(bss.bssid), - frequency: format_frequency(bss.frequency), - band: format_band(bss.frequency), - channel: format_channel(bss.frequency), - dbm: bss.signal_mbm / 100, - - }; - - if (bss.capability & (1 << 1)) - cell.mode = 'Ad-Hoc'; - else if (bss.capability & (1 << 0)) - cell.mode = 'Master'; - else - cell.mode = 'Mesh Point'; - - cell.quality = dbm2quality(cell.dbm); - - for (let ie in bss.information_elements) - switch(ie.type) { - case 0: - case 114: - cell.ssid = ie.data; - break; - - case 7: - cell.country = substr(ie.data, 0, 2); - break; - - case 48: - cell.crypto = { - group: rsn_cipher[+ord(ie.data, 5)] ?? '', - pair: [], - key_mgmt: [], - }; - - let offset = 6; - let count = +ord(ie.data, offset); - offset += 2; - - for (let i = 0; i < count; i++) { - let key = rsn_cipher[+ord(ie.data, offset + 3)]; - if (key) - push(cell.crypto.pair, key); - offset += 4; - } - - count = +ord(ie.data, offset); - offset += 2; - - for (let i = 0; i < count; i++) { - let key = format_mgmt_key(ord(ie.data, offset + 3)); - if (key) - push(cell.crypto.key_mgmt, key); - offset += 4; - } - break; - - case 61: - cell.ht = { - primary_channel: ord(ie.data, 0), - secondary_chan_off: ht_chan_offset[ord(ie.data, 1) & 0x3], - chan_width: ht_chan_width[(ord(ie.data, 1) & 0x4) >> 2], - }; - break; - - case 192: - cell.vht = { - chan_width: vht_chan_width[ord(ie.data, 0)], - center_chan_1: ord(ie.data, 1), - center_chan_2: ord(ie.data, 2), - }; - break; - }; - - - - push(cells, cell); - } - - return cells; -}; diff --git a/feeds/qca/hostapd/files-iwinfo/usr/share/wifi_devices.json b/feeds/qca/hostapd/files-iwinfo/usr/share/wifi_devices.json deleted file mode 100644 index 7e9c63751..000000000 --- a/feeds/qca/hostapd/files-iwinfo/usr/share/wifi_devices.json +++ /dev/null @@ -1,258 +0,0 @@ -{ - "pci": [ - [ "0x0777", "0x11ac", "0x0777", "0xe7f9", 0, 0, "Ubiquiti", "LiteBeam, 5AC" ], - [ "0xffff", "0xffff", "0xffff", "0xb102", 0, 0, "Ubiquiti", "PowerStation2, (18V)" ], - [ "0xffff", "0xffff", "0xffff", "0xb202", 0, 0, "Ubiquiti", "PowerStation2, (16D)" ], - [ "0xffff", "0xffff", "0xffff", "0xb302", 0, 0, "Ubiquiti", "PowerStation2, (EXT)" ], - [ "0xffff", "0xffff", "0xffff", "0xb105", 0, 0, "Ubiquiti", "PowerStation5, (22V)" ], - [ "0xffff", "0xffff", "0xffff", "0xb305", 0, 0, "Ubiquiti", "PowerStation5, (EXT)" ], - [ "0xffff", "0xffff", "0xffff", "0xc302", 0, 0, "Ubiquiti", "PicoStation2" ], - [ "0xffff", "0xffff", "0xffff", "0xc3a2", 10, 0, "Ubiquiti", "PicoStation2, HP" ], - [ "0xffff", "0xffff", "0xffff", "0xa105", 0, 0, "Ubiquiti", "WispStation5" ], - [ "0xffff", "0xffff", "0xffff", "0xa002", 10, 0, "Ubiquiti", "LiteStation2" ], - [ "0xffff", "0xffff", "0xffff", "0xa005", 5, 0, "Ubiquiti", "LiteStation5" ], - [ "0xffff", "0xffff", "0xffff", "0xc002", 10, 0, "Ubiquiti", "NanoStation2" ], - [ "0xffff", "0xffff", "0xffff", "0xc005", 5, 0, "Ubiquiti", "NanoStation5" ], - [ "0xffff", "0xffff", "0xffff", "0xc102", 10, 0, "Ubiquiti", "NanoStation, Loco2" ], - [ "0xffff", "0xffff", "0xffff", "0xc105", 5, 0, "Ubiquiti", "NanoStation, Loco5" ], - [ "0xffff", "0xffff", "0xffff", "0xc202", 10, 0, "Ubiquiti", "Bullet2" ], - [ "0xffff", "0xffff", "0xffff", "0xc205", 5, 0, "Ubiquiti", "Bullet5" ], - [ "0x168c", "0xffff", "0x0777", "0xe002", 6, 0, "Ubiquiti", "airOS, XM" ], - [ "0x168c", "0xffff", "0x0777", "0xe003", 3, 0, "Ubiquiti", "airOS, XM" ], - [ "0x168c", "0xffff", "0x0777", "0xe005", 5, 0, "Ubiquiti", "NanoStation, M5" ], - [ "0x168c", "0xffff", "0x0777", "0xe006", 5, 0, "Ubiquiti", "airOS, XM" ], - [ "0x168c", "0xffff", "0x0777", "0xe009", 6, 0, "Ubiquiti", "NanoStation, Loco, M9" ], - [ "0x168c", "0xffff", "0x0777", "0xe012", 10, 0, "Ubiquiti", "NanoStation, M2" ], - [ "0x168c", "0xffff", "0x0777", "0xe035", 3, 0, "Ubiquiti", "NanoStation, M3" ], - [ "0x168c", "0xffff", "0x0777", "0xe0a2", 2, 0, "Ubiquiti", "NanoStation, Loco, M2" ], - [ "0x168c", "0xffff", "0x0777", "0xe0a5", 1, 0, "Ubiquiti", "NanoStation, Loco, M5" ], - [ "0x168c", "0xffff", "0x0777", "0xe102", 6, 0, "Ubiquiti", "airOS, XM" ], - [ "0x168c", "0xffff", "0x0777", "0xe105", 5, 0, "Ubiquiti", "Rocket, M5" ], - [ "0x168c", "0xffff", "0x0777", "0xe112", 10, 0, "Ubiquiti", "airOS, XM" ], - [ "0x168c", "0xffff", "0x0777", "0xe115", 3, 0, "Ubiquiti", "airOS, XM" ], - [ "0x168c", "0xffff", "0x0777", "0xe1a3", 3, 0, "Ubiquiti", "airOS, XM" ], - [ "0x168c", "0xffff", "0x0777", "0xe1a5", 5, 0, "Ubiquiti", "PowerBridge, M5" ], - [ "0x168c", "0xffff", "0x0777", "0xe1b2", 10, 0, "Ubiquiti", "airOS, XM" ], - [ "0x168c", "0xffff", "0x0777", "0xe1b3", 3, 0, "Ubiquiti", "airOS, XM" ], - [ "0x168c", "0xffff", "0x0777", "0xe1b5", 5, 0, "Ubiquiti", "Rocket, M5" ], - [ "0x168c", "0xffff", "0x0777", "0xe1b6", 5, 0, "Ubiquiti", "airOS, XM" ], - [ "0x168c", "0xffff", "0x0777", "0xe1b9", 6, 0, "Ubiquiti", "Rocket, M9" ], - [ "0x168c", "0xffff", "0x0777", "0xe1c2", 10, 0, "Ubiquiti", "airOS, XM" ], - [ "0x168c", "0xffff", "0x0777", "0xe1c3", 3, 0, "Ubiquiti", "Rocket, M3" ], - [ "0x168c", "0xffff", "0x0777", "0xe1c5", 5, 0, "Ubiquiti", "Rocket, M5, GPS" ], - [ "0x168c", "0xffff", "0x0777", "0xe1c5", 5, 0, "Ubiquiti", "airOS, XM" ], - [ "0x168c", "0xffff", "0x0777", "0xe1d2", 10, 0, "Ubiquiti", "Rocket, M2, Titanium" ], - [ "0x168c", "0xffff", "0x0777", "0xe1d3", 3, 0, "Ubiquiti", "airOS, XM" ], - [ "0x168c", "0xffff", "0x0777", "0xe1d5", 5, 0, "Ubiquiti", "airOS, XM/XW" ], - [ "0x168c", "0xffff", "0x0777", "0xe1d9", 6, 0, "Ubiquiti", "airOS, XM" ], - [ "0x168c", "0xffff", "0x0777", "0xe1e3", 3, 0, "Ubiquiti", "airOS, XM" ], - [ "0x168c", "0xffff", "0x0777", "0xe1e5", 5, 0, "Ubiquiti", "airOS, XM" ], - [ "0x168c", "0xffff", "0x0777", "0xe202", 12, 0, "Ubiquiti", "Bullet, M2" ], - [ "0x168c", "0xffff", "0x0777", "0xe205", 6, 0, "Ubiquiti", "Bullet, M5" ], - [ "0x168c", "0xffff", "0x0777", "0xe212", 1, 0, "Ubiquiti", "AirGrid, M2" ], - [ "0x168c", "0xffff", "0x0777", "0xe215", 1, 0, "Ubiquiti", "AirGrid, M5" ], - [ "0x168c", "0xffff", "0x0777", "0xe232", 2, 0, "Ubiquiti", "NanoBridge, M2" ], - [ "0x168c", "0xffff", "0x0777", "0xe233", 3, 0, "Ubiquiti", "airOS, XM" ], - [ "0x168c", "0xffff", "0x0777", "0xe235", 1, 0, "Ubiquiti", "NanoBridge, M5" ], - [ "0x168c", "0xffff", "0x0777", "0xe239", 6, 0, "Ubiquiti", "NanoBridge, M9" ], - [ "0x168c", "0xffff", "0x0777", "0xe242", 9, 0, "Ubiquiti", "AirGrid, M2, HP" ], - [ "0x168c", "0xffff", "0x0777", "0xe243", 3, 0, "Ubiquiti", "NanoBridge, M3" ], - [ "0x168c", "0xffff", "0x0777", "0xe245", 6, 0, "Ubiquiti", "AirGrid, M5, HP" ], - [ "0x168c", "0xffff", "0x0777", "0xe252", 9, 0, "Ubiquiti", "AirGrid, M2, HP" ], - [ "0x168c", "0xffff", "0x0777", "0xe255", 6, 0, "Ubiquiti", "AirGrid, M5, HP" ], - [ "0x168c", "0xffff", "0x0777", "0xe2a3", 3, 0, "Ubiquiti", "airOS, XM" ], - [ "0x168c", "0xffff", "0x0777", "0xe2a5", 5, 0, "Ubiquiti", "airOS, XM" ], - [ "0x168c", "0xffff", "0x0777", "0xe2b2", 10, 0, "Ubiquiti", "airOS, XM" ], - [ "0x168c", "0xffff", "0x0777", "0xe2b5", 1, 0, "Ubiquiti", "NanoBridge, M5" ], - [ "0x168c", "0xffff", "0x0777", "0xe2b9", 6, 0, "Ubiquiti", "airOS, XM" ], - [ "0x168c", "0xffff", "0x0777", "0xe2c2", 10, 0, "Ubiquiti", "NanoBeam, M2, Int" ], - [ "0x168c", "0xffff", "0x0777", "0xe2c3", 6, 0, "Ubiquiti", "Bullet, M2, XW" ], - [ "0x168c", "0xffff", "0x0777", "0xe2c4", 6, 0, "Ubiquiti", "airOS, XW" ], - [ "0x168c", "0xffff", "0x0777", "0xe2d2", 12, 0, "Ubiquiti", "Bullet, M2, Titanium, HP" ], - [ "0x168c", "0xffff", "0x0777", "0xe2d4", 6, 0, "Ubiquiti", "airOS, XW" ], - [ "0x168c", "0xffff", "0x0777", "0xe2d5", 6, 0, "Ubiquiti", "airOS, XM" ], - [ "0x168c", "0xffff", "0x0777", "0xe2e5", 4, 0, "Ubiquiti", "airOS, XM" ], - [ "0x168c", "0xffff", "0x0777", "0xe302", 12, 0, "Ubiquiti", "PicoStation, M2"], - [ "0x168c", "0xffff", "0x0777", "0xe305", 6, 0, "Ubiquiti", "airOS, XM" ], - [ "0x168c", "0xffff", "0x0777", "0xe345", 6, 0, "Ubiquiti", "WispStation, M5" ], - [ "0x168c", "0xffff", "0x0777", "0xe3a5", 5, 0, "Ubiquiti", "airOS, XM" ], - [ "0x168c", "0xffff", "0x0777", "0xe3b5", 6, 0, "Ubiquiti", "airOS, XM/XW" ], - [ "0x168c", "0xffff", "0x0777", "0xe3e5", 4, 0, "Ubiquiti", "PowerBeam, M5, 300" ], - [ "0x168c", "0xffff", "0x0777", "0xe402", 10, 0, "Ubiquiti", "airOS, XM" ], - [ "0x168c", "0xffff", "0x0777", "0xe405", 1, 0, "Ubiquiti", "airOS, XM" ], - [ "0x168c", "0xffff", "0x0777", "0xe4a2", 1, 0, "Ubiquiti", "AirRouter" ], - [ "0x168c", "0xffff", "0x0777", "0xe4a5", 1, 0, "Ubiquiti", "airOS, XM" ], - [ "0x168c", "0xffff", "0x0777", "0xe4b2", 9, 0, "Ubiquiti", "AirRouter, HP" ], - [ "0x168c", "0xffff", "0x0777", "0xe4d5", 5, 0, "Ubiquiti", "Rocket, M5, Titanium" ], - [ "0x168c", "0xffff", "0x0777", "0xe4e5", 4, 0, "Ubiquiti", "PowerBeam, M5, 400" ], - [ "0x168c", "0xffff", "0x0777", "0xe5e5", 4, 0, "Ubiquiti", "airOS, XW" ], - [ "0x168c", "0xffff", "0x0777", "0xe6a2", 1, 0, "Ubiquiti", "airOS, XM" ], - [ "0x168c", "0xffff", "0x0777", "0xe6b2", 1, 0, "Ubiquiti", "airOS, XM" ], - [ "0x168c", "0xffff", "0x0777", "0xe6b5", 5, 0, "Ubiquiti", "Rocket, M5, XW" ], - [ "0x168c", "0xffff", "0x0777", "0xe6c2", 6, 0, "Ubiquiti", "airOS, XM" ], - [ "0x168c", "0xffff", "0x0777", "0xe6e5", 4, 0, "Ubiquiti", "PowerBeam, M5, 400, ISO" ], - [ "0x168c", "0xffff", "0x0777", "0xe7f8", 2, 0, "Ubiquiti", "airOS, XW" ], - [ "0x168c", "0xffff", "0x0777", "0xe805", 5, 0, "Ubiquiti", "airOS, XM" ], - [ "0x168c", "0xffff", "0x0777", "0xe812", 6, 0, "Ubiquiti", "NanoBeam, M2, 13" ], - [ "0x168c", "0xffff", "0x0777", "0xe815", 4, 0, "Ubiquiti", "NanoBeam, M5, 16" ], - [ "0x168c", "0xffff", "0x0777", "0xe825", 4, 0, "Ubiquiti", "NanoBeam, M5, 19" ], - [ "0x168c", "0xffff", "0x0777", "0xe835", 6, 0, "Ubiquiti", "AirGrid, M5, XW" ], - [ "0x168c", "0xffff", "0x0777", "0xe845", 1, 0, "Ubiquiti", "NanoStation, Loco, M5, XW" ], - [ "0x168c", "0xffff", "0x0777", "0xe855", 5, 0, "Ubiquiti", "NanoStation, M5, XW" ], - [ "0x168c", "0xffff", "0x0777", "0xe865", 6, 0, "Ubiquiti", "LiteBeam, M5" ], - [ "0x168c", "0xffff", "0x0777", "0xe866", 6, 0, "Ubiquiti", "NanoStation, M2, XW" ], - [ "0x168c", "0xffff", "0x0777", "0xe867", 2, 0, "Ubiquiti", "NanoStation, Loco, M2, XW" ], - [ "0x168c", "0xffff", "0x0777", "0xe868", 7, 0, "Ubiquiti", "Rocket, M2, XW" ], - [ "0x168c", "0xffff", "0x0777", "0xe869", 2, 0, "Ubiquiti", "airOS, XW" ], - [ "0x168c", "0xffff", "0x0777", "0xe875", 4, 0, "Ubiquiti", "airOS, XW" ], - [ "0x168c", "0xffff", "0x0777", "0xe879", 2, 0, "Ubiquiti", "airOS, XW" ], - [ "0x168c", "0xffff", "0x0777", "0xe885", 4, 0, "Ubiquiti", "PowerBeam, M5, 620, XW" ], - [ "0x168c", "0xffff", "0x0777", "0xe895", 4, 0, "Ubiquiti", "airOS, XW" ], - [ "0x168c", "0xffff", "0x0777", "0xe8a5", 1, 0, "Ubiquiti", "NanoStation, Loco, M5"], - [ "0x168c", "0xffff", "0x0777", "0xe8b5", 5, 0, "Ubiquiti", "airOS, XM" ], - [ "0x168c", "0x001b", "0x0777", "0x3002", 10, 0, "Ubiquiti", "XR2" ], - [ "0x168c", "0x001b", "0x7777", "0x3002", 10, 0, "Ubiquiti", "XR2" ], - [ "0x168c", "0x001b", "0x0777", "0x3b02", 10, 0, "Ubiquiti", "XR2.3" ], - [ "0x168c", "0x001b", "0x0777", "0x3c02", 10, 0, "Ubiquiti", "XR2.6" ], - [ "0x168c", "0x001b", "0x0777", "0x3b03", 10, 0, "Ubiquiti", "XR3-2.8" ], - [ "0x168c", "0x001b", "0x0777", "0x3c03", 10, 0, "Ubiquiti", "XR3-3.6" ], - [ "0x168c", "0x001b", "0x0777", "0x3003", 10, 0, "Ubiquiti", "XR3" ], - [ "0x168c", "0x001b", "0x0777", "0x3004", 10, 0, "Ubiquiti", "XR4" ], - [ "0x168c", "0x001b", "0x0777", "0x3005", 10, 0, "Ubiquiti", "XR5" ], - [ "0x168c", "0x001b", "0x7777", "0x3005", 10, 0, "Ubiquiti", "XR5" ], - [ "0x168c", "0x001b", "0x0777", "0x3007", 10, 0, "Ubiquiti", "XR7" ], - [ "0x168c", "0x001b", "0x0777", "0x3009", 10, -1520, "Ubiquiti", "XR9" ], - [ "0x168c", "0x001b", "0x168c", "0x2063", 0, 0, "Atheros", "AR5413" ], - [ "0x168c", "0x0013", "0x168c", "0x1042", 1, 0, "Ubiquiti", "SRC" ], - [ "0x168c", "0x0013", "0x0777", "0x2041", 10, 0, "Ubiquiti", "SR2" ], - [ "0x168c", "0x0013", "0x0777", "0x2004", 6, 0, "Ubiquiti", "SR4" ], - [ "0x168c", "0x0013", "0x7777", "0x2004", 6, 0, "Ubiquiti", "SR4" ], - [ "0x168c", "0x0013", "0x0777", "0x1004", 6, 0, "Ubiquiti", "SR4C" ], - [ "0x168c", "0x0013", "0x7777", "0x1004", 6, 0, "Ubiquiti", "SR4C" ], - [ "0x168c", "0x0013", "0x168c", "0x2042", 7, 0, "Ubiquiti", "SR5" ], - [ "0x168c", "0x0013", "0x7777", "0x2009", 12, -1500, "Ubiquiti", "SR9" ], - [ "0x168c", "0x0027", "0x168c", "0x2082", 7, 0, "Ubiquiti", "SR71A" ], - [ "0x168c", "0x0027", "0x0777", "0x4082", 7, 0, "Ubiquiti", "SR71" ], - [ "0x168c", "0x0029", "0x0777", "0x4005", 7, 0, "Ubiquiti", "SR71-15" ], - [ "0x168c", "0x002a", "0x0777", "0xe302", 12, 0, "Ubiquiti", "PicoStation, M2" ], - [ "0x168c", "0x002a", "0x0777", "0xe012", 12, 0, "Ubiquiti", "NanoStation, M2" ], - [ "0x168c", "0x002a", "0x0777", "0xe005", 5, 0, "Ubiquiti", "NanoStation, M5" ], - [ "0x168c", "0x002a", "0x0777", "0xe202", 12, 0, "Ubiquiti", "Bullet, M2" ], - [ "0x168c", "0x002a", "0x0777", "0xe805", 5, 0, "Ubiquiti", "Bullet, M5" ], - [ "0x168c", "0x002a", "0x0777", "0xe345", 0, 0, "Ubiquiti", "WispStation, M5" ], - [ "0x168c", "0x0029", "0x168c", "0xa094", 0, 0, "Atheros", "AR9220" ], - [ "0x168c", "0x0029", "0x168c", "0xa095", 0, 0, "Atheros", "AR9223" ], - [ "0x168c", "0x002a", "0x168c", "0xa093", 0, 0, "Atheros", "AR9280" ], - [ "0x168c", "0x002b", "0x168c", "0xa091", 0, 0, "Atheros", "AR9285" ], - [ "0x168c", "0x002d", "0x168c", "0x209a", 0, 0, "Atheros", "AR9287" ], - [ "0x168c", "0x002e", "0x1a3b", "0x1121", 0, 0, "Atheros", "AR9287" ], - [ "0x168c", "0x002e", "0x0777", "0xe0a2", 8, 0, "Ubiquiti", "NanoStation, Loco, M2, (XM)" ], - [ "0x168c", "0x002e", "0x168c", "0x30a4", 0, 0, "Atheros", "AR9287" ], - [ "0x168c", "0x002e", "0x168c", "0xa199", 0, 0, "Atheros", "AR9287" ], - [ "0x168c", "0x0030", "0x168c", "0x3112", 0, 0, "Atheros", "AR9380" ], - [ "0x168c", "0x0030", "0x168c", "0x3114", 0, 0, "Atheros", "AR9390" ], - [ "0x168c", "0x0033", "0x168c", "0xa120", 0, 0, "Atheros", "AR9580" ], - [ "0x168c", "0x0033", "0x168c", "0xa136", 0, 0, "Atheros", "AR9580" ], - [ "0x168c", "0x0033", "0x168c", "0x3123", 0, 0, "Atheros", "AR9590" ], - [ "0x168c", "0x0033", "0x19b6", "0xd014", 0, 0, "MikroTik", "R11e-5HnD" ], - [ "0x168c", "0x0033", "0x19b6", "0xd057", 0, 0, "MikroTik", "R11e-5HnDr2" ], - [ "0x168c", "0x0033", "0x19b6", "0xd016", 0, 0, "MikroTik", "R11e-2HPnD" ], - [ "0x168c", "0x0034", "0x17aa", "0x3214", 0, 0, "Atheros", "AR9462" ], - [ "0x168c", "0x003c", "0x0000", "0x0000", 0, 0, "Qualcomm, Atheros", "QCA9880" ], - [ "0x168c", "0x003c", "0x168c", "0x3223", 0, 0, "Qualcomm, Atheros", "QCA9880" ], - [ "0x168c", "0x003c", "0x1a56", "0x1420", 0, 0, "Qualcomm, Atheros", "QCA9862" ], - [ "0x168c", "0x003c", "0x19b6", "0xd03c", 0, 0, "Mikrotik", "R11e-5HacT" ], - [ "0x168c", "0x003c", "0x19b6", "0xd075", 0, 0, "Mikrotik", "R11e-5HacD" ], - [ "0x168c", "0x003e", "0x168c", "0x3361", 0, 0, "Qualcomm, Atheros", "QCA6174" ], - [ "0x168c", "0x0040", "0x168c", "0x0002", 0, 0, "Qualcomm, Atheros", "QCA9990" ], - [ "0x168c", "0x0046", "0x168c", "0xcafe", 0, 0, "Qualcomm, Atheros", "QCA9984" ], - [ "0x168c", "0x0050", "0x0000", "0x0000", 0, 0, "Qualcomm, Atheros", "QCA9887" ], - [ "0x168c", "0x0056", "0x0000", "0x0000", 0, 0, "Qualcomm, Atheros", "QCA9886" ], - [ "0x17cb", "0x1104", "0x17cb", "0x1104", 0, 0, "Qualcomm, Atheros", "QCN6024/9024/9074" ], - [ "0x1814", "0x3051", "0x1814", "0x0007", 0, 0, "Ralink", "Rt3051" ], - [ "0x1814", "0x3052", "0x1814", "0x0008", 0, 0, "Ralink", "Rt3052" ], - [ "0x1814", "0x3350", "0x1814", "0x000b", 0, 0, "Ralink", "Rt3350" ], - [ "0x1814", "0x3662", "0x1814", "0x000d", 0, 0, "Ralink", "Rt3662" ], - [ "0x11ab", "0x2a55", "0x11ab", "0x0000", 0, 0, "Marvell", "88W8864" ], - [ "0x02df", "0x9135", "0x0000", "0x0000", 0, 0, "Marvell", "88W8887" ], - [ "0x11ab", "0x2b40", "0x11ab", "0x0000", 0, 0, "Marvell", "88W8964" ], - [ "0x02df", "0x9141", "0x0000", "0x0000", 0, 0, "Marvell", "88W8997" ], - [ "0x14c3", "0x0608", "0x14c3", "0x0608", 0, 0, "AMD", "RZ608" ], - [ "0x14c3", "0x7603", "0x14c3", "0x7603", 0, 0, "MediaTek", "MT7603E" ], - [ "0x14c3", "0x7610", "0x14c3", "0x7610", 0, 0, "MediaTek", "MT7610E" ], - [ "0x14c3", "0x7612", "0x14c3", "0x7612", 0, 0, "MediaTek", "MT7612E" ], - [ "0x14c3", "0x7663", "0x14c3", "0x7663", 0, 0, "MediaTek", "MT7613BE" ], - [ "0x14c3", "0x7615", "0x7615", "0x14c3", 0, 0, "MediaTek", "MT7615E" ], - [ "0x14c3", "0x7628", "0x14c3", "0x0004", 0, 0, "MediaTek", "MT76x8" ], - [ "0x14c3", "0x7650", "0x14c3", "0x7650", 0, 0, "MediaTek", "MT7610E" ], - [ "0x14c3", "0x7662", "0x14c3", "0x7662", 0, 0, "MediaTek", "MT76x2E" ], - [ "0x14c3", "0x7915", "0x14c3", "0x7915", 0, 0, "MediaTek", "MT7915E" ], - [ "0x14c3", "0x7906", "0x14c3", "0x7906", 0, 0, "MediaTek", "MT7916AN" ], - [ "0x14c3", "0x7990", "0x14C3", "0x6639", 0, 0, "MediaTek", "MT7996E" ], - [ "0x14e4", "0xaa52", "0x14e4", "0xaa52", 0, 0, "Broadcom", "BCM43602" ], - [ "0x02d0", "0xa9a6", "0x0000", "0x0000", 0, 0, "Cypress", "CYW43455" ], - [ "0x02d0", "0x4345", "0x0000", "0x0000", 0, 0, "Cypress", "CYW43455" ], - [ "0x1ae9", "0x0310", "0x1ae9", "0x0000", 0, 0, "Wilocity", "Wil6210" ], - [ "0x0000", "0x0000", "0x148f", "0x7601", 0, 0, "MediaTek", "MT7601U" ], - [ "0x0000", "0x0000", "0x0e8d", "0x7961", 0, 0, "MediaTek", "MT7921AU" ], - [ "0x0000", "0x0000", "0x0b05", "0x1833", 0, 0, "ASUS", "USB-AC54" ], - [ "0x0000", "0x0000", "0x0b05", "0x17eb", 0, 0, "ASUS", "USB-AC55" ], - [ "0x0000", "0x0000", "0x0b05", "0x180b", 0, 0, "ASUS", "USB-N53, B1" ], - [ "0x0000", "0x0000", "0x0e8d", "0x7612", 0, 0, "Aukey", "USBAC1200" ], - [ "0x0000", "0x0000", "0x057c", "0x8503", 0, 0, "AVM", "FRITZ!WLAN, AC860" ], - [ "0x0000", "0x0000", "0x7392", "0xb711", 0, 0, "Edimax", "EW-7722UAC" ], - [ "0x0000", "0x0000", "0x0e8d", "0x7632", 0, 0, "High, Cloud", "HC-M7662BU1" ], - [ "0x0000", "0x0000", "0x2c4e", "0x0103", 0, 0, "Mercury", "UD13" ], - [ "0x0000", "0x0000", "0x0846", "0x9053", 0, 0, "Netgear", "A6210" ], - [ "0x0000", "0x0000", "0x045e", "0x02e6", 0, 0, "Microsoft", "XBox, One, Wireless, Adapter" ], - [ "0x0000", "0x0000", "0x045e", "0x02fe", 0, 0, "Microsoft", "XBox, One, Wireless, Adapter" ], - [ "0x0000", "0x0000", "0x148f", "0x7610", 0, 0, "MediaTek", "MT7610U" ], - [ "0x0000", "0x0000", "0x13b1", "0x003e", 0, 0, "Linksys", "AE6000" ], - [ "0x0000", "0x0000", "0x0e8d", "0x7610", 0, 0, "Sabrent", "NTWLAC" ], - [ "0x0000", "0x0000", "0x7392", "0xa711", 0, 0, "Edimax", "7711MAC" ], - [ "0x0000", "0x0000", "0x148f", "0x761a", 0, 0, "TP-Link", "TL-WDN5200" ], - [ "0x0000", "0x0000", "0x0b05", "0x17d1", 0, 0, "ASUS", "USB-AC51" ], - [ "0x0000", "0x0000", "0x0b05", "0x17db", 0, 0, "ASUS", "USB-AC50" ], - [ "0x0000", "0x0000", "0x0df6", "0x0075", 0, 0, "Sitecom", "WLA-3100" ], - [ "0x0000", "0x0000", "0x2019", "0xab31", 0, 0, "Planex", "GW-450D" ], - [ "0x0000", "0x0000", "0x2001", "0x3d02", 0, 0, "D-Link", "DWA-171, rev, B1" ], - [ "0x0000", "0x0000", "0x0586", "0x3425", 0, 0, "Zyxel", "NWD6505" ], - [ "0x0000", "0x0000", "0x07b8", "0x7610", 0, 0, "AboCom", "AU7212" ], - [ "0x0000", "0x0000", "0x04bb", "0x0951", 0, 0, "I-O, DATA", "WN-AC433UK" ], - [ "0x0000", "0x0000", "0x057c", "0x8502", 0, 0, "AVM", "FRITZ!WLAN, AC430" ], - [ "0x0000", "0x0000", "0x293c", "0x5702", 0, 0, "Comcast", "Xfinity, KXW02AAA" ], - [ "0x0000", "0x0000", "0x20f4", "0x806b", 0, 0, "TRENDnet", "TEW-806UBH" ], - [ "0x0000", "0x0000", "0x7392", "0xc711", 0, 0, "Devolo", "WiFi, Stick, ac" ], - [ "0x0000", "0x0000", "0x0df6", "0x0079", 0, 0, "Sitecom", "WL-356" ], - [ "0x0000", "0x0000", "0x2357", "0x0123", 0, 0, "TP-Link", "T2UHP, US, v1" ], - [ "0x0000", "0x0000", "0x2357", "0x010b", 0, 0, "TP-Link", "T2UHP, UN, v1" ], - [ "0x0000", "0x0000", "0x2357", "0x0105", 0, 0, "TP-Link", "Archer, T1U" ], - [ "0x0000", "0x0000", "0x0e8d", "0x7630", 0, 0, "MediaTek", "MT7630U" ], - [ "0x0000", "0x0000", "0x0e8d", "0x7650", 0, 0, "MediaTek", "MT7650U" ], - [ "0x0000", "0x0000", "0x0e8d", "0x7663", 0, 0, "MediaTek", "MT7663U" ], - [ "0x0000", "0x0000", "0x043e", "0x310c", 0, 0, "LG", "LGSBWAC02" ], - [ "0x0000", "0x0000", "0x0bda", "0x8176", 0, 0, "Realtek", "RTL8188CU" ], - [ "0x0000", "0x0000", "0x0bda", "0xf179", 0, 0, "Realtek", "RTL8188FTV" ] - ], - "compatible": { - "qca,ar9130-wmac": [ "Atheros", "AR9130" ], - "qca,ar9330-wmac": [ "Atheros", "AR9330" ], - "qca,ar9340-wmac": [ "Atheros", "AR9340" ], - "qca,qca9530-wmac": [ "Qualcomm Atheros", "QCA9530" ], - "qca,qca9550-wmac": [ "Qualcomm Atheros", "QCA9550" ], - "qca,qca9560-wmac": [ "Qualcomm Atheros", "QCA9560" ], - "qcom,ipq4019-wifi": [ "Qualcomm Atheros", "IPQ4019" ], - "qcom,ipq6018-wifi": [ "Qualcomm Atheros", "IPQ6018" ], - "qcom,ipq8074-wifi": [ "Qualcomm Atheros", "IPQ8074" ], - "mediatek,mt7622-wmac": [ "MediaTek", "MT7622" ], - "mediatek,mt7628-wmac": [ "MediaTek", "MT7628" ], - "mediatek,mt7981-wmac": [ "MediaTek", "MT7981" ], - "mediatek,mt7986-wmac": [ "MediaTek", "MT7986" ], - "ralink,rt2880-wmac": [ "Ralink", "Rt2880" ], - "ralink,rt3050-wmac": [ "Ralink", "Rt3050" ], - "ralink,rt3352-wmac": [ "Ralink", "Rt3352" ], - "ralink,rt3883-wmac": [ "Ralink", "Rt3883" ], - "ralink,rt5350-wmac": [ "Ralink", "Rt5350" ], - "ralink,rt7620-wmac": [ "MediaTek", "MT7620" ] - } -} diff --git a/feeds/qca/mac80211/files/lib/netifd/wireless/mac80211.sh b/feeds/qca/mac80211/files/lib/netifd/wireless/mac80211.sh index d9d92d792..be7eea8f1 100755 --- a/feeds/qca/mac80211/files/lib/netifd/wireless/mac80211.sh +++ b/feeds/qca/mac80211/files/lib/netifd/wireless/mac80211.sh @@ -626,7 +626,7 @@ rename_board_phy_by_name() ( json_select "${phy%.*}" || return 0 json_get_vars path - prev_phy="$(iwinfo nl80211 phyname "path=$path${suffix:++$suffix}")" + prev_phy="$(/usr/share/iwinfo nl80211 phyname "path=$path${suffix:++$suffix}")" [ -n "$prev_phy" ] || return 0 [ "$prev_phy" = "$phy" ] && return 0 @@ -640,7 +640,7 @@ find_phy() { [ -d /sys/class/ieee80211/$phy ] && return 0 } [ -n "$path" ] && { - phy="$(iwinfo nl80211 phyname "path=$path")" + phy="$(/usr/share/iwinfo nl80211 phyname "path=$path")" [ -n "$phy" ] && { rename_board_phy_by_path "$path" return 0 @@ -649,7 +649,7 @@ find_phy() { [ -n "$macaddr" ] && { for phy in $(ls /sys/class/ieee80211 2>/dev/null); do grep -i -q "$macaddr" "/sys/class/ieee80211/${phy}/macaddress" && { - path="$(iwinfo nl80211 path "$phy")" + path="$(/usr/share/iwinfo nl80211 path "$phy")" rename_board_phy_by_path "$path" return 0 } diff --git a/patches/0084-iwinfo-add-ucode-based-version-for-wifi-7.patch b/patches/0084-iwinfo-add-ucode-based-version-for-wifi-7.patch new file mode 100644 index 000000000..94becc420 --- /dev/null +++ b/patches/0084-iwinfo-add-ucode-based-version-for-wifi-7.patch @@ -0,0 +1,1337 @@ +From 1c37b09f50c96890335d56ce9b0837284fd2736c Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Fri, 10 Jan 2025 09:44:47 +0100 +Subject: [PATCH] iwinfo: add ucode based version for wifi-7 + +Signed-off-by: John Crispin +--- + package/network/utils/iwinfo/Makefile | 8 + + .../utils/iwinfo/files-iwinfo/usr/bin/iwinfo | 156 +++++ + .../files-iwinfo/usr/share/iso3166.json | 249 +++++++ + .../files-iwinfo/usr/share/ucode/iwinfo.uc | 606 ++++++++++++++++++ + .../files-iwinfo/usr/share/wifi_devices.json | 258 ++++++++ + 5 files changed, 1277 insertions(+) + create mode 100755 package/network/utils/iwinfo/files-iwinfo/usr/bin/iwinfo + create mode 100644 package/network/utils/iwinfo/files-iwinfo/usr/share/iso3166.json + create mode 100644 package/network/utils/iwinfo/files-iwinfo/usr/share/ucode/iwinfo.uc + create mode 100644 package/network/utils/iwinfo/files-iwinfo/usr/share/wifi_devices.json + +diff --git a/package/network/utils/iwinfo/Makefile b/package/network/utils/iwinfo/Makefile +index e5add395ff..ba453f1b42 100644 +--- a/package/network/utils/iwinfo/Makefile ++++ b/package/network/utils/iwinfo/Makefile +@@ -108,10 +108,18 @@ define Package/libiwinfo-data/install + $(INSTALL_DATA) $(PKG_BUILD_DIR)/devices.txt $(1)/usr/share/libiwinfo/devices.txt + endef + ++ifeq ($(CONFIG_TARGET_ipq95xx)$(CONFIG_TARGET_ipq53xx),y) ++define Package/iwinfo/install ++ $(CP) ./files-iwinfo/* $(1) ++ $(INSTALL_DIR) $(1)/usr/bin ++ $(INSTALL_BIN) $(PKG_BUILD_DIR)/iwinfo $(1)/usr/share/iwinfo ++endef ++else + define Package/iwinfo/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/iwinfo $(1)/usr/bin/iwinfo + endef ++endif + + $(eval $(call BuildPackage,libiwinfo)) + $(eval $(call BuildPackage,libiwinfo-lua)) +diff --git a/package/network/utils/iwinfo/files-iwinfo/usr/bin/iwinfo b/package/network/utils/iwinfo/files-iwinfo/usr/bin/iwinfo +new file mode 100755 +index 0000000000..01285eb385 +--- /dev/null ++++ b/package/network/utils/iwinfo/files-iwinfo/usr/bin/iwinfo +@@ -0,0 +1,156 @@ ++#!/usr/bin/ucode ++ ++'use strict'; ++ ++import * as iwinfo from 'iwinfo'; ++ ++function print_assoclist(stations) { ++ for (let mac, station in stations) { ++ printf(`${station.mac} ${station.signal} dBm / ${station.noise} dBm (SNR ${station.snr}) ${station.inactive_time} ms ago\n`); ++ for (let k in [ 'rx', 'tx' ]) { ++ let bitrate = station[k]; ++ let flags = join(', ', bitrate.flags); ++ ++ printf(`\t${uc(k)}: ${bitrate.bitrate} MBit/s`); ++ if (length(bitrate.flags)) ++ printf(', %s', flags); ++ printf('%10d Pkts.\n', bitrate.packets); ++ } ++ printf(`\texpected throughput: ${station.expected_throughput}\n\n`); ++ } ++} ++ ++function print_countrylist(list) { ++ for (let k, v in list.countries) ++ printf(`${k == list.active ? '*' : ' '} ${k} "${v}"\n`); ++} ++ ++function print_freqlist(channels) { ++ for (let channel in channels) { ++ printf(`${channel.active ? '*' : ' '} ${channel.freq} GHz (Band: ${channel.band} GHz, Channel ${channel.channel})`); ++ if (length(channel.flags)) ++ printf(` [${join(', ', channel.flags)}]`); ++ printf('\n'); ++ } ++} ++ ++function print_htmodelist(htmode) { ++ printf('%s\n', join(' ', htmode)); ++} ++ ++function print_info(list) { ++ let padding = ' '; ++ ++ for (let bss in list) { ++ printf(`${bss.iface} ESSID: "${bss.ssid}"\n`); ++ printf(`${padding}Access Point: ${bss.mac}\n`); ++ printf(`${padding}Mode: ${bss.mode} Channel: ${bss.channel} (${bss.freq} GHz) HT Mode: ${bss.htmode}\n`); ++ printf(`${padding}Center Channel 1: ${bss.center_freq1} 2: ${bss.center_freq2}\n`); ++ printf(`${padding}Tx-Power: ${bss.txpower} dBm Link Quality: ${bss.quality}/70\n`); ++ printf(`${padding}Signal: ${bss.signal} Noise: ${bss.noise}\n`); ++ printf(`${padding}Bit Rate: ${bss.bitrate ?? 'unknown'} MBit/s\n`); ++ printf(`${padding}Encryption: ${bss.encryption}\n`); ++ printf(`${padding}Type: nl80211 HW Mode(s): 802.11${bss.hwmode}\n`); ++ printf(`${padding}Hardware: ${bss.hw_type} [${bss.hw_id}]\n`); ++ printf(`${padding}TX power offset: ${bss.power_offset}\n`); ++ printf(`${padding}Channel offset: ${bss.channel_offset}\n`); ++ printf(`${padding}Supports VAPs: ${bss.vaps} PHY name: ${bss.phy}\n`); ++ if (bss.owe_transition_ifname) ++ printf(`${padding}OWE partner: ${bss.owe_transition_ifname}\n`); ++ printf('\n'); ++ } ++ return 0; ++} ++ ++function print_scan(cells) { ++ let idx = 1; ++ ++ for (let cell in cells) { ++ printf('Cell %02d - Address: %s\n', idx++, cell.bssid); ++ printf('\t Mode: %s Frequency: %s GHz Band: %s GHz Channel: %d\n', cell.mode, cell.frequency, cell.band, cell.channel); ++ printf('\t Signal: %d dBm Quality: %2d/70\n', cell.dbm, cell.quality); ++ ++ if (!length(cell.crypto.key_mgmt)) ++ printf('\t Encryption: NONE\n'); ++ else ++ printf('\t Encryption: %s (%s)\n', join(' / ', cell.crypto.key_mgmt), join(' / ', cell.crypto.pair)); ++ ++ if (cell.ht) { ++ printf('\t HT Operation:\n'); ++ printf('\t\tPrimary Channel: %d\n', cell.ht.primary_channel); ++ printf('\t\tSecondary Channel Offset: %s\n', cell.ht.secondary_chan_off); ++ printf('\t\tChannel Width: %s\n', cell.ht.chan_width); ++ } ++ ++ if (cell.vht) { ++ printf('\t VHT Operation:\n'); ++ printf('\t\tCenter Frequency 1: %d\n', cell.vht.center_chan_1); ++ printf('\t\tCenter Frequency 2: %s\n', cell.vht.center_chan_2); ++ printf('\t\tChannel Width: %s\n', cell.vht.chan_width); ++ } ++ ++ printf('\n'); ++ } ++} ++ ++function print_txpowerlist(list) { ++ for (let power in list) ++ printf('%s %2d dbm (%4d mW)\n', power.active ? '*' : ' ', power.dbm, power.mw); ++} ++ ++let pretty = true; ++if (ARGV[0] == '-j') { ++ pretty = false; ++ shift(ARGV); ++} ++ ++if (!length(ARGV)) { ++ let info = iwinfo.info(); ++ if (pretty) ++ print_info(info); ++ else ++ printf('%.J\n', info); ++ return 0; ++} ++ ++const commands = { ++ assoclist: [ iwinfo.assoclist, print_assoclist ], ++ countrylist: [ iwinfo.countrylist, print_countrylist ], ++ freqlist: [ iwinfo.freqlist, print_freqlist ], ++ htmodelist: [ iwinfo.htmodelist, print_htmodelist ], ++ info: [ iwinfo.info, print_info ], ++ scan: [ iwinfo.scan, print_scan ], ++ txpowerlist: [ iwinfo.txpowerlist, print_txpowerlist ], ++}; ++ ++if (length(ARGV) == 2 && iwinfo.ifaces[ARGV[0]]) ++ for (let cmd, cb in commands) ++ if (substr(cmd, 0, length(ARGV[1])) == ARGV[1]) { ++ let ret = cb[0](ARGV[0]); ++ ++ if (pretty) ++ cb[1](ret); ++ else ++ printf('%.J\n', ret); ++ return 0; ++ } ++ ++switch(ARGV[0]) { ++case 'phy': ++ printf('%.J\n', iwinfo.phys); ++ return 0; ++ ++case 'iface': ++ printf('%.J\n', iwinfo.ifaces); ++ return 0; ++} ++ ++printf('Usage:\n' + ++ '\tiwinfo info\n' + ++ '\tiwinfo scan\n' + ++ '\tiwinfo txpowerlist\n' + ++ '\tiwinfo freqlist\n' + ++ '\tiwinfo assoclist\n' + ++ '\tiwinfo countrylist\n' + ++ '\tiwinfo htmodelist\n' + ++ '\tiwinfo phyname
\n'); +diff --git a/package/network/utils/iwinfo/files-iwinfo/usr/share/iso3166.json b/package/network/utils/iwinfo/files-iwinfo/usr/share/iso3166.json +new file mode 100644 +index 0000000000..ecd0b65383 +--- /dev/null ++++ b/package/network/utils/iwinfo/files-iwinfo/usr/share/iso3166.json +@@ -0,0 +1,249 @@ ++{ ++ "00": "World", ++ "AD": "Andorra", ++ "AE": "United Arab Emirates", ++ "AF": "Afghanistan", ++ "AG": "Antigua and Barbuda", ++ "AI": "Anguilla", ++ "AL": "Albania", ++ "AM": "Armenia", ++ "AN": "Netherlands Antilles", ++ "AO": "Angola", ++ "AQ": "Antarctica", ++ "AR": "Argentina", ++ "AS": "American Samoa", ++ "AT": "Austria", ++ "AU": "Australia", ++ "AW": "Aruba", ++ "AX": "Aland Islands", ++ "AZ": "Azerbaijan", ++ "BA": "Bosnia and Herzegovina", ++ "BB": "Barbados", ++ "BD": "Bangladesh", ++ "BE": "Belgium", ++ "BF": "Burkina Faso", ++ "BG": "Bulgaria", ++ "BH": "Bahrain", ++ "BI": "Burundi", ++ "BJ": "Benin", ++ "BL": "Saint Barthelemy", ++ "BM": "Bermuda", ++ "BN": "Brunei Darussalam", ++ "BO": "Bolivia", ++ "BR": "Brazil", ++ "BS": "Bahamas", ++ "BT": "Bhutan", ++ "BV": "Bouvet Island", ++ "BW": "Botswana", ++ "BY": "Belarus", ++ "BZ": "Belize", ++ "CA": "Canada", ++ "CC": "Cocos (Keeling) Islands", ++ "CD": "Congo", ++ "CF": "Central African Republic", ++ "CG": "Congo", ++ "CH": "Switzerland", ++ "CI": "Cote d'Ivoire", ++ "CK": "Cook Islands", ++ "CL": "Chile", ++ "CM": "Cameroon", ++ "CN": "China", ++ "CO": "Colombia", ++ "CR": "Costa Rica", ++ "CU": "Cuba", ++ "CV": "Cape Verde", ++ "CX": "Christmas Island", ++ "CY": "Cyprus", ++ "CZ": "Czech Republic", ++ "DE": "Germany", ++ "DJ": "Djibouti", ++ "DK": "Denmark", ++ "DM": "Dominica", ++ "DO": "Dominican Republic", ++ "DZ": "Algeria", ++ "EC": "Ecuador", ++ "EE": "Estonia", ++ "EG": "Egypt", ++ "EH": "Western Sahara", ++ "ER": "Eritrea", ++ "ES": "Spain", ++ "ET": "Ethiopia", ++ "FI": "Finland", ++ "FJ": "Fiji", ++ "FK": "Falkland Islands", ++ "FM": "Micronesia", ++ "FO": "Faroe Islands", ++ "FR": "France", ++ "GA": "Gabon", ++ "GB": "United Kingdom", ++ "GD": "Grenada", ++ "GE": "Georgia", ++ "GF": "French Guiana", ++ "GG": "Guernsey", ++ "GH": "Ghana", ++ "GI": "Gibraltar", ++ "GL": "Greenland", ++ "GM": "Gambia", ++ "GN": "Guinea", ++ "GP": "Guadeloupe", ++ "GQ": "Equatorial Guinea", ++ "GR": "Greece", ++ "GS": "South Georgia", ++ "GT": "Guatemala", ++ "GU": "Guam", ++ "GW": "Guinea-Bissau", ++ "GY": "Guyana", ++ "HK": "Hong Kong", ++ "HM": "Heard and McDonald Islands", ++ "HN": "Honduras", ++ "HR": "Croatia", ++ "HT": "Haiti", ++ "HU": "Hungary", ++ "ID": "Indonesia", ++ "IE": "Ireland", ++ "IL": "Israel", ++ "IM": "Isle of Man", ++ "IN": "India", ++ "IO": "Chagos Islands", ++ "IQ": "Iraq", ++ "IR": "Iran", ++ "IS": "Iceland", ++ "IT": "Italy", ++ "JE": "Jersey", ++ "JM": "Jamaica", ++ "JO": "Jordan", ++ "JP": "Japan", ++ "KE": "Kenya", ++ "KG": "Kyrgyzstan", ++ "KH": "Cambodia", ++ "KI": "Kiribati", ++ "KM": "Comoros", ++ "KN": "Saint Kitts and Nevis", ++ "KP": "North Korea", ++ "KR": "South Korea", ++ "KW": "Kuwait", ++ "KY": "Cayman Islands", ++ "KZ": "Kazakhstan", ++ "LA": "Laos", ++ "LB": "Lebanon", ++ "LC": "Saint Lucia", ++ "LI": "Liechtenstein", ++ "LK": "Sri Lanka", ++ "LR": "Liberia", ++ "LS": "Lesotho", ++ "LT": "Lithuania", ++ "LU": "Luxembourg", ++ "LV": "Latvia", ++ "LY": "Libyan Arab Jamahiriya", ++ "MA": "Morocco", ++ "MC": "Monaco", ++ "MD": "Moldova", ++ "ME": "Montenegro", ++ "MF": "Saint Martin (French part)", ++ "MG": "Madagascar", ++ "MH": "Marshall Islands", ++ "MK": "Macedonia", ++ "ML": "Mali", ++ "MM": "Myanmar", ++ "MN": "Mongolia", ++ "MO": "Macao", ++ "MP": "Northern Mariana Islands", ++ "MQ": "Martinique", ++ "MR": "Mauritania", ++ "MS": "Montserrat", ++ "MT": "Malta", ++ "MU": "Mauritius", ++ "MV": "Maldives", ++ "MW": "Malawi", ++ "MX": "Mexico", ++ "MY": "Malaysia", ++ "MZ": "Mozambique", ++ "NA": "Namibia", ++ "NC": "New Caledonia", ++ "NE": "Niger", ++ "NF": "Norfolk Island", ++ "NG": "Nigeria", ++ "NI": "Nicaragua", ++ "NL": "Netherlands", ++ "NO": "Norway", ++ "NP": "Nepal", ++ "NR": "Nauru", ++ "NU": "Niue", ++ "NZ": "New Zealand", ++ "OM": "Oman", ++ "PA": "Panama", ++ "PE": "Peru", ++ "PF": "French Polynesia", ++ "PG": "Papua New Guinea", ++ "PH": "Philippines", ++ "PK": "Pakistan", ++ "PL": "Poland", ++ "PM": "Saint Pierre and Miquelon", ++ "PN": "Pitcairn", ++ "PR": "Puerto Rico", ++ "PS": "Palestinian Territory", ++ "PT": "Portugal", ++ "PW": "Palau", ++ "PY": "Paraguay", ++ "QA": "Qatar", ++ "RE": "Reunion", ++ "RO": "Romania", ++ "RS": "Serbia", ++ "RU": "Russian Federation", ++ "RW": "Rwanda", ++ "SA": "Saudi Arabia", ++ "SB": "Solomon Islands", ++ "SC": "Seychelles", ++ "SD": "Sudan", ++ "SE": "Sweden", ++ "SG": "Singapore", ++ "SH": "St. Helena and Dependencies", ++ "SI": "Slovenia", ++ "SJ": "Svalbard and Jan Mayen", ++ "SK": "Slovakia", ++ "SL": "Sierra Leone", ++ "SM": "San Marino", ++ "SN": "Senegal", ++ "SO": "Somalia", ++ "SR": "Suriname", ++ "ST": "Sao Tome and Principe", ++ "SV": "El Salvador", ++ "SY": "Syrian Arab Republic", ++ "SZ": "Swaziland", ++ "TC": "Turks and Caicos Islands", ++ "TD": "Chad", ++ "TF": "French Southern Territories", ++ "TG": "Togo", ++ "TH": "Thailand", ++ "TJ": "Tajikistan", ++ "TK": "Tokelau", ++ "TL": "Timor-Leste", ++ "TM": "Turkmenistan", ++ "TN": "Tunisia", ++ "TO": "Tonga", ++ "TR": "Turkey", ++ "TT": "Trinidad and Tobago", ++ "TV": "Tuvalu", ++ "TW": "Taiwan", ++ "TZ": "Tanzania", ++ "UA": "Ukraine", ++ "UG": "Uganda", ++ "UM": "U.S. Minor Outlying Islands", ++ "US": "United States", ++ "UY": "Uruguay", ++ "UZ": "Uzbekistan", ++ "VA": "Vatican City State", ++ "VC": "St. Vincent and Grenadines", ++ "VE": "Venezuela", ++ "VG": "Virgin Islands, British", ++ "VI": "Virgin Islands, U.S.", ++ "VN": "Viet Nam", ++ "VU": "Vanuatu", ++ "WF": "Wallis and Futuna", ++ "WS": "Samoa", ++ "YE": "Yemen", ++ "YT": "Mayotte", ++ "ZA": "South Africa", ++ "ZM": "Zambia", ++ "ZW": "Zimbabwe" ++} +diff --git a/package/network/utils/iwinfo/files-iwinfo/usr/share/ucode/iwinfo.uc b/package/network/utils/iwinfo/files-iwinfo/usr/share/ucode/iwinfo.uc +new file mode 100644 +index 0000000000..84615adb5c +--- /dev/null ++++ b/package/network/utils/iwinfo/files-iwinfo/usr/share/ucode/iwinfo.uc +@@ -0,0 +1,606 @@ ++'use strict'; ++ ++import * as nl80211 from 'nl80211'; ++import * as libubus from 'ubus'; ++import { readfile, stat } from "fs"; ++ ++let wifi_devices = json(readfile('/usr/share/wifi_devices.json')); ++let countries = json(readfile('/usr/share/iso3166.json')); ++let board_data = json(readfile('/etc/board.json')); ++ ++export let phys = nl80211.request(nl80211.const.NL80211_CMD_GET_WIPHY, nl80211.const.NLM_F_DUMP, { split_wiphy_dump: true }); ++let interfaces = nl80211.request(nl80211.const.NL80211_CMD_GET_INTERFACE, nl80211.const.NLM_F_DUMP); ++ ++let ubus = libubus.connect(); ++let wireless_status = ubus.call('network.wireless', 'status'); ++ ++function find_phy(wiphy) { ++ for (let k, phy in phys) ++ if (phy.wiphy == wiphy) ++ return phy; ++ return null; ++} ++ ++function get_noise(iface) { ++ for (let phy in phys) { ++ let channels = nl80211.request(nl80211.const.NL80211_CMD_GET_SURVEY, nl80211.const.NLM_F_DUMP, { dev: iface.ifname }); ++ for (let k, channel in channels) ++ if (channel.survey_info.frequency == iface.wiphy_freq) ++ return channel.survey_info.noise; ++ } ++ ++ return -100; ++} ++ ++function get_country(iface) { ++ let reg = nl80211.request(nl80211.const.NL80211_CMD_GET_REG, 0, { dev: iface.ifname }); ++ ++ return reg.reg_alpha2 ?? ''; ++} ++ ++function get_max_power(iface) { ++ let phy = find_phy(iface.wiphy); ++ ++ for (let k, band in phy.wiphy_bands) ++ if (band) ++ for (let freq in band.freqs) ++ if (freq.freq == iface.wiphy_freq) ++ return freq.max_tx_power;; ++ return 0; ++} ++ ++function get_hardware_id(iface) { ++ let hw = { ++ type: 'nl80211', ++ id: 'Generic MAC80211', ++ power_offset: 0, ++ channel_offset: 0, ++ }; ++ ++ let path = `/sys/class/ieee80211/phy${iface.wiphy}/device/`; ++ if (stat(path) + 'vendor') { ++ let data = []; ++ for (let lookup in [ 'vendor', 'device', 'subsystem_vendor', 'subsystem_device' ]) ++ push(data, trim(readfile(path + lookup), '\n')); ++ ++ for (let device in wifi_devices.pci) { ++ let match = 0; ++ for (let i = 0; i < 4; i++) ++ if (lc(data[i]) == lc(device[i])) ++ match++; ++ if (match == 4) { ++ hw.type = `${data[0]}:${data[1]} ${data[2]}:${data[3]}`; ++ hw.power_offset = device[4]; ++ hw.channel_offset = device[5]; ++ hw.id = `${device[6]} ${device[7]}`; ++ } ++ } ++ } ++ ++ let compatible = trim(readfile(`/sys/class/net/${iface.ifname}/device/of_node/compatible`), '\n'); ++ if (compatible && wifi_devices.compatible[compatible]) { ++ hw.id = wifi_devices.compatible[compatible][0] + ' ' + wifi_devices.compatible[compatible][1]; ++ hw.compatible = compatible; ++ hw.type = 'embedded'; ++ } ++ ++ return hw; ++} ++ ++const iftypes = [ ++ 'Unknown', 'Ad-Hoc', 'Client', 'Master', 'Master (VLAN)', ++ 'WDS', 'Monitor', 'Mesh Point', 'P2P Client', 'P2P Go', ++]; ++ ++export let ifaces = {}; ++for (let k, v in interfaces) { ++ let iface = ifaces[v.ifname] = v; ++ ++ iface.mode = iftypes[iface.iftype] ?? 'unknonw', ++ iface.noise = get_noise(iface); ++ iface.country = get_country(iface); ++ iface.max_power = get_max_power(iface); ++ iface.assoclist = nl80211.request(nl80211.const.NL80211_CMD_GET_STATION, nl80211.const.NLM_F_DUMP, { dev: v.ifname }) ?? []; ++ iface.hardware = get_hardware_id(iface); ++ ++ iface.bss_info = ubus.call('hostapd', 'bss_info', { iface: v.ifname }); ++ if (!iface.bss_info) ++ iface.bss_info = ubus.call('wpa_supplicant', 'bss_info', { iface: v.ifname }); ++} ++ ++for (let radio, data in wireless_status) ++ for (let k, v in data.interfaces) { ++ if (!v.ifname || !ifaces[v.ifname]) ++ continue; ++ ++ ifaces[v.ifname].ssid = v.config.ssid; ++ ifaces[v.ifname].radio = data.config; ++ ++ let bss_info = ifaces[v.ifname].bss_info; ++ let owe_transition_ifname = bss_info?.owe_transition_ifname; ++ ++ if (v.config.owe_transition && ifaces[owe_transition_ifname]) { ++ ifaces[v.ifname].owe_transition_ifname = owe_transition_ifname; ++ ifaces[owe_transition_ifname].ssid = v.config.ssid; ++ ifaces[owe_transition_ifname].radio = data.config; ++ ifaces[owe_transition_ifname].owe_transition_ifname = v.ifname ++ } ++ } ++ ++function format_channel(freq) { ++ if (freq < 1000) ++ return 0; ++ if (freq == 2484) ++ return 14; ++ if (freq == 5935) ++ return 2; ++ if (freq < 2484) ++ return (freq - 2407) / 5; ++ if (freq >= 4910 && freq <= 4980) ++ return (freq - 4000) / 5; ++ if (freq < 5950) ++ return (freq - 5000) / 5; ++ if (freq <= 45000) ++ return (freq - 5950) / 5; ++ if (freq >= 58320 && freq <= 70200) ++ return (freq - 56160) / 2160; ++ ++ return 'unknown'; ++} ++ ++function format_band(freq) { ++ if (freq == 5935) ++ return '6'; ++ if (freq < 2484) ++ return '2.4'; ++ if (freq < 5950) ++ return '5'; ++ if (freq <= 45000) ++ return '6'; ++ ++ return '60'; ++} ++ ++function format_frequency(freq) { ++ if (!freq) ++ return 'unknown'; ++ freq = '' + freq; ++ return substr(freq, 0, 1) + '.' + substr(freq, 1); ++} ++ ++function format_rate(rate) { ++ if (!rate) ++ return 'unknown'; ++ return '' + (rate / 10) + '.' + (rate % 10); ++} ++ ++function format_mgmt_key(key) { ++ switch(+key) { ++ case 1: ++ case 11: ++ case 12: ++ case 13: ++ case 14: ++ case 15: ++ case 16: ++ case 17: ++ return '802.1x'; ++ ++ case 2: ++ return 'WPA PSK'; ++ ++ case 4: ++ return 'FT PSK'; ++ ++ case 6: ++ return 'WPA PSK2'; ++ ++ case 8: ++ return 'SAE'; ++ ++ case 18: ++ return 'OWE'; ++ } ++ ++ return null; ++} ++ ++function assoc_flags(data) { ++ const assoc_mhz = { ++ width_40: 40, ++ width_80: 80, ++ width_80p80: '80+80', ++ width_160: 160, ++ width_320: 320, ++ width_10: 10, ++ width_5: 5 ++ }; ++ ++ let mhz = 'unknown'; ++ for (let k, v in assoc_mhz) ++ if (data[k]) ++ mhz = v; ++ ++ const assoc_flags = { ++ mcs: { ++ mcs: 'MCS', ++ }, ++ vht_mcs: { ++ vht_mcs: 'VHT-MCS', ++ vht_nss: 'VHT-NSS', ++ }, ++ he_mcs: { ++ he_mcs: 'HE-MCS', ++ he_nss: 'HE-NSS', ++ he_gi: 'HE-GI', ++ he_dcm: 'HE-DCM', ++ }, ++ eht_mcs: { ++ eht_mcs: 'EHT-MCS', ++ eht_nss: 'EHT-NSS', ++ eht_gi: 'EHT-GI', ++ }, ++ }; ++ ++ let flags = []; ++ for (let k, v in assoc_flags) { ++ if (!data[k]) ++ continue; ++ ++ let first = 0; ++ for (let name, flag in v) { ++ if (data[name] == null) ++ continue; ++ push(flags, `${flag} ${data[name]}`); ++ if (!first++) ++ push(flags, `${mhz}MHz`); ++ } ++ } ++ ++ return flags; ++} ++ ++function dbm2mw(dbm) { ++ const LOG10_MAGIC = 1.25892541179; ++ let res = 1.0; ++ let ip = dbm / 10; ++ let fp = dbm % 10; ++ ++ for (let k = 0; k < ip; k++) ++ res *= 10; ++ for (let k = 0; k < fp; k++) ++ res *= 1.25892541179; ++ ++ return int(res); ++} ++ ++function dbm2quality(dbm) { ++ let quality = dbm; ++ ++ if (quality < -110) ++ quality = -110; ++ else if (quality > -40) ++ quality = -40; ++ quality += 110; ++ ++ return quality; ++} ++ ++function hwmodelist(name) { ++ const mode = { 'HT*': 'n', 'VHT*': 'ac', 'HE*': 'ax' }; ++ let iface = ifaces[name]; ++ let phy = board_data.wlan?.['phy' + iface.wiphy]; ++ if (!phy) ++ return ''; ++ let htmodes = phy.info.bands[uc(iface.radio.band)].modes; ++ let list = []; ++ if (iface.radio.band == '2g' && 'NOHT' in htmodes) ++ push(list, 'g/b'); ++ for (let k, v in mode) ++ for (let htmode in htmodes) ++ if (wildcard(htmode, k)) ++ push(list, v); ++ ++ return join('/', reverse(uniq(list))); ++} ++ ++export function assoclist(dev) { ++ let stations = ifaces[dev].assoclist; ++ let ret = {}; ++ ++ for (let station in stations) { ++ let sta = { ++ mac: uc(station.mac), ++ signal: station.sta_info.signal_avg, ++ noise: ifaces[dev].noise, ++ snr: station.sta_info.signal_avg - ifaces[dev].noise, ++ inactive_time: station.sta_info.inactive_time, ++ rx: { ++ bitrate: format_rate(station.sta_info.rx_bitrate.bitrate), ++ bitrate_raw: station.sta_info.rx_bitrate.bitrate, ++ packets: station.sta_info.rx_packets, ++ flags: assoc_flags(station.sta_info.rx_bitrate), ++ }, ++ tx: { ++ bitrate: format_rate(station.sta_info.tx_bitrate.bitrate), ++ bitrate_raw: station.sta_info.tx_bitrate.bitrate, ++ packets: station.sta_info.tx_packets, ++ flags: assoc_flags(station.sta_info.tx_bitrate), ++ }, ++ expected_throughput: station.sta_info.expected_throughput ?? 'unknown', ++ }; ++ ret[sta.mac] = sta; ++ } ++ ++ return ret; ++}; ++ ++export function freqlist(name) { ++ const freq_flags = { ++ no_10mhz: 'NO_10MHZ', ++ no_20mhz: 'NO_20MHZ', ++ no_ht40_minus: 'NO_HT40-', ++ no_ht40_plus: 'NO_HT40+', ++ no_80mhz: 'NO_80MHZ', ++ no_160mhz: 'NO_160MHZ', ++ indoor_only: 'INDOOR_ONLY', ++ no_ir: 'NO_IR', ++ no_he: 'NO_HE', ++ }; ++ ++ let iface = ifaces[name]; ++ let phy = find_phy(iface.wiphy); ++ let channels = []; ++ ++ for (let k, band in phy.wiphy_bands) { ++ if (!band) ++ continue; ++ ++ let band_name = format_band(band.freqs[0].freq); ++ for (let freq in band.freqs) { ++ if (freq.disabled) ++ continue; ++ ++ let channel = { ++ freq: format_frequency(freq.freq), ++ band: band_name, ++ channel: format_channel(freq.freq), ++ flags: [], ++ active: iface.wiphy_freq == freq.freq, ++ }; ++ ++ for (let k, v in freq_flags) ++ if (freq[k]) ++ push(channel.flags, v); ++ ++ push(channels, channel); ++ } ++ } ++ ++ return channels; ++}; ++ ++export function info(name) { ++ let order = []; ++ for (let iface, data in ifaces) ++ push(order, iface); ++ ++ let list = []; ++ for (let iface in sort(order)) { ++ if (name && iface != name) ++ continue; ++ let data = ifaces[iface]; ++ let dev = { ++ iface, ++ ssid: data.ssid, ++ mac: data.mac, ++ mode: data.mode, ++ channel: format_channel(data.wiphy_freq), ++ freq: format_frequency(data.wiphy_freq), ++ htmode: data.radio.htmode, ++ center_freq1: format_channel(data.center_freq1) || 'unknown', ++ center_freq2: format_channel(data.center_freq2) || 'unknown', ++ txpower: data.wiphy_tx_power_level / 100, ++ noise: data.noise, ++ signal: 0, ++ bitrate: 0, ++ encryption: 'unknown', ++ hwmode: hwmodelist(iface), ++ phy: 'phy' + data.wiphy, ++ vaps: 'no', ++ hw_type: data.hardware.type, ++ hw_id: data.hardware.id, ++ power_offset: data.hardware.power_offset || 'none', ++ channel_offset: data.hardware.channel_offset || 'none', ++ }; ++ ++ let phy = find_phy(data.wiphy); ++ for (let limit in phy.interface_combinations[0]?.limits) ++ if (limit.types?.ap && limit.max > 1) ++ dev.vaps = 'yes'; ++ ++ if (data.bss_info) { ++ if (data.bss_info.wpa_key_mgmt && data.bss_info.wpa_pairwise) ++ dev.encryption = `${replace(data.bss_info.wpa_key_mgmt, ' ', ' / ')} (${data.bss_info.wpa_pairwise})`; ++ else if (data.owe_transition_ifname) ++ dev.encryption = 'none (OWE transition)'; ++ else ++ dev.encryption = 'none'; ++ } ++ ++ let stations = assoclist(iface); ++ for (let k, station in stations) { ++ dev.signal += station.signal; ++ dev.bitrate += station.tx.bitrate_raw; ++ } ++ dev.signal /= length(data.assoclist) || 1; ++ dev.bitrate /= length(data.assoclist) || 1; ++ dev.bitrate = format_rate(dev.bitrate); ++ dev.quality = dbm2quality(dev.signal); ++ ++ if (data.owe_transition_ifname) ++ dev.owe_transition_ifname = data.owe_transition_ifname; ++ ++ push(list, dev); ++ } ++ ++ return list; ++}; ++ ++export function htmodelist(name) { ++ let iface = ifaces[name]; ++ let phy = board_data.wlan?.['phy' + iface.wiphy]; ++ if (!phy) ++ return []; ++ ++ return filter(phy.info.bands[uc(iface.radio.band)].modes, (v) => v != 'NOHT'); ++}; ++ ++export function txpowerlist(name) { ++ let iface = ifaces[name]; ++ let max_power = iface.max_power / 100; ++ let match = iface.wiphy_tx_power_level / 100; ++ let list = []; ++ ++ for (let power = 0; power <= max_power; power++) { ++ let txpower = { ++ dbm: power, ++ mw: dbm2mw(power), ++ active: power == match, ++ }; ++ push(list, txpower); ++ } ++ ++ return list; ++}; ++ ++export function countrylist(dev) { ++ let iface = ifaces[dev]; ++ ++ let list = { ++ active: iface.country, ++ countries, ++ }; ++ ++ return list; ++}; ++ ++export function scan(dev) { ++ const rsn_cipher = [ 'NONE', 'WEP-40', 'TKIP', 'WRAP', 'CCMP', 'WEP-104', 'AES-OCB', 'CKIP', 'GCMP', 'GCMP-256', 'CCMP-256' ]; ++ const ht_chan_offset = [ 'no secondary', 'above', '[reserved]', 'below' ]; ++ const vht_chan_width = [ '20 or 40 MHz', '80 MHz', '80+80 MHz', '160 MHz' ]; ++ const ht_chan_width = [ '20 MHz', '40 MHz or higher' ]; ++ const SCAN_FLAG_AP = (1<<2); ++ ++ let params = { ++ dev, ++ scan_flags: SCAN_FLAG_AP, ++ scan_ssids: [ '' ], ++ }; ++ ++ let res = nl80211.request(nl80211.const.NL80211_CMD_TRIGGER_SCAN, 0, params); ++ if (res === false) { ++ printf("Unable to trigger scan: " + nl80211.error() + "\n"); ++ exit(1); ++ } ++ ++ res = nl80211.waitfor([ ++ nl80211.const.NL80211_CMD_NEW_SCAN_RESULTS, ++ nl80211.const.NL80211_CMD_SCAN_ABORTED ++ ], 5000); ++ ++ if (!res) { ++ printf("Netlink error while awaiting scan results: " + nl80211.error() + "\n"); ++ exit(1); ++ } else if (res.cmd == nl80211.const.NL80211_CMD_SCAN_ABORTED) { ++ printf("Scan aborted by kernel\n"); ++ exit(1); ++ } ++ ++ let scan = nl80211.request(nl80211.const.NL80211_CMD_GET_SCAN, nl80211.const.NLM_F_DUMP, { dev }); ++ ++ let cells = []; ++ for (let k, bss in scan) { ++ bss = bss.bss; ++ let cell = { ++ bssid: uc(bss.bssid), ++ frequency: format_frequency(bss.frequency), ++ band: format_band(bss.frequency), ++ channel: format_channel(bss.frequency), ++ dbm: bss.signal_mbm / 100, ++ ++ }; ++ ++ if (bss.capability & (1 << 1)) ++ cell.mode = 'Ad-Hoc'; ++ else if (bss.capability & (1 << 0)) ++ cell.mode = 'Master'; ++ else ++ cell.mode = 'Mesh Point'; ++ ++ cell.quality = dbm2quality(cell.dbm); ++ ++ for (let ie in bss.information_elements) ++ switch(ie.type) { ++ case 0: ++ case 114: ++ cell.ssid = ie.data; ++ break; ++ ++ case 7: ++ cell.country = substr(ie.data, 0, 2); ++ break; ++ ++ case 48: ++ cell.crypto = { ++ group: rsn_cipher[+ord(ie.data, 5)] ?? '', ++ pair: [], ++ key_mgmt: [], ++ }; ++ ++ let offset = 6; ++ let count = +ord(ie.data, offset); ++ offset += 2; ++ ++ for (let i = 0; i < count; i++) { ++ let key = rsn_cipher[+ord(ie.data, offset + 3)]; ++ if (key) ++ push(cell.crypto.pair, key); ++ offset += 4; ++ } ++ ++ count = +ord(ie.data, offset); ++ offset += 2; ++ ++ for (let i = 0; i < count; i++) { ++ let key = format_mgmt_key(ord(ie.data, offset + 3)); ++ if (key) ++ push(cell.crypto.key_mgmt, key); ++ offset += 4; ++ } ++ break; ++ ++ case 61: ++ cell.ht = { ++ primary_channel: ord(ie.data, 0), ++ secondary_chan_off: ht_chan_offset[ord(ie.data, 1) & 0x3], ++ chan_width: ht_chan_width[(ord(ie.data, 1) & 0x4) >> 2], ++ }; ++ break; ++ ++ case 192: ++ cell.vht = { ++ chan_width: vht_chan_width[ord(ie.data, 0)], ++ center_chan_1: ord(ie.data, 1), ++ center_chan_2: ord(ie.data, 2), ++ }; ++ break; ++ }; ++ ++ ++ ++ push(cells, cell); ++ } ++ ++ return cells; ++}; +diff --git a/package/network/utils/iwinfo/files-iwinfo/usr/share/wifi_devices.json b/package/network/utils/iwinfo/files-iwinfo/usr/share/wifi_devices.json +new file mode 100644 +index 0000000000..7e9c63751b +--- /dev/null ++++ b/package/network/utils/iwinfo/files-iwinfo/usr/share/wifi_devices.json +@@ -0,0 +1,258 @@ ++{ ++ "pci": [ ++ [ "0x0777", "0x11ac", "0x0777", "0xe7f9", 0, 0, "Ubiquiti", "LiteBeam, 5AC" ], ++ [ "0xffff", "0xffff", "0xffff", "0xb102", 0, 0, "Ubiquiti", "PowerStation2, (18V)" ], ++ [ "0xffff", "0xffff", "0xffff", "0xb202", 0, 0, "Ubiquiti", "PowerStation2, (16D)" ], ++ [ "0xffff", "0xffff", "0xffff", "0xb302", 0, 0, "Ubiquiti", "PowerStation2, (EXT)" ], ++ [ "0xffff", "0xffff", "0xffff", "0xb105", 0, 0, "Ubiquiti", "PowerStation5, (22V)" ], ++ [ "0xffff", "0xffff", "0xffff", "0xb305", 0, 0, "Ubiquiti", "PowerStation5, (EXT)" ], ++ [ "0xffff", "0xffff", "0xffff", "0xc302", 0, 0, "Ubiquiti", "PicoStation2" ], ++ [ "0xffff", "0xffff", "0xffff", "0xc3a2", 10, 0, "Ubiquiti", "PicoStation2, HP" ], ++ [ "0xffff", "0xffff", "0xffff", "0xa105", 0, 0, "Ubiquiti", "WispStation5" ], ++ [ "0xffff", "0xffff", "0xffff", "0xa002", 10, 0, "Ubiquiti", "LiteStation2" ], ++ [ "0xffff", "0xffff", "0xffff", "0xa005", 5, 0, "Ubiquiti", "LiteStation5" ], ++ [ "0xffff", "0xffff", "0xffff", "0xc002", 10, 0, "Ubiquiti", "NanoStation2" ], ++ [ "0xffff", "0xffff", "0xffff", "0xc005", 5, 0, "Ubiquiti", "NanoStation5" ], ++ [ "0xffff", "0xffff", "0xffff", "0xc102", 10, 0, "Ubiquiti", "NanoStation, Loco2" ], ++ [ "0xffff", "0xffff", "0xffff", "0xc105", 5, 0, "Ubiquiti", "NanoStation, Loco5" ], ++ [ "0xffff", "0xffff", "0xffff", "0xc202", 10, 0, "Ubiquiti", "Bullet2" ], ++ [ "0xffff", "0xffff", "0xffff", "0xc205", 5, 0, "Ubiquiti", "Bullet5" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe002", 6, 0, "Ubiquiti", "airOS, XM" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe003", 3, 0, "Ubiquiti", "airOS, XM" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe005", 5, 0, "Ubiquiti", "NanoStation, M5" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe006", 5, 0, "Ubiquiti", "airOS, XM" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe009", 6, 0, "Ubiquiti", "NanoStation, Loco, M9" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe012", 10, 0, "Ubiquiti", "NanoStation, M2" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe035", 3, 0, "Ubiquiti", "NanoStation, M3" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe0a2", 2, 0, "Ubiquiti", "NanoStation, Loco, M2" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe0a5", 1, 0, "Ubiquiti", "NanoStation, Loco, M5" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe102", 6, 0, "Ubiquiti", "airOS, XM" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe105", 5, 0, "Ubiquiti", "Rocket, M5" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe112", 10, 0, "Ubiquiti", "airOS, XM" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe115", 3, 0, "Ubiquiti", "airOS, XM" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe1a3", 3, 0, "Ubiquiti", "airOS, XM" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe1a5", 5, 0, "Ubiquiti", "PowerBridge, M5" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe1b2", 10, 0, "Ubiquiti", "airOS, XM" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe1b3", 3, 0, "Ubiquiti", "airOS, XM" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe1b5", 5, 0, "Ubiquiti", "Rocket, M5" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe1b6", 5, 0, "Ubiquiti", "airOS, XM" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe1b9", 6, 0, "Ubiquiti", "Rocket, M9" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe1c2", 10, 0, "Ubiquiti", "airOS, XM" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe1c3", 3, 0, "Ubiquiti", "Rocket, M3" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe1c5", 5, 0, "Ubiquiti", "Rocket, M5, GPS" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe1c5", 5, 0, "Ubiquiti", "airOS, XM" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe1d2", 10, 0, "Ubiquiti", "Rocket, M2, Titanium" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe1d3", 3, 0, "Ubiquiti", "airOS, XM" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe1d5", 5, 0, "Ubiquiti", "airOS, XM/XW" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe1d9", 6, 0, "Ubiquiti", "airOS, XM" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe1e3", 3, 0, "Ubiquiti", "airOS, XM" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe1e5", 5, 0, "Ubiquiti", "airOS, XM" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe202", 12, 0, "Ubiquiti", "Bullet, M2" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe205", 6, 0, "Ubiquiti", "Bullet, M5" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe212", 1, 0, "Ubiquiti", "AirGrid, M2" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe215", 1, 0, "Ubiquiti", "AirGrid, M5" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe232", 2, 0, "Ubiquiti", "NanoBridge, M2" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe233", 3, 0, "Ubiquiti", "airOS, XM" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe235", 1, 0, "Ubiquiti", "NanoBridge, M5" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe239", 6, 0, "Ubiquiti", "NanoBridge, M9" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe242", 9, 0, "Ubiquiti", "AirGrid, M2, HP" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe243", 3, 0, "Ubiquiti", "NanoBridge, M3" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe245", 6, 0, "Ubiquiti", "AirGrid, M5, HP" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe252", 9, 0, "Ubiquiti", "AirGrid, M2, HP" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe255", 6, 0, "Ubiquiti", "AirGrid, M5, HP" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe2a3", 3, 0, "Ubiquiti", "airOS, XM" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe2a5", 5, 0, "Ubiquiti", "airOS, XM" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe2b2", 10, 0, "Ubiquiti", "airOS, XM" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe2b5", 1, 0, "Ubiquiti", "NanoBridge, M5" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe2b9", 6, 0, "Ubiquiti", "airOS, XM" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe2c2", 10, 0, "Ubiquiti", "NanoBeam, M2, Int" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe2c3", 6, 0, "Ubiquiti", "Bullet, M2, XW" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe2c4", 6, 0, "Ubiquiti", "airOS, XW" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe2d2", 12, 0, "Ubiquiti", "Bullet, M2, Titanium, HP" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe2d4", 6, 0, "Ubiquiti", "airOS, XW" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe2d5", 6, 0, "Ubiquiti", "airOS, XM" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe2e5", 4, 0, "Ubiquiti", "airOS, XM" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe302", 12, 0, "Ubiquiti", "PicoStation, M2"], ++ [ "0x168c", "0xffff", "0x0777", "0xe305", 6, 0, "Ubiquiti", "airOS, XM" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe345", 6, 0, "Ubiquiti", "WispStation, M5" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe3a5", 5, 0, "Ubiquiti", "airOS, XM" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe3b5", 6, 0, "Ubiquiti", "airOS, XM/XW" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe3e5", 4, 0, "Ubiquiti", "PowerBeam, M5, 300" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe402", 10, 0, "Ubiquiti", "airOS, XM" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe405", 1, 0, "Ubiquiti", "airOS, XM" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe4a2", 1, 0, "Ubiquiti", "AirRouter" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe4a5", 1, 0, "Ubiquiti", "airOS, XM" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe4b2", 9, 0, "Ubiquiti", "AirRouter, HP" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe4d5", 5, 0, "Ubiquiti", "Rocket, M5, Titanium" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe4e5", 4, 0, "Ubiquiti", "PowerBeam, M5, 400" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe5e5", 4, 0, "Ubiquiti", "airOS, XW" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe6a2", 1, 0, "Ubiquiti", "airOS, XM" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe6b2", 1, 0, "Ubiquiti", "airOS, XM" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe6b5", 5, 0, "Ubiquiti", "Rocket, M5, XW" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe6c2", 6, 0, "Ubiquiti", "airOS, XM" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe6e5", 4, 0, "Ubiquiti", "PowerBeam, M5, 400, ISO" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe7f8", 2, 0, "Ubiquiti", "airOS, XW" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe805", 5, 0, "Ubiquiti", "airOS, XM" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe812", 6, 0, "Ubiquiti", "NanoBeam, M2, 13" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe815", 4, 0, "Ubiquiti", "NanoBeam, M5, 16" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe825", 4, 0, "Ubiquiti", "NanoBeam, M5, 19" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe835", 6, 0, "Ubiquiti", "AirGrid, M5, XW" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe845", 1, 0, "Ubiquiti", "NanoStation, Loco, M5, XW" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe855", 5, 0, "Ubiquiti", "NanoStation, M5, XW" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe865", 6, 0, "Ubiquiti", "LiteBeam, M5" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe866", 6, 0, "Ubiquiti", "NanoStation, M2, XW" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe867", 2, 0, "Ubiquiti", "NanoStation, Loco, M2, XW" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe868", 7, 0, "Ubiquiti", "Rocket, M2, XW" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe869", 2, 0, "Ubiquiti", "airOS, XW" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe875", 4, 0, "Ubiquiti", "airOS, XW" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe879", 2, 0, "Ubiquiti", "airOS, XW" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe885", 4, 0, "Ubiquiti", "PowerBeam, M5, 620, XW" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe895", 4, 0, "Ubiquiti", "airOS, XW" ], ++ [ "0x168c", "0xffff", "0x0777", "0xe8a5", 1, 0, "Ubiquiti", "NanoStation, Loco, M5"], ++ [ "0x168c", "0xffff", "0x0777", "0xe8b5", 5, 0, "Ubiquiti", "airOS, XM" ], ++ [ "0x168c", "0x001b", "0x0777", "0x3002", 10, 0, "Ubiquiti", "XR2" ], ++ [ "0x168c", "0x001b", "0x7777", "0x3002", 10, 0, "Ubiquiti", "XR2" ], ++ [ "0x168c", "0x001b", "0x0777", "0x3b02", 10, 0, "Ubiquiti", "XR2.3" ], ++ [ "0x168c", "0x001b", "0x0777", "0x3c02", 10, 0, "Ubiquiti", "XR2.6" ], ++ [ "0x168c", "0x001b", "0x0777", "0x3b03", 10, 0, "Ubiquiti", "XR3-2.8" ], ++ [ "0x168c", "0x001b", "0x0777", "0x3c03", 10, 0, "Ubiquiti", "XR3-3.6" ], ++ [ "0x168c", "0x001b", "0x0777", "0x3003", 10, 0, "Ubiquiti", "XR3" ], ++ [ "0x168c", "0x001b", "0x0777", "0x3004", 10, 0, "Ubiquiti", "XR4" ], ++ [ "0x168c", "0x001b", "0x0777", "0x3005", 10, 0, "Ubiquiti", "XR5" ], ++ [ "0x168c", "0x001b", "0x7777", "0x3005", 10, 0, "Ubiquiti", "XR5" ], ++ [ "0x168c", "0x001b", "0x0777", "0x3007", 10, 0, "Ubiquiti", "XR7" ], ++ [ "0x168c", "0x001b", "0x0777", "0x3009", 10, -1520, "Ubiquiti", "XR9" ], ++ [ "0x168c", "0x001b", "0x168c", "0x2063", 0, 0, "Atheros", "AR5413" ], ++ [ "0x168c", "0x0013", "0x168c", "0x1042", 1, 0, "Ubiquiti", "SRC" ], ++ [ "0x168c", "0x0013", "0x0777", "0x2041", 10, 0, "Ubiquiti", "SR2" ], ++ [ "0x168c", "0x0013", "0x0777", "0x2004", 6, 0, "Ubiquiti", "SR4" ], ++ [ "0x168c", "0x0013", "0x7777", "0x2004", 6, 0, "Ubiquiti", "SR4" ], ++ [ "0x168c", "0x0013", "0x0777", "0x1004", 6, 0, "Ubiquiti", "SR4C" ], ++ [ "0x168c", "0x0013", "0x7777", "0x1004", 6, 0, "Ubiquiti", "SR4C" ], ++ [ "0x168c", "0x0013", "0x168c", "0x2042", 7, 0, "Ubiquiti", "SR5" ], ++ [ "0x168c", "0x0013", "0x7777", "0x2009", 12, -1500, "Ubiquiti", "SR9" ], ++ [ "0x168c", "0x0027", "0x168c", "0x2082", 7, 0, "Ubiquiti", "SR71A" ], ++ [ "0x168c", "0x0027", "0x0777", "0x4082", 7, 0, "Ubiquiti", "SR71" ], ++ [ "0x168c", "0x0029", "0x0777", "0x4005", 7, 0, "Ubiquiti", "SR71-15" ], ++ [ "0x168c", "0x002a", "0x0777", "0xe302", 12, 0, "Ubiquiti", "PicoStation, M2" ], ++ [ "0x168c", "0x002a", "0x0777", "0xe012", 12, 0, "Ubiquiti", "NanoStation, M2" ], ++ [ "0x168c", "0x002a", "0x0777", "0xe005", 5, 0, "Ubiquiti", "NanoStation, M5" ], ++ [ "0x168c", "0x002a", "0x0777", "0xe202", 12, 0, "Ubiquiti", "Bullet, M2" ], ++ [ "0x168c", "0x002a", "0x0777", "0xe805", 5, 0, "Ubiquiti", "Bullet, M5" ], ++ [ "0x168c", "0x002a", "0x0777", "0xe345", 0, 0, "Ubiquiti", "WispStation, M5" ], ++ [ "0x168c", "0x0029", "0x168c", "0xa094", 0, 0, "Atheros", "AR9220" ], ++ [ "0x168c", "0x0029", "0x168c", "0xa095", 0, 0, "Atheros", "AR9223" ], ++ [ "0x168c", "0x002a", "0x168c", "0xa093", 0, 0, "Atheros", "AR9280" ], ++ [ "0x168c", "0x002b", "0x168c", "0xa091", 0, 0, "Atheros", "AR9285" ], ++ [ "0x168c", "0x002d", "0x168c", "0x209a", 0, 0, "Atheros", "AR9287" ], ++ [ "0x168c", "0x002e", "0x1a3b", "0x1121", 0, 0, "Atheros", "AR9287" ], ++ [ "0x168c", "0x002e", "0x0777", "0xe0a2", 8, 0, "Ubiquiti", "NanoStation, Loco, M2, (XM)" ], ++ [ "0x168c", "0x002e", "0x168c", "0x30a4", 0, 0, "Atheros", "AR9287" ], ++ [ "0x168c", "0x002e", "0x168c", "0xa199", 0, 0, "Atheros", "AR9287" ], ++ [ "0x168c", "0x0030", "0x168c", "0x3112", 0, 0, "Atheros", "AR9380" ], ++ [ "0x168c", "0x0030", "0x168c", "0x3114", 0, 0, "Atheros", "AR9390" ], ++ [ "0x168c", "0x0033", "0x168c", "0xa120", 0, 0, "Atheros", "AR9580" ], ++ [ "0x168c", "0x0033", "0x168c", "0xa136", 0, 0, "Atheros", "AR9580" ], ++ [ "0x168c", "0x0033", "0x168c", "0x3123", 0, 0, "Atheros", "AR9590" ], ++ [ "0x168c", "0x0033", "0x19b6", "0xd014", 0, 0, "MikroTik", "R11e-5HnD" ], ++ [ "0x168c", "0x0033", "0x19b6", "0xd057", 0, 0, "MikroTik", "R11e-5HnDr2" ], ++ [ "0x168c", "0x0033", "0x19b6", "0xd016", 0, 0, "MikroTik", "R11e-2HPnD" ], ++ [ "0x168c", "0x0034", "0x17aa", "0x3214", 0, 0, "Atheros", "AR9462" ], ++ [ "0x168c", "0x003c", "0x0000", "0x0000", 0, 0, "Qualcomm, Atheros", "QCA9880" ], ++ [ "0x168c", "0x003c", "0x168c", "0x3223", 0, 0, "Qualcomm, Atheros", "QCA9880" ], ++ [ "0x168c", "0x003c", "0x1a56", "0x1420", 0, 0, "Qualcomm, Atheros", "QCA9862" ], ++ [ "0x168c", "0x003c", "0x19b6", "0xd03c", 0, 0, "Mikrotik", "R11e-5HacT" ], ++ [ "0x168c", "0x003c", "0x19b6", "0xd075", 0, 0, "Mikrotik", "R11e-5HacD" ], ++ [ "0x168c", "0x003e", "0x168c", "0x3361", 0, 0, "Qualcomm, Atheros", "QCA6174" ], ++ [ "0x168c", "0x0040", "0x168c", "0x0002", 0, 0, "Qualcomm, Atheros", "QCA9990" ], ++ [ "0x168c", "0x0046", "0x168c", "0xcafe", 0, 0, "Qualcomm, Atheros", "QCA9984" ], ++ [ "0x168c", "0x0050", "0x0000", "0x0000", 0, 0, "Qualcomm, Atheros", "QCA9887" ], ++ [ "0x168c", "0x0056", "0x0000", "0x0000", 0, 0, "Qualcomm, Atheros", "QCA9886" ], ++ [ "0x17cb", "0x1104", "0x17cb", "0x1104", 0, 0, "Qualcomm, Atheros", "QCN6024/9024/9074" ], ++ [ "0x1814", "0x3051", "0x1814", "0x0007", 0, 0, "Ralink", "Rt3051" ], ++ [ "0x1814", "0x3052", "0x1814", "0x0008", 0, 0, "Ralink", "Rt3052" ], ++ [ "0x1814", "0x3350", "0x1814", "0x000b", 0, 0, "Ralink", "Rt3350" ], ++ [ "0x1814", "0x3662", "0x1814", "0x000d", 0, 0, "Ralink", "Rt3662" ], ++ [ "0x11ab", "0x2a55", "0x11ab", "0x0000", 0, 0, "Marvell", "88W8864" ], ++ [ "0x02df", "0x9135", "0x0000", "0x0000", 0, 0, "Marvell", "88W8887" ], ++ [ "0x11ab", "0x2b40", "0x11ab", "0x0000", 0, 0, "Marvell", "88W8964" ], ++ [ "0x02df", "0x9141", "0x0000", "0x0000", 0, 0, "Marvell", "88W8997" ], ++ [ "0x14c3", "0x0608", "0x14c3", "0x0608", 0, 0, "AMD", "RZ608" ], ++ [ "0x14c3", "0x7603", "0x14c3", "0x7603", 0, 0, "MediaTek", "MT7603E" ], ++ [ "0x14c3", "0x7610", "0x14c3", "0x7610", 0, 0, "MediaTek", "MT7610E" ], ++ [ "0x14c3", "0x7612", "0x14c3", "0x7612", 0, 0, "MediaTek", "MT7612E" ], ++ [ "0x14c3", "0x7663", "0x14c3", "0x7663", 0, 0, "MediaTek", "MT7613BE" ], ++ [ "0x14c3", "0x7615", "0x7615", "0x14c3", 0, 0, "MediaTek", "MT7615E" ], ++ [ "0x14c3", "0x7628", "0x14c3", "0x0004", 0, 0, "MediaTek", "MT76x8" ], ++ [ "0x14c3", "0x7650", "0x14c3", "0x7650", 0, 0, "MediaTek", "MT7610E" ], ++ [ "0x14c3", "0x7662", "0x14c3", "0x7662", 0, 0, "MediaTek", "MT76x2E" ], ++ [ "0x14c3", "0x7915", "0x14c3", "0x7915", 0, 0, "MediaTek", "MT7915E" ], ++ [ "0x14c3", "0x7906", "0x14c3", "0x7906", 0, 0, "MediaTek", "MT7916AN" ], ++ [ "0x14c3", "0x7990", "0x14C3", "0x6639", 0, 0, "MediaTek", "MT7996E" ], ++ [ "0x14e4", "0xaa52", "0x14e4", "0xaa52", 0, 0, "Broadcom", "BCM43602" ], ++ [ "0x02d0", "0xa9a6", "0x0000", "0x0000", 0, 0, "Cypress", "CYW43455" ], ++ [ "0x02d0", "0x4345", "0x0000", "0x0000", 0, 0, "Cypress", "CYW43455" ], ++ [ "0x1ae9", "0x0310", "0x1ae9", "0x0000", 0, 0, "Wilocity", "Wil6210" ], ++ [ "0x0000", "0x0000", "0x148f", "0x7601", 0, 0, "MediaTek", "MT7601U" ], ++ [ "0x0000", "0x0000", "0x0e8d", "0x7961", 0, 0, "MediaTek", "MT7921AU" ], ++ [ "0x0000", "0x0000", "0x0b05", "0x1833", 0, 0, "ASUS", "USB-AC54" ], ++ [ "0x0000", "0x0000", "0x0b05", "0x17eb", 0, 0, "ASUS", "USB-AC55" ], ++ [ "0x0000", "0x0000", "0x0b05", "0x180b", 0, 0, "ASUS", "USB-N53, B1" ], ++ [ "0x0000", "0x0000", "0x0e8d", "0x7612", 0, 0, "Aukey", "USBAC1200" ], ++ [ "0x0000", "0x0000", "0x057c", "0x8503", 0, 0, "AVM", "FRITZ!WLAN, AC860" ], ++ [ "0x0000", "0x0000", "0x7392", "0xb711", 0, 0, "Edimax", "EW-7722UAC" ], ++ [ "0x0000", "0x0000", "0x0e8d", "0x7632", 0, 0, "High, Cloud", "HC-M7662BU1" ], ++ [ "0x0000", "0x0000", "0x2c4e", "0x0103", 0, 0, "Mercury", "UD13" ], ++ [ "0x0000", "0x0000", "0x0846", "0x9053", 0, 0, "Netgear", "A6210" ], ++ [ "0x0000", "0x0000", "0x045e", "0x02e6", 0, 0, "Microsoft", "XBox, One, Wireless, Adapter" ], ++ [ "0x0000", "0x0000", "0x045e", "0x02fe", 0, 0, "Microsoft", "XBox, One, Wireless, Adapter" ], ++ [ "0x0000", "0x0000", "0x148f", "0x7610", 0, 0, "MediaTek", "MT7610U" ], ++ [ "0x0000", "0x0000", "0x13b1", "0x003e", 0, 0, "Linksys", "AE6000" ], ++ [ "0x0000", "0x0000", "0x0e8d", "0x7610", 0, 0, "Sabrent", "NTWLAC" ], ++ [ "0x0000", "0x0000", "0x7392", "0xa711", 0, 0, "Edimax", "7711MAC" ], ++ [ "0x0000", "0x0000", "0x148f", "0x761a", 0, 0, "TP-Link", "TL-WDN5200" ], ++ [ "0x0000", "0x0000", "0x0b05", "0x17d1", 0, 0, "ASUS", "USB-AC51" ], ++ [ "0x0000", "0x0000", "0x0b05", "0x17db", 0, 0, "ASUS", "USB-AC50" ], ++ [ "0x0000", "0x0000", "0x0df6", "0x0075", 0, 0, "Sitecom", "WLA-3100" ], ++ [ "0x0000", "0x0000", "0x2019", "0xab31", 0, 0, "Planex", "GW-450D" ], ++ [ "0x0000", "0x0000", "0x2001", "0x3d02", 0, 0, "D-Link", "DWA-171, rev, B1" ], ++ [ "0x0000", "0x0000", "0x0586", "0x3425", 0, 0, "Zyxel", "NWD6505" ], ++ [ "0x0000", "0x0000", "0x07b8", "0x7610", 0, 0, "AboCom", "AU7212" ], ++ [ "0x0000", "0x0000", "0x04bb", "0x0951", 0, 0, "I-O, DATA", "WN-AC433UK" ], ++ [ "0x0000", "0x0000", "0x057c", "0x8502", 0, 0, "AVM", "FRITZ!WLAN, AC430" ], ++ [ "0x0000", "0x0000", "0x293c", "0x5702", 0, 0, "Comcast", "Xfinity, KXW02AAA" ], ++ [ "0x0000", "0x0000", "0x20f4", "0x806b", 0, 0, "TRENDnet", "TEW-806UBH" ], ++ [ "0x0000", "0x0000", "0x7392", "0xc711", 0, 0, "Devolo", "WiFi, Stick, ac" ], ++ [ "0x0000", "0x0000", "0x0df6", "0x0079", 0, 0, "Sitecom", "WL-356" ], ++ [ "0x0000", "0x0000", "0x2357", "0x0123", 0, 0, "TP-Link", "T2UHP, US, v1" ], ++ [ "0x0000", "0x0000", "0x2357", "0x010b", 0, 0, "TP-Link", "T2UHP, UN, v1" ], ++ [ "0x0000", "0x0000", "0x2357", "0x0105", 0, 0, "TP-Link", "Archer, T1U" ], ++ [ "0x0000", "0x0000", "0x0e8d", "0x7630", 0, 0, "MediaTek", "MT7630U" ], ++ [ "0x0000", "0x0000", "0x0e8d", "0x7650", 0, 0, "MediaTek", "MT7650U" ], ++ [ "0x0000", "0x0000", "0x0e8d", "0x7663", 0, 0, "MediaTek", "MT7663U" ], ++ [ "0x0000", "0x0000", "0x043e", "0x310c", 0, 0, "LG", "LGSBWAC02" ], ++ [ "0x0000", "0x0000", "0x0bda", "0x8176", 0, 0, "Realtek", "RTL8188CU" ], ++ [ "0x0000", "0x0000", "0x0bda", "0xf179", 0, 0, "Realtek", "RTL8188FTV" ] ++ ], ++ "compatible": { ++ "qca,ar9130-wmac": [ "Atheros", "AR9130" ], ++ "qca,ar9330-wmac": [ "Atheros", "AR9330" ], ++ "qca,ar9340-wmac": [ "Atheros", "AR9340" ], ++ "qca,qca9530-wmac": [ "Qualcomm Atheros", "QCA9530" ], ++ "qca,qca9550-wmac": [ "Qualcomm Atheros", "QCA9550" ], ++ "qca,qca9560-wmac": [ "Qualcomm Atheros", "QCA9560" ], ++ "qcom,ipq4019-wifi": [ "Qualcomm Atheros", "IPQ4019" ], ++ "qcom,ipq6018-wifi": [ "Qualcomm Atheros", "IPQ6018" ], ++ "qcom,ipq8074-wifi": [ "Qualcomm Atheros", "IPQ8074" ], ++ "mediatek,mt7622-wmac": [ "MediaTek", "MT7622" ], ++ "mediatek,mt7628-wmac": [ "MediaTek", "MT7628" ], ++ "mediatek,mt7981-wmac": [ "MediaTek", "MT7981" ], ++ "mediatek,mt7986-wmac": [ "MediaTek", "MT7986" ], ++ "ralink,rt2880-wmac": [ "Ralink", "Rt2880" ], ++ "ralink,rt3050-wmac": [ "Ralink", "Rt3050" ], ++ "ralink,rt3352-wmac": [ "Ralink", "Rt3352" ], ++ "ralink,rt3883-wmac": [ "Ralink", "Rt3883" ], ++ "ralink,rt5350-wmac": [ "Ralink", "Rt5350" ], ++ "ralink,rt7620-wmac": [ "MediaTek", "MT7620" ] ++ } ++} +-- +2.34.1 +