]>
Commit | Line | Data |
---|---|---|
942b5cd8 JB |
1 | #include <errno.h> |
2 | ||
3 | #include "nl80211.h" | |
4 | #include "iw.h" | |
5 | ||
6 | ||
7 | static int handle_bitrates(struct nl80211_state *state, | |
8 | struct nl_cb *cb, | |
9 | struct nl_msg *msg, | |
10 | int argc, char **argv) | |
11 | { | |
12 | struct nlattr *nl_rates, *nl_band; | |
13 | int i; | |
14 | bool have_legacy_24 = false, have_legacy_5 = false; | |
15 | uint8_t legacy_24[32], legacy_5[32]; | |
16 | int n_legacy_24 = 0, n_legacy_5 = 0; | |
17 | uint8_t *legacy = NULL; | |
18 | int *n_legacy = NULL; | |
19 | bool have_mcs_24 = false, have_mcs_5 = false; | |
942b5cd8 JB |
20 | uint8_t mcs_24[77], mcs_5[77]; |
21 | int n_mcs_24 = 0, n_mcs_5 = 0; | |
22 | uint8_t *mcs = NULL; | |
23 | int *n_mcs = NULL; | |
942b5cd8 JB |
24 | enum { |
25 | S_NONE, | |
26 | S_LEGACY, | |
27 | S_MCS, | |
28 | } parser_state = S_NONE; | |
29 | ||
30 | for (i = 0; i < argc; i++) { | |
31 | char *end; | |
bd0f464b | 32 | double tmpd; |
942b5cd8 | 33 | long tmpl; |
942b5cd8 JB |
34 | |
35 | if (strcmp(argv[i], "legacy-2.4") == 0) { | |
36 | if (have_legacy_24) | |
37 | return 1; | |
38 | parser_state = S_LEGACY; | |
39 | legacy = legacy_24; | |
40 | n_legacy = &n_legacy_24; | |
41 | have_legacy_24 = true; | |
42 | } else if (strcmp(argv[i], "legacy-5") == 0) { | |
43 | if (have_legacy_5) | |
44 | return 1; | |
45 | parser_state = S_LEGACY; | |
46 | legacy = legacy_5; | |
47 | n_legacy = &n_legacy_5; | |
48 | have_legacy_5 = true; | |
49 | } | |
942b5cd8 JB |
50 | else if (strcmp(argv[i], "mcs-2.4") == 0) { |
51 | if (have_mcs_24) | |
52 | return 1; | |
53 | parser_state = S_MCS; | |
54 | mcs = mcs_24; | |
55 | n_mcs = &n_mcs_24; | |
56 | have_mcs_24 = true; | |
57 | } else if (strcmp(argv[i], "mcs-5") == 0) { | |
58 | if (have_mcs_5) | |
59 | return 1; | |
60 | parser_state = S_MCS; | |
61 | mcs = mcs_5; | |
62 | n_mcs = &n_mcs_5; | |
63 | have_mcs_5 = true; | |
64 | } | |
942b5cd8 JB |
65 | else switch (parser_state) { |
66 | case S_LEGACY: | |
bd0f464b | 67 | tmpd = strtod(argv[i], &end); |
942b5cd8 JB |
68 | if (*end != '\0') |
69 | return 1; | |
bd0f464b | 70 | if (tmpd < 1 || tmpd > 255 * 2) |
942b5cd8 | 71 | return 1; |
bd0f464b | 72 | legacy[(*n_legacy)++] = tmpd * 2; |
942b5cd8 JB |
73 | break; |
74 | case S_MCS: | |
942b5cd8 JB |
75 | tmpl = strtol(argv[i], &end, 0); |
76 | if (*end != '\0') | |
77 | return 1; | |
78 | if (tmpl < 0 || tmpl > 255) | |
79 | return 1; | |
80 | mcs[(*n_mcs)++] = tmpl; | |
81 | break; | |
942b5cd8 JB |
82 | default: |
83 | return 1; | |
84 | } | |
85 | } | |
86 | ||
87 | nl_rates = nla_nest_start(msg, NL80211_ATTR_TX_RATES); | |
88 | if (!nl_rates) | |
89 | goto nla_put_failure; | |
90 | ||
91 | if (have_legacy_24 || have_mcs_24) { | |
92 | nl_band = nla_nest_start(msg, NL80211_BAND_2GHZ); | |
93 | if (!nl_band) | |
94 | goto nla_put_failure; | |
95 | if (have_legacy_24) | |
96 | nla_put(msg, NL80211_TXRATE_LEGACY, n_legacy_24, legacy_24); | |
942b5cd8 JB |
97 | if (have_mcs_24) |
98 | nla_put(msg, NL80211_TXRATE_MCS, n_mcs_24, mcs_24); | |
942b5cd8 JB |
99 | nla_nest_end(msg, nl_band); |
100 | } | |
101 | ||
102 | if (have_legacy_5 || have_mcs_5) { | |
103 | nl_band = nla_nest_start(msg, NL80211_BAND_5GHZ); | |
104 | if (!nl_band) | |
105 | goto nla_put_failure; | |
106 | if (have_legacy_5) | |
107 | nla_put(msg, NL80211_TXRATE_LEGACY, n_legacy_5, legacy_5); | |
942b5cd8 JB |
108 | if (have_mcs_5) |
109 | nla_put(msg, NL80211_TXRATE_MCS, n_mcs_5, mcs_5); | |
942b5cd8 JB |
110 | nla_nest_end(msg, nl_band); |
111 | } | |
112 | ||
113 | nla_nest_end(msg, nl_rates); | |
114 | ||
115 | return 0; | |
116 | nla_put_failure: | |
117 | return -ENOBUFS; | |
118 | } | |
119 | ||
120 | #define DESCR_LEGACY "[legacy-<2.4|5> <legacy rate in Mbps>*]" | |
942b5cd8 | 121 | #define DESCR DESCR_LEGACY " [mcs-<2.4|5> <MCS index>*]" |
942b5cd8 | 122 | |
135e65d6 SW |
123 | COMMAND(set, bitrates, "[legacy-<2.4|5> <legacy rate in Mbps>*] [mcs-<2.4|5> <MCS index>*]", |
124 | NL80211_CMD_SET_TX_BITRATE_MASK, 0, CIB_NETDEV, handle_bitrates, | |
dce7b720 SM |
125 | "Sets up the specified rate masks.\n" |
126 | "Not passing any arguments would clear the existing mask (if any)."); |