/*
 * Portions of this code are derived from iw-3.17.
 *
 * Copyright (c) 2007, 2008 Johannes Berg
 * Copyright (c) 2007   Andy Lutomirski
 * Copyright (c) 2007   Mike Kershaw
 * Copyright (c) 2008-2009    Luis R. Rodriguez
 * Copyright (c) 2015   Google, Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <glib.h>
#include <inttypes.h>
#include <limits.h>
#include <linux/if_ether.h>
#include <linux/nl80211.h>
#include <math.h>
#include <net/if.h>
#include <netlink/attr.h>
#include <netlink/genl/genl.h>
#include <netlink/genl/ctrl.h>
#include <netlink/msg.h>
#include <netlink/netlink.h>
#include <netlink/socket.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/resource.h>
#include <sys/select.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>


#ifndef UNIT_TESTS
#define STATIONS_DIR "/tmp/stations"
#define WIFIINFO_DIR "/tmp/wifi/wifiinfo"
#endif


// Hash table of known Wifi clients.
GHashTable *clients = NULL;
#define MAX_CLIENT_AGE_SECS  (4 * 60 * 60)


#ifndef UNIT_TESTS
static time_t monotime(void) {
  struct timespec ts;
  if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0) {
    return time(NULL);
  } else {
    return ts.tv_sec;
  }
}
#endif


/*
 * Saved state for each associated Wifi device. Wifi clients drop out
 * after 5 minutes inactive, we want to export information about the
 * client for a while longer than that.
 */
typedef struct client_state {
  #define MAC_STR_LEN 18
  char macstr[MAC_STR_LEN];
  #define IFNAME_STR_LEN 16
  char ifname[IFNAME_STR_LEN];

  double inactive_since;

  uint64_t rx_drop64;

  // Accumulated values from the 32 bit counters.
  uint64_t rx_bytes64;
  uint64_t tx_bytes64;
  uint64_t rx_packets64;
  uint64_t tx_packets64;
  uint64_t tx_retries64;
  uint64_t tx_failed64;

  time_t first_seen;  // CLOCK_MONOTONIC
  time_t last_seen;  // CLOCK_MONOTONIC

  uint32_t inactive_msec;
  uint32_t connected_secs;

  uint32_t rx_bitrate;
  uint32_t rx_bytes;
  uint32_t rx_packets;

  uint32_t tx_bitrate;
  uint32_t tx_bytes;
  uint32_t tx_packets;
  uint32_t tx_retries;
  uint32_t tx_failed;
  uint32_t expected_mbps;

#define MAX_SAMPLE_INDEX 150
  int rx_sample_index;
  uint8_t rx_ht_mcs_samples[MAX_SAMPLE_INDEX];
  uint8_t rx_vht_mcs_samples[MAX_SAMPLE_INDEX];
  uint8_t rx_width_samples[MAX_SAMPLE_INDEX];
  uint8_t rx_ht_nss_samples[MAX_SAMPLE_INDEX];
  uint8_t rx_vht_nss_samples[MAX_SAMPLE_INDEX];
  uint8_t rx_short_gi_samples[MAX_SAMPLE_INDEX];

  int tx_sample_index;
  uint8_t tx_ht_mcs_samples[MAX_SAMPLE_INDEX];
  uint8_t tx_vht_mcs_samples[MAX_SAMPLE_INDEX];
  uint8_t tx_width_samples[MAX_SAMPLE_INDEX];
  uint8_t tx_ht_nss_samples[MAX_SAMPLE_INDEX];
  uint8_t tx_vht_nss_samples[MAX_SAMPLE_INDEX];
  uint8_t tx_short_gi_samples[MAX_SAMPLE_INDEX];

  /*
   * Clients spend a lot of time mostly idle, where they
   * are only sending management frames and ACKs. These
   * tend to be sent at much lower MCS rates than bulk data;
   * if we report that MCS rate it gives a misleading
   * picture of what the client is capable of getting.
   *
   * Instead, we choose the largest sample over the reporting
   * interval. This is more likely to report a meaningful
   * MCS rate.
   */
  uint8_t rx_ht_mcs;
  uint8_t rx_vht_mcs;
  uint8_t rx_width;
  uint8_t rx_ht_nss;
  uint8_t rx_vht_nss;
  uint8_t rx_short_gi;

  uint8_t tx_ht_mcs;
  uint8_t tx_vht_mcs;
  uint8_t tx_width;
  uint8_t tx_ht_nss;
  uint8_t tx_vht_nss;
  uint8_t tx_short_gi;

  /* Track the largest value we've ever seen from this client. This
   * shows client capabilities, even if current interference
   * conditions don't allow it to use its full capability. */
  uint8_t rx_max_ht_mcs;
  uint8_t rx_max_vht_mcs;
  uint8_t rx_max_width;
  uint8_t rx_max_ht_nss;
  uint8_t rx_max_vht_nss;
  uint8_t ever_rx_short_gi;

  uint8_t tx_max_ht_mcs;
  uint8_t tx_max_vht_mcs;
  uint8_t tx_max_width;
  uint8_t tx_max_ht_nss;
  uint8_t tx_max_vht_nss;
  uint8_t ever_tx_short_gi;

  int8_t signal;
  int8_t signal_avg;

  uint8_t authorized:1;
  uint8_t authenticated:1;
  uint8_t preamble:1;
  uint8_t wmm_wme:1;
  uint8_t mfp:1;
  uint8_t tdls_peer:1;
  uint8_t preamble_length:1;
} client_state_t;


typedef struct callback_data {
  time_t mono_now;
} callback_data_t;


/* List of wifi interfaces in the system. */
#define NINTERFACES 16
int ifindexes[NINTERFACES] = {0};
const char *interfaces[NINTERFACES] = {0};
int ninterfaces = 0;

/* FILE handle to /tmp/wifi/wifiinfo, while open. */
static FILE *wifi_info_handle = NULL;


