// Author: Xianjun Jiao // SPDX-FileCopyrightText: 2019 UGent // SPDX-License-Identifier: AGPL-3.0-or-later #include #include #include #include #include #include #include #include #include #include "nl80211.h" #include "sdrctl.h" #include "nl80211_testmode_def.h" static int cb_reg_handler(struct nl_msg *msg, void *arg) { struct nlattr *attrs[NL80211_ATTR_MAX + 1]; struct nlattr *tb[OPENWIFI_ATTR_MAX + 1]; struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); //printf("cb_reg_handler\n"); nla_parse(attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); if (!attrs[NL80211_ATTR_TESTDATA]) return NL_SKIP; nla_parse(tb, OPENWIFI_ATTR_MAX, nla_data(attrs[NL80211_ATTR_TESTDATA]), nla_len(attrs[NL80211_ATTR_TESTDATA]), NULL); //printf("reg addr: %08x\n", nla_get_u32(tb[REG_ATTR_ADDR])); printf("reg val: %08x\n", nla_get_u32(tb[REG_ATTR_VAL])); return NL_SKIP; } static int handle_set_reg(struct nl80211_state *state, struct nl_cb *cb, struct nl_msg *msg, int argc, char **argv, enum id_input id) { struct nlattr *tmdata; char *end; unsigned int reg_cat, reg_addr, reg_val; tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); if (!tmdata) { return 1; } if (strcasecmp(argv[0],"rf")==0) reg_cat=1; else if (strcasecmp(argv[0],"rx_intf")==0) reg_cat = 2; else if (strcasecmp(argv[0],"tx_intf")==0) reg_cat = 3; else if (strcasecmp(argv[0],"rx")==0) reg_cat = 4; else if (strcasecmp(argv[0],"tx")==0) reg_cat = 5; else if (strcasecmp(argv[0],"xpu")==0) reg_cat = 6; else if (strcasecmp(argv[0],"drv_rx")==0) reg_cat = 7; else if (strcasecmp(argv[0],"drv_tx")==0) reg_cat = 8; else if (strcasecmp(argv[0],"drv_xpu")==0) reg_cat = 9; else { printf("Wrong the 1st argument. Should be rf/rx_intf/tx_intf/rx/tx/xpu/drv_rx/drv_tx/drv_xpu\n"); return 1; } reg_addr = strtoul(argv[1], &end, 10); if (*end) { return 1; } reg_addr = reg_addr<<2;//from idx to addr reg_addr = ((reg_cat<<16)|reg_addr); reg_val = strtoul(argv[2], &end, 10); if (*end) { return 1; } NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, REG_CMD_SET); NLA_PUT_U32(msg, REG_ATTR_ADDR, reg_addr); NLA_PUT_U32(msg, REG_ATTR_VAL, reg_val); nla_nest_end(msg, tmdata); printf("reg cat: %d\n", reg_cat); printf("reg addr: %08x\n", reg_addr); printf("reg val: %08x\n", reg_val); return 0; nla_put_failure: return -ENOBUFS; } COMMAND(set, reg, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_set_reg, "set reg"); static int handle_get_reg(struct nl80211_state *state, struct nl_cb *cb, struct nl_msg *msg, int argc, char **argv, enum id_input id) { char *end; struct nlattr *tmdata; unsigned int reg_cat, reg_addr; tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); if (!tmdata) return 1; if (strcasecmp(argv[0],"rf")==0) reg_cat=1; else if (strcasecmp(argv[0],"rx_intf")==0) reg_cat = 2; else if (strcasecmp(argv[0],"tx_intf")==0) reg_cat = 3; else if (strcasecmp(argv[0],"rx")==0) reg_cat = 4; else if (strcasecmp(argv[0],"tx")==0) reg_cat = 5; else if (strcasecmp(argv[0],"xpu")==0) reg_cat = 6; else if (strcasecmp(argv[0],"drv_rx")==0) reg_cat = 7; else if (strcasecmp(argv[0],"drv_tx")==0) reg_cat = 8; else if (strcasecmp(argv[0],"drv_xpu")==0) reg_cat = 9; else { printf("Wrong the 1st argument. Should be rf/rx_intf/tx_intf/rx/tx/xpu/drv_rx/drv_tx/drv_xpu\n"); return 1; } reg_addr = strtoul(argv[1], &end, 10); if (*end) { return 1; } reg_addr = reg_addr<<2;//from idx to addr reg_addr = ((reg_cat<<16)|reg_addr); printf("SENDaddr: %08x\n", reg_addr); NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, REG_CMD_GET); NLA_PUT_U32(msg, REG_ATTR_ADDR, reg_addr); nla_nest_end(msg, tmdata); nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_reg_handler, NULL); return 0; nla_put_failure: return -ENOBUFS; } COMMAND(get, reg, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_get_reg, "get reg"); static int cb_openwifi_rssi_th_handler(struct nl_msg *msg, void *arg) { struct nlattr *attrs[NL80211_ATTR_MAX + 1]; struct nlattr *tb[OPENWIFI_ATTR_MAX + 1]; struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); nla_parse(attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); if (!attrs[NL80211_ATTR_TESTDATA]) return NL_SKIP; nla_parse(tb, OPENWIFI_ATTR_MAX, nla_data(attrs[NL80211_ATTR_TESTDATA]), nla_len(attrs[NL80211_ATTR_TESTDATA]), NULL); printf("openwifi rssi_th: %d\n", nla_get_u32(tb[OPENWIFI_ATTR_RSSI_TH])); return NL_SKIP; } static int handle_set_rssi_th(struct nl80211_state *state, struct nl_cb *cb, struct nl_msg *msg, int argc, char **argv, enum id_input id) { struct nlattr *tmdata; char *end; unsigned int tmp; tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); if (!tmdata) { return 1; } tmp = strtoul(argv[0], &end, 10); if (*end) { return 1; } NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_SET_RSSI_TH); NLA_PUT_U32(msg, OPENWIFI_ATTR_RSSI_TH, tmp); nla_nest_end(msg, tmdata); printf("openwifi rssi_th: %d\n", tmp); return 0; nla_put_failure: return -ENOBUFS; } COMMAND(set, rssi_th, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_set_rssi_th, "set rssi_th"); static int handle_set_tsf(struct nl80211_state *state, struct nl_cb *cb, struct nl_msg *msg, int argc, char **argv, enum id_input id) { struct nlattr *tmdata; char *end; unsigned int high_tsf, low_tsf; tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); if (!tmdata) { return 1; } high_tsf = strtoul(argv[0], &end, 10); if (*end) { return 1; } low_tsf = strtoul(argv[1], &end, 10); if (*end) { return 1; } NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_SET_TSF); NLA_PUT_U32(msg, OPENWIFI_ATTR_HIGH_TSF, high_tsf); NLA_PUT_U32(msg, OPENWIFI_ATTR_LOW_TSF, low_tsf); nla_nest_end(msg, tmdata); printf("high_tsf val: %08x\n", high_tsf); printf("low_tsf val: %08x\n", low_tsf); return 0; /*struct nlattr *tmdata; char *end; unsigned int tmp; tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); if (!tmdata) { return 1; } tmp = strtoul(argv[0], &end, 10); if (*end) { return 1; } NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_SET_TSF); NLA_PUT_U64(msg, OPENWIFI_ATTR_TSF, tmp); nla_nest_end(msg, tmdata); printf("openwifi tsf: %d\n", tmp); return 0;*/ nla_put_failure: return -ENOBUFS; } COMMAND(set, tsf, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_set_tsf, "set tsf"); static int handle_get_rssi_th(struct nl80211_state *state, struct nl_cb *cb, struct nl_msg *msg, int argc, char **argv, enum id_input id) { struct nlattr *tmdata; tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); if (!tmdata) return 1; NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_GET_RSSI_TH); nla_nest_end(msg, tmdata); nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_openwifi_rssi_th_handler, NULL); return 0; nla_put_failure: return -ENOBUFS; } COMMAND(get, rssi_th, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_get_rssi_th, "get rssi_th"); static int cb_openwifi_slice_total_handler(struct nl_msg *msg, void *arg) { struct nlattr *attrs[NL80211_ATTR_MAX + 1]; struct nlattr *tb[OPENWIFI_ATTR_MAX + 1]; struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); unsigned int tmp; nla_parse(attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); if (!attrs[NL80211_ATTR_TESTDATA]) return NL_SKIP; nla_parse(tb, OPENWIFI_ATTR_MAX, nla_data(attrs[NL80211_ATTR_TESTDATA]), nla_len(attrs[NL80211_ATTR_TESTDATA]), NULL); tmp = nla_get_u32(tb[OPENWIFI_ATTR_SLICE_TOTAL]); printf("openwifi slice_total (duration) %dus of slice %d\n", tmp&0xFFFFF, tmp>>20); return NL_SKIP; } static int handle_set_slice_total(struct nl80211_state *state, struct nl_cb *cb, struct nl_msg *msg, int argc, char **argv, enum id_input id) { struct nlattr *tmdata; char *end; unsigned int tmp; tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); if (!tmdata) { return 1; } tmp = strtoul(argv[0], &end, 10); if (*end) { return 1; } NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_SET_SLICE_TOTAL); NLA_PUT_U32(msg, OPENWIFI_ATTR_SLICE_TOTAL, tmp); nla_nest_end(msg, tmdata); printf("openwifi slice_total (duration): %dus\n", tmp); return 0; nla_put_failure: return -ENOBUFS; } COMMAND(set, slice_total, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_set_slice_total, "set slice_total"); static int handle_get_slice_total(struct nl80211_state *state, struct nl_cb *cb, struct nl_msg *msg, int argc, char **argv, enum id_input id) { struct nlattr *tmdata; tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); if (!tmdata) return 1; NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_GET_SLICE_TOTAL); nla_nest_end(msg, tmdata); nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_openwifi_slice_total_handler, NULL); return 0; nla_put_failure: return -ENOBUFS; } COMMAND(get, slice_total, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_get_slice_total, "get slice_total"); // static int cb_openwifi_slice_total1_handler(struct nl_msg *msg, void *arg) // { // struct nlattr *attrs[NL80211_ATTR_MAX + 1]; // struct nlattr *tb[OPENWIFI_ATTR_MAX + 1]; // struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); // nla_parse(attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); // if (!attrs[NL80211_ATTR_TESTDATA]) // return NL_SKIP; // nla_parse(tb, OPENWIFI_ATTR_MAX, nla_data(attrs[NL80211_ATTR_TESTDATA]), nla_len(attrs[NL80211_ATTR_TESTDATA]), NULL); // printf("openwifi slice_total1 (duration): %dus\n", nla_get_u32(tb[OPENWIFI_ATTR_SLICE_TOTAL1])); // return NL_SKIP; // } // static int handle_set_slice_total1(struct nl80211_state *state, // struct nl_cb *cb, // struct nl_msg *msg, // int argc, char **argv, // enum id_input id) // { // struct nlattr *tmdata; // char *end; // unsigned int tmp; // tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); // if (!tmdata) { // return 1; // } // tmp = strtoul(argv[0], &end, 10); // if (*end) { // return 1; // } // NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_SET_SLICE_TOTAL1); // NLA_PUT_U32(msg, OPENWIFI_ATTR_SLICE_TOTAL1, tmp); // nla_nest_end(msg, tmdata); // printf("openwifi slice_total1 (duration): %dus\n", tmp); // return 0; // nla_put_failure: // return -ENOBUFS; // } // COMMAND(set, slice_total1, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_set_slice_total1, "set slice_total1"); // static int handle_get_slice_total1(struct nl80211_state *state, // struct nl_cb *cb, // struct nl_msg *msg, // int argc, char **argv, // enum id_input id) // { // struct nlattr *tmdata; // tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); // if (!tmdata) // return 1; // NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_GET_SLICE_TOTAL1); // nla_nest_end(msg, tmdata); // nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_openwifi_slice_total1_handler, NULL); // return 0; // nla_put_failure: // return -ENOBUFS; // } // COMMAND(get, slice_total1, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_get_slice_total1, "get slice_total1"); static int cb_openwifi_slice_start_handler(struct nl_msg *msg, void *arg) { struct nlattr *attrs[NL80211_ATTR_MAX + 1]; struct nlattr *tb[OPENWIFI_ATTR_MAX + 1]; struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); unsigned int tmp; nla_parse(attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); if (!attrs[NL80211_ATTR_TESTDATA]) return NL_SKIP; nla_parse(tb, OPENWIFI_ATTR_MAX, nla_data(attrs[NL80211_ATTR_TESTDATA]), nla_len(attrs[NL80211_ATTR_TESTDATA]), NULL); tmp = nla_get_u32(tb[OPENWIFI_ATTR_SLICE_START]); printf("openwifi slice_start (duration) %dus of slice %d\n", tmp&0xFFFFF, tmp>>20); return NL_SKIP; } static int handle_set_slice_start(struct nl80211_state *state, struct nl_cb *cb, struct nl_msg *msg, int argc, char **argv, enum id_input id) { struct nlattr *tmdata; char *end; unsigned int tmp; tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); if (!tmdata) { return 1; } tmp = strtoul(argv[0], &end, 10); if (*end) { return 1; } NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_SET_SLICE_START); NLA_PUT_U32(msg, OPENWIFI_ATTR_SLICE_START, tmp); nla_nest_end(msg, tmdata); printf("openwifi slice_start (duration): %dus\n", tmp); return 0; nla_put_failure: return -ENOBUFS; } COMMAND(set, slice_start, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_set_slice_start, "set slice_start"); static int handle_get_slice_start(struct nl80211_state *state, struct nl_cb *cb, struct nl_msg *msg, int argc, char **argv, enum id_input id) { struct nlattr *tmdata; tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); if (!tmdata) return 1; NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_GET_SLICE_START); nla_nest_end(msg, tmdata); nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_openwifi_slice_start_handler, NULL); return 0; nla_put_failure: return -ENOBUFS; } COMMAND(get, slice_start, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_get_slice_start, "get slice_start"); // static int cb_openwifi_slice_start1_handler(struct nl_msg *msg, void *arg) // { // struct nlattr *attrs[NL80211_ATTR_MAX + 1]; // struct nlattr *tb[OPENWIFI_ATTR_MAX + 1]; // struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); // nla_parse(attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); // if (!attrs[NL80211_ATTR_TESTDATA]) // return NL_SKIP; // nla_parse(tb, OPENWIFI_ATTR_MAX, nla_data(attrs[NL80211_ATTR_TESTDATA]), nla_len(attrs[NL80211_ATTR_TESTDATA]), NULL); // printf("openwifi slice_start1 (duration): %dus\n", nla_get_u32(tb[OPENWIFI_ATTR_SLICE_START1])); // return NL_SKIP; // } // static int handle_set_slice_start1(struct nl80211_state *state, // struct nl_cb *cb, // struct nl_msg *msg, // int argc, char **argv, // enum id_input id) // { // struct nlattr *tmdata; // char *end; // unsigned int tmp; // tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); // if (!tmdata) { // return 1; // } // tmp = strtoul(argv[0], &end, 10); // if (*end) { // return 1; // } // NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_SET_SLICE_START1); // NLA_PUT_U32(msg, OPENWIFI_ATTR_SLICE_START1, tmp); // nla_nest_end(msg, tmdata); // printf("openwifi slice_start1 (duration): %dus\n", tmp); // return 0; // nla_put_failure: // return -ENOBUFS; // } // COMMAND(set, slice_start1, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_set_slice_start1, "set slice_start1"); // static int handle_get_slice_start1(struct nl80211_state *state, // struct nl_cb *cb, // struct nl_msg *msg, // int argc, char **argv, // enum id_input id) // { // struct nlattr *tmdata; // tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); // if (!tmdata) // return 1; // NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_GET_SLICE_START1); // nla_nest_end(msg, tmdata); // nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_openwifi_slice_start1_handler, NULL); // return 0; // nla_put_failure: // return -ENOBUFS; // } // COMMAND(get, slice_start1, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_get_slice_start1, "get slice_start1"); static int cb_openwifi_slice_end_handler(struct nl_msg *msg, void *arg) { struct nlattr *attrs[NL80211_ATTR_MAX + 1]; struct nlattr *tb[OPENWIFI_ATTR_MAX + 1]; struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); unsigned int tmp; nla_parse(attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); if (!attrs[NL80211_ATTR_TESTDATA]) return NL_SKIP; nla_parse(tb, OPENWIFI_ATTR_MAX, nla_data(attrs[NL80211_ATTR_TESTDATA]), nla_len(attrs[NL80211_ATTR_TESTDATA]), NULL); tmp = nla_get_u32(tb[OPENWIFI_ATTR_SLICE_END]); printf("openwifi slice_end (duration) %dus of slice %d\n", tmp&0xFFFFF, tmp>>20); return NL_SKIP; } static int handle_set_slice_end(struct nl80211_state *state, struct nl_cb *cb, struct nl_msg *msg, int argc, char **argv, enum id_input id) { struct nlattr *tmdata; char *end; unsigned int tmp; tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); if (!tmdata) { return 1; } tmp = strtoul(argv[0], &end, 10); if (*end) { return 1; } NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_SET_SLICE_END); NLA_PUT_U32(msg, OPENWIFI_ATTR_SLICE_END, tmp); nla_nest_end(msg, tmdata); printf("openwifi slice_end (duration): %dus\n", tmp); return 0; nla_put_failure: return -ENOBUFS; } COMMAND(set, slice_end, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_set_slice_end, "set slice_end"); static int handle_get_slice_end(struct nl80211_state *state, struct nl_cb *cb, struct nl_msg *msg, int argc, char **argv, enum id_input id) { struct nlattr *tmdata; tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); if (!tmdata) return 1; NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_GET_SLICE_END); nla_nest_end(msg, tmdata); nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_openwifi_slice_end_handler, NULL); return 0; nla_put_failure: return -ENOBUFS; } COMMAND(get, slice_end, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_get_slice_end, "get slice_end"); // static int cb_openwifi_slice_end1_handler(struct nl_msg *msg, void *arg) // { // struct nlattr *attrs[NL80211_ATTR_MAX + 1]; // struct nlattr *tb[OPENWIFI_ATTR_MAX + 1]; // struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); // nla_parse(attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); // if (!attrs[NL80211_ATTR_TESTDATA]) // return NL_SKIP; // nla_parse(tb, OPENWIFI_ATTR_MAX, nla_data(attrs[NL80211_ATTR_TESTDATA]), nla_len(attrs[NL80211_ATTR_TESTDATA]), NULL); // printf("openwifi slice_end1 (duration): %dus\n", nla_get_u32(tb[OPENWIFI_ATTR_SLICE_END1])); // return NL_SKIP; // } // static int handle_set_slice_end1(struct nl80211_state *state, // struct nl_cb *cb, // struct nl_msg *msg, // int argc, char **argv, // enum id_input id) // { // struct nlattr *tmdata; // char *end; // unsigned int tmp; // tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); // if (!tmdata) { // return 1; // } // tmp = strtoul(argv[0], &end, 10); // if (*end) { // return 1; // } // NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_SET_SLICE_END1); // NLA_PUT_U32(msg, OPENWIFI_ATTR_SLICE_END1, tmp); // nla_nest_end(msg, tmdata); // printf("openwifi slice_end1 (duration): %dus\n", tmp); // return 0; // nla_put_failure: // return -ENOBUFS; // } // COMMAND(set, slice_end1, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_set_slice_end1, "set slice_end1"); // static int handle_get_slice_end1(struct nl80211_state *state, // struct nl_cb *cb, // struct nl_msg *msg, // int argc, char **argv, // enum id_input id) // { // struct nlattr *tmdata; // tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); // if (!tmdata) // return 1; // NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_GET_SLICE_END1); // nla_nest_end(msg, tmdata); // nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_openwifi_slice_end1_handler, NULL); // return 0; // nla_put_failure: // return -ENOBUFS; // } // COMMAND(get, slice_end1, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_get_slice_end1, "get slice_end1"); static int cb_openwifi_slice_idx_handler(struct nl_msg *msg, void *arg) { struct nlattr *attrs[NL80211_ATTR_MAX + 1]; struct nlattr *tb[OPENWIFI_ATTR_MAX + 1]; struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); nla_parse(attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); if (!attrs[NL80211_ATTR_TESTDATA]) return NL_SKIP; nla_parse(tb, OPENWIFI_ATTR_MAX, nla_data(attrs[NL80211_ATTR_TESTDATA]), nla_len(attrs[NL80211_ATTR_TESTDATA]), NULL); printf("openwifi slice_idx in hex: %08x\n", nla_get_u32(tb[OPENWIFI_ATTR_SLICE_IDX])); return NL_SKIP; } static int handle_set_slice_idx(struct nl80211_state *state, struct nl_cb *cb, struct nl_msg *msg, int argc, char **argv, enum id_input id) { struct nlattr *tmdata; char *end; unsigned int slice_idx; //printf("handle_set_slice_idx\n"); tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); if (!tmdata) { //printf("handle_set_slice_idx 1\n"); return 1; } slice_idx = strtoul(argv[0], &end, 16); if (*end) { //printf("handle_set_slice_idx 2 %d\n", slice_idx); return 1; } NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_SET_SLICE_IDX); NLA_PUT_U32(msg, OPENWIFI_ATTR_SLICE_IDX, slice_idx); nla_nest_end(msg, tmdata); printf("openwifi slice_idx in hex: %08x\n", slice_idx); return 0; nla_put_failure: return -ENOBUFS; } COMMAND(set, slice_idx, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_set_slice_idx, "set slice_idx"); static int handle_get_slice_idx(struct nl80211_state *state, struct nl_cb *cb, struct nl_msg *msg, int argc, char **argv, enum id_input id) { struct nlattr *tmdata; tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); if (!tmdata) return 1; NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_GET_SLICE_IDX); nla_nest_end(msg, tmdata); nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_openwifi_slice_idx_handler, NULL); return 0; nla_put_failure: return -ENOBUFS; } COMMAND(get, slice_idx, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_get_slice_idx, "get slice_idx"); static int cb_openwifi_slice_target_mac_addr_handler(struct nl_msg *msg, void *arg) { struct nlattr *attrs[NL80211_ATTR_MAX + 1]; struct nlattr *tb[OPENWIFI_ATTR_MAX + 1]; struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); nla_parse(attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); if (!attrs[NL80211_ATTR_TESTDATA]) return NL_SKIP; nla_parse(tb, OPENWIFI_ATTR_MAX, nla_data(attrs[NL80211_ATTR_TESTDATA]), nla_len(attrs[NL80211_ATTR_TESTDATA]), NULL); printf("openwifi slice_target_mac_addr(low32) in hex: %08x\n", nla_get_u32(tb[OPENWIFI_ATTR_ADDR])); return NL_SKIP; } static int handle_set_slice_target_mac_addr(struct nl80211_state *state, struct nl_cb *cb, struct nl_msg *msg, int argc, char **argv, enum id_input id) { struct nlattr *tmdata; char *end; unsigned int slice_target_mac_addr; tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); if (!tmdata) return 1; slice_target_mac_addr = strtoul(argv[0], &end, 16); if (*end) return 1; NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_SET_ADDR); NLA_PUT_U32(msg, OPENWIFI_ATTR_ADDR, slice_target_mac_addr); nla_nest_end(msg, tmdata); printf("openwifi slice_target_mac_addr(low32) in hex: %08x\n", slice_target_mac_addr); return 0; nla_put_failure: return -ENOBUFS; } COMMAND(set, addr, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_set_slice_target_mac_addr, "set addr"); static int handle_get_slice_target_mac_addr(struct nl80211_state *state, struct nl_cb *cb, struct nl_msg *msg, int argc, char **argv, enum id_input id) { struct nlattr *tmdata; tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); if (!tmdata) return 1; NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_GET_ADDR); nla_nest_end(msg, tmdata); nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_openwifi_slice_target_mac_addr_handler, NULL); return 0; nla_put_failure: return -ENOBUFS; } COMMAND(get, addr, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_get_slice_target_mac_addr, "get addr"); static int cb_openwifi_gap_handler(struct nl_msg *msg, void *arg) { struct nlattr *attrs[NL80211_ATTR_MAX + 1]; struct nlattr *tb[OPENWIFI_ATTR_MAX + 1]; struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); nla_parse(attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); if (!attrs[NL80211_ATTR_TESTDATA]) return NL_SKIP; nla_parse(tb, OPENWIFI_ATTR_MAX, nla_data(attrs[NL80211_ATTR_TESTDATA]), nla_len(attrs[NL80211_ATTR_TESTDATA]), NULL); printf("openwifi GAP (usec): %d\n", nla_get_u32(tb[OPENWIFI_ATTR_GAP])); return NL_SKIP; } static int handle_set_gap(struct nl80211_state *state, struct nl_cb *cb, struct nl_msg *msg, int argc, char **argv, enum id_input id) { struct nlattr *tmdata; char *end; unsigned int gap_us; //printf("handle_set_gap\n"); tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); if (!tmdata) return 1; gap_us = strtoul(argv[0], &end, 10); if (*end) return 1; NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_SET_GAP); NLA_PUT_U32(msg, OPENWIFI_ATTR_GAP, gap_us); nla_nest_end(msg, tmdata); return 0; nla_put_failure: return -ENOBUFS; } COMMAND(set, gap, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_set_gap, "set inter frame gap of openwifi radio"); static int handle_get_gap(struct nl80211_state *state, struct nl_cb *cb, struct nl_msg *msg, int argc, char **argv, enum id_input id) { struct nlattr *tmdata; tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); if (!tmdata) return 1; NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, OPENWIFI_CMD_GET_GAP); nla_nest_end(msg, tmdata); nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_openwifi_gap_handler, NULL); return 0; nla_put_failure: return -ENOBUFS; } COMMAND(get, gap, "", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_get_gap, "get inter frame gap of openwifi radio");