2 * set_oeminfo.c from Access Point SNMP Utils for Linux
4 * Copyright (c) 2005 Jan Rafaj <jr-aputils at cedric dot unob dot cz>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License Version 2 from
8 * June 1991 as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include <sys/types.h>
28 #define S_STRUCTVERSION _("Info structure version: ")
29 #define S_MAC _("[M] Device MAC address: ")
30 #define V_OUI _(" Manufacturer with this OUI: ")
31 #define S_REGDOM _("[D] Regulatory domain: ")
32 #define S_PRODTYPE _("[T] Product type: ")
33 #define S_OEMNAME _("[E] OEM name: ")
34 #define S_OEMID _("[I] OEM ID: ")
35 #define S_PRODNAME _("[N] Product name: ")
36 #define S_HWREV _("[H] Hardware revision: ")
37 #define S_COUNTRYC _("[O] Country code: ")
38 #define S_DEFCHAN _("[C] Default channel: ")
39 #define S_CHANNELS _("[A] Calibrated channels: ")
40 #define S_TXPOWER _("[P] Nominal Tx Power (CR31) value for calibrated channels: ")
41 #define OEMSET_HELP _("Keys in brackets - set corresponding option; W - write conf; Q - quit to menu")
43 extern WINDOW *main_sub;
45 extern char *channels[];
46 extern rdprops regdom_types[];
48 // TODO: test & fix for big-endian archs
50 void atmel_set_oeminfo()
52 char sysDeviceInfo[] = {
53 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x01, 0x05, 0x00
55 // Following one is only available in newer ATMEL12350 MIBs
56 char sysDeviceMoreInfo[] = {
57 0x2B, 0x06, 0x01, 0x04, 0x01, 0xE0, 0x3E, 0x01, 0x01, 0x01, 0x08, 0x00
62 int i, rd_idx, st_len;
64 struct sysDeviceInfo_128 str128; /* SHORTst */
65 struct sysDeviceInfo_160 str160; /* LONGst */
68 * These have to represent used sysDeviceInfo_{128,160} members
69 * Note that sysOIDSize, sysOID and PID_VID can NOT be written
70 * using sysDevice*Info OIDs at all - the only way to change them
71 * (highly discouraged !) is in OEM configuration file, using AP RFMD
72 * or AP INTERSIL configuration editor, followed by uploading this file
73 * to the AP using ATMEL tftp client - this way, *all* defaults
76 uint32_t StructVersion; // [4]
77 char *MacAddress; // [6]
78 // [2 reserved for SHORTst; 0 for LONGst]
79 char Channel = 0; // LONGst specific: [0 for SHORTst; 1 for LONGst]
80 uint32_t RegulatoryDomain; // [4 for SHORTst; 1 for LONGst]
81 uint32_t ProductType; // [4]
82 char *OEMName; // [32]
83 uint32_t OEMID; // [4]
84 char *ProductName; // [32]
85 uint32_t HardwareRevision; // [4]
86 /* the rest is LONGst specific */
87 char *PID_VID = NULL; // [0 for SHORTst; 4 for LONGst]
88 uint32_t sysOIDSize = 0; // [0 for SHORTst; 4 for LONGst]
89 uint16_t *sysOID = NULL; // [0 for SHORTst; 32 for LONGst]
90 char *CountryCode = NULL; // [0 for SHORTst; 3 for LONGst]
91 // [0 for SHORTst; 1 reserved for LONGst]
92 uint16_t ChannelInformation = 0; // [0 for SHORTst; 2 for LONGst]
93 // [0 for SHORTst; 2 reserved for LONGst]
94 char *TxPower = NULL; // [0 for SHORTst; 14 for LONGst]
95 // [0 for SHORTst; 10 reserved for LONGst]
99 wattrset(main_sub, A_BOLD);
100 mvwaddstr(main_sub, 2, 4,
101 _("THIS IS A SECRET MENU LEADING TO VERY DANGEROUS OPTIONS."));
102 mvwaddstr(main_sub, 3, 8,
103 _("It is intended only for WISPs and repair shops."));
104 wattrset(main_sub, A_NORMAL);
106 mvwaddstr(main_sub, 5, 1,
107 _("It allows to set OEM information stored in the AP (like its"));
108 mvwaddstr(main_sub, 6, 1,
109 _("MAC address, manuf. name, OEM ID, etc.). BE ABSOLUTELY SURE"));
110 mvwaddstr(main_sub, 7, 1,
111 _("THAT YOU KNOW WHAT YOU ARE DOING, AND THAT YOU HAVE THE"));
112 mvwaddstr(main_sub, 8, 1,
113 _("LEGAL RIGHT TO DO ANY MODIFICATION. Disobserving of these"));
114 mvwaddstr(main_sub, 9, 1,
115 _("rules may lead you into a conflict with your local"));
116 mvwaddstr(main_sub, 10, 1,
117 _("regulations and/or law."));
118 mvwaddstr(main_sub, 11, 1,
119 _("Also be warned that the setting of any from these options"));
120 mvwaddstr(main_sub, 12, 1,
121 _("may DAMAGE YOUR AP (other reason why this menu is hidden)."));
122 mvwaddstr(main_sub, 13, 1,
123 _("Values changed here will NOT be restored upon reset"));
124 mvwaddstr(main_sub, 14, 1,
125 _("of the device to factory defaults! It is advisable to"));
126 mvwaddstr(main_sub, 15, 1,
127 _("write them down somewhere prior their changing."));
128 mvwaddstr(main_sub, 16, 1,
129 _("Finally, note that you need to use MANUFACTURER community, "));
130 mvwaddstr(main_sub, 17, 1,
131 _("in order to be able to do any OEM info modification."));
132 mvwaddstr(main_sub, 18, 1,
133 _("Proceed further only at your full risk and responsibility. "));
134 mvwaddstr(main_sub, 19, 1,
135 _("You got the warnings."));
141 print_top(NULL, _("OEM Info settings"));
143 if (ap_type == ATMEL12350) {
144 sysDeviceInfo[5] = 0xE0;
145 sysDeviceInfo[6] = 0x3E;
148 varbinds[0].oid = sysDeviceInfo;
149 varbinds[0].len_oid = sizeof(sysDeviceInfo);
150 varbinds[0].value = sysDeviceInfo;
151 varbinds[0].len_val = 0;
152 varbinds[0].type = NULL_VALUE;
154 print_help(WAIT_RET);
155 if (snmp(varbinds, 1, GET) <= 0) {
156 print_helperr(ERR_RET);
160 st_len = varbinds[0].len_val;
162 if (st_len == 92 || st_len == 128) { /* SHORTst */
163 memcpy(&str128, varbinds[0].value,
164 sizeof(struct sysDeviceInfo_128));
165 StructVersion = str128.StructVersion;
166 MacAddress = str128.MacAddress;
167 RegulatoryDomain = str128.RegulatoryDomain;
168 ProductType = str128.ProductType;
169 OEMName = str128.OEMName;
170 OEMID = str128.OEMID;
171 ProductName = str128.ProductName;
172 HardwareRevision = str128.HardwareRevision;
173 } else { /* st_len == 160 => LONGst */
174 memcpy(&str160, varbinds[0].value,
175 sizeof(struct sysDeviceInfo_160));
176 StructVersion = str160.StructVersion;
177 MacAddress = str160.MacAddress;
178 Channel = str160.Channel;
179 RegulatoryDomain = str160.RegulatoryDomain;
180 ProductType = str160.ProductType;
181 OEMName = str160.OEMName;
182 OEMID = str160.OEMID;
183 ProductName = str160.ProductName;
184 HardwareRevision = str160.HardwareRevision;
185 PID_VID = str160.PID_VID;
186 sysOIDSize = str160.sysOIDSize;
187 sysOID = str160.sysOID;
188 CountryCode = str160.CountryCode;
189 ChannelInformation = str160.ChannelInformation;
190 TxPower = str160.TxPower;
195 sprintf(message, "%s%u", S_STRUCTVERSION, StructVersion);
196 mvwaddstr(main_sub, 0, 0, message);
198 sprintf(message, "%s%02X%02X%02X%02X%02X%02X", S_MAC,
199 MacAddress[0] & 0xFF, MacAddress[1] & 0xFF, MacAddress[2] & 0xFF,
200 MacAddress[3] & 0xFF, MacAddress[4] & 0xFF, MacAddress[5] & 0xFF);
201 mvwaddstr(main_sub, 1, 0, message);
202 sprintf(message, "%s%s", V_OUI, oui2manufacturer(MacAddress));
203 mvwaddstr(main_sub, 2, 0, message);
205 rd_idx = regdom_idx(RegulatoryDomain);
206 sprintf(message, "%s%s [%d]", S_REGDOM,
207 regdom_types[rd_idx].desc, RegulatoryDomain);
208 mvwaddstr(main_sub, 3, 0, message);
210 mvwaddstr(main_sub, 4, 0, S_OEMNAME);
211 for (i = 0; i < 32 && OEMName[i]; i++)
212 waddch(main_sub, OEMName[i]);
214 sprintf(message, "%s%u", S_OEMID, OEMID);
215 mvwaddstr(main_sub, 5, 0, message);
217 mvwaddstr(main_sub, 6, 0, S_PRODNAME);
218 for (i = 0; i < 32 && ProductName[i]; i++)
219 waddch(main_sub, ProductName[i]);
221 sprintf(message, _("%s%u"), S_PRODTYPE, ProductType);
222 mvwaddstr(main_sub, 7, 0, message);
224 sprintf(message, "%s%u", S_HWREV, HardwareRevision);
225 mvwaddstr(main_sub, 8, 0, message);
227 wmove(main_sub, 9, 0);
228 for (i = 0; ++i < COLS - MCOLS; waddch(main_sub, ACS_BSBS));
231 sprintf(message, "%s%s", S_COUNTRYC, CountryCode);
232 mvwaddstr(main_sub, 10, 0, message);
234 sprintf(message, "%s%02u (%u MHz)", S_DEFCHAN, Channel,
236 mvwaddstr(main_sub, 11, 0, message);
239 while(ChannelInformation >> i) i++;
240 sprintf(message, "%s%i", S_CHANNELS, i);
241 mvwaddstr(main_sub, 12, 0, message);
243 sprintf(message, "%s%u", S_TXPOWER,
244 TxPower[regdom_types[rd_idx].first_ch] & 0xFF);
245 mvwaddstr(main_sub, 13, 0, message);
247 wmove(main_sub, 18, 0);
248 for (i = 0; i < 14; i++) {
249 sprintf(message, "%-3u ", TxPower[i] & 0xFF);
250 waddstr(main_sub, message);
254 wmove(main_sub, 14, 0);
255 for (i = 0; ++i < COLS - MCOLS; waddch(main_sub, ACS_BSBS));
257 sprintf(message, "System control OID part [%u elements]: ", sysOIDSize);
258 mvwaddstr(main_sub, 15, 0, message);
260 while (i < (int)sysOIDSize) {
261 sprintf(message, ".%u", sysOID[i++]);
262 waddstr(main_sub, message);
265 sprintf(message, "USB Vendor ID: 0x%04X", (PID_VID[0] & 0xFF) |
266 ((PID_VID[1] & 0xFF) << 8));
267 mvwaddstr(main_sub, 16, 0, message);
269 sprintf(message, "USB Product ID: 0x%04X", (PID_VID[2] & 0xFF) |
270 ((PID_VID[3] & 0xFF) << 8));
271 mvwaddstr(main_sub, 17, 0, message);
276 print_help(OEMSET_HELP);
283 get_mac(MacAddress, 1, strlen(S_MAC));
284 clear_main_new(2, 3);
285 sprintf(message, "%s%s", V_OUI, oui2manufacturer(MacAddress));
286 mvwaddstr(main_sub, 2, 0, message);
291 for (i = 0; regdom_types[i].code; i++);
292 regdoms = malloc(i * sizeof(char *));
294 for (i = 0; regdom_types[i].code; i++) {
295 sprintf(message, "[%3u] %s", regdom_types[i].code,
296 regdom_types[i].desc);
297 regdoms[i] = (char *)
298 malloc(strlen(message) + 1);
299 strcpy(regdoms[i], message);
302 rd_idx = menu_choose(3, strlen(S_REGDOM), regdoms, i);
303 clear_main_new(3, 4);
304 RegulatoryDomain = regdom_types[rd_idx].code;
305 sprintf(message, "%s [%d]", regdom_types[rd_idx].desc,
307 print_menusel(3, 0, S_REGDOM, message);
315 Channel = regdom_types[rd_idx].first_ch;
316 sprintf(message, "%02u (%u MHz)", Channel,
318 print_menusel(11, 0, S_DEFCHAN, message);
323 get_value(OEMName, 4, strlen(S_OEMNAME), -32, ANY_STRING,
328 get_value(message, 5, strlen(S_OEMID), 11, INT_STRING,
329 0, 0xFFFFFFFF, OEMSET_HELP);
330 OEMID = atoi(message);
334 get_value(ProductName, 6, strlen(S_PRODNAME), -32, ANY_STRING,
339 get_value(message, 7, strlen(S_PRODTYPE), 11, INT_STRING,
340 0, 0xFFFFFFFF, OEMSET_HELP);
341 ProductType = atoi(message);
345 get_value(message, 8, strlen(S_HWREV), 11,
346 INT_STRING, 0, 0xFFFFFFFF, OEMSET_HELP);
347 HardwareRevision = atoi(message);
351 if (st_len == 92 || st_len == 128)
354 get_value(CountryCode, 10, strlen(S_COUNTRYC), 3, ANY_STRING,
359 if (st_len == 92 || st_len == 128)
362 Channel = menu_choose(11 - regdom_types[rd_idx].chans / 2,
363 strlen(S_DEFCHAN) - 2,
364 #ifndef NO_REG_DOMAIN
365 channels + regdom_types[rd_idx].first_ch - 1,
366 regdom_types[rd_idx].chans) + regdom_types[rd_idx].first_ch;
370 sprintf(message, "%02u (%u MHz)", Channel, 2407 + 5 * Channel);
371 print_menusel(11, 0, S_DEFCHAN, message);
375 if (st_len == 92 || st_len == 128)
378 get_value(message, 12, strlen(S_CHANNELS), 3, INT_STRING, 1, 14,
380 memset((void *)TxPower + 1, 0, 13);
381 for(i = 1; i < atoi(message); i++)
382 TxPower[i] = TxPower[0];
384 i = 1 << (atoi(message) - 1);
385 ChannelInformation = i | (i - 1);
389 if (st_len == 92 || st_len == 128)
392 get_value(message, 13, strlen(S_TXPOWER), 4, INT_STRING, 0, 255,
394 c = atoi(message) & 0xFF;
396 memset((void *)TxPower, 0, 14);
398 while(ChannelInformation >> i) {
403 memset((void *)TxPower, 0, 14);
404 for (i = regdom_types[rd_idx].first_ch; i <
405 regdom_types[rd_idx].first_ch + regdom_types[rd_idx].chans; i++)
414 varbinds[0].oid = sysDeviceInfo;
415 varbinds[0].len_oid = sizeof(sysDeviceInfo);
416 varbinds[0].type = STRING_VALUE;
418 if (st_len == 92 || st_len == 128) { /* SHORTst */
419 str128.RegulatoryDomain = RegulatoryDomain;
420 str128.ProductType = ProductType;
421 str128.OEMID = OEMID;
422 str128.HardwareRevision = HardwareRevision;
423 varbinds[0].value = (char *) &str128;
424 varbinds[0].len_val =
425 sizeof(struct sysDeviceInfo_128);
426 } else { /* st_len == 160 => LONGst */
427 str160.Channel = Channel;
428 str160.RegulatoryDomain = RegulatoryDomain;
429 str160.ProductType = ProductType;
430 str160.OEMID = OEMID;
431 str160.HardwareRevision = HardwareRevision;
432 str160.ChannelInformation = ChannelInformation;
433 varbinds[0].value = (char *) &str160;
434 /* first 92 bytes of struct sysDeviceInfo_160 here */
435 varbinds[0].len_val = 92;
438 print_help(WAIT_SET);
439 if (snmp(varbinds, 1, SET) <= 0) {
440 print_helperr(ERR_SET);
445 varbinds[0].oid = sysDeviceMoreInfo;
446 varbinds[0].len_oid = sizeof(sysDeviceMoreInfo);
447 varbinds[0].type = STRING_VALUE;
448 /* last 32 bytes of struct sysDeviceInfo_160 here */
449 varbinds[0].value = (char *) &str160.CountryCode;
450 varbinds[0].len_val = 32;
451 if (snmp(varbinds, 1, SET) <= 0) {
452 print_helperr(ERR_SET);
457 wbkgd(main_sub, A_NORMAL);
459 print_help(DONE_SET);
467 print_top(NULL, NULL);