static void ClearClientStateCounters(client_state_t *state)
{
  char macstr[MAC_STR_LEN];

  memcpy(macstr, state->macstr, sizeof(macstr));
  memset(state, 0, sizeof(*state));
  memcpy(state->macstr, macstr, sizeof(state->macstr));
}


static int GetIfIndex(const char *ifname)
{
  int fd;
  struct ifreq ifr;

  if (strlen(ifname) >= sizeof(ifr.ifr_name)) {
    fprintf(stderr, "interface name %s is too long\n", ifname);
    exit(1);
  }

  if ((fd = socket(AF_PACKET, SOCK_DGRAM, 0)) < 0) {
    perror("socket");
    exit(1);
  }

  memset(&ifr, 0, sizeof(ifr));
  snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", ifname);

  if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) {
    char errbuf[128];
    snprintf(errbuf, sizeof(errbuf), "SIOCGIFINDEX %s", ifname);
    perror(errbuf);
    close(fd);
    exit(1);
  }

  close(fd);
  return ifr.ifr_ifindex;
}  /* GetIfIndex */


static int InterfaceListCallback(struct nl_msg *msg, void *arg)
{
  struct nlattr *il[NL80211_ATTR_MAX + 1];
  struct genlmsghdr *gh = nlmsg_data(nlmsg_hdr(msg));

  nla_parse(il, NL80211_ATTR_MAX, genlmsg_attrdata(gh, 0),
      genlmsg_attrlen(gh, 0), NULL);

  if (il[NL80211_ATTR_IFNAME]) {
    const char *name = nla_get_string(il[NL80211_ATTR_IFNAME]);
    if (interfaces[ninterfaces] != NULL) {
      free((void *)interfaces[ninterfaces]);
    }
    interfaces[ninterfaces] = strdup(name);
    ifindexes[ninterfaces] = GetIfIndex(name);
    ninterfaces++;
  }

  return NL_OK;
}


static void HandleNLCommand(struct nl_sock *nlsk, int nl80211_id, int n,
                            int cb(struct nl_msg *, void *),
                            int cmd, int flag)
{
  struct nl_msg *msg;
  int ifindex = n >= 0 ? ifindexes[n] : -1;
  const char *ifname = n>=0 ? interfaces[n] : NULL;

  if (nl_socket_modify_cb(nlsk, NL_CB_VALID, NL_CB_CUSTOM,
                          cb, (void *)ifname)) {
    fprintf(stderr, "nl_socket_modify_cb failed\n");
    exit(1);
  }

  if ((msg = nlmsg_alloc()) == NULL) {
    fprintf(stderr, "nlmsg_alloc failed\n");
    exit(1);
  }
  if (genlmsg_put(msg, 0, 0, nl80211_id, 0, flag,
                  cmd, 0) == NULL) {
    fprintf(stderr, "genlmsg_put failed\n");
    exit(1);
  }

  if (ifindex >= 0 && nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex)) {
    fprintf(stderr, "NL80211_CMD_GET_STATION put IFINDEX failed\n");
    exit(1);
  }

  if (nl_send_auto(nlsk, msg) < 0) {
    fprintf(stderr, "nl_send_auto failed\n");
    exit(1);
  }
  nlmsg_free(msg);
}


void RequestInterfaceList(struct nl_sock *nlsk, int nl80211_id)
{
  HandleNLCommand(nlsk, nl80211_id, -1, InterfaceListCallback,
                  NL80211_CMD_GET_INTERFACE, NLM_F_DUMP);
}  /* RequestInterfaceList */


int NlFinish(struct nl_msg *msg, void *arg)
{
  int *ret = arg;
  *ret = 1;
  return NL_OK;
}


struct nl_sock *InitNetlinkSocket()
{
  struct nl_sock *nlsk;
  if ((nlsk = nl_socket_alloc()) == NULL) {
    fprintf(stderr, "socket allocation failed\n");
    exit(1);
  }

  if (genl_connect(nlsk) != 0) {
    fprintf(stderr, "genl_connect failed\n");
    exit(1);
  }

  if (nl_socket_set_nonblocking(nlsk)) {
    fprintf(stderr, "nl_socket_set_nonblocking failed\n");
    exit(1);
  }

  return nlsk;
}  /* InitNetlinkSocket */


static void ProcessNetlinkMessages(struct nl_sock *nlsk, int *done)
{
  for (;;) {
    int s = nl_socket_get_fd(nlsk);
    fd_set rfds;
    struct timeval timeout = { .tv_sec = 1, .tv_usec = 0 };

    FD_ZERO(&rfds);
    FD_SET(s, &rfds);

    if (select(s + 1, &rfds, NULL, NULL, &timeout) <= 0) {
      break;
    }

    if (FD_ISSET(s, &rfds)) {
      nl_recvmsgs_default(nlsk);
    }

    if (*done) {
      break;
    }
  }
}


static uint32_t GetBitrate(struct nlattr *attr)
{
  int rate = 0;
  struct nlattr *ri[NL80211_RATE_INFO_MAX + 1];
  static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = {
    [NL80211_RATE_INFO_BITRATE] = { .type = NLA_U16 },
  };

  if (nla_parse_nested(ri, NL80211_RATE_INFO_MAX, attr, rate_policy)) {
    fprintf(stderr, "nla_parse_nested NL80211_RATE_INFO_MAX failed");
    return 0;
  }

  if (ri[NL80211_RATE_INFO_BITRATE]) {
    rate = nla_get_u16(ri[NL80211_RATE_INFO_BITRATE]);
  }

  return rate;
}


