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