]> git.decadent.org.uk Git - ap-utils.git/blob - lib/set_oeminfo.c
Imported Upstream version 1.5~pre1
[ap-utils.git] / lib / set_oeminfo.c
1 /*
2  *      sysinfo_set.c from Access Point SNMP Utils for Linux
3  *
4  * Copyright (c) Jan Rafaj <jr-aputils at cedric dot unob dot cz>
5  *
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.
9  *
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.
14  *
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
18  *
19  */
20
21 #include <stdlib.h>
22 #include <unistd.h>
23 #include <sys/time.h>
24 #include <sys/types.h>
25 #include "ap-utils.h"
26
27 #define S_STRUCTVERSION _("Info structure version: ")
28 #define S_MAC _("[M] Device MAC address: ")
29 #define V_OUI _("    Manufacturer with this OUI: ")
30 #define S_DEFCHAN _("[C] Default channel: ")
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_PIDVID _("[V] PID & VID: ")
38 #define S_COUNTRYC _("[O] Country code: ")
39 // #define S_CHANNELS _("[A] Available channels: ")
40 #define S_TXPOWER _("[P] Nominal Tx Power (CR31) value for all used channels: ")
41 #define OEMSET_HELP _("Keys in brackets - set corresponding option; W - write conf; Q - quit to menu")
42
43 extern WINDOW *main_sub;
44 extern short ap_type;
45 extern char *channels[];
46 extern rdprops regdom_types[];
47
48 // TODO: test & fix for big-endian archs
49
50 void atmel_set_oeminfo()
51 {
52     char sysDeviceInfo[] = {
53         0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x01, 0x05, 0x00
54     };
55     // Following one is only available in ATMEL12350 MIBs
56     char sysDeviceMoreInfo[] = {
57         0x2B, 0x06, 0x01, 0x04, 0x01, 0xE0, 0x3E, 0x01, 0x01, 0x01, 0x08, 0x00
58     };
59
60     char message[200], c;
61     char **regdoms;
62     int i, rd_idx;
63     varbind varbinds[1];
64     struct sysDeviceInfo_ATMEL410 str410;
65     struct sysDeviceInfo_ATMEL12350 str12350;
66
67     /*
68      * These have to represent used sysDeviceInfo_{ATMEL410,ATMEL12350} members
69      * Note that sysOIDSize and sysOID can NOT be written using sysDevice*Info
70      * OID at all.
71      */
72     uint32_t StructVersion;     // [4]
73     char *MacAddress;           // [6]
74                                 // [2 reserved for ATMEL410; 0 for ATMEL12350]
75     char Channel = 0; // ATMEL12350 specific; [0 for AT.410; 1 for ATMEL12350]
76     uint32_t RegulatoryDomain;  // [4 for ATMEL410; 1 for ATMEL12350]
77     uint32_t ProductType;       // [4]
78     char *OEMName;              // [32]
79     uint32_t OEMID;             // [4]
80     char *ProductName;          // [32]
81     uint32_t HardwareRevision;  // [4]
82     /* the rest is ATMEL12350 specific */
83     char *PID_VID = NULL;       // [0 for ATMEL410; 4 for ATMEL12350]
84     uint32_t sysOIDSize = 0;    // [0 for ATMEL410; 4 for ATMEL12350]
85     uint16_t *sysOID = NULL;    // [0 for ATMEL410; 32 for ATMEL12350]
86     char *CountryCode = NULL;   // [0 for ATMEL410; 3 for ATMEL12350]
87                                 // [0 for ATMEL410; 1 reserved for ATMEL12350]
88     uint16_t ChannelInformation = 0; // [0 for ATMEL410; 2 for ATMEL12350]
89                                 // [0 for ATMEL410; 2 reserved for ATMEL12350]
90     char *TxPower = NULL;       // [0 for ATMEL410; 14 for ATMEL12350]
91                                 // [0 for ATMEL410; 10 reserved for ATMEL12350]
92     clear_main(0);
93     noecho();
94
95     wattrset(main_sub, A_BOLD);
96     mvwaddstr(main_sub, 2, 4,
97         _("THIS IS A SECRET MENU LEADING TO VERY DANGEROUS OPTIONS."));
98     mvwaddstr(main_sub, 3, 8,
99         _("It is intended only for WISPs and repair shops."));
100     wattrset(main_sub, A_NORMAL);
101
102     mvwaddstr(main_sub, 5, 1,
103         _("It allows to set OEM information stored in the AP (like its"));
104     mvwaddstr(main_sub, 6, 1,
105         _("MAC address, manuf. name, OEM ID, etc.). BE ABSOLUTELY SURE"));
106     mvwaddstr(main_sub, 7, 1,
107         _("THAT YOU KNOW WHAT YOU ARE DOING, AND THAT YOU HAVE THE"));
108     mvwaddstr(main_sub, 8, 1,
109         _("LEGAL RIGHT TO DO ANY MODIFICATION. Disobserving of these"));
110     mvwaddstr(main_sub, 9, 1,
111         _("rules may lead you into a conflict with your local"));
112     mvwaddstr(main_sub, 10, 1,
113         _("regulations and/or law."));
114     mvwaddstr(main_sub, 11, 1,
115         _("Also be warned that the setting of any from these options"));
116     mvwaddstr(main_sub, 12, 1,
117         _("may DAMAGE YOUR AP (other reason why this menu is hidden)."));
118     mvwaddstr(main_sub, 13, 1,
119         _("Values changed here will NOT be restored upon reset"));
120     mvwaddstr(main_sub, 14, 1,
121         _("of the device to factory defaults! It is advisable to"));
122     mvwaddstr(main_sub, 15, 1,
123         _("write them down somewhere prior their changing."));
124     mvwaddstr(main_sub, 16, 1,
125         _("Finally, note that you need to use MANUFACTURER community, "));
126     mvwaddstr(main_sub, 17, 1,
127         _("in order to be able to do any OEM info modification."));
128     mvwaddstr(main_sub, 18, 1,
129         _("Proceed further only at your full risk and responsibility. "));
130     mvwaddstr(main_sub, 19, 1,
131         _("You got the warnings."));
132     wrefresh(main_sub);
133
134     if (help_ysn())
135         return;
136
137     print_top(NULL, _("OEM Info settings"));
138
139     if (ap_type == ATMEL12350) {
140         sysDeviceInfo[5] = 0xE0;
141         sysDeviceInfo[6] = 0x3E;
142     }
143
144     varbinds[0].oid = sysDeviceInfo;
145     varbinds[0].len_oid = sizeof(sysDeviceInfo);
146     varbinds[0].value = sysDeviceInfo;
147     varbinds[0].len_val = 0;
148     varbinds[0].type = NULL_VALUE;
149
150     print_help(WAIT_RET);
151     if (snmp(varbinds, 1, GET) <= 0) {
152         print_helperr(ERR_RET);
153         goto exit;
154     }
155
156     if (ap_type == ATMEL410) {
157         memcpy(&str410, varbinds[0].value,
158             sizeof(struct sysDeviceInfo_ATMEL410));
159         StructVersion           = str410.StructVersion;
160         MacAddress              = str410.MacAddress;
161         RegulatoryDomain        = str410.RegulatoryDomain;
162         ProductType             = str410.ProductType;
163         OEMName                 = str410.OEMName;
164         OEMID                   = str410.OEMID;
165         ProductName             = str410.ProductName;
166         HardwareRevision        = str410.HardwareRevision;
167     } else { /* ATMEL12350 */
168         memcpy(&str12350, varbinds[0].value,
169             sizeof(struct sysDeviceInfo_ATMEL12350));
170         StructVersion           = str12350.StructVersion;
171         MacAddress              = str12350.MacAddress;
172         Channel                 = str12350.Channel;
173         RegulatoryDomain        = str12350.RegulatoryDomain;
174         ProductType             = str12350.ProductType;
175         OEMName                 = str12350.OEMName;
176         OEMID                   = str12350.OEMID;
177         ProductName             = str12350.ProductName;
178         HardwareRevision        = str12350.HardwareRevision;
179         PID_VID                 = str12350.PID_VID;
180         sysOIDSize              = str12350.sysOIDSize;
181         sysOID                  = str12350.sysOID;
182         CountryCode             = str12350.CountryCode;
183         ChannelInformation      = str12350.ChannelInformation;
184         TxPower                 = str12350.TxPower;
185     }
186
187     clear_main(0);
188
189     sprintf(message, "%s%u", S_STRUCTVERSION, StructVersion);
190     mvwaddstr(main_sub, 0, 0, message);
191
192     sprintf(message, "%s%02X%02X%02X%02X%02X%02X", S_MAC,
193         MacAddress[0] & 0xFF, MacAddress[1] & 0xFF, MacAddress[2] & 0xFF,
194         MacAddress[3] & 0xFF, MacAddress[4] & 0xFF, MacAddress[5] & 0xFF);
195     mvwaddstr(main_sub, 1, 0, message);
196     sprintf(message, "%s%s", V_OUI, oui2manufacturer(MacAddress));
197     mvwaddstr(main_sub, 2, 0, message);
198
199     rd_idx = regdom_idx(RegulatoryDomain);
200     sprintf(message, "%s%s [%d]", S_REGDOM,
201         regdom_types[rd_idx].desc, RegulatoryDomain);
202     mvwaddstr(main_sub, 3, 0, message);
203
204     mvwaddstr(main_sub, 4, 0, S_OEMNAME);
205     for (i = 0; i < 32 && OEMName[i]; i++)
206         waddch(main_sub, OEMName[i]);
207
208     sprintf(message, "%s%u", S_OEMID, OEMID);
209     mvwaddstr(main_sub, 5, 0, message);
210
211     mvwaddstr(main_sub, 6, 0, S_PRODNAME);
212     for (i = 0; i < 32 && ProductName[i]; i++)
213         waddch(main_sub, ProductName[i]);
214
215     sprintf(message, _("%s%u"), S_PRODTYPE, ProductType);
216     mvwaddstr(main_sub, 7, 0, message);
217
218     sprintf(message, "%s%u", S_HWREV, HardwareRevision);
219     mvwaddstr(main_sub, 8, 0, message);
220
221     if (ap_type == ATMEL12350) {
222         sprintf(message, "%s%02u (%u MHz)", S_DEFCHAN, Channel,
223             2407 + 5 * Channel);
224         mvwaddstr(main_sub, 9, 0, message);
225
226         wmove(main_sub, 10, 0);
227         for (i = 0; i++ < COLS - MCOLS; waddch(main_sub, ACS_BSBS));
228
229         sprintf(message, "%s%s", S_COUNTRYC, CountryCode);
230         mvwaddstr(main_sub, 11, 0, message);
231
232 //      TODO: find out what format this is in [apparently 2x uint16?]
233 //      sprintf(message, "%s%u %u %u %u", S_PIDVID,
234 //          PID_VID[0] & 0xFF, PID_VID[1] & 0xFF,
235 //          PID_VID[2] & 0xFF, PID_VID[3] & 0xFF);
236 //      mvwaddstr(main_sub, 12, 0, message);
237
238 //      TODO: find out what format ChannelInformation is in & enable this
239 //      sprintf(message, "%s%u", S_CHANNELS, ChannelInformation);
240 //      mvwaddstr(main_sub, 13, 0, message);
241
242         sprintf(message, "%s%u", S_TXPOWER,
243             TxPower[regdom_types[rd_idx].first_ch] & 0xFF);
244         mvwaddstr(main_sub, 12, 0, message);
245 #if 0 /* DEBUG */
246         wmove(main_sub, 17, 0);
247         for (i = 0; i < 14; i++) {
248             sprintf(message, "%-3u ", TxPower[i] & 0xFF);
249             waddstr(main_sub, message);
250         }
251 #endif /* DEBUG */
252
253         sprintf(message, "[-] First %u OID elements: .%u.%u.%u.%u",
254             sysOIDSize / 2, sysOID[0], sysOID[1], sysOID[2], sysOID[3]);
255         mvwaddstr(main_sub, 13, 0, message);
256     }
257     wrefresh(main_sub);
258
259     print_help(OEMSET_HELP);
260
261     while (1) {
262         c = getch();
263         switch (c) {
264             case 'm':
265             case 'M':
266                 get_mac(MacAddress, 1, strlen(S_MAC));
267                 clear_main_new(2, 3);
268                 sprintf(message, "%s%s", V_OUI, oui2manufacturer(MacAddress));
269                 mvwaddstr(main_sub, 2, 0, message);
270                 wrefresh(main_sub);
271                 continue;
272             case 'd':
273             case 'D':
274                 for (i = 0; regdom_types[i].code; i++);
275                 regdoms = malloc(i * sizeof(char *));
276
277                 for (i = 0; regdom_types[i].code; i++) {
278                     sprintf(message, "[%3u] %s", regdom_types[i].code,
279                         regdom_types[i].desc);
280                     regdoms[i] = (char *)
281                         malloc(strlen(message) + 1);
282                     strcpy(regdoms[i], message);
283                 }
284
285                 rd_idx = menu_choose(3, strlen(S_REGDOM), regdoms, i);
286                 clear_main_new(3, 4);
287                 RegulatoryDomain = regdom_types[rd_idx].code;
288                 sprintf(message, "%s [%d]", regdom_types[rd_idx].desc,
289                     RegulatoryDomain);
290                 print_menusel(3, 0, S_REGDOM, message);
291
292                 while (i-- != 0)
293                     free(regdoms[i]);
294
295                 free(regdoms);
296
297                 if (ap_type == ATMEL12350) {
298                     Channel = regdom_types[rd_idx].first_ch;
299                     sprintf(message, "%02u (%u MHz)", Channel,
300                         2407 + 5 * Channel);
301                     print_menusel(9, 0, S_DEFCHAN, message);
302                 }
303                 continue;
304             case 'e':
305             case 'E':
306                 get_value(OEMName, 4, strlen(S_OEMNAME), -32, ANY_STRING,
307                     0, 0, NULL);
308                 continue;
309             case 'i':
310             case 'I':
311                 get_value(message, 5, strlen(S_OEMID), 11, INT_STRING,
312                     0, 0xFFFFFFFF, OEMSET_HELP);
313                 OEMID = atoi(message);
314                 continue;
315             case 'n':
316             case 'N':
317                 get_value(ProductName, 6, strlen(S_PRODNAME), -32, ANY_STRING,
318                     0, 0, NULL);
319                 continue;
320             case 't':
321             case 'T':
322                 get_value(message, 7, strlen(S_PRODTYPE), 11, INT_STRING,
323                     0, 0xFFFFFFFF, OEMSET_HELP);
324                 ProductType = atoi(message);
325                 continue;
326             case 'h':
327             case 'H':
328                 get_value(message, 8, strlen(S_HWREV), 11,
329                     INT_STRING, 0, 0xFFFFFFFF, OEMSET_HELP);
330                 HardwareRevision = atoi(message);
331                 continue;
332             case 'c':
333             case 'C':
334                 if (ap_type != ATMEL12350)
335                     continue;
336
337                 Channel = menu_choose(3, strlen(S_DEFCHAN) - 2,
338 #ifndef NO_REG_DOMAIN
339                 channels + regdom_types[rd_idx].first_ch - 1,
340                 regdom_types[rd_idx].chans) + regdom_types[rd_idx].first_ch;
341 #else
342                 channels, 14) + 1;
343 #endif
344                 sprintf(message, "%02u (%u MHz)", Channel, 2407 + 5 * Channel);
345                 print_menusel(9, 0, S_DEFCHAN, message);
346                 continue;
347             case 'o':
348             case 'O':
349                 if (ap_type != ATMEL12350)
350                     continue;
351
352                 get_value(CountryCode, 11, strlen(S_COUNTRYC), 3, ANY_STRING,
353                     0, 0, NULL);
354                 continue;
355             case 'p':
356             case 'P':
357                 if (ap_type != ATMEL12350)
358                     continue;
359
360                 memset((void *)TxPower, 0, 14);
361                 get_value(message, 12, strlen(S_TXPOWER), 4, INT_STRING, 0, 255,
362                     OEMSET_HELP);
363                 c = atoi(message) & 0xFF;
364                 for (i = regdom_types[rd_idx].first_ch; i <
365                 regdom_types[rd_idx].first_ch + regdom_types[rd_idx].chans; i++)
366                    TxPower[i - 1] = c;
367
368                 continue;
369             case 'q':
370             case 'Q':
371                 goto quit;
372             case 'w':
373             case 'W':
374                 varbinds[0].oid = sysDeviceInfo;
375                 varbinds[0].len_oid = sizeof(sysDeviceInfo);
376                 varbinds[0].type = STRING_VALUE;
377
378                 if (ap_type == ATMEL410) {
379                     str410.RegulatoryDomain     = RegulatoryDomain;
380                     str410.ProductType          = ProductType;
381                     str410.OEMID                = OEMID;
382                     str410.HardwareRevision     = HardwareRevision;
383                     varbinds[0].value = (char *) &str410;
384                     varbinds[0].len_val =
385                         sizeof(struct sysDeviceInfo_ATMEL410);
386                 } else { /* ATMEL12350 */
387                     str12350.Channel            = Channel;
388                     str12350.RegulatoryDomain   = RegulatoryDomain;
389                     str12350.ProductType        = ProductType;
390                     str12350.OEMID              = OEMID;
391                     str12350.HardwareRevision   = HardwareRevision;
392 //                  str12350.ChannelInformation = ChannelInformation;
393                     varbinds[0].value = (char *) &str12350;
394                     // first 92 bytes of struct sysDeviceInfo_ATMEL12350 here
395                     varbinds[0].len_val = 92;
396                 }
397
398                 print_help(WAIT_SET);
399                 if (snmp(varbinds, 1, SET) <= 0) {
400                     print_helperr(ERR_SET);
401                     goto exit;
402                 }
403
404                 if (ap_type == ATMEL12350) {
405                     varbinds[0].oid = sysDeviceMoreInfo;
406                     varbinds[0].len_oid = sizeof(sysDeviceMoreInfo);
407                     varbinds[0].type = STRING_VALUE;
408                     // last 32 bytes of struct sysDeviceInfo_ATMEL12350 here
409                     varbinds[0].value = (char *) &str12350.CountryCode;
410                     varbinds[0].len_val = 32;
411                     if (snmp(varbinds, 1, SET) <= 0) {
412                         print_helperr(ERR_SET);
413                         goto exit;
414                     }
415                 }
416
417                 print_help(DONE_SET);
418                 goto exit;
419         }
420     }
421
422   exit:
423     getch();
424   quit:
425     print_top(NULL, NULL);
426     clear_main(0);
427 }
428