static void GetMCS(struct nlattr *attr,
    int *mcs, int *vht_mcs, int *width, int *short_gi, int *vht_nss)
{
  int w160 = 0, w80_80 = 0, w80 = 0, w40 = 0;
  struct nlattr *ri[NL80211_RATE_INFO_MAX + 1];
  static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = {
    [NL80211_RATE_INFO_MCS] = { .type = NLA_U8 },
    [NL80211_RATE_INFO_VHT_MCS] = { .type = NLA_U8 },
    [NL80211_RATE_INFO_VHT_NSS] = { .type = NLA_U8 },
    [NL80211_RATE_INFO_40_MHZ_WIDTH] = { .type = NLA_FLAG },
    [NL80211_RATE_INFO_80_MHZ_WIDTH] = { .type = NLA_FLAG },
    [NL80211_RATE_INFO_80P80_MHZ_WIDTH] = { .type = NLA_FLAG },
    [NL80211_RATE_INFO_160_MHZ_WIDTH] = { .type = NLA_FLAG },
    [NL80211_RATE_INFO_SHORT_GI] = { .type = NLA_FLAG },
  };

  if (nla_parse_nested(ri, NL80211_RATE_INFO_MAX, attr, rate_policy)) {
    fprintf(stderr, "nla_parse_nested NL80211_RATE_INFO_MAX failed");
    return;
  }

  if (ri[NL80211_RATE_INFO_MCS]) {
    *mcs = nla_get_u8(ri[NL80211_RATE_INFO_MCS]);
  }
  if (ri[NL80211_RATE_INFO_VHT_MCS]) {
    *vht_mcs = nla_get_u8(ri[NL80211_RATE_INFO_VHT_MCS]);
  }
  if (ri[NL80211_RATE_INFO_VHT_NSS]) {
    *vht_nss = nla_get_u8(ri[NL80211_RATE_INFO_VHT_NSS]);
  }
  if (ri[NL80211_RATE_INFO_160_MHZ_WIDTH])   w160 = 1;
  if (ri[NL80211_RATE_INFO_80P80_MHZ_WIDTH]) w80_80 = 1;
  if (ri[NL80211_RATE_INFO_80_MHZ_WIDTH])    w80 = 1;
  if (ri[NL80211_RATE_INFO_40_MHZ_WIDTH])    w40 = 1;
  if (ri[NL80211_RATE_INFO_SHORT_GI])        *short_gi = 1;

  if (w160 || w80_80) {
    *width = 160;
  } else if (w80) {
    *width = 80;
  } else if (w40) {
    *width = 40;
  } else {
    *width = 20;
  }
}


static client_state_t *FindClientState(const uint8_t mac[6])
{
  client_state_t *s;
  char macstr[MAC_STR_LEN];

  snprintf(macstr, sizeof(macstr), "%02x:%02x:%02x:%02x:%02x:%02x",
      mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);

  /* Find any existing state for this STA, or allocate new. */
  if ((s = (client_state_t *)g_hash_table_lookup(clients, macstr)) == NULL) {
    s = (client_state_t *)malloc(sizeof(*s));
    memset(s, 0, sizeof(*s));
    memcpy(s->macstr, macstr, sizeof(s->macstr));
    s->first_seen = monotime();
    g_hash_table_insert(clients, strdup(macstr), s);
  }

  return s;
}


static int HtMcsToNss(int rxmcs)
{
  /* https://en.wikipedia.org/wiki/IEEE_802.11n-2009 */
  switch(rxmcs) {
    case 0 ... 7:   return 1;
    case 8 ... 15:  return 2;
    case 16 ... 23: return 3;
    case 24 ... 31: return 4;
    case 32:        return 1;
    case 33 ... 38: return 2;
    case 39 ... 52: return 3;
    case 53 ... 76: return 4;
    default:        return 0;
  }
}

