/*
 * Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

/*
 * WiFi Testbed Regulatory
 *
 * Userspace helper which sends regulatory domains to Linux via nl80211.
 * This code is based on CRDA.  Plese see LICENSE.CRDA for the license
 * associated with the original code.
 */

#include <arpa/inet.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

#include <linux/nl80211.h>
#include <netlink/attr.h>
#include <netlink/genl/ctrl.h>
#include <netlink/genl/family.h>
#include <netlink/genl/genl.h>
#include <netlink/msg.h>

/* Constants used for creating a single "allow anything" rule */
#define RULE_FREQ_RANGE_MIN_KHZ 2000000
#define RULE_FREQ_RANGE_MAX_KHZ 6000000
#define RULE_BANDWIDTH_MAX_KHZ 80000
#define RULE_ANTENNA_GAIN_MAX_MBI 300
#define RULE_EIRP_MAX_MBM 2300

struct nl80211_state {
  struct nl_sock *nl_sock;
  struct nl_cache *nl_cache;
  struct genl_family *nl80211;
};

static int nl80211_init(struct nl80211_state *state) {
  int err;

  state->nl_sock = nl_socket_alloc();
  if (!state->nl_sock) {
    fprintf(stderr, "Failed to allocate netlink sock.\n");
    return -ENOMEM;
  }

  if (genl_connect(state->nl_sock)) {
    fprintf(stderr, "Failed to connect to generic netlink.\n");
    err = -ENOLINK;
    goto out_sock_destroy;
  }

  if (genl_ctrl_alloc_cache(state->nl_sock, &state->nl_cache)) {
    fprintf(stderr, "Failed to allocate generic netlink cache.\n");
    err = -ENOMEM;
    goto out_sock_destroy;
  }

  state->nl80211 = genl_ctrl_search_by_name(state->nl_cache, "nl80211");
  if (!state->nl80211) {
    fprintf(stderr, "nl80211 not found.\n");
    err = -ENOENT;
    goto out_cache_free;
  }

  return 0;

 out_cache_free:
  nl_cache_free(state->nl_cache);
 out_sock_destroy:
  nl_socket_free(state->nl_sock);
  return err;
}

static void nl80211_cleanup(struct nl80211_state *state) {
  genl_family_put(state->nl80211);
  nl_cache_free(state->nl_cache);
  nl_socket_free(state->nl_sock);
}

static int reg_handler(struct nl_msg *msg, void *arg) {
  return NL_SKIP;
}

static int wait_handler(struct nl_msg *msg, void *arg) {
  int *finished = arg;
  *finished = 1;
  return NL_STOP;
}

static int error_handler(struct sockaddr_nl *nla,
                         struct nlmsgerr *err,
                         void *arg) {
  fprintf(stderr, "nl80211 error %d\n", err->error);
  exit(err->error);
}

static inline int is_world_regdom(const char *alpha2) {
  if (alpha2[0] == '0' && alpha2[1] == '0')
    return 1;
  return 0;
}

static inline int is_alpha2(const char *alpha2) {
  if (isupper(alpha2[0]) && isupper(alpha2[1]))
    return 1;
  return 0;
}

static inline int is_valid_regdom(const char *alpha2) {
  if (is_alpha2(alpha2) || is_world_regdom(alpha2))
    return 1;
  return 0;
}

int main(int argc, char **argv) {
  int r;
  char alpha2[3] = { '0', '0' };
  char *env_country;
  struct nl80211_state nlstate;
  struct nl_cb *cb = NULL;
  struct nl_msg *msg;
  int finished = 0;

  struct nlattr *nl_reg_rules;
  struct ieee80211_regdomain *rd = NULL;
  struct nlattr *nl_reg_rule;

  if (argc != 1) {
    fprintf(stderr, "Usage: %s\n", argv[0]);
    return 1;
  }

  env_country = getenv("COUNTRY");
  if (env_country) {
    if (!is_valid_regdom(env_country)) {
      fprintf(stderr, "COUNTRY environment variable must be "
              "ISO ISO 3166-1-alpha-2 (uppercase) or 00\n");
      return 1;
    }
    memcpy(alpha2, env_country, 2);
  }

  r = nl80211_init(&nlstate);
  if (r) {
    return 1;
  }

  msg = nlmsg_alloc();
  if (!msg) {
    fprintf(stderr, "Failed to allocate netlink message.\n");
    r = -1;
    goto out;
  }

  genlmsg_put(msg, 0, 0, genl_family_get_id(nlstate.nl80211), 0,
    0, NL80211_CMD_SET_REG, 0);

  NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2, alpha2);
  NLA_PUT_U8(msg, NL80211_ATTR_DFS_REGION, NL80211_DFS_UNSET);

  nl_reg_rules = nla_nest_start(msg, NL80211_ATTR_REG_RULES);
  if (!nl_reg_rules) {
    r = -1;
    goto nla_put_failure;
  }

  nl_reg_rule = nla_nest_start(msg, 0);
  if (!nl_reg_rule)
    goto nla_put_failure;

  NLA_PUT_U32(msg, NL80211_ATTR_REG_RULE_FLAGS, 0);
  NLA_PUT_U32(msg, NL80211_ATTR_FREQ_RANGE_START,
        RULE_FREQ_RANGE_MIN_KHZ);
  NLA_PUT_U32(msg, NL80211_ATTR_FREQ_RANGE_END,
        RULE_FREQ_RANGE_MAX_KHZ);
  NLA_PUT_U32(msg, NL80211_ATTR_FREQ_RANGE_MAX_BW,
        RULE_BANDWIDTH_MAX_KHZ);
  NLA_PUT_U32(msg, NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN,
        RULE_ANTENNA_GAIN_MAX_MBI);
  NLA_PUT_U32(msg, NL80211_ATTR_POWER_RULE_MAX_EIRP,
        RULE_EIRP_MAX_MBM);

  nla_nest_end(msg, nl_reg_rule);
  nla_nest_end(msg, nl_reg_rules);

  cb = nl_cb_alloc(NL_CB_CUSTOM);
  if (!cb)
    goto out_cb_put;

  r = nl_send_auto_complete(nlstate.nl_sock, msg);

  if (r < 0) {
    fprintf(stderr, "Failed to send regulatory request: %d\n", r);
    goto out_cb_put;
  }

  nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, reg_handler, NULL);
  nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, wait_handler, &finished);
  nl_cb_err(cb, NL_CB_CUSTOM, error_handler, NULL);

  if (!finished) {
    r = nl_wait_for_ack(nlstate.nl_sock);
    if (r < 0) {
      fprintf(stderr, "Failed to set regulatory domain: "
              "%s (%d)\n", nl_geterror(r), r);
      goto out_cb_put;
    }
  }

out_cb_put:
  nl_cb_put(cb);
nla_put_failure:
  nlmsg_free(msg);
out:
  nl80211_cleanup(&nlstate);
  free(rd);

  return r != 0;
}
