diff --git a/hmac-userspace-daemon/Makefile b/hmac-userspace-daemon/Makefile deleted file mode 100644 index c5a3c1b..0000000 --- a/hmac-userspace-daemon/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -all: hybrid_tdma_csma_mac_x86 - -hybrid_tdma_csma_mac_x86: - g++ hybrid_tdma_csma_mac.c -I /usr/include/libnl3/ -DCONFIG_LIBNL30 -o hmac_userspace_daemon -levent -lnl-genl-3 -lnl-3 -lzmq -lstdc++ -lpthread -clean: - rm hmac_userspace_daemon diff --git a/hmac-userspace-daemon/hybrid_tdma_csma_mac.c b/hmac-userspace-daemon/hybrid_tdma_csma_mac.c deleted file mode 100644 index ad2c773..0000000 --- a/hmac-userspace-daemon/hybrid_tdma_csma_mac.c +++ /dev/null @@ -1,491 +0,0 @@ -/* - * Userland part of the hybrid TDMA/CSMA MAC processor which is responsible for sending the configuration at - * the beginning of each time slot to the ATH9k WiFi driver using Netlink. - * - * build with: make all - * - * @authors S Zehl, A. Zubow - */ - -#include -#include -#include -#include -#include -#ifdef _EVENT_HAVE_SYS_TIME_H -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "../backports-3.12.8-1/include/uapi/linux/nl80211.h" -#include "iw.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// struct to be passed via netlink to ath9k driver -struct tid_sleep_tuple -{ - char mac[6]; // destination MAC address - char mask; // TID mask -}; - -int mDebug = 0; - -int isRunning = 1; - -// Used by local controller for communication with mac processor -int LOCAL_MAC_PROCESSOR_CTRL_PORT = 1217; - -// variables set at start-up -long slotDuration = 10000; // mus -int slotsPerFrame = 10; // e.g. 10 -char * interface; // e.g. wifi0 -char * configuration; // e.g. 1,mac_addr,tid_map;2,mac_addr,tid_map - -// updated at runtime -std::string *schedule_per_slot = NULL; - -struct nl80211_state state; - -// internal state for keeping slotting time aligned -long oldtime_l = 0; -int event_is_persistent; -const int estimatePrecisionEveryNslots = 1000; -int times[estimatePrecisionEveryNslots]; -int cnt = 0; -long gl_clock = 0; // global clock w/ step size of slotDuration -long slotCnt = 0; // total slot counter -long frameCnt = 0; // total frame counter - -/////////////////////////////////////////////////////////////////////////////// - -/** helper functions for string manipulation */ -std::vector &split(const std::string &s, char delim, std::vector &elems) { - std::stringstream ss(s); - std::string item; - while (std::getline(ss, item, delim)) { - elems.push_back(item); - } - return elems; -} - -/** helper functions for string manipulation */ -std::vector split(const std::string &s, char delim) { - std::vector elems; - split(s, delim, elems); - return elems; -} - -/** - * Called at start-up or in case of reconfiguration. - */ -void updateSchedule(std::string &msg) { - - // init - for (int i=0; i msg_parts = split(msg, '#'); - - for (int k=0; k entry = split(msg_parts[k], ','); - - int slot_id = atoi(entry[0].c_str()); - const char * mac_addr = entry[1].c_str(); - int tid_mask = atoi(entry[2].c_str()); - - std::stringstream ss; - if (schedule_per_slot[slot_id].empty()) { - ss << mac_addr << "," << entry[2].c_str(); - } else { - ss << schedule_per_slot[slot_id] << "#" << mac_addr << "," << entry[2].c_str(); - } - - schedule_per_slot[slot_id] = ss.str(); - } -} - -/** Worker thread responsible for receiving new configuration updates */ -void *worker_routine (void *arg) -{ - std::cout << "Worker routine started ... ready to receive new configuration messages via ZMQ socket." << std::endl; - - zmq::context_t *context = (zmq::context_t *) arg; - zmq::socket_t socket (*context, ZMQ_REP); - - std::stringstream ss; - ss << "tcp://*:" << LOCAL_MAC_PROCESSOR_CTRL_PORT; - socket.bind (ss.str().c_str()); - //socket.bind ("ipc:///tmp/localmacprocessor"); - - while (true) { - zmq::message_t request; - - // Wait for next request from client - socket.recv (&request); - - std::string msg = std::string(static_cast(request.data()), request.size()); - std::cout << "Received new configuration update: " << msg << std::endl; - - if (msg.find("TERMINATE") == 0) { - // shutdown process - isRunning = 0; - } else { - // update slot schedule - updateSchedule(msg); - } - - sleep (0.1); - - // Send ACK to client - zmq::message_t reply(2); - memcpy ((void *) reply.data(), "OK", 2); - socket.send(reply); - if(isRunning == 0) - { - socket.close(); - break; - } - } - return 0; -} - -/** netlink error handling */ -static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, - void *arg) -{ - int *ret = (int*) arg; - *ret = err->error; - - printf("->CFG80211 returns: error: No:%d, %s\n",err->error, strerror((-1)*err->error)); - return NL_STOP; -} - -static int finish_handler(struct nl_msg *msg, void *arg) -{ - int *ret = (int*) arg; - *ret = 0; - return NL_SKIP; -} - -static int ack_handler(struct nl_msg *msg, void *arg) -{ - int *ret = (int*) arg; - *ret = 0; - return NL_STOP; -} - -static int send_nl_msg(std::string& schedule) -{ - if (mDebug == 1) { - std::cout << "Send schedule via netlink to ath9k driver: " << schedule << std::endl; - } - - std::vector tuples = split(schedule, '#'); - - struct nl_cb *cb; - struct nl_cb *s_cb; - struct nl_msg *msg; - signed long long devidx = 0; - int err = 0; - devidx = if_nametoindex(interface); - - msg = nlmsg_alloc(); - if (!msg) { - fprintf(stderr, "failed to allocate netlink message\n"); - return 2; - } - - cb = nl_cb_alloc(NL_CB_DEFAULT); - s_cb = nl_cb_alloc(NL_CB_DEFAULT); - if (!cb || !s_cb) { - fprintf(stderr, "failed to allocate netlink callbacks\n"); - err = 2; - goto out_free_msg; - } - - // create NetLink message - genlmsg_put(msg, 0, 0, state.nl80211_id, 0, 0, NL80211_ATTR_TID_SLEEP_CTRL, 0); - NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, devidx); - - // update tids_tuple with current slot schedule - uint8_t mac_u8[6]; - struct tid_sleep_tuple tids_tuple[tuples.size()]; - for (int k=0; k tuple = split(tuples[k], ','); - sscanf(tuple[0].c_str(), "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &mac_u8[0], &mac_u8[1], &mac_u8[2], &mac_u8[3], &mac_u8[4], &mac_u8[5]); - int tid_mask = atoi(tuple[1].c_str()); - - for (int zz=0; zz<6; zz++) { - tids_tuple[k].mac[zz] = mac_u8[zz]; - } - tids_tuple[k].mask = tid_mask; - } - - NLA_PUT(msg, NL80211_ATTR_TID_SLEEP_CTRL_DATA, sizeof(struct tid_sleep_tuple)*tuples.size(), (const void *) &tids_tuple[0]); - nl_socket_set_cb(state.nl_sock, s_cb); - - // send message - err = nl_send_auto_complete(state.nl_sock, msg); - if (err < 0) - goto out; - - err = 1; - - nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err); - nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err); - nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err); - - while (err > 0) { - nl_recvmsgs(state.nl_sock, cb); - } - - out: - nl_cb_put(cb); - out_free_msg: - nlmsg_free(msg); - return err; - nla_put_failure: - fprintf(stderr, "building message failed\n"); - return 2; -} - -/** initialize netlink */ -static int nl80211_init(struct nl80211_state *state) -{ - int err; - - printf("nl80211 init called v2\n"); - - state->nl_sock = nl_socket_alloc(); - if (!state->nl_sock) { - fprintf(stderr, "Failed to allocate netlink socket.\n"); - return -ENOMEM; - } - - nl_socket_set_buffer_size(state->nl_sock, 8192, 8192); - - if (genl_connect(state->nl_sock)) { - fprintf(stderr, "Failed to connect to generic netlink.\n"); - err = -ENOLINK; - goto out_handle_destroy; - } - - state->nl80211_id = genl_ctrl_resolve(state->nl_sock, "nl80211"); - if (state->nl80211_id < 0) { - fprintf(stderr, "nl80211 not found.\n"); - err = -ENOENT; - goto out_handle_destroy; - } - - return 0; - - out_handle_destroy: - nl_socket_free(state->nl_sock); - - return err; -} - -/** timer callback called at the beginning of each new slot */ -static void -timeout_cb(evutil_socket_t fd, short event, void *arg) -{ - struct timeval newtime, difference; - struct event *timeout = (struct event *)arg; - long error = 0; - - if (isRunning == 0) { - printf("Terminating ...\n"); - return; - } - - evutil_gettimeofday(&newtime, NULL); - long newtime_l = 1000000 * newtime.tv_sec + newtime.tv_usec; - - if (gl_clock == 0) { - gl_clock = (newtime_l / slotDuration) * slotDuration; - slotCnt = 0; - frameCnt = 0; - } else { - gl_clock = gl_clock + (slotDuration % 1000000); - slotCnt++; - frameCnt = slotCnt / slotsPerFrame; - } - // current frame number - long relFrameNum = slotCnt % slotsPerFrame; - - // estimate slot scheduling precision - if(cnt < estimatePrecisionEveryNslots) { - times[cnt] = newtime_l; - cnt++; - } else if(cnt == estimatePrecisionEveryNslots) { - double sum = 0; - for(int i = 1; i < estimatePrecisionEveryNslots; i++) { - sum += times[i] - times[i-1]; - } - sum = sum / (estimatePrecisionEveryNslots-1); - - printf("Average slot duration: %.2f\n", sum); - cnt = 0; - } - - if (!event_is_persistent) { - struct timeval tv; - evutil_timerclear(&tv); - - if (oldtime_l != 0) { - error = 2 * (newtime_l - gl_clock); - } - - tv.tv_sec = slotDuration / 1000000; - tv.tv_usec = (slotDuration % 1000000) - error; - - event_add(timeout, &tv); - oldtime_l = newtime_l; - - send_nl_msg(schedule_per_slot[relFrameNum]); - } -} - -/** main entry point */ -int -main(int argc, char **argv) -{ - struct event timeout; - struct timeval tv; - struct event_base *base; - int flags; - int err; - char * inter_ptr; - char * conf_ptr; - int opt = 0; - char *mac = NULL; - char *guard_frames = NULL; - char *best_effort = NULL; - char *voice = NULL; - char *pt; - interface = '\0'; - configuration = '\0'; - - while ((opt = getopt(argc, argv, "d:i:f:n:c:")) != -1) { - switch(opt) { - case 'd': - mDebug = atoi(optarg); - printf("\nDebug = %d", mDebug); - break; - case 'i': - inter_ptr = optarg; - interface = (char *) malloc(strlen(inter_ptr)); - strcpy(interface, inter_ptr); - printf("\nInterface = %s", interface); - break; - case 'f': - slotDuration = atoi(optarg); - printf("\nSlot Duration = %lu", slotDuration); - break; - case 'n': - slotsPerFrame = atoi(optarg); - printf("\nTotal number of slots in frame = %d", slotsPerFrame); - break; - case 'c': - conf_ptr = optarg; - configuration = (char *) malloc(strlen(conf_ptr)); - strcpy(configuration, conf_ptr); - printf("\nConfig = %s", configuration); - break; - case '?': - printf("Usage: ./hybrid_tdma_csma_mac -i wifi0 -f 20000 -n 10\n"); - break; - } - } - - // init schedule - schedule_per_slot = new std::string[slotsPerFrame]; - - // update schedule - std::string msg(configuration); - updateSchedule(msg); - - if (interface == NULL) { - printf("Error no interface supplied. Usage: ./hybrid_tdma_csma_mac -i wifi0 -f 20000 -n 10\n"); - return -1; - } - - printf("Using init schedule w/:\n"); - - for(int i=0; i<10; i++) { - printf("#%d: %s, ", i, schedule_per_slot[i].c_str()); - } - - // Prepare our context and sockets - zmq::context_t context (1); - - try { - pthread_t worker; - pthread_create (&worker, NULL, worker_routine, (void *) &context); - } catch (const std::exception& ex) { - std::cerr << "Error setting up ZMQ: " << ex.what() << std::endl; - return -1; - } catch (...) { - std::cerr << "Other strange error!!! " << std::endl; - return -1; - } - - err = nl80211_init(&state); - - event_is_persistent = 0; - flags = 0; - - /* Initalize the event library */ - base = event_base_new(); - - /* Initalize one event */ - event_assign(&timeout, base, -1, flags, timeout_cb, (void*) &timeout); - - evutil_timerclear(&tv); - - /* align schedule to seconds */ - struct timeval curTime; - evutil_gettimeofday(&curTime, NULL); - - int mus = 1000000 - curTime.tv_usec; - tv.tv_sec = 1; - tv.tv_usec = mus; - event_add(&timeout, &tv); - - event_base_dispatch(base); - - return (0); -} - diff --git a/hmac-userspace-daemon/ieee80211.h b/hmac-userspace-daemon/ieee80211.h deleted file mode 100644 index 8745608..0000000 --- a/hmac-userspace-daemon/ieee80211.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef __IEEE80211 -#define __IEEE80211 - -/* 802.11n HT capability AMPDU settings (for ampdu_params_info) */ -#define IEEE80211_HT_AMPDU_PARM_FACTOR 0x03 -#define IEEE80211_HT_AMPDU_PARM_DENSITY 0x1C - -#define IEEE80211_HT_CAP_SUP_WIDTH_20_40 0x0002 -#define IEEE80211_HT_CAP_SGI_40 0x0040 -#define IEEE80211_HT_CAP_MAX_AMSDU 0x0800 - -#define IEEE80211_HT_MCS_MASK_LEN 10 - -/** - * struct ieee80211_mcs_info - MCS information - * @rx_mask: RX mask - * @rx_highest: highest supported RX rate. If set represents - * the highest supported RX data rate in units of 1 Mbps. - * If this field is 0 this value should not be used to - * consider the highest RX data rate supported. - * @tx_params: TX parameters - */ -struct ieee80211_mcs_info { - __u8 rx_mask[IEEE80211_HT_MCS_MASK_LEN]; - __u16 rx_highest; - __u8 tx_params; - __u8 reserved[3]; -} __attribute__ ((packed)); - - -/** - * struct ieee80211_ht_cap - HT capabilities - * - * This structure is the "HT capabilities element" as - * described in 802.11n D5.0 7.3.2.57 - */ -struct ieee80211_ht_cap { - __u16 cap_info; - __u8 ampdu_params_info; - - /* 16 bytes MCS information */ - struct ieee80211_mcs_info mcs; - - __u16 extended_ht_cap_info; - __u32 tx_BF_cap_info; - __u8 antenna_selection_info; -} __attribute__ ((packed)); - -struct ieee80211_vht_mcs_info { - __u16 rx_vht_mcs; - __u16 rx_highest; - __u16 tx_vht_mcs; - __u16 tx_highest; -} __attribute__ ((packed)); - -struct ieee80211_vht_cap { - __u32 cap_info; - struct ieee80211_vht_mcs_info mcs; -} __attribute__ ((packed)); - -#endif /* __IEEE80211 */ diff --git a/hmac-userspace-daemon/iw.h b/hmac-userspace-daemon/iw.h deleted file mode 100644 index 550f087..0000000 --- a/hmac-userspace-daemon/iw.h +++ /dev/null @@ -1,177 +0,0 @@ -#ifndef __IW_H -#define __IW_H - -#include -#include -#include -#include -#include -#include - -#include "ieee80211.h" - -#define ETH_ALEN 6 - -/* libnl 1.x compatibility code */ -#if !defined(CONFIG_LIBNL20) && !defined(CONFIG_LIBNL30) -# define nl_sock nl_handle -#endif - -struct nl80211_state { - struct nl_sock *nl_sock; - int nl80211_id; -}; - -enum command_identify_by { - CIB_NONE, - CIB_PHY, - CIB_NETDEV, - CIB_WDEV, -}; - -enum id_input { - II_NONE, - II_NETDEV, - II_PHY_NAME, - II_PHY_IDX, - II_WDEV, -}; - -struct cmd { - const char *name; - const char *args; - const char *help; - const enum nl80211_commands cmd; - int nl_msg_flags; - int hidden; - const enum command_identify_by idby; - /* - * The handler should return a negative error code, - * zero on success, 1 if the arguments were wrong - * and the usage message should and 2 otherwise. - */ - int (*handler)(struct nl80211_state *state, - struct nl_cb *cb, - struct nl_msg *msg, - int argc, char **argv, - enum id_input id); - const struct cmd *(*selector)(int argc, char **argv); - const struct cmd *parent; -}; - -#define ARRAY_SIZE(ar) (sizeof(ar)/sizeof(ar[0])) -#define DIV_ROUND_UP(x, y) (((x) + (y - 1)) / (y)) - -#define __COMMAND(_section, _symname, _name, _args, _nlcmd, _flags, _hidden, _idby, _handler, _help, _sel)\ - static struct cmd \ - __cmd ## _ ## _symname ## _ ## _handler ## _ ## _nlcmd ## _ ## _idby ## _ ## _hidden\ - __attribute__((used)) __attribute__((section("__cmd"))) = { \ - .name = (_name), \ - .args = (_args), \ - .cmd = (_nlcmd), \ - .nl_msg_flags = (_flags), \ - .hidden = (_hidden), \ - .idby = (_idby), \ - .handler = (_handler), \ - .help = (_help), \ - .parent = _section, \ - .selector = (_sel), \ - } -#define __ACMD(_section, _symname, _name, _args, _nlcmd, _flags, _hidden, _idby, _handler, _help, _sel, _alias)\ - __COMMAND(_section, _symname, _name, _args, _nlcmd, _flags, _hidden, _idby, _handler, _help, _sel);\ - static const struct cmd *_alias = &__cmd ## _ ## _symname ## _ ## _handler ## _ ## _nlcmd ## _ ## _idby ## _ ## _hidden -#define COMMAND(section, name, args, cmd, flags, idby, handler, help) \ - __COMMAND(&(__section ## _ ## section), name, #name, args, cmd, flags, 0, idby, handler, help, NULL) -#define COMMAND_ALIAS(section, name, args, cmd, flags, idby, handler, help, selector, alias)\ - __ACMD(&(__section ## _ ## section), name, #name, args, cmd, flags, 0, idby, handler, help, selector, alias) -#define HIDDEN(section, name, args, cmd, flags, idby, handler) \ - __COMMAND(&(__section ## _ ## section), name, #name, args, cmd, flags, 1, idby, handler, NULL, NULL) - -#define TOPLEVEL(_name, _args, _nlcmd, _flags, _idby, _handler, _help) \ - struct cmd \ - __section ## _ ## _name \ - __attribute__((used)) __attribute__((section("__cmd"))) = { \ - .name = (#_name), \ - .args = (_args), \ - .cmd = (_nlcmd), \ - .nl_msg_flags = (_flags), \ - .idby = (_idby), \ - .handler = (_handler), \ - .help = (_help), \ - } -#define SECTION(_name) \ - struct cmd __section ## _ ## _name \ - __attribute__((used)) __attribute__((section("__cmd"))) = { \ - .name = (#_name), \ - .hidden = 1, \ - } - -#define DECLARE_SECTION(_name) \ - extern struct cmd __section ## _ ## _name; - -extern const char iw_version[]; - -extern int iw_debug; - -int handle_cmd(struct nl80211_state *state, enum id_input idby, - int argc, char **argv); - -struct print_event_args { - struct timeval ts; /* internal */ - bool have_ts; /* must be set false */ - bool frame, time, reltime; -}; - -__u32 listen_events(struct nl80211_state *state, - const int n_waits, const __u32 *waits); -int __prepare_listen_events(struct nl80211_state *state); -__u32 __do_listen_events(struct nl80211_state *state, - const int n_waits, const __u32 *waits, - struct print_event_args *args); - - -int mac_addr_a2n(unsigned char *mac_addr, char *arg); -void mac_addr_n2a(char *mac_addr, unsigned char *arg); -int parse_hex_mask(char *hexmask, unsigned char **result, size_t *result_len, - unsigned char **mask); -unsigned char *parse_hex(char *hex, size_t *outlen); - -int parse_keys(struct nl_msg *msg, char **argv, int argc); - -void print_ht_mcs(const __u8 *mcs); -void print_ampdu_length(__u8 exponent); -void print_ampdu_spacing(__u8 spacing); -void print_ht_capability(__u16 cap); -void print_vht_info(__u32 capa, const __u8 *mcs); - -char *channel_width_name(enum nl80211_chan_width width); -const char *iftype_name(enum nl80211_iftype iftype); -const char *command_name(enum nl80211_commands cmd); -int ieee80211_channel_to_frequency(int chan, enum nl80211_band band); -int ieee80211_frequency_to_channel(int freq); - -void print_ssid_escaped(const uint8_t len, const uint8_t *data); - -int nl_get_multicast_id(struct nl_sock *sock, const char *family, const char *group); - -char *reg_initiator_to_string(__u8 initiator); - -const char *get_reason_str(uint16_t reason); -const char *get_status_str(uint16_t status); - -enum print_ie_type { - PRINT_SCAN, - PRINT_LINK, -}; - -#define BIT(x) (1ULL<<(x)) - -void print_ies(unsigned char *ie, int ielen, bool unknown, - enum print_ie_type ptype); - -void parse_bitrate(struct nlattr *bitrate_attr, char *buf, int buflen); - -DECLARE_SECTION(set); -DECLARE_SECTION(get); - -#endif /* __IW_H */