static int StationDumpCallback(struct nl_msg *msg, void *arg)
{
  const char *ifname = (const char *)arg;
  struct genlmsghdr *gh = nlmsg_data(nlmsg_hdr(msg));
  struct nlattr *tb[NL80211_ATTR_MAX + 1] = {0};
  struct nlattr *si[NL80211_STA_INFO_MAX + 1] = {0};
  uint8_t *mac;
  client_state_t *state;
  static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
    [NL80211_STA_INFO_INACTIVE_TIME] = { .type = NLA_U32 },
    [NL80211_STA_INFO_RX_BITRATE] = { .type = NLA_NESTED },
    [NL80211_STA_INFO_RX_BYTES] = { .type = NLA_U32 },
    [NL80211_STA_INFO_RX_PACKETS] = { .type = NLA_U32 },
    [NL80211_STA_INFO_TX_BITRATE] = { .type = NLA_NESTED },
    [NL80211_STA_INFO_TX_BYTES] = { .type = NLA_U32 },
    [NL80211_STA_INFO_TX_PACKETS] = { .type = NLA_U32 },
    [NL80211_STA_INFO_TX_RETRIES] = { .type = NLA_U32 },
    [NL80211_STA_INFO_TX_FAILED] = { .type = NLA_U32 },
    [NL80211_STA_INFO_CONNECTED_TIME] = { .type = NLA_U32 },
    [NL80211_STA_INFO_SIGNAL] = { .type = NLA_U8 },
    [NL80211_STA_INFO_SIGNAL_AVG] = { .type = NLA_U8 },
    [NL80211_STA_INFO_STA_FLAGS] = {
      .minlen = sizeof(struct nl80211_sta_flag_update) },

#ifdef NL80211_RECENT_FIELDS
    [NL80211_STA_INFO_RX_DROP_MISC] = { .type = NLA_U64 },
    [NL80211_STA_INFO_EXPECTED_THROUGHPUT] = { .type = NLA_U32 },
#endif
  };

  if (nla_parse(tb, NL80211_ATTR_MAX,
                genlmsg_attrdata(gh, 0), genlmsg_attrlen(gh, 0), NULL)) {
    fprintf(stderr, "nla_parse failed.\n");
    return NL_SKIP;
  }

  if (!tb[NL80211_ATTR_STA_INFO]) {
    return NL_SKIP;
  }

  if (nla_parse_nested(si, NL80211_STA_INFO_MAX,
                       tb[NL80211_ATTR_STA_INFO],
                       stats_policy)) {
    fprintf(stderr, "nla_parse_nested failed\n");
    return NL_SKIP;
  }

  if (!tb[NL80211_ATTR_MAC]) {
    fprintf(stderr, "No NL80211_ATTR_MAC\n");
    return NL_SKIP;
  }

  mac = (uint8_t *)nla_data(tb[NL80211_ATTR_MAC]);
  state = FindClientState(mac);

  if (strcasecmp(state->ifname, ifname) != 0) {
    /* Client moved from one interface to another */
    ClearClientStateCounters(state);
  }

  state->last_seen = monotime();
  snprintf(state->ifname, sizeof(state->ifname), "%s", ifname);

  if (si[NL80211_STA_INFO_INACTIVE_TIME]) {
    uint32_t inactive_msec = nla_get_u32(si[NL80211_STA_INFO_INACTIVE_TIME]);
    double inactive_since = time(NULL) - ((double)inactive_msec / 1000.0);

    state->inactive_msec = inactive_msec;
    if ((fabs(inactive_since - state->inactive_since)) > 2.0) {
      state->inactive_since = inactive_since;
    }
  }

  if (si[NL80211_STA_INFO_RX_BITRATE]) {
    int rx_ht_mcs=0, rx_vht_mcs=0, rx_vht_nss=0, rx_width=0, rx_short_gi=0;
    int ht_nss;
    int n = state->rx_sample_index + 1;

    if (n >= MAX_SAMPLE_INDEX) n = 0;

    state->rx_bitrate = GetBitrate(si[NL80211_STA_INFO_RX_BITRATE]);
    GetMCS(si[NL80211_STA_INFO_RX_BITRATE], &rx_ht_mcs, &rx_vht_mcs,
        &rx_width, &rx_short_gi, &rx_vht_nss);

    state->rx_ht_mcs_samples[n] = rx_ht_mcs;
    if (rx_ht_mcs > state->rx_max_ht_mcs) state->rx_max_ht_mcs = rx_ht_mcs;

    ht_nss = HtMcsToNss(rx_ht_mcs);
    state->rx_ht_nss_samples[n] = ht_nss;
    if (ht_nss > state->rx_max_ht_nss) state->rx_max_ht_nss = ht_nss;

    state->rx_vht_mcs_samples[n] = rx_vht_mcs;
    if (rx_vht_mcs > state->rx_max_vht_mcs) state->rx_max_vht_mcs = rx_vht_mcs;

    state->rx_vht_nss_samples[n] = rx_vht_nss;
    if (rx_vht_nss > state->rx_max_vht_nss) state->rx_max_vht_nss = rx_vht_nss;

    state->rx_short_gi_samples[n] = rx_short_gi;
    if (rx_short_gi) state->ever_rx_short_gi = 1;

    state->rx_width_samples[n] = rx_width;
    if (rx_width > state->rx_max_width) state->rx_max_width = rx_width;

    state->rx_sample_index = n;
  }
  if (si[NL80211_STA_INFO_RX_BYTES]) {
    uint32_t last_rx_bytes = state->rx_bytes;
    state->rx_bytes = nla_get_u32(si[NL80211_STA_INFO_RX_BYTES]);
    state->rx_bytes64 += (state->rx_bytes - last_rx_bytes);
  }
  if (si[NL80211_STA_INFO_RX_PACKETS]) {
    uint32_t last_rx_packets = state->rx_packets;
    state->rx_packets = nla_get_u32(si[NL80211_STA_INFO_RX_PACKETS]);
    state->rx_packets64 += (state->rx_packets - last_rx_packets);
  }
  if (si[NL80211_STA_INFO_TX_BITRATE]) {
    int tx_ht_mcs=0, tx_vht_mcs=0, tx_vht_nss=0, tx_width=0, tx_short_gi=0;
    int ht_nss;
    int n = state->tx_sample_index + 1;

    if (n >= MAX_SAMPLE_INDEX) n = 0;

    state->tx_bitrate = GetBitrate(si[NL80211_STA_INFO_TX_BITRATE]);
    GetMCS(si[NL80211_STA_INFO_TX_BITRATE], &tx_ht_mcs, &tx_vht_mcs,
        &tx_width, &tx_short_gi, &tx_vht_nss);

    state->tx_ht_mcs_samples[n] = tx_ht_mcs;
    if (tx_ht_mcs > state->tx_max_ht_mcs) state->tx_max_ht_mcs = tx_ht_mcs;

    ht_nss = HtMcsToNss(tx_ht_mcs);
    state->tx_ht_nss_samples[n] = ht_nss;
    if (ht_nss > state->tx_max_ht_nss) state->tx_max_ht_nss = ht_nss;

    state->tx_vht_mcs_samples[n] = tx_vht_mcs;
    if (tx_vht_mcs > state->tx_max_vht_mcs) state->tx_max_vht_mcs = tx_vht_mcs;

    state->tx_vht_nss_samples[n] = tx_vht_nss;
    if (tx_vht_nss > state->tx_max_vht_nss) state->tx_max_vht_nss = tx_vht_nss;

    state->tx_short_gi_samples[n] = tx_short_gi;
    if (tx_short_gi) state->ever_tx_short_gi = 1;

    state->tx_width_samples[n] = tx_width;
    if (tx_width > state->tx_max_width) state->tx_max_width = tx_width;

    state->tx_sample_index = n;
  }
  if (si[NL80211_STA_INFO_TX_BYTES]) {
    uint32_t last_tx_bytes = state->tx_bytes;
    state->tx_bytes = nla_get_u32(si[NL80211_STA_INFO_TX_BYTES]);
    state->tx_bytes64 += (state->tx_bytes - last_tx_bytes);
  }
  if (si[NL80211_STA_INFO_TX_PACKETS]) {
    uint32_t last_tx_packets = state->tx_packets;
    state->tx_packets = nla_get_u32(si[NL80211_STA_INFO_TX_PACKETS]);
    state->tx_packets64 += (state->tx_packets - last_tx_packets);
  }
  if (si[NL80211_STA_INFO_TX_RETRIES]) {
    uint32_t last_tx_retries = state->tx_retries;
    state->tx_retries = nla_get_u32(si[NL80211_STA_INFO_TX_RETRIES]);
    state->tx_retries64 += (state->tx_retries - last_tx_retries);
  }
  if (si[NL80211_STA_INFO_TX_FAILED]) {
    uint32_t last_tx_failed = state->tx_failed;
    state->tx_failed = nla_get_u32(si[NL80211_STA_INFO_TX_FAILED]);
    state->tx_failed64 += (state->tx_failed - last_tx_failed);
  }
  if (si[NL80211_STA_INFO_CONNECTED_TIME]) {
    state->connected_secs = nla_get_u32(si[NL80211_STA_INFO_CONNECTED_TIME]);
  }
  if (si[NL80211_STA_INFO_SIGNAL]) {
    state->signal = (int8_t)nla_get_u8(si[NL80211_STA_INFO_SIGNAL]);
  }
  if (si[NL80211_STA_INFO_SIGNAL_AVG]) {
    state->signal_avg = (int8_t)nla_get_u8(si[NL80211_STA_INFO_SIGNAL_AVG]);
  }

  if (si[NL80211_STA_INFO_STA_FLAGS]) {
    struct nl80211_sta_flag_update *sta_flags;
    sta_flags = (struct nl80211_sta_flag_update *)nla_data(
        si[NL80211_STA_INFO_STA_FLAGS]);

    #define BIT(x) ((sta_flags->mask & (1ULL<<(x))) ? 1 : 0)
    state->authorized = BIT(NL80211_STA_FLAG_AUTHORIZED);
    state->authenticated = BIT(NL80211_STA_FLAG_AUTHENTICATED);
    state->preamble = BIT(NL80211_STA_FLAG_SHORT_PREAMBLE);
    state->wmm_wme = BIT(NL80211_STA_FLAG_WME);
    state->mfp = BIT(NL80211_STA_FLAG_MFP);
    state->tdls_peer = BIT(NL80211_STA_FLAG_TDLS_PEER);
    state->preamble_length = BIT(NL80211_STA_FLAG_SHORT_PREAMBLE);
    #undef BIT
  }

