From 0525f2f57a1a3362f59fe711a65bd1796141134b Mon Sep 17 00:00:00 2001 From: kr venkatvishal Date: Mon, 28 Oct 2024 09:24:44 -0700 Subject: [PATCH] HOS-21926 Ap5020/Awe3 - Plugin ah_wireless_v2 Creating new plugin for Wifi7 compiatble devices --- plugins/inputs/ah_wireless_v2/README.md | 4381 +++++++++++++++++ .../ah_wireless_v2/ah_wireless_defines_v2.go | 960 ++++ .../inputs/ah_wireless_v2/ah_wireless_v2.go | 1921 ++++++++ plugins/inputs/all/all.go | 1 + 4 files changed, 7263 insertions(+) create mode 100644 plugins/inputs/ah_wireless_v2/README.md create mode 100644 plugins/inputs/ah_wireless_v2/ah_wireless_defines_v2.go create mode 100644 plugins/inputs/ah_wireless_v2/ah_wireless_v2.go diff --git a/plugins/inputs/ah_wireless_v2/README.md b/plugins/inputs/ah_wireless_v2/README.md new file mode 100644 index 0000000000000..92ebc3d878958 --- /dev/null +++ b/plugins/inputs/ah_wireless_v2/README.md @@ -0,0 +1,4381 @@ +# ah_wireless Input Plugin + +The `ah_wireless` plugin gather metrics on the wireless statistics from HiveOS. + +## Configuration + +```toml +# Read metrics about wireless stats +[[inputs.ah_wireless]] + # Sample interval + interval = "5s" + # Interface names from where stats to be collected + ifname = ["wifi0","wifi1"] +``` + +## Metrics + +There are two Metrics: +RfStats +and +ClientStats + +- RfStats + - device: + - serialnumber (string) + - items: + - channelUtilization: + - interferenceUtilization: + + txUtilization: + + rxUtilization: + + rxInbssUtilization: + + rxObssUtilization: + + wifinterferenceUtilization: + + noise: + + crcErrorRate: + + txPackets: + description: Counter - Number of transmitted packets. + type: integer + format: int64 + txErrors: + description: Counter - Number of transmitted packets with errors. + type: integer + format: int64 + txDropped: + description: Counter - Number of dropped transmit packets. + type: integer + format: int64 + txHwDropped: + description: Counter - Number of dropped transmit packets by HW. + type: integer + format: int64 + txSwDropped: + description: Counter - Number of dropped transmit packets by SW. + type: integer + format: int64 + txBytes: + description: Counter - Number of transmitted bytes. + type: integer + format: int64 + txRetryCount: + description: Counter - Number of transmit retries. + type: integer + format: int64 + txRate: + $ref: "../../../common/components/schemas/FloatGauge.yaml" + txUnicastPackets: + description: Counter - Number of transmitted Unicast packets. + type: integer + format: int64 + txMulticastPackets: + description: Counter - Number of transmitted Multicast packets. + type: integer + format: int64 + txMulticastBytes: + description: Counter - Number of transmitted Multicast bytes. + type: integer + format: int64 + txBcastPackets: + description: Counter - Number of transmitted Broadcast packets. + type: integer + format: int64 + txBcastBytes: + description: Counter - Number of transmitted Broadcast bytes. + type: integer + format: int64 + rxPackets: + description: Counter - Number of received packets. + type: integer + format: int64 + rxErrors: + description: Counter - Number of received packets with errors. + type: integer + format: int64 + rxDropped: + description: Counter - Number of dropped receive packets. + type: integer + format: int64 + rxBytes: + description: Counter - Number of received bytes. + type: integer + format: int64 + rxRetryCount: + description: Counter - Number of receive retries. + type: integer + format: int64 + rxRate: + + rxUnicastPackets: + description: Counter - Number of received Unicast packets. + type: integer + format: int64 + rxMulticastPackets: + description: Counter - Number of received Multicast packets. + type: integer + format: int64 + rxMulticastBytes: + description: Counter - Number of received Multicast bytes. + type: integer + format: int64 + rxBcastPackets: + description: Counter - Number of received Broadcast packets. + type: integer + format: int64 + rxBcastBytes: + description: Counter - Number of received Broadcast bytes. + type: integer + format: int64 + bsSpCnt: + description: Band steering suppress count. + type: integer + format: int32 + lbSpCnt: + description: Load balance suppress count. + type: integer + format: int32 + snrSpCnt: + description: Weak snr suppress count. + type: integer + format: int32 + snAnswerCnt: + description: Safety net answer (safety net check fail) count. + type: integer + format: int32 + rxPrbSpCnt: + description: Probe request suppressed count . + type: integer + format: int32 + rxAuthCnt: + description: Auth request suppressed count. + type: integer + format: int32 + txBitrateSuc: + description: Total TX bit rate success distribution percentage. + type: integer + format: int8 + rxBitrateSuc: + description: Total RX bit rate success distribution percentage. + type: integer + format: int8 + rxRateStats: + description: rx distribution bit rate + type: array + + txRateStats: + description: tx distribution bit rate + type: array + + clientCount: + +ClientStats: +description: |- + assocTime: Wireless association time in milliseconds. + authTime: Authentication time in milliseconds. + dhcpTime: Time to obtain IP address in milliseconds. + dnsTime: Time to resolve domain names in milliseconds. +type: object +properties: + keys: + mac: + type: string + description: Client MAC address + pattern: "^([0-9A-F]{2}:){5}([0-9A-F]{2})$" + ifIndex: + description: radio interface. + type: integer + format: int32 + ssid: + description: Client SSID name + type: string + txPackets: + description: TX data frame count. + type: integer + format: int32 + txBytes: + description: TX data byte count. + type: integer + format: int32 + txDrop: + description: TX frames are dropped due to max retried. + type: integer + format: int32 + slaDrop: + description: number of SAL violation traps occurred. + type: integer + format: int32 + rxPackets: + description: RX data frame count. + type: integer + format: int32 + rxBytes: + description: RX data byte count. + type: integer + format: int32 + rxDrop: + description: RX frames dropped due to decrypt, MIC error etc. + type: integer + format: int32 + avgSnr: + description: Average SNR (dB). + type: integer + format: int8 + psTimes: + description: Client entered into power save mode times. + type: integer + format: int32 + radioScore: + description: Radio link score (client SLA score). + type: integer + format: int8 + ipNetScore: + description: IP network connectivity score. + type: integer + format: int8 + appScore: + description: Application health score. + type: integer + format: int8 + phyMode: + description: client radio mode. + type: integer + format: int8 + rssi: + description: client rssi. + type: integer + format: int8 + os: + description: client OS name + type: string + name: + description: user name + type: string + host: + description: host name + type: string + profName: + description: user profile name + type: string + dhcpIp: + description: DHCP server IP. + type: integer + format: int32 + gwIp: + description: gateway IP. + type: integer + format: int32 + dnsIp: + description: DNS server IP. + type: integer + format: int32 + clientIp: + description: Client IP address. + type: integer + format: int32 + dhcpTime: + type: integer + format: int32 + gwTime: + type: integer + format: int32 + dnsTime: + type: integer + format: int32 + clientTime: + type: integer + format: int64 + rxRateStats: + description: rx rate counter + type: array + + txRateStats: + description: tx rate counter + type: array + + txNssUsage: + description: TX spatial stream percentage. + type: array + maxItems: 4 + items: + type: integer + format: int8 + txAirtime: + description: station TX airtime percentage. + + rxAirtime: + description: station RX airtime percentage. + + bwUsage: + description: Bandwidth usages. + + required: + keys + +## Troubleshooting + +On HiveOS, we can check output by executing hiden commands: +_show report snapshot client +and +_show report snapshot interface + +## Example Output + +```shell +{ + 'rfStats': [ + { + 'device': { + 'serialnumber': '${SERIALNUM}' + }, + 'items': [ + { + 'bsSpCnt': 0, + 'channelUtilization': { + 'avg': 0, + 'max': 0, + 'min': 0 + }, + 'clientCount': 1, + 'crcErrorRate': { + 'avg': 1437555618742272, + 'max': 1437555618742272, + 'min': 1437555618742272 + }, + 'interferenceUtilization': { + 'avg': 0, + 'max': 0, + 'min': 0 + }, + 'keys': { + 'ifindex': 17, + 'name': 'wifi0' + }, + 'lbSpCnt': 0, + 'noise': { + 'avg': 0, + 'max': 0, + 'min': 0 + }, + 'rxAuthCnt': 0, + 'rxBcastBytes': 0, + 'rxBcastPackets': 0, + 'rxBitrateSuc': 0, + 'rxBytes': 243859054, + 'rxDropped': 0, + 'rxErrors': 0, + 'rxInbssUtilization': { + 'avg': 0, + 'max': 0, + 'min': 0 + }, + 'rxMulticastBytes': 65442, + 'rxMulticastPackets': 0, + 'rxObssUtilization': { + 'avg': 0, + 'max': 0, + 'min': 0 + }, + 'rxPackets': 623559, + 'rxPrbSpCnt': 0, + 'rxProbeSup': 0, + 'rxRate': { + 'avg': 0, + 'max': 0, + 'min': 0 + }, + 'rxRateStats': { + '0': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '1': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '10': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '100': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '101': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '102': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '103': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '104': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '105': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '106': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '107': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '108': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '109': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '11': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '110': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '111': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '112': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '113': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '114': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '115': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '116': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '117': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '118': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '119': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '12': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '120': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '121': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '122': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '123': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '124': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '125': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '126': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '127': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '128': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '129': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '13': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '130': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '131': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '132': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '133': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '134': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '135': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '136': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '137': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '138': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '139': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '14': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '140': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '141': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '142': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '143': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '144': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '145': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '146': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '147': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '148': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '149': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '15': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '150': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '151': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '152': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '153': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '154': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '155': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '156': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '157': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '158': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '159': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '16': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '160': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '161': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '162': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '163': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '164': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '165': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '166': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '167': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '168': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '169': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '17': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '170': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '171': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '172': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '173': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '174': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '175': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '176': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '177': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '178': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '179': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '18': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '180': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '181': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '182': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '183': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '184': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '185': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '186': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '187': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '188': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '189': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '19': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '190': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '191': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '2': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '20': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '21': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '22': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '23': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '24': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '25': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '26': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '27': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '28': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '29': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '3': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '30': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '31': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '32': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '33': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '34': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '35': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '36': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '37': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '38': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '39': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '4': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '40': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '41': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '42': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '43': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '44': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '45': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '46': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '47': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '48': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '49': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '5': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '50': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '51': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '52': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '53': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '54': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '55': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '56': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '57': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '58': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '59': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '6': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '60': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '61': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '62': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '63': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '64': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '65': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '66': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '67': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '68': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '69': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '7': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '70': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '71': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '72': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '73': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '74': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '75': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '76': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '77': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '78': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '79': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '8': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '80': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '81': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '82': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '83': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '84': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '85': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '86': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '87': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '88': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '89': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '9': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '90': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '91': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '92': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '93': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '94': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '95': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '96': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '97': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '98': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '99': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + } + }, + 'rxRetryCount': 0, + 'rxSwDropped': 0, + 'rxUnicastPackets': 0, + 'rxUtilization': { + 'avg': 0, + 'max': 0, + 'min': 0 + }, + 'snAnswerCnt': 0, + 'snrSpCnt': 0, + 'txBcastBytes': 0, + 'txBcastPackets': 0, + 'txBitrateSuc': 0, + 'txBytes': 992704, + 'txDropped': 0, + 'txErrors': 697, + 'txHwDropped': 0, + 'txMulticastBytes': 0, + 'txMulticastPackets': 0, + 'txPackets': 7794, + 'txRate': { + 'avg': 0, + 'max': 0, + 'min': 0 + }, + 'txRateStats': { + '0': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '1': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '10': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '100': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '101': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '102': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '103': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '104': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '105': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '106': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '107': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '108': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '109': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '11': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '110': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '111': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '112': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '113': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '114': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '115': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '116': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '117': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '118': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '119': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '12': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '120': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '121': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '122': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '123': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '124': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '125': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '126': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '127': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '128': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '129': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '13': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '130': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '131': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '132': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '133': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '134': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '135': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '136': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '137': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '138': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '139': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '14': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '140': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '141': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '142': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '143': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '144': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '145': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '146': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '147': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '148': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '149': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '15': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '150': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '151': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '152': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '153': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '154': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '155': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '156': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '157': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '158': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '159': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '16': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '160': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '161': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '162': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '163': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '164': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '165': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '166': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '167': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '168': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '169': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '17': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '170': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '171': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '172': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '173': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '174': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '175': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '176': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '177': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '178': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '179': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '18': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '180': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '181': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '182': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '183': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '184': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '185': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '186': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '187': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '188': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '189': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '19': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '190': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '191': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '2': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '20': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '21': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '22': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '23': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '24': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '25': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '26': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '27': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '28': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '29': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '3': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '30': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '31': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '32': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '33': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '34': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '35': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '36': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '37': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '38': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '39': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '4': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '40': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '41': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '42': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '43': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '44': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '45': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '46': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '47': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '48': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '49': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '5': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '50': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '51': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '52': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '53': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '54': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '55': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '56': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '57': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '58': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '59': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '6': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '60': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '61': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '62': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '63': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '64': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '65': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '66': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '67': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '68': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '69': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '7': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '70': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '71': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '72': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '73': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '74': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '75': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '76': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '77': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '78': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '79': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '8': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '80': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '81': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '82': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '83': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '84': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '85': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '86': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '87': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '88': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '89': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '9': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '90': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '91': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '92': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '93': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '94': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '95': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '96': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '97': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '98': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '99': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + } + }, + 'txRetryCount': 0, + 'txSwDropped': 0, + 'txUnicastPackets': 0, + 'txUtilization': { + 'avg': 0, + 'max': 0, + 'min': 0 + }, + 'wifinterferenceUtilization': { + 'avg': 0, + 'max': 0, + 'min': 0 + } + }, + { + 'bsSpCnt': 0, + 'channelUtilization': { + 'avg': 0, + 'max': 0, + 'min': 0 + }, + 'clientCount': 1, + 'crcErrorRate': { + 'avg': 789668392075264, + 'max': 789668392075264, + 'min': 789668392075264 + }, + 'interferenceUtilization': { + 'avg': 0, + 'max': 0, + 'min': 0 + }, + 'keys': { + 'ifindex': 15, + 'name': 'wifi1' + }, + 'lbSpCnt': 0, + 'noise': { + 'avg': 0, + 'max': 0, + 'min': 0 + }, + 'rxAuthCnt': 0, + 'rxBcastBytes': 9746, + 'rxBcastPackets': 0, + 'rxBitrateSuc': 0, + 'rxBytes': 243860736, + 'rxDropped': 0, + 'rxErrors': 0, + 'rxInbssUtilization': { + 'avg': 0, + 'max': 0, + 'min': 0 + }, + 'rxMulticastBytes': 65440, + 'rxMulticastPackets': 0, + 'rxObssUtilization': { + 'avg': 0, + 'max': 0, + 'min': 0 + }, + 'rxPackets': 623563, + 'rxPrbSpCnt': 0, + 'rxProbeSup': 0, + 'rxRate': { + 'avg': 0, + 'max': 0, + 'min': 0 + }, + 'rxRateStats': { + '0': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '1': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '10': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '100': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '101': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '102': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '103': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '104': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '105': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '106': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '107': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '108': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '109': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '11': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '110': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '111': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '112': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '113': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '114': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '115': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '116': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '117': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '118': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '119': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '12': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '120': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '121': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '122': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '123': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '124': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '125': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '126': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '127': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '128': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '129': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '13': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '130': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '131': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '132': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '133': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '134': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '135': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '136': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '137': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '138': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '139': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '14': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '140': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '141': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '142': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '143': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '144': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '145': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '146': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '147': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '148': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '149': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '15': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '150': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '151': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '152': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '153': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '154': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '155': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '156': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '157': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '158': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '159': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '16': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '160': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '161': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '162': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '163': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '164': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '165': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '166': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '167': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '168': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '169': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '17': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '170': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '171': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '172': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '173': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '174': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '175': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '176': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '177': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '178': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '179': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '18': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '180': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '181': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '182': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '183': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '184': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '185': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '186': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '187': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '188': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '189': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '19': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '190': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '191': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '2': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '20': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '21': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '22': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '23': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '24': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '25': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '26': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '27': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '28': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '29': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '3': { + 'kbps': 1, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '30': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '31': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '32': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '33': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '34': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '35': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '36': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '37': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '38': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '39': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '4': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '40': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '41': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '42': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '43': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '44': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '45': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '46': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '47': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '48': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '49': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '5': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '50': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '51': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '52': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '53': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '54': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '55': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '56': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '57': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '58': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '59': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '6': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '60': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '61': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '62': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '63': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '64': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '65': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '66': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '67': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '68': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '69': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '7': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '70': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '71': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '72': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '73': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '74': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '75': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '76': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '77': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '78': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '79': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '8': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '80': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '81': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '82': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '83': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '84': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '85': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '86': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '87': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '88': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '89': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '9': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '90': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '91': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '92': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '93': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '94': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '95': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '96': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '97': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '98': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '99': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + } + }, + 'rxRetryCount': 210, + 'rxSwDropped': 0, + 'rxUnicastPackets': 0, + 'rxUtilization': { + 'avg': 0, + 'max': 0, + 'min': 0 + }, + 'snAnswerCnt': 0, + 'snrSpCnt': 0, + 'txBcastBytes': 214994, + 'txBcastPackets': 0, + 'txBitrateSuc': 0, + 'txBytes': 992704, + 'txDropped': 0, + 'txErrors': 697, + 'txHwDropped': 697, + 'txMulticastBytes': 776836, + 'txMulticastPackets': 0, + 'txPackets': 7794, + 'txRate': { + 'avg': 0, + 'max': 0, + 'min': 0 + }, + 'txRateStats': { + '0': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '1': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '10': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '100': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '101': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '102': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '103': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '104': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '105': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '106': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '107': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '108': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '109': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '11': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '110': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '111': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '112': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '113': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '114': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '115': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '116': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '117': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '118': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '119': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '12': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '120': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '121': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '122': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '123': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '124': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '125': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '126': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '127': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '128': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '129': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '13': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '130': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '131': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '132': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '133': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '134': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '135': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '136': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '137': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '138': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '139': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '14': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '140': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '141': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '142': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '143': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '144': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '145': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '146': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '147': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '148': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '149': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '15': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '150': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '151': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '152': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '153': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '154': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '155': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '156': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '157': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '158': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '159': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '16': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '160': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '161': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '162': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '163': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '164': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '165': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '166': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '167': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '168': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '169': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '17': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '170': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '171': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '172': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '173': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '174': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '175': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '176': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '177': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '178': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '179': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '18': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '180': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '181': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '182': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '183': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '184': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '185': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '186': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '187': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '188': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '189': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '19': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '190': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '191': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '2': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '20': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '21': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '22': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '23': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '24': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '25': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '26': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '27': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '28': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '29': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '3': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '30': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '31': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '32': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '33': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '34': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '35': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '36': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '37': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '38': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '39': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '4': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '40': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '41': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '42': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '43': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '44': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '45': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '46': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '47': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '48': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '49': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '5': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '50': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '51': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '52': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '53': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '54': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '55': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '56': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '57': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '58': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '59': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '6': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '60': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '61': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '62': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '63': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '64': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '65': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '66': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '67': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '68': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '69': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '7': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '70': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '71': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '72': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '73': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '74': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '75': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '76': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '77': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '78': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '79': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '8': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '80': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '81': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '82': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '83': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '84': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '85': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '86': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '87': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '88': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '89': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '9': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '90': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '91': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '92': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '93': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '94': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '95': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '96': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '97': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '98': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + }, + '99': { + 'kbps': 0, + 'rateDtn': 0, + 'rateSucDtn': 0 + } + }, + 'txRetryCount': 0, + 'txSwDropped': 0, + 'txUnicastPackets': 0, + 'txUtilization': { + 'avg': 0, + 'max': 0, + 'min': 0 + }, + 'wifinterferenceUtilization': { + 'avg': 0, + 'max': 0, + 'min': 0 + } + } + ], + 'name': 'RfStats', + 'ts': 1722327710 + } + ] +} + +``` diff --git a/plugins/inputs/ah_wireless_v2/ah_wireless_defines_v2.go b/plugins/inputs/ah_wireless_v2/ah_wireless_defines_v2.go new file mode 100644 index 0000000000000..a730230572aeb --- /dev/null +++ b/plugins/inputs/ah_wireless_v2/ah_wireless_defines_v2.go @@ -0,0 +1,960 @@ +package ah_wireless_v2 + +import ( + "golang.org/x/sys/unix" + "unsafe" + "fmt" +) + +const ( + AH_FE_DEV_NAME = "/dev/fe" + SIOCIWFIRSTPRIV = 0x8BE0 + SIOCGRADIOSTATS = unix.SIOCDEVPRIVATE + 1 + IEEE80211_IOCTL_GETPARAM = SIOCIWFIRSTPRIV + 1 + IEEE80211_RATE_MAXSIZE = 36 + WME_NUM_AC = 4 + VAP_BUFF_SIZE = 3090 + NS_HW_RATE_SIZE = 192 + AH_IEEE80211_ATR_MAX = 96 + AH_GET_STATION_NETWORK_HEALTH = 157 + AH_FLOW_GET_STATION_SERVER_IP = 200 + AH_FE_IOCTL_FLOW = 0x4000 + IEEE80211_IOCTL_GENERIC_PARAM = unix.SIOCDEVPRIVATE + 15 + IEEE80211_MESHID_LEN = 32 + AH_IEEE80211_STANAME_LEN = 16 + IEEE80211_PARAM_NUM_ASSOCS = 608 + MACADDR_LEN = 6 + AH_MAX_SSID_LEN = 32 + AH_TX_NSS_MAX = 4 + AH_SQ_GROUP_MAX = 8 + AH_MAX_DNS_LIST = 4 + RF_STAT_OUT_FILE = "/tmp/rfStatOut" + CLT_STAT_OUT_FILE = "/tmp/clientStatOut" +) + +const ( + AH_SQ_TYPE_RSSI = iota + AH_SQ_TYPE_NOISE + AH_SQ_TYPE_SNR + AH_SQ_TYPE_MAX +) + +const ( + AH_IEEE80211_CMD_NONE = iota + AH_IEEE80211_SET_STA_VLAN /* set station valn */ + AH_IEEE80211_GET_STA_VLAN /* get station valn */ + AH_IEEE80211_SET_DOSCFG /* set dos config */ + AH_IEEE80211_GET_DOSCFG /* get dos config */ + AH_IEEE80211_FF_ADD_CFG /* add ff */ + AH_IEEE80211_FF_DEL_CFG /* del ff */ + AH_IEEE80211_FF_GET_CFG /* get ff */ + AH_IEEE80211_FF_GET_CFG_BYID /* get ff by id */ + AH_IEEE80211_FF_GET_CNT /* get ff cnt */ + AH_IEEE80211_GET_LB_STATUS + AH_IEEE80211_GET_LB_DATA + AH_IEEE80211_CLR_STA_STATS + AH_IEEE80211_CLR_80211_STATS + AH_IEEE80211_SET_STA_UPID + AH_IEEE80211_GET_STA_UPID + AH_IEEE80211_SET_NODE_ID + AH_IEEE80211_GET_ACSPIE + AH_IEEE80211_GET_ACSPNBR_TBL + AH_IEEE80211_QUERY_ACSPNBR + AH_IEEE80211_SET_BGSCAN_CFG + AH_IEEE80211_GET_BGSCAN_CFG + AH_IEEE80211_GET_BGSCAN_STATS + AH_IEEE80211_GET_IDP_AP_TBL + AH_IEEE80211_SET_IDP_CFG + AH_IEEE80211_GET_IDP_CFG + AH_IEEE80211_GET_ALL_STA + AH_IEEE80211_GET_ONE_STA + AH_IEEE80211_GET_LB_STATS + AH_IEEE80211_DEAUTH_STA + AH_IEEE80211_SEND_PROBEREQ + AH_IEEE80211_SET_STANAME + AH_IEEE80211_START_IDP_IND /* start IDP in-network detection */ + AH_IEEE80211_SET_AUTHMODE + AH_IEEE80211_SEND_MICFAIL + AH_IEEE80211_GET_NBR_RATE + AH_IEEE80211_GET_ONE_NBR_RATE + AH_IEEE80211_SET_IDP_AP_CAT /* set idp ap category */ + AH_IEEE80211_SET_ADDI_AUTH_FLAG + AH_IEEE80211_GET_ONE_STA_INFO + AH_IEEE80211_SET_CONTX_MODE /* enable continuous tx */ + AH_IEEE80211_CLR_CONTX_MODE /* disable continuous tx */ + AH_IEEE80211_GET_NBR_AVGRSSI + AH_IEEE80211_SET_TX_RATESET /* set tx rate set */ + AH_IEEE80211_GET_TX_RATESET /* get tx rate set */ + AH_IEEE80211_SET_RX_ONLY /* enable rx only test */ + AH_IEEE80211_CLR_RX_ONLY /* disable rx only test */ + AH_IEEE80211_SET_LCS_TAG /* start/stop tag report */ + AH_IEEE80211_SET_LCS_MU /* start/stop mu report */ + AH_IEEE80211_GET_LCS_TAG_STATS /* get lcs tag statistics */ + AH_IEEE80211_CLR_LCS_TAG_STATS /* clear lcs tag statistics */ + AH_IEEE80211_GET_LCS_MISC_STATS /* get lcs misc statistics */ + AH_IEEE80211_CLR_LCS_MISC_STATS /* clear lcs misc statistics */ + AH_IEEE80211_SET_LCS_RATE_LIMIT /* set lcs rate limit threshold */ + AH_IEEE80211_GET_LCS_RATE_LIMIT /* set lcs rate limit threshold */ + AH_IEEE80211_SET_PKT_CPT /* set pkt capture parameters */ + AH_IEEE80211_GET_PKT_CPT_STATS /* get pkt capture related stats */ + AH_IEEE80211_GET_AIRTIME_STATS + AH_IEEE80211_SET_DISTANCE /* set radio operating distance in meter */ + AH_IEEE80211_GET_DISTANCE /* get radio operating distance in meter */ + AH_IEEE80211_SET_ANT_PORT /* set antenna port to be used for tx/rx */ + AH_IEEE80211_GET_ANT_PORT /* get antenna port to be used for tx/rx */ + AH_IEEE80211_GET_ATR_TBL + AH_IEEE80211_SEND_MGMT_FRAME /* asking driver to send a mgmt frame */ + AH_IEEE80211_EXEC_MITIGATE_AP /* exec mitigate action on rogue AP */ + AH_IEEE80211_GET_IDP_STA_TBL /* get clients connect to rogue AP */ + AH_IEEE80211_CLR_ROGUE_AP /* clear rogue AP(s) */ + AH_IEEE80211_SET_LTA_TRACK_OBJ /* set lta track object */ + AH_IEEE80211_GET_LTA_RPT_TBL /* get lta station report table */ + AH_IEEE80211_GET_LTA_STATS /* get lta statistics */ + AH_IEEE80211_CLR_LTA_STATS /* clear lta statistics */ + AH_IEEE80211_GET_CCA /* get cca stats, don't use later */ + AH_IEEE80211_SET_MESH_JOIN_REQ /* set mesh join req */ + AH_IEEE80211_SET_ASM_BEHAVIOR /* set ASM behavior criteria */ + AH_IEEE80211_SET_ASM_ACTION /* set ASM action criteria */ + AH_IEEE80211_GET_CONN_BNCHMRK /* get client connectivity benchmark score */ + AH_IEEE80211_SET_CONN_BNCHMRK /* set client connectivity benchmark score */ + AH_IEEE80211_SET_STA_IDLE_TIME /* set client idle_out time, in second*/ + AH_IEEE80211_GET_STA_IDLE_TIME /* get client idle_out time, in second*/ + IEEE80211_GET_WIFI_STA_STATS /* get all clients' stats for one radio */ + AH_IEEE80211_SET_HDD_CFG /* get hdd config */ + AH_IEEE80211_GET_HDD_CFG /* set hdd config */ + AH_IEEE80211_GET_HDD_STATS /* get hdd statistics */ + AH_IEEE80211_CLR_HDD_STATS /* clear hdd statistics */ + AH_IEEE80211_GET_HDD_RAIDO_LOAD /* get hdd radio load */ + AH_IEEE80211_GET_HDD_STA_RLS /* get client local release flag */ + AH_IEEE80211_ADD_HDD_5G_ENTRY /* add an entry to 5g client list (test command) */ + AH_IEEE80211_CLR_HDD_5G_TBL /* clear hdd 5G capable client table node(s) */ + AH_IEEE80211_CLR_HDD_SUP_TBL /* clear hdd suppress table node(s) */ + AH_IEEE80211_GET_HDD_SUP_TBL /* get hdd suppress table */ + AH_IEEE80211_GET_HDD_NT /* get hdd table HDD-2 */ + AH_IEEE80211_ADD_HDD_BPS_OUI /* add hdd bcast probe suppression OUI entry */ + AH_IEEE80211_DEL_HDD_BPS_OUI /* delete hdd bcast probe suppression OUI entry */ + AH_IEEE80211_GET_HDD_BPS_OUI_COUNT /* get count of hdd bcast probe suppression OUI entries */ + AH_IEEE80211_GET_HDD_BPS_OUI /* get hdd bcast probe suppression OUI entries */ + AH_IEEE80211_GET_CYCLE_COUNTS /* get cycle counts */ + AH_IEEE80211_GET_RD_MAX_TX_PWR /* get RF regulatory domain max tx power limit */ + AH_IEEE80211_SET_CHANNEL_COST /* set channel cost */ + AH_IEEE80211_SET_EXCLUDED_CHANNELS /* set list of excluded channels (ACSP) */ + AH_IEEE80211_SET_SPECTRAL_CHAN /* set spectral scan channel */ + AH_IEEE80211_SET_SPECTRAL_ACTION /* start/stop spectral scan */ + AH_IEEE80211_SET_MCAST_UCAST_CONV_MODE /* Configure multicast to unicast conversion mode (DISABLED/ALWAYS/AUTO) */ + AH_IEEE80211_GET_MCAST_UCAST_CONV_MODE /* Get current value of multicast to unicast conversion mode */ + AH_IEEE80211_SET_MCAST_CONV_CU_THRESH /* Set Multicast conversion CU Threshold */ + AH_IEEE80211_GET_MCAST_CONV_CU_THRESH /* Get Multicast conversion CU Threshold */ + AH_IEEE80211_SET_MCAST_CONV_MEMBER_THRESH /* Set Multicast conversion Membership Count Threshold */ + AH_IEEE80211_GET_MCAST_CONV_MEMBER_THRESH /* Get Multicast conversion Membership Count Threshold */ + AH_IEEE80211_GET_MCAST_CONV_STATS_SIZE /* Get Multicast Group Statistics structure size */ + AH_IEEE80211_GET_MCAST_CONV_STATS /* Get Multicast Group Statistics */ + AH_IEEE80211_CLR_MCAST_CONV_STATS /* Clear Multicast Group Statistics */ + AH_IEEE80211_SEND_ANT_ALIGN_REQ_FRM + AH_IEEE80211_GET_ANT_ALIGN_RSP_DATA + AH_IEEE80211_SET_IDP_STA_CAT + AH_IEEE80211_SET_RRM_QUIET_PARA /* RRM QUIET PARA */ + AH_IEEE80211_GET_ADMCTL_TSINFO /* Get Admctl Tsinfo */ + AH_IEEE80211_GET_ADMCTL_TSINFO_LIST /* Get Admctl Tsinfo LIST*/ + AH_IEEE80211_SET_ADMCTL_BW + AH_IEEE80211_SET_MDIE /* Set MDIE PARAM */ + AH_IEEE80211_SET_PRESENCE_CFG + AH_IEEE80211_GET_PRESENCE_CFG + AH_IEEE80211_GET_PRESENCE_DATA + AH_IEEE80211_SET_SENSOR_CFG + AH_IEEE80211_SET_VHT_MCS_MAP /* set mcs map in VHT capability IE */ + AH_IEEE80211_GET_VHT_MCS_MAP /* get mcs map in VHT capability IE */ + AH_IEEE80211_SET_ACSP_NODE_IPV6 +//#ifdef AH_RADIO_BCM + AH_IEEE80211_SET_BRCM_MSGLEVEL + AH_IEEE80211_GET_BRCM_MSGLEVEL + AH_IEEE80211_SET_BRCM_EMSGLEVEL + AH_IEEE80211_GET_BRCM_EMSGLEVEL + AH_IEEE80211_SET_BRCM_PHYMSGLEVEL + AH_IEEE80211_GET_BRCM_PHYMSGLEVEL + AH_IEEE80211_SET_AWEMSGLEVEL + AH_IEEE80211_GET_AWEMSGLEVEL + AH_IEEE80211_SET_IEMMSGLEVEL + AH_IEEE80211_GET_IEMMSGLEVEL + AH_IEEE80211_SET_TXBF_MODE + AH_IEEE80211_GET_TXBF_MODE + AH_IEEE80211_SET_VHT2G_MODE + AH_IEEE80211_GET_VHT2G_MODE +//#ifdef AH_SUPPORT_ANTENNA_TYPE + AH_IEEE80211_SET_ANTENNA_TYPE +//#endif + AH_IEEE80211_DBGREQ_SENDBCNRPT + AH_IEEE80211_DBGREQ_SENDTSMRPT + AH_IEEE80211_DBGREQ_SENDDELTS + AH_IEEE80211_SET_TPC + AH_IEEE80211_DBGREQ_SENDBSTMREQ /* WNM Operation */ +//#endif +//#ifdef AH_SUPPORT_DOS + AH_IEEE80211_SET_DOS_EXT_ENABLE + AH_IEEE80211_GET_DOS_EXT_ENABLE + AH_IEEE80211_ADD_DOS_EXT_BLOCK + AH_IEEE80211_DEL_DOS_EXT_BLOCK + AH_IEEE80211_GET_DOS_EXT_USRLIST + AH_IEEE80211_GET_DOS_EXT_BANLIST +//#endif +//#ifdef AH_SUPPORT_MUMIMO + AH_IEEE80211_GET_MUMIMO_COUNTERS + AH_IEEE80211_CLEAR_MUMIMO_COUNTERS + AH_IEEE80211_GET_MUMIMO_CANDIDATES + AH_IEEE80211_SET_MUTX + AH_IEEE80211_SET_MU_FEATURES + AH_IEEE80211_SET_MUMIMO_STA_RXCHAINS + AH_IEEE80211_SET_MU_SOUNDING_INTERVAL +//#endif +//#ifdef AH_ZWDFS_SUPPORT + AH_IEEE80211_SET_ZEROWAIT_DFS +//#ifdef AH_ZWDFS_CFG_SUPPORT + AH_IEEE80211_SET_ZWDFS_CFG +//#endif +//#endif +//#ifdef AH_AIRIQ_SUPPORT + AH_IEEE80211_SET_SPECTRAL_INTERVAL /* set spectral scan interval */ + AH_IEEE80211_SET_SPECTRAL_AIRIQ_MODE /* set spectral airiq mode */ + AH_IEEE80211_GET_SPECTRAL_FREQ_INFO /* get spectral freq info */ + AH_IEEE80211_GET_OPERATE_TX_CHAIN /* get operate Tx chain */ + AH_IEEE80211_GET_OPERATE_RX_CHAIN /* get operate Rx chain */ +//#endif + AH_IEEE80211_GET_RADIO_MODE +//#ifdef AH_SUPPORT_SDR + AH_IEEE80211_GET_SDR_NBR_TBL +//#endif +//#ifdef AH_SUPPORT_DYNAMIC_CHANNEL_WIDTH + AH_IEEE80211_SET_DYNAMIC_CHANNEL_WIDTH + AH_IEEE80211_SET_DYNAMIC_CHANNEL_WIDTH_THRESH + AH_IEEE80211_GET_DYNAMIC_CHANNEL_WIDTH_HISTORY + AH_IEEE80211_CLEAR_DYNAMIC_CHANNEL_WIDTH_HISTORY +//#endif + AH_IEEE80211_SET_RADARARGS /* set PHY radar parameters */ + AH_IEEE80211_SET_RADARTHR /* set PHY radar threshhold parameters */ + AH_IEEE80211_INCR_DFS_SENSE_RANGE /* increase DFS sence range */ + AH_IEEE80211_RESET_DFS_SENSE_RANGE /* reset DFS sense range */ + AH_IEEE80211_SET_ACSP_ACTIVE /* set acsp active flag */ + AH_IEEE80211_GET_POWER_LIMIT /* get hw power limit */ + AH_IEEE80211_GET_NBR_MAX_RATE /* get nbr max tx rate in Kbps */ + AH_IEEE80211_GET_ONE_ACSP_NBR + AH_IEEE80211_GET_CHNL_SCAN_STATS /* get channel scan results(cca/chanim stats) */ +//#ifdef AH_SUPPORT_HOSTNAME_IN_BCN + AH_IEEE80211_GET_HOSTNAME_IN_BCN_ENABLE /* get hostname-in-beacon enable */ + AH_IEEE80211_SET_HOSTNAME_IN_BCN_ENABLE /* enable/disable hostname in beacon */ +//#endif +//#ifdef AH_SUPPORT_RX_SENSITIVITY + AH_IEEE80211_SET_ED_THRESHOLD /* set energy detection threshold */ + AH_IEEE80211_SET_RXDESENS /* set rx sensitivity */ +//#endif +//#ifdef AH_SUPPORT_PER_VLAN_GTK + AH_IEEE80211_GET_ALL_STA_VLAN_GTK +//#endif + AH_IEEE80211_SET_RRM_NBR_LIST_DUAL_BAND + AH_IEEE80211_SET_RRM_NBR_LIST_BAND_MAX + AH_IEEE80211_SET_BSS_TRANS_DISASSOC_IMMT + AH_IEEE80211_SET_BSS_TRANS_DISASSOC_IMMT_TIMER + AH_IEEE80211_SET_11KV_FAILED_ACTIONS +//#ifdef AH_NETWORK360_CLT_CAPS + AH_IEEE80211_CLT_CAPS_DEL_STA +//#endif +//#ifdef AH_NETWORK360_WIFI_STATS + AH_IEEE80211_SQ_GROUP_RANGE +//#endif +//#ifdef AH_SUPPORT_11AX + AH_IEEE80211_SET_HE_MCS_MAP /* set he mcs map */ + AH_IEEE80211_GET_HE_MCS_MAP /* get he mcs map */ + AH_IEEE80211_SET_HE_OFDMA_DL /* configure downlink OFDMA */ + AH_IEEE80211_GET_HE_OFDMA_DL /* get the status of downlink OFDMA */ +//#ifdef AH_SUPPORT_11AX_FEATURES + AH_IEEE80211_SET_HE_OFDMA_UL /* configure uplink OFDMA */ + AH_IEEE80211_GET_HE_OFDMA_UL /* get the status of uplink OFDMA */ + AH_IEEE80211_SET_HE_BSS_COLOR /* configure BSS color */ + AH_IEEE80211_GET_HE_BSS_COLOR /* get the status of BSS color */ + AH_IEEE80211_SET_TWT /* configure TWT */ + AH_IEEE80211_GET_TWT /* get the status of TWT */ +//#endif +//#endif + AH_IEEE80211_GET_CHNL_STATS /* get channel util, tx util and rx util etc */ + AH_IEEE80211_GET_TXCORE /* get txcore of radio */ + AH_IEEE80211_GET_HW_PWR_LIMIT /* get hw power limit of radio */ + AH_IEEE80211_GET_DFS_STATE /* get DFS state of radio */ +//#ifdef AH_SUPPORT_ADSP_SENSOR + AH_IEEE80211_SET_ADSP_SENSOR_CFG + AH_IEEE80211_GET_ADSP_SENSOR_CFG + AH_IEEE80211_SET_WIPSK_CHANSPEC +//#endif + AH_IEEE80211_SEND_CSA /* send channel switch announcement */ + AH_IEEE80211_GET_IF_COUNTRY /* get interface brcm cc */ + AH_IEEE80211_SET_RSNXE_CAP /* set RSN Extended IE capabilities*/ +//#ifdef AH_SUPPORT_AFC + AH_IEEE80211_GET_AFC_INFO /* get AFC info */ +//#endif +//#ifdef AH_SUPPORT_11MC + AH_IEEE80211_SET_FTM /* set FTM and LCI */ +//#endif +//#if AH_SUPPORT_USEG + AH_IEEE80211_SET_USEG_BCAST_FILTER /* set PCG broadcast filter */ + AH_IEEE80211_SET_USEG_MCAST_FILTER /* set PCG multicast filter */ +//#endif +) + +const ( + IEEE80211_MODE_AUTO = iota /* autoselect */ + IEEE80211_MODE_11A /* 5GHz, OFDM */ + IEEE80211_MODE_11B /* 2GHz, CCK */ + IEEE80211_MODE_11G /* 2GHz, OFDM */ + IEEE80211_MODE_FH /* 2GHz, GFSK */ + IEEE80211_MODE_TURBO_A /* 5GHz, OFDM, 2x clock dynamic turbo */ + IEEE80211_MODE_TURBO_G /* 2GHz, OFDM, 2x clock dynamic turbo*/ + IEEE80211_MODE_11NA_HT20 /* 5Ghz, HT20 */ + IEEE80211_MODE_11NG_HT20 /* 2Ghz, HT20 */ + IEEE80211_MODE_11NA_HT40PLUS /* 5Ghz, HT40 (ext ch +1) */ + IEEE80211_MODE_11NA_HT40MINUS /* 5Ghz, HT40 (ext ch -1) */ + IEEE80211_MODE_11NG_HT40PLUS /* 2Ghz, HT40 (ext ch +1) */ + IEEE80211_MODE_11NG_HT40MINUS /* 2Ghz, HT40 (ext ch -1) */ + IEEE80211_MODE_11NG_HT40 /* 2Ghz, Auto HT40 */ + IEEE80211_MODE_11NA_HT40 /* 2Ghz, Auto HT40 */ + IEEE80211_MODE_11AC_VHT20 /* 5Ghz, VHT20 */ + IEEE80211_MODE_11AC_VHT40PLUS /* 5Ghz, VHT40 (Ext ch +1) */ + IEEE80211_MODE_11AC_VHT40MINUS /* 5Ghz VHT40 (Ext ch -1) */ + IEEE80211_MODE_11AC_VHT40 /* 5Ghz, VHT40 */ + IEEE80211_MODE_11AC_VHT80 /* 5Ghz, VHT80 */ + IEEE80211_MODE_11AC_VHT160 /* 5Ghz, VHT160 */ + IEEE80211_MODE_11AX_2G_HE20 /* 2Ghz, HE20 */ + IEEE80211_MODE_11AX_2G_HE40 /* 2Ghz, HE40 */ + + IEEE80211_MODE_11AX_5G_HE20 /* 5Ghz, HE20 */ + IEEE80211_MODE_11AX_5G_HE40 /* 5Ghz, HE40 */ + IEEE80211_MODE_11AX_5G_HE80 /* 5Ghz, HE80 */ + IEEE80211_MODE_11AX_5G_HE160 /* 5Ghz, HE160 */ + + IEEE80211_MODE_11AX_6G_HE20 /* 6Ghz, HE20 */ + IEEE80211_MODE_11AX_6G_HE40 /* 6Ghz, HE40 */ + IEEE80211_MODE_11AX_6G_HE80 /* 6Ghz, HE80 */ + IEEE80211_MODE_11AX_6G_HE160 /* 6Ghz, HE160 */ + IEEE80211_MODE_LAST +) + +const ( + AH_DCD_NMS_PHY_MODE_A = iota + AH_DCD_NMS_PHY_MODE_B + AH_DCD_NMS_PHY_MODE_G + AH_DCD_NMS_PHY_MODE_AC = iota + 2 + AH_DCD_NMS_PHY_MODE_NA + AH_DCD_NMS_PHY_MODE_NG + AH_DCD_NMS_PHY_MODE_AX_2G + AH_DCD_NMS_PHY_MODE_AX_5G + AH_DCD_NMS_PHY_MODE_AX_6G +) + +const ( + AH_DCD_CLT_SCORE_POOR = 0 + AH_DCD_CLT_SCORE_ACCEPTABLE = 40 + AH_DCD_CLT_SCORE_GOOD = 100 +) + + +type IFReqData struct { + Name [unix.IFNAMSIZ]byte + Data uintptr +} + +type ah_ieee80211_atr_info struct{ + rxc_pcnt int32 + rxf_pcnt int32 + rxf_obss int32 + rxf_inbss int32 + wifi_interference int32 + txf_pcnt int32 + nfarray [2]int16 + valid int32 /* mark this bucket as either valid or invalid */ +} + + +type ah_ieee80211_atr_user struct{ + count uint32 /* air-time ring buffer count */ + atr_info [AH_IEEE80211_ATR_MAX]ah_ieee80211_atr_info +} + +type ah_ieee80211_hdd_stats struct { + bs_sp_cnt uint32 /* band steering suppress count */ + lb_sp_cnt uint32 /* load balance suppress count */ + snr_sp_cnt uint32 /* weak snr suppress count */ + sn_answer_cnt uint32 /* safety net answer (safety net check fail) count */ +} + +type ieee80211req_cfg_atr struct{ + cmd uint32 + resv uint32 /* Let following struct to align to 64bit for 64 bit machine, + otherwise copy bgscan and lb status may with wrong value */ + atr ah_ieee80211_atr_user + unused uint32 +} + +type ieee80211req_cfg_hdd struct{ + cmd uint32 + resv uint32 /* Let following struct to align to 64bit for 64 bit machine, + otherwise copy bgscan and lb status may with wrong value */ + hdd_stats ah_ieee80211_hdd_stats + unused uint32 +} + +type iw_point struct +{ +// pointer uintptr /* Pointer to the data (in user space) */ + pointer unsafe.Pointer + length uint16 /* number of fields or size in bytes */ + flags uint16 /* Optional params */ +} + +type iwreq struct +{ + ifrn_name [unix.IFNAMSIZ]byte /* if name, e.g. "eth0" */ + data iw_point +} + +type ah_dcd_dev_stats struct{ + rx_packets uint64 /* total packets received */ + tx_packets uint64 /* total packets transmitted */ + rx_bytes uint64 /* total bytes received */ + tx_bytes uint64 /* total bytes transmitted */ + rx_errors uint32 /* bad packets received */ + tx_errors uint32 /* packet transmit problems */ + rx_dropped uint32 /* no space in linux buffers */ + tx_dropped uint32 /* no space available in linux */ + rx_multicast uint32 /* multicast packets received */ + rx_compressed uint32 + tx_compressed uint32 + collisions uint32 + + rx_unicast uint32 + rx_broadcast uint32 + tx_unicast uint32 + tx_broadcast uint32 + tx_multicast uint32 + + + /* detailed rx_errors: */ + rx_length_errors uint32 + rx_over_errors uint32 /* receiver ring buff overflow */ + rx_crc_errors uint32 /* recved pkt with crc error */ + rx_frame_errors uint32 /* recv'd frame alignment error */ + rx_fifo_errors uint32 /* recv'r fifo overrun */ + rx_missed_errors uint32 /* receiver missed packet */ + /* detailed tx_errors */ + tx_aborted_errors uint32 + tx_carrier_errors uint32 + tx_fifo_errors uint32 + tx_heartbeat_errors uint32 + tx_window_errors uint32 +} + +type ieee80211_node_rate_stats struct { + ns_unicasts uint32 /* tx/rx total unicasts */ + ns_retries uint32 /* tx/rx total retries */ + ns_rateKbps uint32 /* rate in Kpbs */ +} + +type utilization_data struct { + intfer_util_min int32 + intfer_util_max int32 + intfer_util_avg int32 + + chan_util_min int32 + chan_util_max int32 + chan_util_avg int32 + + tx_util_min int32 + tx_util_max int32 + tx_util_avg int32 + + rx_util_min int32 + rx_util_max int32 + rx_util_avg int32 + + rx_ibss_util_min int32 + rx_ibss_util_max int32 + rx_ibss_util_avg int32 + + rx_obss_util_min int32 + rx_obss_util_max int32 + rx_obss_util_avg int32 + + wifi_i_util_min int32 + wifi_i_util_max int32 + wifi_i_util_avg int32 + + noise_min int16 + noise_max int16 + noise_avg int16 + + crc_err_rate_min uint64 + crc_err_rate_max uint64 + crc_err_rate_avg uint64 +} + +type awestats struct { + ast_as wl_stats + ast_uapsdqnuldepth uint32 /* count of UAPSD QoS NULL frames in uapsd queue */ + ast_uapsdresetdrop_pkts uint32 /* count of UAPSD frames dropped because of chip reset */ + ast_tx_xtxop uint32 /* tx failed due to exceeding txop */ + ast_tx_xtimer uint32 /* tx failed due to tx timer expired */ + ast_cwm_mac40to20 uint32 /* dynamic channel width change from HT40 to HT20 */ + ast_cwm_mac20to40 uint32 /* dynamic channel width change from H */ + phy_stats wl_phy_stats /* phy stats */ + ast_rx_mgt uint32 /* management frames received */ + ast_rx_ctl uint32 /* control frames received */ + ast_rx_flush uint32 /* packet flush */ + ast_rx_bufsize uint32 /* wrong buffer size */ + ast_rx_keyix_errors uint32 /* keyix erros by Atheros chip */ + ast_rx_antenna_errors uint32 /* antenaa errors by Atheros chip */ + ast_rx_short_frames uint32 /* frames too short */ + ast_rx_ieee_queue_depth uint32 /* per radio rx ieee80211 queue depth */ + ast_tx_failed uint32 /* ath_tx_start failed */ + ast_tx_ps_full uint32 /* power save queue full */ + ast_tx_buf_count uint32 /* available tx buffer */ + ast_buf_wo_count uint32 /* # of times buffer workaround counter kicked in */ + ast_tx_buf_max_count uint32 /* max tx buffer */ + ast_tx_hw_othererr uint32 /* other hw tx error */ + ast_rx_bcast uint32 /* rx broadcast data frame */ + ast_rx_mcast uint32 /* rx multicast data frame */ + ast_tx_wme_ac [WME_NUM_AC]uint32 /* tx WME AC data frame */ +//#ifdef AH_SUPPORT_MUMIMO + ast_tx_wme_ac_mu [WME_NUM_AC]uint32 /* tx WME AC MU-MIMO data frame */ +//#endif + ast_tx_drain uint32 /* tx drain data frame */ + ast_tx_blckd_drops uint32 /* tx drop due to tx blocked to a station */ + ast_tx_captured uint32 /* captured total num of tx frames */ + ast_rx_captured uint32 /* captured total num of rx frames */ + ast_tx_queue_scheds uint32 /* txq schedules because of congestion */ + ast_beacon_stucks uint32 /* number of beacon stucks */ + ast_pci_errors uint32 /* number of PCI read/write timeout errors */ + ast_tx_rix_invalids uint32 /* tx rate index invalids */ + ast_rx_rix_invalids uint32 /* tx rate index invalids */ + ast_bandwidth uint32 /* total bandwidth: rx + tx */ + + ast_rx_rate_stats [NS_HW_RATE_SIZE]ieee80211_node_rate_stats + ast_tx_rate_stats [NS_HW_RATE_SIZE]ieee80211_node_rate_stats + + ast_tx_airtime uint64 /* tx airtime (us) */ + ast_rx_airtime uint64 /* rx airtime (us) */ + ast_crcerr_airtime uint64 /* crc eror airtime (us) */ + ast_noise_floor int16 + pad [6]byte + ast_rx_mcast_bytes uint64 + ast_rx_bcast_bytes uint64 + ast_rx_retry uint32 + + is_rx_hdd_probe_sup uint32 + is_rx_hdd_auth_sup uint32 + + magic uint32 +} + +type wl_stats struct { + ast_rx_bytes uint32 /* total number of bytes received */ + ast_tx_bytes uint32 /* total number of bytes transmitted */ + + ast_tx_packets uint32 /* packet sent on the interface */ + ast_rx_packets uint32 /* packet received on the interface */ + ast_tx_mgmt uint32 /* management frames transmitted */ + ast_tx_discard uint32 /* frames discarded prior to assoc */ + ast_tx_invalid uint32 /* frames discarded 'cuz device gone */ + ast_tx_qstop uint32 /* tx queue stopped 'cuz full */ + ast_tx_encap uint32 /* tx encapsulation failed */ + ast_tx_nonode uint32 /* tx failed 'cuz no node */ + ast_tx_nobuf uint32 /* tx failed 'cuz no tx buffer (data) */ + ast_tx_nobufmgt uint32 /* tx failed 'cuz no tx buffer (mgmt)*/ + + ast_tx_bcast uint32 + ast_tx_mcast uint32 + ast_tx_bcast_bytes uint32 + ast_tx_mcast_bytes uint32 + ast_tx_noack uint32 /* tx frames with no ack marked */ + ast_tx_cts uint32 /* tx frames with cts enabled */ + ast_tx_protect uint32 /* tx frames with protection */ + ast_tx_xretries uint32 /* tx failed 'cuz too many retries */ + + ast_be_xmit uint32 /* beacons transmitted */ + ast_tx_shortpre uint32 /* tx frames with short preamble */ + ast_tx_altrate uint32 /* tx frames with alternate rate */ + + ast_tx_ok uint32 /* tx ok data frame */ + ast_tx_fail uint32 /* tx fail data frame */ + + ast_rxorn uint32 /* rx overrun interrupts */ + ast_txurn uint32 /* tx underrun interrupts */ + + ast_tx_fifoerr uint32 /* tx failed 'cuz FIFO underrun */ + ast_tx_filtered uint32 /* tx failed 'cuz xmit filtered */ + + ast_rx_orn uint32 /* rx failed 'cuz of desc overrun */ + ast_rx_badcrypt uint32 /* rx failed 'cuz decryption */ + ast_rx_badmic uint32 /* rx failed 'cuz MIC failure */ + ast_rx_nobuf uint32 /* rx setup failed 'cuz no skbuff */ + ast_rx_swdecrypt uint32 /* rx frames sw decrypted due to key miss */ + ast_rx_num_data uint32 + ast_rx_num_mgmt uint32 + ast_rx_num_ctl uint32 + ast_rx_num_unknown uint32 + + ast_11n_stats wl_11n_stats /* 11n statistics */ + + ast_rx_rssi int8 /* last rx rssi */ + pad [3]byte + ast_chan_switch uint32 /* no. of channel switch */ + ast_be_nobuf uint32 /* no skbuff available for beacon */ + ast_tx_mu uint32 +} + +type wl_11n_stats struct { + rx_pkts uint32 /* rx pkts */ + tx_bars uint32 /* tx bars sent */ + tx_bars_drop uint32 /* dropped tx bar frames */ + rx_bars uint32 /* rx bars */ + tx_compaggr uint32 /* tx aggregated completions */ + /* BCM XXX Not used yet */ + rx_compaggr uint32 + txaggr_compxretry uint32 + txunaggr_xretry uint32 + tx_compunaggr uint32 + tx_bawadv uint32 + rx_aggr uint32 + tx_retries uint32 /* tx retries of sub frames */ + tx_xretries uint32 + pad [4]byte +} + +/* + * try to mirro ath_phy_stats here + */ +type wl_phy_stats struct { + ast_tx_rts uint64 /* RTS success count */ + ast_tx_shortretry uint64 /* tx on-chip retries (short). RTSFailCnt */ + ast_tx_longretry uint64 /* tx on-chip retries (long). DataFailCnt */ + ast_rx_tooshort uint64 /* rx discarded 'cuz frame too short */ + ast_rx_toobig uint64 /* rx discarded 'cuz frame too large */ + //u_int64_t ast_rx_err uint64 /* rx error */ + ast_rx_crcerr uint64 /* rx failed 'cuz of bad CRC */ + ast_rx_crcerr_no_phyerr uint64 /* rx crcerr without phy err */ //TBD + ast_rx_fifoerr uint64 /* rx failed 'cuz of FIFO overrun */ + ast_rx_phyerr uint64 /* rx PHY error summary count */ + //u_int64_t ast_rx_decrypterr uint64 /* rx decryption error */ + //u_int64_t ast_rx_demicerr uint64 /* rx demic error */ + //u_int64_t ast_rx_demicok uint64 /* rx demic ok */ + //u_int64_t ast_rx_delim_pre_crcerr uint64 /* pre-delimiter crc errors */ + //u_int64_t ast_rx_delim_post_crcerr uint64 /* post-delimiter crc errors */ + //u_int64_t ast_rx_decrypt_busyerr uint64 /* decrypt busy errors */ + //u_int64_t ast_rx_phy [32]uint64 /* rx PHY error per-code counts */ +} + +type ah_signal_quality_range struct +{ + min int8 + max int8 +} + +type ah_signal_quality_stats struct +{ + asqrange ah_signal_quality_range + count uint32 +} + +type ah_ieee80211_sta_stats_item struct { + ns_mac [MACADDR_LEN]byte /* client mac address */ + ns_ssid [AH_MAX_SSID_LEN + 1]byte /* ssid associated */ + ns_snr int8 /* signal noise ratio */ + ns_tx_airtime uint64 /* tx airtime */ + ns_rx_airtime uint64 /* rx airtime */ + ns_tx_drops uint32 /* tx excessive retries, fifo err etc */ + ns_rx_drops uint32 /* due to: duplicate seq numbers, decrypt errors, security replay checking*/ + ns_tx_data uint32 /* tx data frames */ + pad1 [4]byte + ns_tx_bytes uint64 /* tx data count (bytes) */ + ns_rx_data uint32 /* rx data frames */ + pad2 [4]byte + ns_rx_bytes uint64 /* rx data count (bytes) */ + ns_sla_traps uint32 /* sent how many sla violation traps */ + ns_sla_bm_score uint32 /* sla benchmark core */ + ns_app_health_score uint32 /* application health score */ + ns_ps_times uint32 /* indicate client entered into power save time */ + ns_rx_probereq uint32 /* rx probe request frames */ + ns_rx_mcast uint32 /* rx multi/broadcast frames */ + + ns_rx_rate_stats [NS_HW_RATE_SIZE]ieee80211_node_rate_stats + ns_tx_rate_stats [NS_HW_RATE_SIZE]ieee80211_node_rate_stats +//#ifdef AH_CLIENT360_PHASE2_EXT_RADIO + ns_tx_nss [AH_TX_NSS_MAX]uint32 /* pkt number per tx spatial stream */ +//#endif +//#ifdef AH_NETWORK360_WIFI_STATS + ns_sq_group [AH_SQ_TYPE_MAX][AH_SQ_GROUP_MAX]ah_signal_quality_stats +//#endif +} + + +type ah_ieee80211_get_wifi_sta_stats struct { + pointer unsafe.Pointer + count uint16 /* air-time ring buffer count */ +} + +type ieee80211req_cfg_sta struct { + cmd uint32 + resv uint32 /* Let following struct to align to 64bit for 64 bit machine, + otherwise copy bgscan and lb status may with wrong value */ + wifi_sta_stats ah_ieee80211_get_wifi_sta_stats +} + + +type iwreq_data struct +{ + data uint32 +} + +type iwreq_clt struct +{ + ifr_name [unix.IFNAMSIZ]byte /* if name, e.g. "eth0" */ + u iwreq_data +} + +type ah_ieee80211_sta_info struct { + mac [MACADDR_LEN]uint8 + noise_floor int16 + rssi int32 + tx_ratekbps int32 + tx_pkts uint32 + pad1 [4]byte + tx_bytes uint64 + rx_ratekbps int32 + rx_pkts uint32 + rx_bytes uint64 + bw uint32 + pad2 [4]byte +} + +type ieee80211req_cfg_one_sta struct{ + cmd uint32 + resv uint32 /* Let following struct to align to 64bit for 64 bit machine, + otherwise copy bgscan and lb status may with wrong value */ + sta_info ah_ieee80211_sta_info +} + +type ah_fw_dev_msg struct { + hdr ah_fe_ioctl_hdr + data ah_flow_get_sta_net_health_msg +} + +type ah_fw_dev_ip_msg struct { + hdr ah_fe_ioctl_hdr + data ah_flow_get_sta_server_ip_msg +} + + + + +/* FE ioctl generic data structure */ +type ah_fe_ioctl_hdr struct { + retval int32 /* return value */ + msg_type uint16 /* sub message type */ + msg_size uint16 /* I/O msg size not including header */ +} + +type ah_flow_get_sta_net_health_msg struct { + mac [MACADDR_LEN]uint8 + pad [2]byte + net_health_score int32 +} + +type ieee80211req_sta_info struct{ + isi_freq uint16 /* MHz */ + isi_len uint16 /* length (mult of 4) */ + isi_flags uint32 /* channel flags */ + isi_authmode uint8 /* authentication algorithm */ + isi_rssi int8 + isi_capinfo uint16 /* capabilities */ + isi_erp uint8 /* ERP element */ + isi_macaddr [MACADDR_LEN]uint8 + isi_nrates uint8 + isi_rates [IEEE80211_RATE_MAXSIZE]uint8 /* negotiated rates */ + isi_txrate uint8 /* index to isi_rates[] */ + isi_txratekbps uint32 /* tx rate in Kbps, for 11n */ + uisi_ie_len int16 /* IE length */ + isi_associd uint16 /* assoc response */ + isi_txpower uint16 /* current tx power */ + isi_vlan uint16 /* vlan tag */ + isi_cipher uint8 + isi_pmf uint8 /* 802.11w: sta in MFP (or PMF) */ + isi_assoc_time uint32 /* sta association time */ + + isi_htcap uint16 /* HT capabilities */ + isi_rxratekbps uint32 /* rx rate in Kbps */ + + + /* We use this as a common variable for legacy rates + and lln. We do not attempt to make it symmetrical + to isi xratekbps and isi xrate, which seem to be + separate due to legacy code. */ + /* XXX frag state? */ + /* variable length IE data */ + + /* fix me XXX move to awe side */ + + isi_ah_flags uint32 /* aerohive flags */ + + isi_mesh_flag uint32 /* mesh state machine flags */ + isi_ucast_keyix uint16 /* unicast key index */ + isi_mcast_keyix [2]uint16 /* multicast key index */ + isi_mesh_state uint8 /* mesh state */ + isi_mesh_role uint8 /* mesh association role */ + + isi_meshid [IEEE80211_MESHID_LEN + 1]uint8 /* mesh id */ + + isi_addition_auth_flag uint8 /* addtional auth flag */ + isi_upid uint32 /* user profile ID */ + isi_phymode uint32 /* physical mode */ + isi_power_mode uint32 /* power mode */ + + isi_name [AH_IEEE80211_STANAME_LEN + 1]byte + isi_chwidth uint32 + isi_noise_floor int16 /* noise floor */ + isi_release_flag int16 /* release flag for high density */ + + + isi_vhtcap uint32 + + isi_mu_groupid uint8 + + isi_roaming_time_start uint32 + isi_assoc_phase_time uint32 /* time used in assoc phase in millisecond */ + + isi_negotiate_Kbps uint32 /* negotiate rate, max supported rate in Kbps */ + +} + +type ieee80211req_cfg_one_sta_info struct{ + cmd uint32 + resv uint32 /* Let following struct to align to 64bit for 64 bit machine, + otherwise copy bgscan and lb status may with wrong value */ + mac [MACADDR_LEN]uint8 + pad ieee80211req_sta_info + +} + +type ah_dns_time struct { + dns_ip uint32 + dns_response_time uint32 + failure_cnt uint32 +} + +type ah_flow_get_sta_server_ip_msg struct { + + mac [MACADDR_LEN]uint8 + client_static_ip uint32 + dhcp_server uint32 + dhcp_time int32 + gateway uint32 + dns [AH_MAX_DNS_LIST]ah_dns_time + num_dns_servers uint8 +} + +type saved_stats struct { + tx_airtime_min uint64 + tx_airtime_max uint64 + tx_airtime_average uint64 + + rx_airtime_min uint64 + rx_airtime_max uint64 + rx_airtime_average uint64 + + bw_usage_min uint64 + bw_usage_max uint64 + bw_usage_average uint64 + + tx_airtime uint64 + rx_airtime uint64 +} + +type ah_dcd_stats_report_rate_stats struct { + kbps uint32 /* TX/RX rate Kbps */ + rate_dtn uint8 /* TX/RX bit rate distribution */ + rate_suc_dtn uint8 /* TX/RX bit rate sucess distribution */ +} + + +type ah_dcd_stats_report_int_data struct { + + tx_bit_rate [NS_HW_RATE_SIZE]ah_dcd_stats_report_rate_stats + rx_bit_rate [NS_HW_RATE_SIZE]ah_dcd_stats_report_rate_stats + +} + +type rt_sta_data struct { + hostname string + os string + user string +} + + +func ah_ifname_radio2vap(radio_name string ) string { + switch { + case radio_name == "wifi0": + return "wifi0.1" + case radio_name == "wifi1": + return "wifi1.1" + case radio_name == "wifi2": + return "wifi2.1" + default: + return "invalid" + } +} + +func getMacProtoMode(phymode uint32) uint32 { + + switch phymode{ + case IEEE80211_MODE_11A, IEEE80211_MODE_TURBO_A: + return AH_DCD_NMS_PHY_MODE_A + + case IEEE80211_MODE_11B: + return AH_DCD_NMS_PHY_MODE_B + + case IEEE80211_MODE_11NA_HT20, IEEE80211_MODE_11NA_HT40PLUS, IEEE80211_MODE_11NA_HT40MINUS, IEEE80211_MODE_11NA_HT40: + return AH_DCD_NMS_PHY_MODE_NA + + case IEEE80211_MODE_11NG_HT20, IEEE80211_MODE_11NG_HT40PLUS, IEEE80211_MODE_11NG_HT40MINUS, IEEE80211_MODE_11NG_HT40: + return AH_DCD_NMS_PHY_MODE_NG + + case IEEE80211_MODE_11AC_VHT20, IEEE80211_MODE_11AC_VHT40PLUS, IEEE80211_MODE_11AC_VHT40MINUS, IEEE80211_MODE_11AC_VHT40, IEEE80211_MODE_11AC_VHT80: + return AH_DCD_NMS_PHY_MODE_AC + + case IEEE80211_MODE_11AX_2G_HE20, IEEE80211_MODE_11AX_2G_HE40: + return AH_DCD_NMS_PHY_MODE_AX_2G + + case IEEE80211_MODE_11AX_5G_HE20, IEEE80211_MODE_11AX_5G_HE40, IEEE80211_MODE_11AX_5G_HE80, IEEE80211_MODE_11AX_5G_HE160: + return AH_DCD_NMS_PHY_MODE_AX_5G + + case IEEE80211_MODE_11AX_6G_HE20, IEEE80211_MODE_11AX_6G_HE40, IEEE80211_MODE_11AX_6G_HE80, IEEE80211_MODE_11AX_6G_HE160: + return AH_DCD_NMS_PHY_MODE_AX_6G + + default : + return AH_DCD_NMS_PHY_MODE_G + } + + return AH_DCD_NMS_PHY_MODE_G +} + +func intToIp(num uint32) string { + + b := make([]byte, 4) + b[0] = byte(num) + b[1] = byte(num >> 8) + b[2] = byte(num >> 16) + b[3] = byte(num >> 24) + return fmt.Sprintf("%d.%d.%d.%d",b[0],b[1],b[2],b[3]) +} + +func reportGetDiff(curr uint32, last uint32) uint32 { + if curr >= last { + return (curr - last) + } else { + return curr + } +} diff --git a/plugins/inputs/ah_wireless_v2/ah_wireless_v2.go b/plugins/inputs/ah_wireless_v2/ah_wireless_v2.go new file mode 100644 index 0000000000000..351ae28d0951a --- /dev/null +++ b/plugins/inputs/ah_wireless_v2/ah_wireless_v2.go @@ -0,0 +1,1921 @@ +package ah_wireless_v2 + +import ( + "log" + "os" + "bytes" + "strconv" + "syscall" + "strings" + "sync" + "time" + "os/exec" + "fmt" + "sort" + "unsafe" + "github.com/influxdata/telegraf" + "github.com/influxdata/telegraf/plugins/inputs" + "golang.org/x/sys/unix" +) + +var ( + offsetsMutex = new(sync.Mutex) + newLineByte = []byte("\n") +) + + +type Ah_wireless struct { + fd int + fe_fd uintptr + intf_m map[string]map[string]string + arp_m map[string]string + Ifname []string `toml:"ifname"` + closed chan struct{} + numclient [4]int + timer_count uint8 + entity map[string]map[string]unsafe.Pointer + Log telegraf.Logger `toml:"-"` + last_rf_stat [4]awestats + last_ut_data [4]utilization_data + last_clt_stat [4][50]ah_ieee80211_sta_stats_item + last_sq map[string]map[int]map[int]ah_signal_quality_stats +} + + +func ah_ioctl(fd uintptr, op, argp uintptr) error { + _, _, errno := syscall.RawSyscall(syscall.SYS_IOCTL, uintptr(fd), uintptr(op), argp) + if errno != 0 { + return errno + } + return nil +} + + +const sampleConfig = ` +[[inputs.ah_wireless_v2]] + interval = "5s" + ifname = ["wifi0","wifi1"] +` +func NewAh_wireless(id int) *Ah_wireless { + var err error + // Create RAW Socket. + fd, err := unix.Socket(unix.AF_INET, unix.SOCK_DGRAM, 0) + if err != nil { + return nil + } + + + if id != -1 { + open(fd, id) + } + + return &Ah_wireless{ + fd: fd, + timer_count: 0, + } + +} + +func get_rt_sta_info(t *Ah_wireless, mac_adrs string) *rt_sta_data { + app := "telegraf_helper" + + arg0 := mac_adrs + + cmd := exec.Command(app, arg0) + output, err := cmd.Output() + + if err != nil { + log.Printf(err.Error()) + return nil + } + + + lines := strings.Split(string(output),"\n") + + data := rt_sta_data{} + + var os_line, host_line, user_line string + + // Loop over the line to find and extract OS and HostName ans UserName + for _, line := range lines { + if strings.HasPrefix(line, "OS:") { + os_line = strings.TrimSpace(strings.TrimPrefix(line, "OS:")) + } else if strings.HasPrefix(line, "HostName:") { + host_line = strings.TrimSpace(strings.TrimPrefix(line, "HostName:")) + }else if strings.HasPrefix(line, "UserName:") { + user_line = strings.TrimSpace(strings.TrimPrefix(line, "UserName:")) + } + } + + data.os = string(os_line) + data.hostname = string(host_line) + data.user = string(user_line) + + + return &data +} + +func getHDDStat(fd int, ifname string) *ah_ieee80211_hdd_stats { + + var cfg *ieee80211req_cfg_hdd + cfg = new(ieee80211req_cfg_hdd) + + + /* first 4 bytes is subcmd */ + cfg.cmd = AH_IEEE80211_GET_HDD_STATS; + + iwp := iw_point{pointer: unsafe.Pointer(cfg)} + + request := iwreq{data: iwp} + + request.data.length = VAP_BUFF_SIZE + + copy(request.ifrn_name[:], ah_ifname_radio2vap(ifname)) + + offsetsMutex.Lock() + + if err := ah_ioctl(uintptr(fd), IEEE80211_IOCTL_GENERIC_PARAM, uintptr(unsafe.Pointer(&request))); err != nil { + log.Printf("getHDDStat ioctl data error %s",err) + offsetsMutex.Unlock() + return nil + } + offsetsMutex.Unlock() + + return &cfg.hdd_stats + +} + +func getAtrTbl(fd int, ifname string) *ah_ieee80211_atr_user { + var cfg *ieee80211req_cfg_atr + cfg = new(ieee80211req_cfg_atr) + + /* first 4 bytes is subcmd */ + cfg.cmd = AH_IEEE80211_GET_ATR_TBL; + + iwp := iw_point{pointer: unsafe.Pointer(cfg)} + + request := iwreq{data: iwp} + + request.data.length = VAP_BUFF_SIZE + + copy(request.ifrn_name[:], ah_ifname_radio2vap(ifname)) + + offsetsMutex.Lock() + + if err := ah_ioctl(uintptr(fd), IEEE80211_IOCTL_GENERIC_PARAM, uintptr(unsafe.Pointer(&request))); err != nil { + log.Printf("getAtrTbl ioctl data error %s",err) + offsetsMutex.Unlock() + return nil + } + + offsetsMutex.Unlock() + + return &cfg.atr + +} + + +func getRFStat(fd int, ifname string) *awestats { + + var p *awestats + p = new(awestats) + + request := IFReqData{Data: uintptr(unsafe.Pointer(p))} + copy(request.Name[:], ifname) + + offsetsMutex.Lock() + + if err := ah_ioctl(uintptr(fd), SIOCGRADIOSTATS, uintptr(unsafe.Pointer(&request))); err != nil { + log.Printf("getRFStat ioctl data error %s",err) + offsetsMutex.Unlock() + return nil + } + + offsetsMutex.Unlock() + + return p +} + +func getStaStat(fd int, ifname string, buf unsafe.Pointer,count int) *ah_ieee80211_get_wifi_sta_stats { + + var cfg *ieee80211req_cfg_sta + cfg = new(ieee80211req_cfg_sta) + + /* first 4 bytes is subcmd */ + cfg.cmd = IEEE80211_GET_WIFI_STA_STATS + cfg.wifi_sta_stats.count = uint16(count) + cfg.wifi_sta_stats.pointer = buf + + iwp := iw_point{pointer: unsafe.Pointer(cfg)} + + request := iwreq{data: iwp} + + request.data.length = VAP_BUFF_SIZE + + copy(request.ifrn_name[:], ah_ifname_radio2vap(ifname)) + + offsetsMutex.Lock() + + if err := ah_ioctl(uintptr(fd), IEEE80211_IOCTL_GENERIC_PARAM, uintptr(unsafe.Pointer(&request))); err != nil { + log.Printf("getStaStat ioctl data error %s",err) + offsetsMutex.Unlock() + return nil + } + + offsetsMutex.Unlock() + + return &cfg.wifi_sta_stats +} + +func getNumAssocs (fd int, ifname string) uint32 { + + ird := iwreq_data{} + + /* first 4 bytes is subcmd */ + ird.data = IEEE80211_PARAM_NUM_ASSOCS + + request := iwreq_clt{u: ird} + + copy(request.ifr_name[:], ah_ifname_radio2vap(ifname)) + + + offsetsMutex.Lock() + + if err := ah_ioctl(uintptr(fd), IEEE80211_IOCTL_GETPARAM, uintptr(unsafe.Pointer(&request))); err != nil { + log.Printf("getNumAssocs ioctl data error %s",err) + offsetsMutex.Unlock() + return 0 + } + + + offsetsMutex.Unlock() + + return uint32(request.u.data) +} + +func getOneStaInfo(fd int, ifname string, mac_ad [MACADDR_LEN]uint8) *ah_ieee80211_sta_info { + var cfg *ieee80211req_cfg_one_sta + cfg = new(ieee80211req_cfg_one_sta) + + /* first 4 bytes is subcmd */ + cfg.cmd = AH_IEEE80211_GET_ONE_STA_INFO; + cfg.sta_info.mac = mac_ad + iwp := iw_point{pointer: unsafe.Pointer(cfg)} + request := iwreq{data: iwp} + request.data.length = VAP_BUFF_SIZE + copy(request.ifrn_name[:], ifname) + + offsetsMutex.Lock() + if err := ah_ioctl(uintptr(fd), IEEE80211_IOCTL_GENERIC_PARAM, uintptr(unsafe.Pointer(&request))); err != nil { + log.Printf("getOneStaInfo ioctl data error %s",err) + offsetsMutex.Unlock() + return nil + } + + offsetsMutex.Unlock() + + return &cfg.sta_info + +} + +func getOneSta(fd int, ifname string, mac_ad [MACADDR_LEN]uint8) unsafe.Pointer { + var cfg *ieee80211req_cfg_one_sta_info + cfg = new(ieee80211req_cfg_one_sta_info) + + /* first 4 bytes is subcmd */ + cfg.cmd = AH_IEEE80211_GET_ONE_STA + cfg.mac = mac_ad + iwp := iw_point{pointer: unsafe.Pointer(cfg)} + request := iwreq{data: iwp} + request.data.length = VAP_BUFF_SIZE + copy(request.ifrn_name[:], ah_ifname_radio2vap(ifname)) + + offsetsMutex.Lock() + if err := ah_ioctl(uintptr(fd), IEEE80211_IOCTL_GENERIC_PARAM, uintptr(unsafe.Pointer(&request))); err != nil { + log.Printf("getOneSta ioctl data error %s",err) + offsetsMutex.Unlock() + return nil + } + offsetsMutex.Unlock() + + return request.data.pointer + +} + +func getProcNetDev(ifname string) *ah_dcd_dev_stats { + table, err := os.ReadFile("/proc/net/dev") + if err != nil { + return nil; + } + + lines := bytes.Split([]byte(table), newLineByte) + + var intfname string + var stats = new(ah_dcd_dev_stats) + comp := fmt.Sprintf(" %s:",ifname) + + for _, curLine := range lines { + if strings.Contains(string(curLine), comp) { + fmt.Sscanf(string(curLine), + "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d", + &intfname, + &stats.rx_bytes, + &stats.rx_packets, + &stats.rx_errors, + &stats.rx_dropped, + &stats.rx_fifo_errors, + &stats.rx_frame_errors, + &stats.rx_compressed, /* missing for <= 1 */ + &stats.rx_multicast, /* missing for <= 1 */ + &stats.tx_bytes, /* missing for 0 */ + &stats.tx_packets, + &stats.tx_errors, + &stats.tx_dropped, + &stats.tx_fifo_errors, + &stats.collisions, + &stats.tx_carrier_errors, + &stats.tx_compressed, + &stats.tx_multicast, + &stats.rx_unicast, + &stats.rx_broadcast, + &stats.tx_unicast, + &stats.tx_broadcast) + + } + } + + return stats +} + +func getIfIndex(fd int, ifname string) int { + ifr, err := unix.NewIfreq(ifname) + + if err != nil { + log.Printf("failed to create ifreq %v", err) + } + + offsetsMutex.Lock() + + if err := unix.IoctlIfreq(fd, unix.SIOCGIFINDEX, ifr); err != nil { + log.Printf("getIfIndex ioctl error %s",err) + offsetsMutex.Unlock() + return -1 + } + + offsetsMutex.Unlock() + return int(ifr.Uint32()) + +} + +func load_ssid(t *Ah_wireless, ifname string) { + + for i := 1; i < 1024; i++ { + vifname := ifname + "." + strconv.Itoa(i) + + app := "wl" + + arg0 := "-i" + arg1 := vifname + arg2 := "status" + // arg3 := "| grep \"SSID: \"\\\"" + //log.Printf(app + " " + arg0 + " " + arg1 + " " + arg2) + + cmd := exec.Command(app, arg0, arg1, arg2) + output, err := cmd.Output() + + if err != nil { + log.Printf(err.Error()) + return + } + + lines := strings.Split(string(output),"\n") + + temp := strings.Split(lines[0]," ") + + ssid := strings.Trim(temp[1], "\"") + t.intf_m[ifname][ssid] = vifname + } +} + +func load_arp_table(t *Ah_wireless) { + + app := "arp" + arg := "-v" + + cmd := exec.Command(app, arg) + + arp_str, err := cmd.Output() + + if err != nil { + log.Printf(err.Error()) + return + } + + arp_lines := strings.Split(string(arp_str),"\n") + + for i :=0; i 1 { + arp_eliments := strings.Split(arp_lines[i]," ") + t.arp_m[arp_eliments[3]] = arp_eliments[1] + } + } + +} + +func getFeIpnetScore(fd uintptr, clmac [MACADDR_LEN]uint8) int32 { + + msg := ah_flow_get_sta_net_health_msg{ + mac: clmac, + net_health_score: 0, + } + ihdr := ah_fe_ioctl_hdr{ + retval: -1, + msg_type: AH_GET_STATION_NETWORK_HEALTH, + msg_size: uint16(unsafe.Sizeof(msg)), + } + dev_msg := ah_fw_dev_msg{ + hdr: ihdr, + data: msg, + } + + offsetsMutex.Lock() + + if err := ah_ioctl(fd, AH_FE_IOCTL_FLOW, uintptr(unsafe.Pointer(&dev_msg))); err != nil { + log.Printf("getFeIpnetScore ioctl data error %s",err) + offsetsMutex.Unlock() + return -1 + } + + offsetsMutex.Unlock() + + if dev_msg.hdr.retval < 0 { + log.Printf("Open ioctl data erro") + return -1 + } + + return dev_msg.data.net_health_score +} + +func getFeServerIp(fd uintptr, clmac [MACADDR_LEN]uint8) *ah_flow_get_sta_server_ip_msg { + + msg := ah_flow_get_sta_server_ip_msg{ + mac: clmac, + } + ihdr := ah_fe_ioctl_hdr{ + retval: -1, + msg_type: AH_FLOW_GET_STATION_SERVER_IP, + msg_size: uint16(unsafe.Sizeof(msg)), + } + dev_msg := ah_fw_dev_ip_msg{ + hdr: ihdr, + data: msg, + } + + offsetsMutex.Lock() + + if err := ah_ioctl(fd, AH_FE_IOCTL_FLOW, uintptr(unsafe.Pointer(&dev_msg))); err != nil { + log.Printf("getFeServerIp ioctl data error %s",err) + offsetsMutex.Unlock() + return nil + } + + offsetsMutex.Unlock() + + + if dev_msg.hdr.retval < 0 { + log.Printf("Open ioctl data erro") + return nil + } + + return &dev_msg.data +} + +func open(fd, id int) *Ah_wireless { + + //getProcNetDev("wifi1") + //defer unix.Close(fd) + + return &Ah_wireless{fd: fd, closed: make(chan struct{})} +} + +func (t *Ah_wireless) SampleConfig() string { + return sampleConfig +} + +func (t *Ah_wireless) Description() string { + return "Hive OS wireless stat" +} + +func (t *Ah_wireless) Init() error { + return nil +} + + +func dumpOutput(outfile string , outline string, append int) error { + + var f *os.File + var err error + + if append == 1 { + f, err = os.OpenFile(outfile, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600) + } else { + f, err = os.Create(outfile) + } + if err != nil { + log.Printf(fmt.Sprint(err)) + return err + } + + if append == 1 { + f.WriteString("\n\n\n\n") + if err != nil { + f.Close() + log.Printf(fmt.Sprint(err)) + return err + } + } + + f.WriteString(outline) + + if err != nil { + f.Close() + log.Printf(fmt.Sprint(err)) + return err + } + + err = f.Close() + if err != nil { + log.Printf(fmt.Sprint(err)) + return err + } + + return nil + +} + +func Gather_Rf_Avg(t *Ah_wireless, acc telegraf.Accumulator) error { + var ii int + ii = 0 + for _, intfName := range t.Ifname { + + var rfstat *awestats + var devstats *ah_dcd_dev_stats + var ifindex int + var atrStat *ah_ieee80211_atr_user + var hddStat *ah_ieee80211_hdd_stats + + var idx int + var tmp_count1 int64 + var tmp_count2 int64 + + var tx_total int64 + var rx_total int64 + var tmp_count3 int32 + var tmp_count4 int32 + var tot_tx_bitrate_retries uint32 + var tot_rx_bitrate_retries uint32 + + var rf_report ah_dcd_stats_report_int_data + + rfstat = getRFStat(t.fd, intfName) + if (rfstat == nil) { + continue + } + + ifindex = getIfIndex(t.fd, intfName) + if (ifindex <= 0) { + continue + } + devstats = getProcNetDev(intfName) + if (devstats == nil) { + continue + } + atrStat = getAtrTbl(t.fd, intfName) + if (atrStat == nil) { + continue + } + hddStat = getHDDStat(t.fd, intfName) + if (hddStat == nil) { + continue + } + + + /* We need check and aggregation Tx/Rx bit rate distribution + * prcentage, if the bit rate equal in radio interface or client reporting. + */ + + for i := 0; i < NS_HW_RATE_SIZE; i++{ + + if ((rfstat.ast_rx_rate_stats[i].ns_rateKbps == 0) && (rfstat.ast_tx_rate_stats[i].ns_rateKbps == 0)) { + continue + } + + for j := (i+1); j < NS_HW_RATE_SIZE; j++ { + if ((rfstat.ast_rx_rate_stats[i].ns_rateKbps != 0) && (rfstat.ast_rx_rate_stats[i].ns_rateKbps == rfstat.ast_rx_rate_stats[j].ns_rateKbps)) { + rfstat.ast_rx_rate_stats[i].ns_unicasts += rfstat.ast_rx_rate_stats[j].ns_unicasts; + rfstat.ast_rx_rate_stats[i].ns_retries += rfstat.ast_rx_rate_stats[j].ns_retries; + rfstat.ast_rx_rate_stats[j].ns_rateKbps = 0; + rfstat.ast_rx_rate_stats[j].ns_unicasts = 0; + rfstat.ast_rx_rate_stats[j].ns_retries = 0; + } + if ((rfstat.ast_tx_rate_stats[i].ns_rateKbps != 0) && (rfstat.ast_tx_rate_stats[i].ns_rateKbps == rfstat.ast_tx_rate_stats[j].ns_rateKbps)) { + rfstat.ast_tx_rate_stats[i].ns_unicasts += rfstat.ast_tx_rate_stats[j].ns_unicasts; + rfstat.ast_tx_rate_stats[i].ns_retries += rfstat.ast_tx_rate_stats[j].ns_retries; + rfstat.ast_tx_rate_stats[j].ns_rateKbps = 0; + rfstat.ast_tx_rate_stats[j].ns_unicasts = 0; + rfstat.ast_tx_rate_stats[j].ns_retries = 0; + } + } + } + + + +/* Rate Calculation Copied from DCD code */ + + /* Tx/Rx bit rate distribution */ + for idx = 0; idx < NS_HW_RATE_SIZE; idx++ { + tx_total += int64(reportGetDiff(rfstat.ast_tx_rate_stats[idx].ns_unicasts, + t.last_rf_stat[ii].ast_tx_rate_stats[idx].ns_unicasts)) + + rx_total += int64(reportGetDiff(rfstat.ast_rx_rate_stats[idx].ns_unicasts, + t.last_rf_stat[ii].ast_rx_rate_stats[idx].ns_unicasts)) + + tot_tx_bitrate_retries += reportGetDiff(rfstat.ast_tx_rate_stats[idx].ns_retries, + t.last_rf_stat[ii].ast_tx_rate_stats[idx].ns_retries) + + tot_rx_bitrate_retries += reportGetDiff(rfstat.ast_rx_rate_stats[idx].ns_retries, + t.last_rf_stat[ii].ast_rx_rate_stats[idx].ns_retries) + + } + + + for idx = 0; idx < NS_HW_RATE_SIZE; idx++ { + + tmp_count3 = int32(rfstat.ast_tx_rate_stats[idx].ns_unicasts - t.last_rf_stat[ii].ast_tx_rate_stats[idx].ns_unicasts) + if (tx_total > 0 && tmp_count3 > 0) { + rf_report.tx_bit_rate[idx].rate_dtn = uint8((int64(tmp_count3) * 100) / tx_total) + } else { + rf_report.tx_bit_rate[idx].rate_dtn = 0; + } + tmp_count4 = int32(rfstat.ast_rx_rate_stats[idx].ns_unicasts - t.last_rf_stat[ii].ast_rx_rate_stats[idx].ns_unicasts) + if (rx_total > 0 && tmp_count4 > 0) { + rf_report.rx_bit_rate[idx].rate_dtn = uint8((int64(tmp_count4) * 100) / rx_total) + } else { + rf_report.rx_bit_rate[idx].rate_dtn = 0; + } + + /* Tx/Rx bit rate success distribution */ + tmp_count1 = int64(rfstat.ast_tx_rate_stats[idx].ns_retries - t.last_rf_stat[ii].ast_tx_rate_stats[idx].ns_retries) + tmp_count2 = tmp_count1 + int64(tmp_count3) + if (tmp_count2 > 0 && rf_report.tx_bit_rate[idx].rate_dtn > 0) { + rf_report.tx_bit_rate[idx].rate_suc_dtn = uint8((int64(tmp_count3) * 100) / tmp_count2) + if (rf_report.tx_bit_rate[idx].rate_suc_dtn > 100) { + rf_report.tx_bit_rate[idx].rate_suc_dtn = 100 + log.Printf("stats report int data process: rate_suc_dtn1 is more than 100%\n") + } + } else { + rf_report.tx_bit_rate[idx].rate_suc_dtn = 0; + } + + tmp_count1 = int64(rfstat.ast_rx_rate_stats[idx].ns_retries - t.last_rf_stat[ii].ast_rx_rate_stats[idx].ns_retries) + tmp_count2 = tmp_count1 + int64(tmp_count4) + if (tmp_count2 > 0 && rf_report.rx_bit_rate[idx].rate_dtn > 0) { + rf_report.rx_bit_rate[idx].rate_suc_dtn = uint8((int64(tmp_count4) * 100) / tmp_count2) + if (rf_report.rx_bit_rate[idx].rate_suc_dtn > 100) { + rf_report.rx_bit_rate[idx].rate_suc_dtn = 100; + log.Printf("stats report int data process: rate_suc_dtn2 is more than 100%\n"); + } + + } else { + rf_report.rx_bit_rate[idx].rate_suc_dtn = 0; + } + rf_report.tx_bit_rate[idx].kbps = rfstat.ast_tx_rate_stats[idx].ns_rateKbps; + rf_report.rx_bit_rate[idx].kbps = rfstat.ast_rx_rate_stats[idx].ns_rateKbps; + } + +/* Rate calculation copied from DCD code */ + + if (t.last_ut_data[ii].noise_min == 0) || (t.last_ut_data[ii].noise_min >= rfstat.ast_noise_floor) { + t.last_ut_data[ii].noise_min = rfstat.ast_noise_floor + } + if (t.last_ut_data[ii].noise_max == 0 ) || (t.last_ut_data[ii].noise_max <= rfstat.ast_noise_floor) { + t.last_ut_data[ii].noise_max = rfstat.ast_noise_floor + } + t.last_ut_data[ii].noise_avg = (t.last_ut_data[ii].noise_avg + rfstat.ast_noise_floor)/2 + + if (t.last_ut_data[ii].crc_err_rate_min == 0 ) || (t.last_ut_data[ii].crc_err_rate_min >= rfstat.phy_stats.ast_rx_crcerr) { + t.last_ut_data[ii].crc_err_rate_min = rfstat.phy_stats.ast_rx_crcerr + } + if (t.last_ut_data[ii].crc_err_rate_max == 0 ) || (t.last_ut_data[ii].crc_err_rate_max <= rfstat.phy_stats.ast_rx_crcerr) { + t.last_ut_data[ii].crc_err_rate_max = rfstat.phy_stats.ast_rx_crcerr + } + t.last_ut_data[ii].crc_err_rate_avg = (t.last_ut_data[ii].crc_err_rate_avg + rfstat.phy_stats.ast_rx_crcerr)/2 + + if atrStat.count > 0 { + + rx_util := atrStat.atr_info[atrStat.count - 1].rxf_pcnt + tx_util := atrStat.atr_info[atrStat.count - 1].txf_pcnt + + total_util := atrStat.atr_info[atrStat.count - 1].rxc_pcnt + + var chan_util int32 + var interface_utiliation int32 + if total_util > 100 { + chan_util = 100 + } else { + chan_util = int32(total_util) + } + + /* Calculate Utilization */ + if (total_util > (rx_util + tx_util)) { + interface_utiliation = int32(total_util) - int32(rx_util) - int32(tx_util) + } else { + interface_utiliation = 0 + } + if (t.last_ut_data[ii].intfer_util_min == 0) || (t.last_ut_data[ii].intfer_util_min >= interface_utiliation) { + t.last_ut_data[ii].intfer_util_min = interface_utiliation + } + if (t.last_ut_data[ii].intfer_util_max == 0) || (t.last_ut_data[ii].intfer_util_max <= interface_utiliation) { + t.last_ut_data[ii].intfer_util_max = interface_utiliation + } + t.last_ut_data[ii].intfer_util_avg = (t.last_ut_data[ii].intfer_util_avg + interface_utiliation)/2 + + if (t.last_ut_data[ii].chan_util_min == 0 ) || (t.last_ut_data[ii].chan_util_min >= chan_util) { + t.last_ut_data[ii].chan_util_min = chan_util + } + if (t.last_ut_data[ii].chan_util_max == 0 ) || (t.last_ut_data[ii].chan_util_max <= chan_util) { + t.last_ut_data[ii].chan_util_max = chan_util + } + t.last_ut_data[ii].chan_util_avg = (t.last_ut_data[ii].chan_util_avg + chan_util)/2 + + if (t.last_ut_data[ii].tx_util_min == 0) || (t.last_ut_data[ii].tx_util_min >= tx_util) { + t.last_ut_data[ii].tx_util_min = tx_util + } + if (t.last_ut_data[ii].tx_util_max == 0) || (t.last_ut_data[ii].tx_util_max <= tx_util) { + t.last_ut_data[ii].tx_util_max = tx_util + } + t.last_ut_data[ii].tx_util_avg = (t.last_ut_data[ii].tx_util_avg + tx_util)/2 + + if (t.last_ut_data[ii].rx_util_min == 0) || (t.last_ut_data[ii].rx_util_min >= rx_util) { + t.last_ut_data[ii].rx_util_min = rx_util + } + if (t.last_ut_data[ii].rx_util_max == 0) || (t.last_ut_data[ii].rx_util_max <= rx_util) { + t.last_ut_data[ii].rx_util_max = rx_util + } + t.last_ut_data[ii].rx_util_avg = (t.last_ut_data[ii].rx_util_avg + rx_util)/2 + + + if (t.last_ut_data[ii].rx_ibss_util_min == 0) || (t.last_ut_data[ii].rx_ibss_util_min >= atrStat.atr_info[atrStat.count - 1].rxf_inbss) { + t.last_ut_data[ii].rx_ibss_util_min = atrStat.atr_info[atrStat.count - 1].rxf_inbss + } + if (t.last_ut_data[ii].rx_ibss_util_max == 0) || (t.last_ut_data[ii].rx_ibss_util_max <= atrStat.atr_info[atrStat.count - 1].rxf_inbss) { + t.last_ut_data[ii].rx_ibss_util_max = atrStat.atr_info[atrStat.count - 1].rxf_inbss + } + t.last_ut_data[ii].rx_ibss_util_avg = (t.last_ut_data[ii].rx_ibss_util_avg + atrStat.atr_info[atrStat.count - 1].rxf_inbss)/2 + + if (t.last_ut_data[ii].rx_obss_util_min == 0) || (t.last_ut_data[ii].rx_obss_util_min >= atrStat.atr_info[atrStat.count - 1].rxf_obss) { + t.last_ut_data[ii].rx_obss_util_min = atrStat.atr_info[atrStat.count - 1].rxf_obss + } + if (t.last_ut_data[ii].rx_obss_util_max == 0) || (t.last_ut_data[ii].rx_obss_util_max <= atrStat.atr_info[atrStat.count - 1].rxf_obss) { + t.last_ut_data[ii].rx_obss_util_max = atrStat.atr_info[atrStat.count - 1].rxf_obss + } + t.last_ut_data[ii].rx_obss_util_avg = (t.last_ut_data[ii].rx_obss_util_avg + atrStat.atr_info[atrStat.count - 1].rxf_obss)/2 + + /* Calculate Utilization */ + + } + + t.last_rf_stat[ii] = *rfstat + ii++ + } + + return nil +} + + + +func Gather_Rf_Stat(t *Ah_wireless, acc telegraf.Accumulator) error { + var ii int + ii = 0 + for _, intfName := range t.Ifname { + + var rfstat *awestats + var devstats *ah_dcd_dev_stats + var ifindex int + var atrStat *ah_ieee80211_atr_user + var hddStat *ah_ieee80211_hdd_stats + + var idx int + var tmp_count1 int64 + var tmp_count2 int64 + //var tx_ok uint64 + //var rx_ok uint64 + var tx_total int64 + var rx_total int64 + var tmp_count3 int32 + var tmp_count4 int32 + var tot_tx_bitrate_retries uint32 + var tot_rx_bitrate_retries uint32 + + var rf_report ah_dcd_stats_report_int_data + + rfstat = getRFStat(t.fd, intfName) + if (rfstat == nil) { + continue + } + + ifindex = getIfIndex(t.fd, intfName) + if (ifindex <= 0) { + continue + } + devstats = getProcNetDev(intfName) + if (devstats == nil) { + continue + } + atrStat = getAtrTbl(t.fd, intfName) + if (atrStat == nil) { + continue + } + hddStat = getHDDStat(t.fd, intfName) + if (hddStat == nil) { + continue + } + + + /* We need check and aggregation Tx/Rx bit rate distribution + * prcentage, if the bit rate equal in radio interface or client reporting. + */ + + for i := 0; i < NS_HW_RATE_SIZE; i++{ + + if ((rfstat.ast_rx_rate_stats[i].ns_rateKbps == 0) && (rfstat.ast_tx_rate_stats[i].ns_rateKbps == 0)) { + continue + } + + for j := (i+1); j < NS_HW_RATE_SIZE; j++ { + if ((rfstat.ast_rx_rate_stats[i].ns_rateKbps != 0) && (rfstat.ast_rx_rate_stats[i].ns_rateKbps == rfstat.ast_rx_rate_stats[j].ns_rateKbps)) { + rfstat.ast_rx_rate_stats[i].ns_unicasts += rfstat.ast_rx_rate_stats[j].ns_unicasts; + rfstat.ast_rx_rate_stats[i].ns_retries += rfstat.ast_rx_rate_stats[j].ns_retries; + rfstat.ast_rx_rate_stats[j].ns_rateKbps = 0; + rfstat.ast_rx_rate_stats[j].ns_unicasts = 0; + rfstat.ast_rx_rate_stats[j].ns_retries = 0; + } + if ((rfstat.ast_tx_rate_stats[i].ns_rateKbps != 0) && (rfstat.ast_tx_rate_stats[i].ns_rateKbps == rfstat.ast_tx_rate_stats[j].ns_rateKbps)) { + rfstat.ast_tx_rate_stats[i].ns_unicasts += rfstat.ast_tx_rate_stats[j].ns_unicasts; + rfstat.ast_tx_rate_stats[i].ns_retries += rfstat.ast_tx_rate_stats[j].ns_retries; + rfstat.ast_tx_rate_stats[j].ns_rateKbps = 0; + rfstat.ast_tx_rate_stats[j].ns_unicasts = 0; + rfstat.ast_tx_rate_stats[j].ns_retries = 0; + } + } + } + + + +/* Rate Calculation Copied from DCD code */ + + /* Tx/Rx bit rate distribution */ + for idx = 0; idx < NS_HW_RATE_SIZE; idx++ { + tx_total += int64(reportGetDiff(rfstat.ast_tx_rate_stats[idx].ns_unicasts, + t.last_rf_stat[ii].ast_tx_rate_stats[idx].ns_unicasts)) + + rx_total += int64(reportGetDiff(rfstat.ast_rx_rate_stats[idx].ns_unicasts, + t.last_rf_stat[ii].ast_rx_rate_stats[idx].ns_unicasts)) + + tot_tx_bitrate_retries += reportGetDiff(rfstat.ast_tx_rate_stats[idx].ns_retries, + t.last_rf_stat[ii].ast_tx_rate_stats[idx].ns_retries) + + tot_rx_bitrate_retries += reportGetDiff(rfstat.ast_rx_rate_stats[idx].ns_retries, + t.last_rf_stat[ii].ast_rx_rate_stats[idx].ns_retries) + + } + //tx_ok = uint64(tx_total) + //rx_ok = uint64(rx_total) + + + + for idx = 0; idx < NS_HW_RATE_SIZE; idx++ { + + tmp_count3 = int32(rfstat.ast_tx_rate_stats[idx].ns_unicasts - t.last_rf_stat[ii].ast_tx_rate_stats[idx].ns_unicasts) + if (tx_total > 0 && tmp_count3 > 0) { + rf_report.tx_bit_rate[idx].rate_dtn = uint8((int64(tmp_count3) * 100) / tx_total) + } else { + rf_report.tx_bit_rate[idx].rate_dtn = 0; + } + tmp_count4 = int32(rfstat.ast_rx_rate_stats[idx].ns_unicasts - t.last_rf_stat[ii].ast_rx_rate_stats[idx].ns_unicasts) + if (rx_total > 0 && tmp_count4 > 0) { + rf_report.rx_bit_rate[idx].rate_dtn = uint8((int64(tmp_count4) * 100) / rx_total) + } else { + rf_report.rx_bit_rate[idx].rate_dtn = 0; + } + + /* Tx/Rx bit rate success distribution */ + tmp_count1 = int64(rfstat.ast_tx_rate_stats[idx].ns_retries - t.last_rf_stat[ii].ast_tx_rate_stats[idx].ns_retries) + tmp_count2 = tmp_count1 + int64(tmp_count3) + if (tmp_count2 > 0 && rf_report.tx_bit_rate[idx].rate_dtn > 0) { + rf_report.tx_bit_rate[idx].rate_suc_dtn = uint8((int64(tmp_count3) * 100) / tmp_count2) + if (rf_report.tx_bit_rate[idx].rate_suc_dtn > 100) { + rf_report.tx_bit_rate[idx].rate_suc_dtn = 100 + log.Printf("stats report int data process: rate_suc_dtn1 is more than 100%\n") + } + } else { + rf_report.tx_bit_rate[idx].rate_suc_dtn = 0; + } + + tmp_count1 = int64(rfstat.ast_rx_rate_stats[idx].ns_retries - t.last_rf_stat[ii].ast_rx_rate_stats[idx].ns_retries) + tmp_count2 = tmp_count1 + int64(tmp_count4) + if (tmp_count2 > 0 && rf_report.rx_bit_rate[idx].rate_dtn > 0) { + rf_report.rx_bit_rate[idx].rate_suc_dtn = uint8((int64(tmp_count4) * 100) / tmp_count2) + if (rf_report.rx_bit_rate[idx].rate_suc_dtn > 100) { + rf_report.rx_bit_rate[idx].rate_suc_dtn = 100; + log.Printf("stats report int data process: rate_suc_dtn2 is more than 100%\n"); + } + + } else { + rf_report.rx_bit_rate[idx].rate_suc_dtn = 0; + } + rf_report.tx_bit_rate[idx].kbps = rfstat.ast_tx_rate_stats[idx].ns_rateKbps; + rf_report.rx_bit_rate[idx].kbps = rfstat.ast_rx_rate_stats[idx].ns_rateKbps; + } + +/* Rate calculation copied from DCD code */ + + fields := map[string]interface{}{ + + "name_keys": intfName, + "ifindex_keys": ifindex, + + } + + if (t.last_ut_data[ii].noise_min == 0) || (t.last_ut_data[ii].noise_min >= rfstat.ast_noise_floor) { + t.last_ut_data[ii].noise_min = rfstat.ast_noise_floor + } + if (t.last_ut_data[ii].noise_max == 0 ) || (t.last_ut_data[ii].noise_max <= rfstat.ast_noise_floor) { + t.last_ut_data[ii].noise_max = rfstat.ast_noise_floor + } + t.last_ut_data[ii].noise_avg = (t.last_ut_data[ii].noise_avg + rfstat.ast_noise_floor)/2 + + if (t.last_ut_data[ii].crc_err_rate_min == 0 ) || (t.last_ut_data[ii].crc_err_rate_min >= rfstat.phy_stats.ast_rx_crcerr) { + t.last_ut_data[ii].crc_err_rate_min = rfstat.phy_stats.ast_rx_crcerr + } + if (t.last_ut_data[ii].crc_err_rate_max == 0 ) || (t.last_ut_data[ii].crc_err_rate_max <= rfstat.phy_stats.ast_rx_crcerr) { + t.last_ut_data[ii].crc_err_rate_max = rfstat.phy_stats.ast_rx_crcerr + } + t.last_ut_data[ii].crc_err_rate_avg = (t.last_ut_data[ii].crc_err_rate_avg + rfstat.phy_stats.ast_rx_crcerr)/2 + + if atrStat.count > 0 { + + rx_util := atrStat.atr_info[atrStat.count - 1].rxf_pcnt + tx_util := atrStat.atr_info[atrStat.count - 1].txf_pcnt + + total_util := atrStat.atr_info[atrStat.count - 1].rxc_pcnt + + var chan_util int32 + var interface_utiliation int32 + if total_util > 100 { + chan_util = 100 + } else { + chan_util = int32(total_util) + } + + /* Calculate Utilization */ + if (total_util > (rx_util + tx_util)) { + interface_utiliation = int32(total_util) - int32(rx_util) - int32(tx_util) + } else { + interface_utiliation = 0 + } + if (t.last_ut_data[ii].intfer_util_min == 0) || (t.last_ut_data[ii].intfer_util_min >= interface_utiliation) { + t.last_ut_data[ii].intfer_util_min = interface_utiliation + } + if (t.last_ut_data[ii].intfer_util_max == 0) || (t.last_ut_data[ii].intfer_util_max <= interface_utiliation) { + t.last_ut_data[ii].intfer_util_max = interface_utiliation + } + t.last_ut_data[ii].intfer_util_avg = (t.last_ut_data[ii].intfer_util_avg + interface_utiliation)/2 + + if (t.last_ut_data[ii].chan_util_min == 0 ) || (t.last_ut_data[ii].chan_util_min >= chan_util) { + t.last_ut_data[ii].chan_util_min = chan_util + } + if (t.last_ut_data[ii].chan_util_max == 0 ) || (t.last_ut_data[ii].chan_util_max <= chan_util) { + t.last_ut_data[ii].chan_util_max = chan_util + } + t.last_ut_data[ii].chan_util_avg = (t.last_ut_data[ii].chan_util_avg + chan_util)/2 + + if (t.last_ut_data[ii].tx_util_min == 0) || (t.last_ut_data[ii].tx_util_min >= tx_util) { + t.last_ut_data[ii].tx_util_min = tx_util + } + if (t.last_ut_data[ii].tx_util_max == 0) || (t.last_ut_data[ii].tx_util_max <= tx_util) { + t.last_ut_data[ii].tx_util_max = tx_util + } + t.last_ut_data[ii].tx_util_avg = (t.last_ut_data[ii].tx_util_avg + tx_util)/2 + + if (t.last_ut_data[ii].rx_util_min == 0) || (t.last_ut_data[ii].rx_util_min >= rx_util) { + t.last_ut_data[ii].rx_util_min = rx_util + } + if (t.last_ut_data[ii].rx_util_max == 0) || (t.last_ut_data[ii].rx_util_max <= rx_util) { + t.last_ut_data[ii].rx_util_max = rx_util + } + t.last_ut_data[ii].rx_util_avg = (t.last_ut_data[ii].rx_util_avg + rx_util)/2 + + + if (t.last_ut_data[ii].rx_ibss_util_min == 0) || (t.last_ut_data[ii].rx_ibss_util_min >= atrStat.atr_info[atrStat.count - 1].rxf_inbss) { + t.last_ut_data[ii].rx_ibss_util_min = atrStat.atr_info[atrStat.count - 1].rxf_inbss + } + if (t.last_ut_data[ii].rx_ibss_util_max == 0) || (t.last_ut_data[ii].rx_ibss_util_max <= atrStat.atr_info[atrStat.count - 1].rxf_inbss) { + t.last_ut_data[ii].rx_ibss_util_max = atrStat.atr_info[atrStat.count - 1].rxf_inbss + } + t.last_ut_data[ii].rx_ibss_util_avg = (t.last_ut_data[ii].rx_ibss_util_avg + atrStat.atr_info[atrStat.count - 1].rxf_inbss)/2 + + if (t.last_ut_data[ii].rx_obss_util_min == 0) || (t.last_ut_data[ii].rx_obss_util_min >= atrStat.atr_info[atrStat.count - 1].rxf_obss) { + t.last_ut_data[ii].rx_obss_util_min = atrStat.atr_info[atrStat.count - 1].rxf_obss + } + if (t.last_ut_data[ii].rx_obss_util_max == 0) || (t.last_ut_data[ii].rx_obss_util_max <= atrStat.atr_info[atrStat.count - 1].rxf_obss) { + t.last_ut_data[ii].rx_obss_util_max = atrStat.atr_info[atrStat.count - 1].rxf_obss + } + t.last_ut_data[ii].rx_obss_util_avg = (t.last_ut_data[ii].rx_obss_util_avg + atrStat.atr_info[atrStat.count - 1].rxf_obss)/2 + + if (t.last_ut_data[ii].wifi_i_util_min == 0) || (t.last_ut_data[ii].wifi_i_util_min >= atrStat.atr_info[atrStat.count-1].wifi_interference) { + t.last_ut_data[ii].wifi_i_util_min = atrStat.atr_info[atrStat.count-1].wifi_interference + } + if (t.last_ut_data[ii].wifi_i_util_max == 0) || (t.last_ut_data[ii].wifi_i_util_max <= atrStat.atr_info[atrStat.count-1].wifi_interference) { + t.last_ut_data[ii].wifi_i_util_max = atrStat.atr_info[atrStat.count-1].wifi_interference + } + t.last_ut_data[ii].wifi_i_util_avg = (t.last_ut_data[ii].wifi_i_util_avg + atrStat.atr_info[atrStat.count-1].wifi_interference) / 2 + /* Calculate Utilization */ + + + fields["interferenceUtilization_min"] = t.last_ut_data[ii].intfer_util_min + fields["interferenceUtilization_max"] = t.last_ut_data[ii].intfer_util_max + fields["interferenceUtilization_avg"] = t.last_ut_data[ii].intfer_util_avg + + + fields["channelUtilization_min"] = t.last_ut_data[ii].chan_util_min + fields["channelUtilization_max"] = t.last_ut_data[ii].chan_util_max + fields["channelUtilization_avg"] = t.last_ut_data[ii].chan_util_avg + + fields["txUtilization_min"] = t.last_ut_data[ii].tx_util_min + fields["txUtilization_max"] = t.last_ut_data[ii].tx_util_max + fields["txUtilization_avg"] = t.last_ut_data[ii].tx_util_avg + + fields["rxUtilization_min"] = t.last_ut_data[ii].rx_util_min + fields["rxUtilization_max"] = t.last_ut_data[ii].rx_util_max + fields["rxUtilization_avg"] = t.last_ut_data[ii].rx_util_avg + + fields["rxInbssUtilization_min"] = t.last_ut_data[ii].rx_ibss_util_min + fields["rxInbssUtilization_max"] = t.last_ut_data[ii].rx_ibss_util_max + fields["rxInbssUtilization_avg"] = t.last_ut_data[ii].rx_ibss_util_avg + + fields["rxObssUtilization_min"] = t.last_ut_data[ii].rx_obss_util_min + fields["rxObssUtilization_max"] = t.last_ut_data[ii].rx_obss_util_max + fields["rxObssUtilization_avg"] = t.last_ut_data[ii].rx_obss_util_avg + + fields["wifinterferenceUtilization_min"] = t.last_ut_data[ii].wifi_i_util_min + fields["wifinterferenceUtilization_max"] = t.last_ut_data[ii].wifi_i_util_max + fields["wifinterferenceUtilization_avg"] = t.last_ut_data[ii].wifi_i_util_avg + + } else { + fields["channelUtilization_min"] = 0 + fields["channelUtilization_max"] = 0 + fields["channelUtilization_avg"] = 0 + + fields["txUtilization_min"] = 0 + fields["txUtilization_max"] = 0 + fields["txUtilization_avg"] = 0 + + fields["rxUtilization_min"] = 0 + fields["rxUtilization_max"] = 0 + fields["rxUtilization_avg"] = 0 + + fields["rxInbssUtilization_min"] = 0 + fields["rxInbssUtilization_max"] = 0 + fields["rxInbssUtilization_avg"] = 0 + + fields["rxObssUtilization_min"] = 0 + fields["rxObssUtilization_max"] = 0 + fields["rxObssUtilization_avg"] = 0 + + fields["wifinterferenceUtilization_min"] = 0 + fields["wifinterferenceUtilization_max"] = 0 + fields["wifinterferenceUtilization_avg"] = 0 + + } + + fields["wifinterferenceUtilization_min"] = t.last_ut_data[ii].wifi_i_util_min + fields["wifinterferenceUtilization_max"] = t.last_ut_data[ii].wifi_i_util_max + fields["wifinterferenceUtilization_avg"] = t.last_ut_data[ii].wifi_i_util_avg + + fields["noise_min"] = t.last_ut_data[ii].noise_min + fields["noise_max"] = t.last_ut_data[ii].noise_max + fields["noise_avg"] = t.last_ut_data[ii].noise_avg + + fields["crcErrorRate_min"] = t.last_ut_data[ii].crc_err_rate_min + fields["crcErrorRate_max"] = t.last_ut_data[ii].crc_err_rate_max + fields["crcErrorRate_avg"] = t.last_ut_data[ii].crc_err_rate_avg + + + fields["txPackets"] = devstats.tx_packets + fields["txErrors"] = devstats.tx_errors + fields["txDropped"] = devstats.tx_dropped + fields["txHwDropped"] = rfstat.ast_as.ast_tx_shortpre + rfstat.ast_as.ast_tx_xretries + rfstat.ast_as.ast_tx_fifoerr + fields["txSwDropped"] = devstats.tx_dropped + fields["txBytes"] = devstats.tx_bytes + fields["txRetryCount"] = rfstat.phy_stats.ast_tx_shortretry + rfstat.phy_stats.ast_tx_longretry + + fields["txRate_min"] = rfstat.ast_tx_rate_stats[0].ns_rateKbps + fields["txRate_max"] = rfstat.ast_tx_rate_stats[0].ns_rateKbps + fields["txRate_avg"] = rfstat.ast_tx_rate_stats[0].ns_rateKbps + + fields["txUnicastPackets"] = rfstat.ast_tx_rate_stats[0].ns_unicasts + fields["txMulticastPackets"] = rfstat.ast_as.ast_tx_mcast + fields["txMulticastBytes"] = rfstat.ast_as.ast_tx_mcast_bytes + fields["txBcastBytes"] = rfstat.ast_as.ast_tx_bcast_bytes + fields["txBcastPackets"] = rfstat.ast_as.ast_tx_bcast + + fields["rxPackets"] = devstats.rx_packets + fields["rxErrors"] = devstats.rx_errors + fields["rxDropped"] = devstats.rx_dropped + fields["rxBytes"] = devstats.rx_bytes + fields["rxRetryCount"] = rfstat.ast_rx_retry + + fields["rxRate_min"] = rfstat.ast_rx_rate_stats[0].ns_rateKbps + fields["rxRate_max"] = rfstat.ast_rx_rate_stats[0].ns_rateKbps + fields["rxRate_avg"] = rfstat.ast_rx_rate_stats[0].ns_rateKbps + + fields["rxMulticastBytes"] = rfstat.ast_rx_mcast_bytes + fields["rxMulticastPackets"] = rfstat.ast_rx_mcast + fields["rxBcastPackets"] = rfstat.ast_rx_bcast + fields["rxBcastBytes"] = rfstat.ast_rx_bcast_bytes + + fields["bsSpCnt"] = hddStat.bs_sp_cnt + fields["snrSpCnt"] = hddStat.snr_sp_cnt + fields["snAnswerCnt"] = reportGetDiff(hddStat.sn_answer_cnt, hddStat.sn_answer_cnt) + fields["rxPrbSpCnt"] = rfstat.is_rx_hdd_probe_sup + fields["rxAuthCnt"] = rfstat.is_rx_hdd_auth_sup + + fields["txBitrateSuc"] = rfstat.ast_tx_rix_invalids + fields["rxBitrateSuc"] = rfstat.ast_rx_rix_invalids + + for i := 0; i < NS_HW_RATE_SIZE; i++{ + kbps := fmt.Sprintf("kbps_%d_rxRateStats",i) + rateDtn := fmt.Sprintf("rateDtn_%d_rxRateStats",i) + rateSucDtn := fmt.Sprintf("rateSucDtn_%d_rxRateStats",i) + fields[kbps] = rf_report.rx_bit_rate[i].kbps + fields[rateDtn] = rf_report.rx_bit_rate[i].rate_dtn + fields[rateSucDtn] = rf_report.rx_bit_rate[i].rate_suc_dtn + } + + + for i := 0; i < NS_HW_RATE_SIZE; i++{ + kbps := fmt.Sprintf("kbps_%d_txRateStats",i) + rateDtn := fmt.Sprintf("rateDtn_%d_txRateStats",i) + rateSucDtn := fmt.Sprintf("rateSucDtn_%d_txRateStats",i) + fields[kbps] = rf_report.tx_bit_rate[i].kbps + fields[rateDtn] = rf_report.tx_bit_rate[i].rate_dtn + fields[rateSucDtn] = rf_report.tx_bit_rate[i].rate_suc_dtn + } + + fields["clientCount"] = t.numclient[ii] + fields["lbSpCnt"] = hddStat.lb_sp_cnt + fields["rxProbeSup"] = rfstat.is_rx_hdd_probe_sup + fields["rxSwDropped"] = devstats.rx_dropped + fields["rxUnicastPackets"] = rfstat.ast_rx_rate_stats[0].ns_unicasts + + + acc.AddGauge("RfStats", fields, nil) + + var s string + + s = "Stats of interface " + intfName + "\n\n" + + for k, v := range fields { + if fmt.Sprint(v) == "0" { // Check if the value is zero + delete(fields, k) + } + } + + keys := make([]string, 0, len(fields)) + + for k := range fields{ + keys = append(keys, k) + } + + sort.Strings(keys) + + for _, k := range keys { + s = s + k + " : " + fmt.Sprint(fields[k]) + "\n" + } + + s = s + "---------------------------------------------------------------------------------------------\n" + + log.Printf("ah_wireless_v2: radio status is processed") + + dumpOutput(RF_STAT_OUT_FILE, s, 1) + + t.last_rf_stat[ii] = *rfstat + ii++ + } + + return nil +} + +func Gather_Client_Stat(t *Ah_wireless, acc telegraf.Accumulator) error { + tags := map[string]string{ + } + + + fields2 := map[string]interface{}{ + } + + var ii int + var client_mac string + ii = 0 + + + for _, intfName2 := range t.Ifname { + + var cltstat *ah_ieee80211_get_wifi_sta_stats + var ifindex2 int + var numassoc int + var stainfo *ah_ieee80211_sta_info + + var tot_rx_tx uint32 + var tot_rate_frame uint32 + var tot_pcnt int64 + var conn_score int64 + var tx_total int64 + var rx_total int64 + var tx_retries uint32 + //var tx_retry_rate uchar + var idx int + var tmp_count1 int32 + var tmp_count2 int32 + var tmp_count3 uint32 + var tmp_count4 uint32 + var tmp_count5 uint64 + var tmp_count6 uint64 + var rf_report ah_dcd_stats_report_int_data + var tot_tx_bitrate_retries uint32 + var tot_rx_bitrate_retries uint32 + + var client_ssid string + + numassoc = int(getNumAssocs(t.fd, intfName2)) + + t.numclient[ii] = numassoc + + if(numassoc == 0) { + ii++ + continue + } + + + clt_item := make([]ah_ieee80211_sta_stats_item, numassoc) + + + ifindex2 = getIfIndex(t.fd, intfName2) + if(ifindex2 <= 0 ) { + continue + } + + cltstat = getStaStat(t.fd, intfName2, unsafe.Pointer(&clt_item[0]), numassoc) + + for cn := 0; cn < numassoc; cn++ { + //if ( clt_item[cn] == nil) { + // continue + //} + client_ssid = string(bytes.Trim(clt_item[cn].ns_ssid[:], "\x00")) + + if(clt_item[cn].ns_mac[0] !=0 || clt_item[cn].ns_mac[1] !=0 || clt_item[cn].ns_mac[2] !=0 || clt_item[cn].ns_mac[3] !=0 || clt_item[cn].ns_mac[4] != 0 || clt_item[cn].ns_mac[5]!=0) { + cintfName := t.intf_m[intfName2][client_ssid] + client_mac = fmt.Sprintf("%02x:%02x:%02x:%02x:%02x:%02x",clt_item[cn].ns_mac[0],clt_item[cn].ns_mac[1],clt_item[cn].ns_mac[2],clt_item[cn].ns_mac[3],clt_item[cn].ns_mac[4],clt_item[cn].ns_mac[5]) + + + stainfo = getOneStaInfo(t.fd, cintfName, clt_item[cn].ns_mac) + + if(stainfo==nil) { + log.Printf("Error in getOneStaInfo") + continue + } + + if stainfo.rssi == 0 { + continue + } + } else { + stainfo = nil + continue + } + + f := init_fe() + ipnet_score := getFeIpnetScore(f.Fd(), clt_item[cn].ns_mac) + sta_ip := getFeServerIp(f.Fd(), clt_item[cn].ns_mac) + f.Close() + + //client_mac := fmt.Sprintf("%02x:%02x:%02x:%02x:%02x:%02x",clt_item[cn].ns_mac[0],clt_item[cn].ns_mac[1],clt_item[cn].ns_mac[2],clt_item[cn].ns_mac[3],clt_item[cn].ns_mac[4],clt_item[cn].ns_mac[5]) + cfgptr := getOneSta(t.fd, intfName2, clt_item[cn].ns_mac) + + if(cfgptr == nil) { + continue + } + + /* Calculation for Signal Quality as per DCD stats */ + var changed bool + var clt_sq [AH_SQ_TYPE_MAX][AH_SQ_GROUP_MAX]ah_signal_quality_stats + changed = false + + if(t.last_sq[client_mac] == nil) { + t.last_sq[client_mac] = make(map[int]map[int]ah_signal_quality_stats) + + for i := 0; i < AH_SQ_TYPE_MAX; i++ { + for j := 0; j < AH_SQ_GROUP_MAX; j++ { + clt_sq[i][j].asqrange.min = clt_item[cn].ns_sq_group[i][j].asqrange.min + clt_sq[i][j].asqrange.max = clt_item[cn].ns_sq_group[i][j].asqrange.max + clt_sq[i][j].count = clt_item[cn].ns_sq_group[i][j].count + } + } + + } else { + + for i := 0; i < AH_SQ_TYPE_MAX; i++ { + for j := 0; j < AH_SQ_GROUP_MAX; j++ { + if ((t.last_sq[client_mac][i][j].asqrange.min != clt_item[cn].ns_sq_group[i][j].asqrange.min) || + (t.last_sq[client_mac][i][j].asqrange.max != clt_item[cn].ns_sq_group[i][j].asqrange.max)) { + /* the range is changed, just reset snapshot */ + changed = true; + break; + } + } + } + + for i := 0; i < AH_SQ_TYPE_MAX; i++ { + for j := 0; j < AH_SQ_GROUP_MAX; j++ { + clt_sq[i][j].asqrange.min = clt_item[cn].ns_sq_group[i][j].asqrange.min + clt_sq[i][j].asqrange.max = clt_item[cn].ns_sq_group[i][j].asqrange.max + if (changed) { + clt_sq[i][j].count = clt_item[cn].ns_sq_group[i][j].count; + } else if (clt_item[cn].ns_sq_group[i][j].count > t.last_sq[client_mac][i][j].count) { + clt_sq[i][j].count = clt_item[cn].ns_sq_group[i][j].count - t.last_sq[client_mac][i][j].count; + } else { + clt_sq[i][j].count = 0; + } + } + } + + } + + for i := 0; i < AH_SQ_TYPE_MAX; i++ { + t.last_sq[client_mac][i] = make(map[int]ah_signal_quality_stats) + for j := 0; j < AH_SQ_GROUP_MAX; j++ { + t.last_sq[client_mac][i][j] = clt_item[cn].ns_sq_group[i][j] + } + } + + /* Calculation for Signal Quality as per DCD stats end */ + + var onesta *ieee80211req_sta_info = (*ieee80211req_sta_info)(cfgptr) + + var clt_last_stats *saved_stats = (*saved_stats)(t.entity[intfName2][client_mac]) + +/* + if (clt_last_stats != nil) { + clt_last_stats.tx_airtime_min = ((clt_last_stats.tx_airtime_min /10) / (60 *1000)) + clt_last_stats.tx_airtime_max = ((clt_last_stats.tx_airtime_max /10) / (60 *1000)) + clt_last_stats.tx_airtime_average = ((clt_last_stats.tx_airtime_average /10) / (60 *1000)) + + clt_last_stats.rx_airtime_min = ((clt_last_stats.rx_airtime_min /10) / (60 *1000)) + clt_last_stats.rx_airtime_max = ((clt_last_stats.rx_airtime_max /10) / (60 *1000)) + clt_last_stats.rx_airtime_average = ((clt_last_stats.rx_airtime_average /10) / (60 *1000)) + + if (clt_last_stats.tx_airtime_min > 100) { + clt_last_stats.tx_airtime_min = 100 + } + + if (clt_last_stats.tx_airtime_max > 100) { + clt_last_stats.tx_airtime_max = 100 + } + + if (clt_last_stats.tx_airtime_average > 100) { + clt_last_stats.tx_airtime_average = 100 + } + + if (clt_last_stats.rx_airtime_min > 100) { + clt_last_stats.rx_airtime_min = 100 + } + + if (clt_last_stats.rx_airtime_max > 100) { + clt_last_stats.rx_airtime_max = 100 + } + + if (clt_last_stats.rx_airtime_average > 100) { + clt_last_stats.rx_airtime_average = 100 + } + } +*/ + + /* We need check and aggregation Tx/Rx bit rate distribution + * prcentage, if the bit rate equal in radio interface or client reporting. + */ + + for i := 0; i < NS_HW_RATE_SIZE; i++{ + + if ((clt_item[cn].ns_rx_rate_stats[i].ns_rateKbps == 0) && (clt_item[cn].ns_tx_rate_stats[i].ns_rateKbps == 0)) { + continue + } + + for j := (i+1); j < NS_HW_RATE_SIZE; j++ { + if ((clt_item[cn].ns_rx_rate_stats[i].ns_rateKbps != 0) && (clt_item[cn].ns_rx_rate_stats[i].ns_rateKbps == clt_item[cn].ns_rx_rate_stats[j].ns_rateKbps)) { + clt_item[cn].ns_rx_rate_stats[i].ns_unicasts += clt_item[cn].ns_rx_rate_stats[j].ns_unicasts; + clt_item[cn].ns_rx_rate_stats[i].ns_retries += clt_item[cn].ns_rx_rate_stats[j].ns_retries; + clt_item[cn].ns_rx_rate_stats[j].ns_rateKbps = 0; + clt_item[cn].ns_rx_rate_stats[j].ns_unicasts = 0; + clt_item[cn].ns_rx_rate_stats[j].ns_retries = 0; + } + if ((clt_item[cn].ns_tx_rate_stats[i].ns_rateKbps != 0) && (clt_item[cn].ns_tx_rate_stats[i].ns_rateKbps == clt_item[cn].ns_tx_rate_stats[j].ns_rateKbps)) { + clt_item[cn].ns_tx_rate_stats[i].ns_unicasts += clt_item[cn].ns_tx_rate_stats[j].ns_unicasts; + clt_item[cn].ns_tx_rate_stats[i].ns_retries += clt_item[cn].ns_tx_rate_stats[j].ns_retries; + clt_item[cn].ns_tx_rate_stats[j].ns_rateKbps = 0; + clt_item[cn].ns_tx_rate_stats[j].ns_unicasts = 0; + clt_item[cn].ns_tx_rate_stats[j].ns_retries = 0; + } + } + } + + /* Rate stat from DCD */ + for idx = 0; idx < NS_HW_RATE_SIZE; idx++ { + if ( clt_item[cn].ns_tx_rate_stats[idx].ns_unicasts > t.last_clt_stat[ii][cn].ns_tx_rate_stats[idx].ns_unicasts) { + tx_total += int64(clt_item[cn].ns_tx_rate_stats[idx].ns_unicasts - t.last_clt_stat[ii][cn].ns_tx_rate_stats[idx].ns_unicasts) + } + + if (clt_item[cn].ns_rx_rate_stats[idx].ns_unicasts > t.last_clt_stat[ii][cn].ns_rx_rate_stats[idx].ns_unicasts) { + rx_total += int64(clt_item[cn].ns_rx_rate_stats[idx].ns_unicasts - t.last_clt_stat[ii][cn].ns_rx_rate_stats[idx].ns_unicasts) + } + + if (clt_item[cn].ns_tx_rate_stats[idx].ns_retries > t.last_clt_stat[ii][cn].ns_tx_rate_stats[idx].ns_retries) { + tot_tx_bitrate_retries += clt_item[cn].ns_tx_rate_stats[idx].ns_retries - t.last_clt_stat[ii][cn].ns_tx_rate_stats[idx].ns_retries; + } + + if (clt_item[cn].ns_rx_rate_stats[idx].ns_retries > t.last_clt_stat[ii][cn].ns_rx_rate_stats[idx].ns_retries) { + tot_rx_bitrate_retries += clt_item[cn].ns_rx_rate_stats[idx].ns_retries - t.last_clt_stat[ii][cn].ns_rx_rate_stats[idx].ns_retries; + } + } + + tx_ok := tx_total + rx_ok := rx_total + + tot_unicasts := rx_ok + tx_ok + if tot_unicasts > 100 { + tot_unicasts /= 100 + } else { + tot_unicasts = 1 + } + /* Tx/Rx bit rate distribution */ + for idx = 0; idx < NS_HW_RATE_SIZE; idx++ { + tmp_count1 = int32(clt_item[cn].ns_tx_rate_stats[idx].ns_unicasts - t.last_clt_stat[ii][cn].ns_tx_rate_stats[idx].ns_unicasts) + if (tx_total > 0 && tmp_count1 > 0) { + rf_report.tx_bit_rate[idx].rate_dtn = uint8((int64(tmp_count1) * 100) / tx_total) + } else { + rf_report.tx_bit_rate[idx].rate_dtn = 0; + } + + tmp_count2 = int32(clt_item[cn].ns_rx_rate_stats[idx].ns_unicasts - t.last_clt_stat[ii][cn].ns_rx_rate_stats[idx].ns_unicasts) + if (rx_total > 0 && tmp_count2 > 0) { + rf_report.rx_bit_rate[idx].rate_dtn = uint8((int64(tmp_count2) * 100) / rx_total) + } else { + rf_report.rx_bit_rate[idx].rate_dtn = 0; + } + + /* Tx/Rx bit rate success distribution */ + tmp_count3 = uint32(clt_item[cn].ns_tx_rate_stats[idx].ns_retries - t.last_clt_stat[ii][cn].ns_tx_rate_stats[idx].ns_retries) + tmp_count5 = uint64(tmp_count1) + uint64(tmp_count3) + if (tmp_count5 > 0 && rf_report.tx_bit_rate[idx].rate_dtn > 0) { + rf_report.tx_bit_rate[idx].rate_suc_dtn = uint8((uint64(tmp_count1) * 100) / tmp_count5) + if (rf_report.tx_bit_rate[idx].rate_suc_dtn > 100) { + rf_report.tx_bit_rate[idx].rate_suc_dtn = 100 + log.Printf("stats report client data process: rate_suc_dtn1 is more than 100%\n") + } + } else { + rf_report.tx_bit_rate[idx].rate_suc_dtn = 0; + } + tx_retries += tmp_count3; + + tmp_count4 = clt_item[cn].ns_rx_rate_stats[idx].ns_retries - t.last_clt_stat[ii][cn].ns_rx_rate_stats[idx].ns_retries + tmp_count6 = uint64(tmp_count2) + uint64(tmp_count4) + if (tmp_count6 > 0 && rf_report.rx_bit_rate[idx].rate_dtn > 0) { + rf_report.rx_bit_rate[idx].rate_suc_dtn = uint8((uint64(tmp_count2) * 100) / tmp_count6) + if (rf_report.rx_bit_rate[idx].rate_suc_dtn > 100) { + rf_report.rx_bit_rate[idx].rate_suc_dtn = 100 + log.Printf("stats report client data process: rate_suc_dtn2 is more than 100%\n") + } + } else { + rf_report.rx_bit_rate[idx].rate_suc_dtn = 0 + } + + rf_report.tx_bit_rate[idx].kbps = clt_item[cn].ns_tx_rate_stats[idx].ns_rateKbps + rf_report.rx_bit_rate[idx].kbps = clt_item[cn].ns_rx_rate_stats[idx].ns_rateKbps + } + /* Rate stat from DCD */ + + for i := 0; i < NS_HW_RATE_SIZE; i++ { + if clt_item[cn].ns_rx_rate_stats[i].ns_unicasts != 0 || clt_item[cn].ns_tx_rate_stats[i].ns_unicasts != 0 { + if clt_item[cn].ns_tx_rate_stats[i].ns_unicasts >= t.last_clt_stat[ii][cn].ns_tx_rate_stats[i].ns_unicasts || + clt_item[cn].ns_rx_rate_stats[i].ns_unicasts >= t.last_clt_stat[ii][cn].ns_rx_rate_stats[i].ns_unicasts { + tot_rx_tx = (clt_item[cn].ns_tx_rate_stats[i].ns_unicasts + clt_item[cn].ns_rx_rate_stats[i].ns_unicasts + + clt_item[cn].ns_rx_rate_stats[i].ns_retries + clt_item[cn].ns_tx_rate_stats[i].ns_retries) - + (t.last_clt_stat[ii][cn].ns_tx_rate_stats[i].ns_unicasts + + t.last_clt_stat[ii][cn].ns_rx_rate_stats[i].ns_unicasts + + t.last_clt_stat[ii][cn].ns_rx_rate_stats[i].ns_retries + + t.last_clt_stat[ii][cn].ns_tx_rate_stats[i].ns_retries) + } else { + tot_rx_tx = 0 + } + tot_rate_frame += tot_rx_tx + + if tot_rx_tx > 100 { + tot_rx_tx /= 100 + } else { + tot_rx_tx = 1 + } + success_count := (clt_item[cn].ns_rx_rate_stats[i].ns_unicasts + clt_item[cn].ns_tx_rate_stats[i].ns_unicasts) - + (t.last_clt_stat[ii][cn].ns_rx_rate_stats[i].ns_unicasts + t.last_clt_stat[ii][cn].ns_tx_rate_stats[i].ns_unicasts) + success := success_count / tot_rx_tx + + if tot_unicasts != 0 { + tot_pcnt = int64(success_count) / tot_unicasts + } + + rate_score := (clt_item[cn].ns_tx_rate_stats[i].ns_rateKbps) / 1000 + conn_score = (int64(rate_score) * int64(success) * tot_pcnt) + } + } + var rssi int + var radio_link_score int64 + if (stainfo != nil) { + rssi = int(stainfo.rssi) + int(stainfo.noise_floor) + } else { + rssi = 0 + } + var tmp_count1 int64 + if tot_rate_frame > (600 * 20) { + if clt_item[cn].ns_sla_bm_score > 0 { + tmp_count1 = (50 * conn_score) / int64(clt_item[cn].ns_sla_bm_score) + if tmp_count1 > AH_DCD_CLT_SCORE_GOOD { + radio_link_score = AH_DCD_CLT_SCORE_GOOD + fmt.Println("radio link score is more than 100") + } else { + radio_link_score = tmp_count1 + } + } else { + radio_link_score = AH_DCD_CLT_SCORE_GOOD + } + } else { + if rssi <= -85 { + radio_link_score = AH_DCD_CLT_SCORE_POOR + } else if rssi < -70 { + radio_link_score = AH_DCD_CLT_SCORE_ACCEPTABLE + } else { + radio_link_score = AH_DCD_CLT_SCORE_GOOD + } + } + t.last_clt_stat[ii][cn] = clt_item[cn] + + var rt_sta *rt_sta_data + rt_sta = get_rt_sta_info(t, client_mac) + + fields2["ifname"] = intfName2 + fields2["ifIndex"] = ifindex2 + + fields2["mac_keys"] = client_mac + + fields2["number"] = cltstat.count + fields2["ssid"] = client_ssid + fields2["txPackets"] = stainfo.tx_pkts + fields2["txBytes"] = stainfo.tx_bytes + fields2["txDrop"] = clt_item[cn].ns_tx_drops + fields2["slaDrop"] = clt_item[cn].ns_sla_traps + fields2["rxPackets"] = stainfo.rx_pkts + fields2["rxBytes"] = stainfo.rx_bytes + fields2["rxDrop"] = clt_item[cn].ns_tx_drops + fields2["avgSnr"] = clt_item[cn].ns_snr + fields2["psTimes"] = clt_item[cn].ns_ps_times + fields2["radioScore"] = radio_link_score + fields2["ipNetScore"] = ipnet_score + if ipnet_score == 0 { + fields2["appScore"] = ipnet_score + } else { + fields2["appScore"] = clt_item[cn].ns_app_health_score + } + fields2["phyMode"] = getMacProtoMode(onesta.isi_phymode) + if(stainfo != nil) { + fields2["rssi"] = int(stainfo.rssi) + int(stainfo.noise_floor) + } else { + fields2["rssi"] = 0 + } + fields2["os"] = rt_sta.os + fields2["name"] = string(onesta.isi_name[:]) + fields2["host"] = rt_sta.hostname + fields2["profName"] = "default-profile" /* TBD (Needs shared memory of dcd) */ + fields2["dhcpIp"] = intToIp(sta_ip.dhcp_server) + fields2["gwIp"] = intToIp(sta_ip.gateway) + fields2["dnsIp"] = intToIp(sta_ip.dns[0].dns_ip) + fields2["clientIp"] = intToIp(sta_ip.client_static_ip) + fields2["dhcpTime"] = sta_ip.dhcp_time + fields2["gwTime"] = 0 /* TBD (Needs shared memory of auth2) */ + fields2["dnsTime"] = sta_ip.dns[0].dns_response_time + fields2["clientTime"] = onesta.isi_assoc_time + + + for i := 0; i < AH_TX_NSS_MAX; i++{ + txNssUsage := fmt.Sprintf("txNssUsage_%d",i) + fields2[txNssUsage] = clt_item[cn].ns_tx_nss[i] + } + + + + for i := 0; i < NS_HW_RATE_SIZE; i++{ + kbps := fmt.Sprintf("kbps_%d_rxRateStats",i) + rateDtn := fmt.Sprintf("rateDtn_%d_rxRateStats",i) + rateSucDtn := fmt.Sprintf("rateSucDtn_%d_rxRateStats",i) + fields2[kbps] = rf_report.rx_bit_rate[i].kbps + fields2[rateDtn] = rf_report.rx_bit_rate[i].rate_dtn + fields2[rateSucDtn] = rf_report.rx_bit_rate[i].rate_suc_dtn + } + + + for i := 0; i < NS_HW_RATE_SIZE; i++{ + kbps := fmt.Sprintf("kbps_%d_txRateStats",i) + rateDtn := fmt.Sprintf("rateDtn_%d_txRateStats",i) + rateSucDtn := fmt.Sprintf("rateSucDtn_%d_txRateStats",i) + fields2[kbps] = rf_report.tx_bit_rate[i].kbps + fields2[rateDtn] = rf_report.tx_bit_rate[i].rate_dtn + fields2[rateSucDtn] = rf_report.tx_bit_rate[i].rate_suc_dtn + } + + if (clt_last_stats != nil) { + fields2["txAirtime_min"] = clt_last_stats.tx_airtime_min + fields2["txAirtime_max"] = clt_last_stats.tx_airtime_max + fields2["txAirtime_avg"] = clt_last_stats.tx_airtime_average + + fields2["rxAirtime_min"] = clt_last_stats.rx_airtime_min + fields2["rxAirtime_max"] = clt_last_stats.rx_airtime_max + fields2["rxAirtime_avg"] = clt_last_stats.rx_airtime_average + + fields2["bwUsage_min"] = clt_last_stats.bw_usage_min + fields2["bwUsage_max"] = clt_last_stats.bw_usage_max + fields2["bwUsage_avg"] = clt_last_stats.bw_usage_average + } + + for i := 0; i < AH_SQ_GROUP_MAX; i++{ + rangeMin := fmt.Sprintf("rangeMin_%d_sqRssi",i) + rangeMax := fmt.Sprintf("rangeMax_%d_sqRssi",i) + countt := fmt.Sprintf("count_%d_sqRssi",i) + fields2[rangeMin] = clt_sq[0][i].asqrange.min + fields2[rangeMax] = clt_sq[0][i].asqrange.max + fields2[countt] = clt_sq[0][i].count + } + + for i := 0; i < AH_SQ_GROUP_MAX; i++{ + rangeMin := fmt.Sprintf("rangeMin_%d_sqNoise",i) + rangeMax := fmt.Sprintf("rangeMax_%d_sqNoise",i) + countt := fmt.Sprintf("count_%d_sqNoise",i) + fields2[rangeMin] = clt_sq[1][i].asqrange.min + fields2[rangeMax] = clt_sq[1][i].asqrange.max + fields2[countt] = clt_sq[1][i].count + } + + for i := 0; i < AH_SQ_GROUP_MAX; i++{ + rangeMin := fmt.Sprintf("rangeMin_%d_sqSnr",i) + rangeMax := fmt.Sprintf("rangeMax_%d_sqSnr",i) + countt := fmt.Sprintf("count_%d_sqSnr",i) + fields2[rangeMin] = clt_sq[2][i].asqrange.min + fields2[rangeMax] = clt_sq[2][i].asqrange.max + fields2[countt] = clt_sq[2][i].count + } + + acc.AddFields("ClientStats", fields2, tags, time.Now()) + + + clt_new_stats := saved_stats{} + clt_new_stats.tx_airtime = clt_item[cn].ns_tx_airtime + clt_new_stats.rx_airtime = clt_item[cn].ns_rx_airtime + t.entity[intfName2][client_mac] = unsafe.Pointer(&clt_new_stats) + + + var s string + + s = "Stats of client [" + client_mac + "]\n\n" + + for k, v := range fields2 { + if fmt.Sprint(v) == "0" { // Check if the value is zero + delete(fields2, k) + } + } + + keys := make([]string, 0, len(fields2)) + + for k := range fields2{ + keys = append(keys, k) + } + + sort.Strings(keys) + + for _, k := range keys { + s = s + k + " : " + fmt.Sprint(fields2[k]) + "\n" + } + + s = s + "---------------------------------------------------------------------------------------------\n" + + + dumpOutput(CLT_STAT_OUT_FILE, s, 1) + + } + ii++ + + } + + log.Printf("ah_wireless_v2: client status is processed") + + return nil +} + +func Gather_AirTime(t *Ah_wireless, acc telegraf.Accumulator) error { + + for _, intfName2 := range t.Ifname { + + var numassoc1 int + var client_mac1 string + + numassoc1 = int(getNumAssocs(t.fd, intfName2)) + + if(numassoc1 == 0) { + continue + } + + + clt_item := make([]ah_ieee80211_sta_stats_item, numassoc1) + + getStaStat(t.fd, intfName2, unsafe.Pointer(&clt_item[0]), numassoc1) + + for cn := 0; cn < numassoc1; cn++ { + + if(clt_item[cn].ns_mac[0] !=0 || clt_item[cn].ns_mac[1] !=0 || clt_item[cn].ns_mac[2] !=0 || clt_item[cn].ns_mac[3] !=0 || clt_item[cn].ns_mac[4] != 0 || clt_item[cn].ns_mac[5]!=0) { + + client_mac1 = fmt.Sprintf("%02x:%02x:%02x:%02x:%02x:%02x",clt_item[cn].ns_mac[0],clt_item[cn].ns_mac[1],clt_item[cn].ns_mac[2],clt_item[cn].ns_mac[3],clt_item[cn].ns_mac[4],clt_item[cn].ns_mac[5]) + } else { + + continue + } + + var clt_last_stats *saved_stats = (*saved_stats)(t.entity[intfName2][client_mac1]) + + if(clt_last_stats == nil) { + clt_new_stats := saved_stats{ + tx_airtime_min:0, + tx_airtime_max:0, + tx_airtime_average:0, + rx_airtime_min:0, + rx_airtime_max:0, + rx_airtime_average:0, + bw_usage_min:0, + bw_usage_max:0, + bw_usage_average:0, + tx_airtime:0, + rx_airtime:0} + t.entity[intfName2][client_mac1] = unsafe.Pointer(&clt_new_stats) + return nil + } + + clt_new_stats := saved_stats{} + + /* Calculate tx airtime min, max, average */ + + if ((clt_last_stats.tx_airtime_min > clt_item[cn].ns_tx_airtime) || (clt_last_stats.tx_airtime_min == 0) ) { + clt_new_stats.tx_airtime_min = clt_item[cn].ns_tx_airtime - clt_last_stats.tx_airtime + } else { + clt_new_stats.tx_airtime_min = clt_last_stats.tx_airtime_min + } + + if (clt_last_stats.tx_airtime_max < clt_item[cn].ns_tx_airtime ) { + clt_new_stats.tx_airtime_max = clt_item[cn].ns_tx_airtime - clt_last_stats.tx_airtime + } else { + clt_new_stats.tx_airtime_max = clt_last_stats.tx_airtime_max + } + + clt_new_stats.tx_airtime_average = ((clt_last_stats.tx_airtime_average + clt_new_stats.tx_airtime_min + clt_new_stats.tx_airtime_max)/3) + + /* Calculate rx airtime min, max, average */ + + if ((clt_last_stats.rx_airtime_min > clt_item[cn].ns_rx_airtime) || (clt_last_stats.rx_airtime_min == 0) ) { + clt_new_stats.rx_airtime_min = clt_item[cn].ns_rx_airtime - clt_last_stats.rx_airtime + } else { + clt_new_stats.rx_airtime_min = clt_last_stats.rx_airtime_min + } + + if (clt_last_stats.rx_airtime_max < clt_item[cn].ns_rx_airtime ) { + clt_new_stats.rx_airtime_max = clt_item[cn].ns_rx_airtime - clt_last_stats.rx_airtime + } else { + clt_new_stats.rx_airtime_max = clt_last_stats.rx_airtime_max + } + + clt_new_stats.rx_airtime_average = ((clt_last_stats.rx_airtime_average + clt_new_stats.rx_airtime_min + clt_new_stats.rx_airtime_max)/3) + + /* Calculate bandwidth usage min, max, average */ + + bw_usage := (((clt_item[cn].ns_tx_bytes + clt_item[cn].ns_rx_bytes) * 8) / (60)) / 1000; + + if ((clt_last_stats.bw_usage_min > bw_usage) || (clt_last_stats.bw_usage_min == 0)) { + clt_new_stats.bw_usage_min = bw_usage + } else { + clt_new_stats.bw_usage_min = clt_last_stats.bw_usage_min + } + + if (clt_last_stats.bw_usage_max < bw_usage) { + clt_new_stats.bw_usage_max = bw_usage + } else { + clt_new_stats.bw_usage_max = clt_last_stats.bw_usage_max + } + + clt_new_stats.tx_airtime = clt_last_stats.tx_airtime + clt_new_stats.rx_airtime = clt_last_stats.rx_airtime + + clt_new_stats.bw_usage_average = ((clt_last_stats.bw_usage_average + clt_new_stats.bw_usage_min + clt_new_stats.bw_usage_max)/3) + t.entity[intfName2][client_mac1] = unsafe.Pointer(&clt_new_stats) + } + + } + + return nil +} + +func (t *Ah_wireless) Gather(acc telegraf.Accumulator) error { + if t.timer_count == 9 { + dumpOutput(RF_STAT_OUT_FILE, "RF Stat Input Plugin Output", 0) + dumpOutput(CLT_STAT_OUT_FILE, "Client Stat Input Plugin Output", 0) + for _, intfName := range t.Ifname { + t.intf_m[intfName] = make(map[string]string) + load_ssid(t, intfName) + } + Gather_Client_Stat(t, acc) + Gather_Rf_Stat(t, acc) + t.timer_count = 0 + + t.last_rf_stat = [4]awestats{} + t.last_ut_data = [4]utilization_data{} + t.last_clt_stat = [4][50]ah_ieee80211_sta_stats_item{} + + } else { + Gather_AirTime(t,acc) + Gather_Rf_Avg(t,acc) + t.timer_count++ + } + + return nil +} + + + +func (t *Ah_wireless) Start(acc telegraf.Accumulator) error { + t.intf_m = make(map[string]map[string]string) + t.entity = make(map[string]map[string]unsafe.Pointer) + t.last_sq = make(map[string]map[int]map[int]ah_signal_quality_stats) + + for _, intfName := range t.Ifname { + t.entity[intfName] = make(map[string]unsafe.Pointer) +// load_ssid(t, intfName) + } + return nil +} + +func init_fe() *os.File { + file, err := os.Open(AH_FE_DEV_NAME) + if err != nil { + log.Printf("Error opening file:", err) + return nil + } + + // Get the current flags + flags, err := unix.FcntlInt(file.Fd(), syscall.F_GETFD, 0) + if err != nil { + log.Printf("Error getting flags:", err) + return nil + } + + flags |= unix.FD_CLOEXEC + + // Set the close-on-exec flag + _, err = unix.FcntlInt(file.Fd(), syscall.F_SETFD, flags) + if err != nil { + log.Printf("Error setting flags:", err) + return nil + } + return file +} + + +func (t *Ah_wireless) Stop() { + unix.Close(t.fd) +} + + +func init() { + inputs.Add("ah_wireless_v2", func() telegraf.Input { + return NewAh_wireless(1) + }) +} diff --git a/plugins/inputs/all/all.go b/plugins/inputs/all/all.go index cde549b52ce3e..483c249140dab 100644 --- a/plugins/inputs/all/all.go +++ b/plugins/inputs/all/all.go @@ -209,4 +209,5 @@ import ( // _ "github.com/influxdata/telegraf/plugins/inputs/zipkin" // _ "github.com/influxdata/telegraf/plugins/inputs/zookeeper" // _ "github.com/influxdata/telegraf/plugins/inputs/ah_wireless" +// _ "github.com/influxdata/telegraf/plugins/inputs/ah_wireless_v2" )