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