#ifdef NL80211_RECENT_FIELDS
  if (si[NL80211_STA_INFO_RX_DROP_MISC]) {
    state->rx_drop64 = nla_get_u64(si[NL80211_STA_INFO_RX_DROP_MISC]);
  }
  if (si[NL80211_STA_INFO_EXPECTED_THROUGHPUT]) {
    state->expected_mbps =
      nla_get_u32(si[NL80211_STA_INFO_EXPECTED_THROUGHPUT]);
  }
#endif

  return NL_OK;
}  /* StationDumpCallback */


void RequestAssociatedDevices(struct nl_sock *nlsk,
    int nl80211_id, int n)
{
  HandleNLCommand(nlsk, nl80211_id, n, StationDumpCallback,
                  NL80211_CMD_GET_STATION, NLM_F_DUMP);
}  /* RequestAssociatedDevices */


static void ClearClientCounters(client_state_t *state)
{
  /* Kernel cleared its counters when client re-joined the WLAN,
   * clear out previous state as well. */
  state->rx_bytes = 0;
  state->rx_packets = 0;
  state->tx_bytes = 0;
  state->tx_packets = 0;
  state->tx_retries = 0;
  state->tx_failed = 0;
}


static gboolean AgeOutClient(gpointer key, gpointer value, gpointer user_data)
{
  client_state_t *state = (client_state_t *)value;
  time_t mono_now = monotime();

  if ((mono_now - state->last_seen) > MAX_CLIENT_AGE_SECS) {
    char filename[PATH_MAX];
    snprintf(filename, sizeof(filename), "%s/%s", STATIONS_DIR, state->macstr);
    unlink(filename);
    return TRUE;
  }

  if (state->connected_secs < 60) {
    /* If the client recently dropped off and came back, clear any counters
     * we've been maintaining. */
    ClearClientCounters(state);
  }

  return FALSE;
}


static void ConsolidateClientSamples(gpointer key, gpointer value,
    gpointer user_data)
{
  client_state_t *state = (client_state_t *)value;
  int i;
  uint8_t rx_ht_mcs=0, rx_vht_mcs=0, rx_width=0, rx_ht_nss=0;
  uint8_t rx_vht_nss=0, rx_short_gi=0;
  uint8_t tx_ht_mcs=0, tx_vht_mcs=0, tx_width=0, tx_ht_nss=0;
  uint8_t tx_vht_nss=0, tx_short_gi=0;

  for (i = 0; i < MAX_SAMPLE_INDEX; ++i) {
    if (state->rx_ht_mcs_samples[i] > rx_ht_mcs) {
      rx_ht_mcs = state->rx_ht_mcs_samples[i];
    }
    if (state->rx_vht_mcs_samples[i] > rx_vht_mcs) {
      rx_vht_mcs = state->rx_vht_mcs_samples[i];
    }
    if (state->rx_width_samples[i] > rx_width) {
      rx_width = state->rx_width_samples[i];
    }
    if (state->rx_ht_nss_samples[i] > rx_ht_nss) {
      rx_ht_nss = state->rx_ht_nss_samples[i];
    }
    if (state->rx_vht_nss_samples[i] > rx_vht_nss) {
      rx_vht_nss = state->rx_vht_nss_samples[i];
    }
    if (state->rx_short_gi_samples[i] > rx_short_gi) {
      rx_short_gi = state->rx_short_gi_samples[i];
    }

    if (state->tx_ht_mcs_samples[i] > tx_ht_mcs) {
      tx_ht_mcs = state->tx_ht_mcs_samples[i];
    }
    if (state->tx_vht_mcs_samples[i] > tx_vht_mcs) {
      tx_vht_mcs = state->tx_vht_mcs_samples[i];
    }
    if (state->tx_width_samples[i] > tx_width) {
      tx_width = state->tx_width_samples[i];
    }
    if (state->tx_ht_nss_samples[i] > tx_ht_nss) {
      tx_ht_nss = state->tx_ht_nss_samples[i];
    }
    if (state->tx_vht_nss_samples[i] > tx_vht_nss) {
      tx_vht_nss = state->tx_vht_nss_samples[i];
    }
    if (state->tx_short_gi_samples[i] > tx_short_gi) {
      tx_short_gi = state->tx_short_gi_samples[i];
    }
  }

  state->rx_ht_mcs = rx_ht_mcs;
  state->rx_vht_mcs = rx_vht_mcs;
  state->rx_width = rx_width;
  state->rx_ht_nss = rx_ht_nss;
  state->rx_vht_nss = rx_vht_nss;
  state->rx_short_gi = rx_short_gi;

  state->tx_ht_mcs = tx_ht_mcs;
  state->tx_vht_mcs = tx_vht_mcs;
  state->tx_width = tx_width;
  state->tx_ht_nss = tx_ht_nss;
  state->tx_vht_nss = tx_vht_nss;
  state->tx_short_gi = tx_short_gi;
}


static void ClientStateToJson(gpointer key, gpointer value, gpointer user_data)
{
  const client_state_t *state = (const client_state_t *)value;
  char tmpfile[PATH_MAX];
  char filename[PATH_MAX];
  time_t mono_now = monotime();
  FILE *f;

  snprintf(tmpfile, sizeof(tmpfile), "%s/%s.new", STATIONS_DIR, state->macstr);
  snprintf(filename, sizeof(filename), "%s/%s", STATIONS_DIR, state->macstr);

  if ((f = fopen(tmpfile, "w+")) == NULL) {
    char errbuf[80];
    snprintf(errbuf, sizeof(errbuf), "fopen %s", tmpfile);
    perror(errbuf);
    return;
  }

  fprintf(f, "{\n");

  fprintf(f, "  \"addr\": \"%s\",\n", state->macstr);
  fprintf(f, "  \"inactive since\": %.3f,\n", state->inactive_since);
  fprintf(f, "  \"inactive msec\": %u,\n", state->inactive_msec);

  fprintf(f, "  \"active\": %s,\n",
      ((mono_now - state->last_seen) < 600) ? "true" : "false");

  fprintf(f, "  \"rx bitrate\": %u.%u,\n",
      (state->rx_bitrate / 10), (state->rx_bitrate % 10));
  fprintf(f, "  \"rx bytes\": %u,\n", state->rx_bytes);
  fprintf(f, "  \"rx packets\": %u,\n", state->rx_packets);

  fprintf(f, "  \"tx bitrate\": %u.%u,\n",
      (state->tx_bitrate / 10), (state->tx_bitrate % 10));
  fprintf(f, "  \"tx bytes\": %u,\n", state->tx_bytes);
  fprintf(f, "  \"tx packets\": %u,\n", state->tx_packets);
  fprintf(f, "  \"tx retries\": %u,\n", state->tx_retries);
  fprintf(f, "  \"tx failed\": %u,\n", state->tx_failed);

  fprintf(f, "  \"rx mcs\": %u,\n", state->rx_ht_mcs);
  fprintf(f, "  \"rx max mcs\": %u,\n", state->rx_max_ht_mcs);
  fprintf(f, "  \"rx vht mcs\": %u,\n", state->rx_vht_mcs);
  fprintf(f, "  \"rx max vht mcs\": %u,\n", state->rx_max_vht_mcs);
  fprintf(f, "  \"rx width\": %u,\n", state->rx_width);
  fprintf(f, "  \"rx max width\": %u,\n", state->rx_max_width);
  fprintf(f, "  \"rx ht_nss\": %u,\n", state->rx_ht_nss);
  fprintf(f, "  \"rx max ht_nss\": %u,\n", state->rx_max_ht_nss);
  fprintf(f, "  \"rx vht_nss\": %u,\n", state->rx_vht_nss);
  fprintf(f, "  \"rx max vht_nss\": %u,\n", state->rx_max_vht_nss);

  #define BOOL(x) (x ? "true" : "false")
  fprintf(f, "  \"rx SHORT_GI\": %s,\n", BOOL(state->rx_short_gi));
  fprintf(f, "  \"rx SHORT_GI seen\": %s,\n", BOOL(state->ever_rx_short_gi));
  #undef BOOL

  fprintf(f, "  \"signal\": %hhd,\n", state->signal);
  fprintf(f, "  \"signal_avg\": %hhd,\n", state->signal_avg);

  #define BOOL(x) (x ? "yes" : "no")
  fprintf(f, "  \"authorized\": \"%s\",\n", BOOL(state->authorized));
  fprintf(f, "  \"authenticated\": \"%s\",\n", BOOL(state->authenticated));
  fprintf(f, "  \"preamble\": \"%s\",\n", BOOL(state->preamble));
  fprintf(f, "  \"wmm_wme\": \"%s\",\n", BOOL(state->wmm_wme));
  fprintf(f, "  \"mfp\": \"%s\",\n", BOOL(state->mfp));
  fprintf(f, "  \"tdls_peer\": \"%s\",\n", BOOL(state->tdls_peer));
  #undef BOOL

  fprintf(f, "  \"preamble length\": \"%s\",\n",
      (state->preamble_length ? "short" : "long"));

  fprintf(f, "  \"rx bytes64\": %" PRIu64 ",\n", state->rx_bytes64);
  fprintf(f, "  \"rx drop64\": %" PRIu64 ",\n", state->rx_drop64);
  fprintf(f, "  \"tx bytes64\": %" PRIu64 ",\n", state->tx_bytes64);
  fprintf(f, "  \"tx retries64\": %" PRIu64 ",\n", state->tx_retries64);
  fprintf(f, "  \"expected Mbps\": %u.%03u,\n",
          (state->expected_mbps / 1000), (state->expected_mbps % 1000));

  fprintf(f, "  \"ifname\": \"%s\"\n", state->ifname);
  fprintf(f, "}\n");

  fclose(f);
  if (rename(tmpfile, filename)) {
    char errstr[160];
    snprintf(errstr, sizeof(errstr), "%s: rename %s to %s",
        __FUNCTION__, tmpfile, filename);
    perror(errstr);
  }
}


static void ClientStateToLog(gpointer key, gpointer value, gpointer user_data)
{
  const client_state_t *state = (const client_state_t *)value;
  const callback_data_t *cb_data = (const callback_data_t *)user_data;
  time_t mono_now = cb_data->mono_now;

  if (!state->authorized || !state->authenticated) {
    /* Don't log about non-associated clients */
    return;
  }

  if ((mono_now - state->first_seen) < 120) {
    /* Allow data to accumulate before beginning to log it. */
    return;
  }

  printf(
      "%s %s %ld %" PRIu64 ",%" PRIu64 ",%" PRIu64 ",%" PRIu64 ",%" PRIu64
      " %c,%hhd,%hhd,%u,%u,%u,%u,%u,%d"
      " %u,%u,%u,%u,%u,%d"
      " %u,%u,%u,%u,%u,%d"
      " %u,%u,%u,%u,%u,%d"
      "\n",
      state->macstr, state->ifname,
      ((mono_now - state->last_seen) + (state->inactive_msec / 1000)),

      /* L2 traffic stats */
      state->rx_bytes64, state->rx_drop64, state->tx_bytes64,
      state->tx_retries64, state->tx_failed64,

      /* L1 information */
      (state->preamble_length ? 'S' : 'L'),
      state->signal, state->signal_avg,
      state->rx_ht_mcs, state->rx_ht_nss,
      state->rx_vht_mcs, state->rx_vht_nss,
      state->rx_width, state->rx_short_gi,

      /* information about the maximum we've ever seen from this client. */
      state->rx_max_ht_mcs, state->rx_max_ht_nss,
      state->rx_max_vht_mcs, state->rx_max_vht_nss,
      state->rx_max_width, state->ever_rx_short_gi,

      state->tx_ht_mcs, state->tx_ht_nss,
      state->tx_vht_mcs, state->tx_vht_nss,
      state->tx_width, state->tx_short_gi,

      /* information about the maximum we've ever seen from this client. */
      state->tx_max_ht_mcs, state->tx_max_ht_nss,
      state->tx_max_vht_mcs, state->tx_max_vht_nss,
      state->tx_max_width, state->ever_tx_short_gi);
}


void ConsolidateAssociatedDevices()
{
  g_hash_table_foreach_remove(clients, AgeOutClient, NULL);
  g_hash_table_foreach(clients, ConsolidateClientSamples, NULL);
}


/* Walk through all Wifi clients, printing their info to JSON files. */
void UpdateAssociatedDevices()
{
  g_hash_table_foreach(clients, ClientStateToJson, NULL);
}


void LogAssociatedDevices()
{
  callback_data_t cb_data;

  memset(&cb_data, 0, sizeof(cb_data));
  cb_data.mono_now = monotime();
  g_hash_table_foreach(clients, ClientStateToLog, &cb_data);
}


static int ieee80211_frequency_to_channel(int freq)
{
  /* see 802.11-2007 17.3.8.3.2 and Annex J */
  if (freq == 2484)
    return 14;
  else if (freq < 2484)
    return (freq - 2407) / 5;
  else if (freq >= 4910 && freq <= 4980)
    return (freq - 4000) / 5;
  else if (freq <= 45000) /* DMG band lower limit */
    return (freq - 5000) / 5;
  else if (freq >= 58320 && freq <= 64800)
    return (freq - 56160) / 2160;
  else
    return 0;
}


static void print_ssid_escaped(FILE *f, int len, const uint8_t *data)
{
  int i;

  for (i = 0; i < len; i++) {
    switch(data[i]) {
      case '\\': fprintf(f, "\\\\"); break;
      case '"': fprintf(f, "\\\""); break;
      case '\b': fprintf(f, "\\b"); break;
      case '\f': fprintf(f, "\\f"); break;
      case '\n': fprintf(f, "\\n"); break;
      case '\r': fprintf(f, "\\r"); break;
      case '\t': fprintf(f, "\\t"); break;
      default:
        if ((data[i] <= 0x1f) || !isprint(data[i])) {
          fprintf(f, "\\u00%02x", data[i]);
        } else {
          fprintf(f, "%c", data[i]);
        }
        break;
    }
  }
}


static int WlanInfoCallback(struct nl_msg *msg, void *arg)
{
  struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
  struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];

  nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
            genlmsg_attrlen(gnlh, 0), NULL);

  if (tb_msg[NL80211_ATTR_MAC]) {
    unsigned char *mac_addr = nla_data(tb_msg[NL80211_ATTR_MAC]);
    fprintf(wifi_info_handle,
            "  \"BSSID\": \"%02x:%02x:%02x:%02x:%02x:%02x\",\n",
            mac_addr[0], mac_addr[1], mac_addr[2],
            mac_addr[3], mac_addr[4], mac_addr[5]);
  }
  if (tb_msg[NL80211_ATTR_SSID]) {
    fprintf(wifi_info_handle, "  \"SSID\": \"");
    print_ssid_escaped(wifi_info_handle, nla_len(tb_msg[NL80211_ATTR_SSID]),
                       nla_data(tb_msg[NL80211_ATTR_SSID]));
    fprintf(wifi_info_handle, "\",\n");
  }
  if (tb_msg[NL80211_ATTR_WIPHY_FREQ]) {
    uint32_t freq = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_FREQ]);
    fprintf(wifi_info_handle, "  \"Channel\": %d,\n",
            ieee80211_frequency_to_channel(freq));
  }

  return NL_SKIP;
}


void RequestWifiInfo(struct nl_sock *nlsk, int nl80211_id, int n)
{
  HandleNLCommand(nlsk, nl80211_id, n, WlanInfoCallback,
                  NL80211_CMD_GET_INTERFACE, 0);
}


static int RegdomainCallback(struct nl_msg *msg, void *arg)
{
  struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
  struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
  char *reg;

  nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
            genlmsg_attrlen(gnlh, 0), NULL);

  if (!tb_msg[NL80211_ATTR_REG_ALPHA2]) {
    return NL_SKIP;
  }

  if (!tb_msg[NL80211_ATTR_REG_RULES]) {
    return NL_SKIP;
  }

  reg = nla_data(tb_msg[NL80211_ATTR_REG_ALPHA2]);
  fprintf(wifi_info_handle, "  \"RegDomain\": \"%c%c\",\n", reg[0], reg[1]);

  return NL_SKIP;
}


void RequestRegdomain(struct nl_sock *nlsk, int nl80211_id)
{
  HandleNLCommand(nlsk, nl80211_id, -1, RegdomainCallback,
                  NL80211_CMD_GET_REG, 0);
}


void UpdateWifiShow(struct nl_sock *nlsk, int nl80211_id, int n)
{
  char tmpfile[PATH_MAX];
  char filename[PATH_MAX];
  char autofile[PATH_MAX];
  const char *ifname = interfaces[n];
  int done = 0;
  struct stat buffer;
  FILE *fptr;

  if (!ifname || !ifname[0]) {
    return;
  }

  snprintf(tmpfile, sizeof(tmpfile), "%s/%s.new", WIFIINFO_DIR, ifname);
  snprintf(filename, sizeof(filename), "%s/%s", WIFIINFO_DIR, ifname);

  if ((wifi_info_handle = fopen(tmpfile, "w+")) == NULL) {
    perror("fopen");
    return;
  }

  fprintf(wifi_info_handle, "{\n");
  done = 0;
  RequestWifiInfo(nlsk, nl80211_id, n);
  ProcessNetlinkMessages(nlsk, &done);

  done = 0;
  RequestRegdomain(nlsk, nl80211_id);
  ProcessNetlinkMessages(nlsk, &done);

  snprintf(autofile, sizeof(autofile), "/tmp/autochan.%s", ifname);
  if (stat(autofile, &buffer) == 0) {
    fprintf(wifi_info_handle, "  \"AutoChannel\": true,\n");
  } else {
    fprintf(wifi_info_handle, "  \"AutoChannel\": false,\n");
  }
  snprintf(autofile, sizeof(autofile), "/tmp/autotype.%s", ifname);
  if ((fptr = fopen(autofile, "r")) == NULL) {
    fprintf(wifi_info_handle, "  \"AutoType\": \"LOW\"\n");
  } else {
    char buf[24];
    if (fgets(buf, sizeof(buf), fptr) != NULL) {
      fprintf(wifi_info_handle, "  \"AutoType\": \"%s\"\n", buf);
    }
    fclose(fptr);
    fptr = NULL;
  }
  fprintf(wifi_info_handle, "}\n");

  fclose(wifi_info_handle);
  wifi_info_handle = NULL;
  if (rename(tmpfile, filename)) {
    char errbuf[256];
    snprintf(errbuf, sizeof(errbuf), "%s: rename %s to %s : errno=%d",
        __FUNCTION__, tmpfile, filename, errno);
    perror(errbuf);
  }
}

#ifndef UNIT_TESTS
static void TouchUpdateFile()
{
  char filename[PATH_MAX];
  int fd;

  snprintf(filename, sizeof(filename), "%s/updated.new", STATIONS_DIR);
  if ((fd = open(filename, O_CREAT | O_WRONLY, 0666)) < 0) {
    perror("TouchUpdatedFile open");
    exit(1);
  }

  if (write(fd, "updated", 7) < 7) {
    perror("TouchUpdatedFile write");
    exit(1);
  }

  close(fd);
} /* TouchUpdateFile */


int main(int argc, char **argv)
{
  int done = 0;
  int nl80211_id = -1;
  struct nl_sock *nlsk = NULL;
  struct rlimit rlim;

  memset(&rlim, 0, sizeof(rlim));
  if (getrlimit(RLIMIT_AS, &rlim)) {
    perror("getrlimit RLIMIT_AS failed");
    exit(1);
  }
  rlim.rlim_cur = 6 * 1024 * 1024;
  if (setrlimit(RLIMIT_AS, &rlim)) {
    perror("getrlimit RLIMIT_AS failed");
    exit(1);
  }

  setlinebuf(stdout);

  clients = g_hash_table_new_full(g_str_hash, g_str_equal, free, free);

  nlsk = InitNetlinkSocket();
  if (nl_socket_modify_cb(nlsk, NL_CB_FINISH, NL_CB_CUSTOM, NlFinish, &done)) {
    fprintf(stderr, "nl_socket_modify_cb failed\n");
    exit(1);
  }
  if ((nl80211_id = genl_ctrl_resolve(nlsk, "nl80211")) < 0) {
    fprintf(stderr, "genl_ctrl_resolve failed\n");
    exit(1);
  }

  while (1) {
    int i, j;

    /* Check if new interfaces have appeared */
    ninterfaces = 0;
    RequestInterfaceList(nlsk, nl80211_id);
    ProcessNetlinkMessages(nlsk, &done);
    for (i = 0; i < ninterfaces; ++i) {
      UpdateWifiShow(nlsk, nl80211_id, i);
    }

    /* Accumulate MAX_SAMPLE_INDEX samples between calls to
     * LogAssociatedDevices() */
    for (i = 0; i < MAX_SAMPLE_INDEX; ++i) {
      sleep(2);
      for (j = 0; j < ninterfaces; ++j) {
        done = 0;
        RequestAssociatedDevices(nlsk, nl80211_id, j);
        ProcessNetlinkMessages(nlsk, &done);
        ConsolidateAssociatedDevices();
        UpdateAssociatedDevices();
      }
      TouchUpdateFile();
    }
    LogAssociatedDevices();
  }

  exit(0);
}
#endif  /* UNIT_TESTS */
