]> git.decadent.org.uk Git - ap-utils.git/blobdiff - lib/set_oeminfo.c
Imported Upstream version 1.5~pre1
[ap-utils.git] / lib / set_oeminfo.c
diff --git a/lib/set_oeminfo.c b/lib/set_oeminfo.c
new file mode 100644 (file)
index 0000000..a150bd4
--- /dev/null
@@ -0,0 +1,428 @@
+/*
+ *      sysinfo_set.c from Access Point SNMP Utils for Linux
+ *
+ * Copyright (c) Jan Rafaj <jr-aputils at cedric dot unob dot cz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 from
+ * June 1991 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include "ap-utils.h"
+
+#define S_STRUCTVERSION _("Info structure version: ")
+#define S_MAC _("[M] Device MAC address: ")
+#define V_OUI _("    Manufacturer with this OUI: ")
+#define S_DEFCHAN _("[C] Default channel: ")
+#define S_REGDOM _("[D] Regulatory domain: ")
+#define S_PRODTYPE _("[T] Product type: ")
+#define S_OEMNAME _("[E] OEM name: ")
+#define S_OEMID _("[I] OEM ID: ")
+#define S_PRODNAME _("[N] Product name: ")
+#define S_HWREV _("[H] Hardware revision: ")
+// #define S_PIDVID _("[V] PID & VID: ")
+#define S_COUNTRYC _("[O] Country code: ")
+// #define S_CHANNELS _("[A] Available channels: ")
+#define S_TXPOWER _("[P] Nominal Tx Power (CR31) value for all used channels: ")
+#define OEMSET_HELP _("Keys in brackets - set corresponding option; W - write conf; Q - quit to menu")
+
+extern WINDOW *main_sub;
+extern short ap_type;
+extern char *channels[];
+extern rdprops regdom_types[];
+
+// TODO: test & fix for big-endian archs
+
+void atmel_set_oeminfo()
+{
+    char sysDeviceInfo[] = {
+       0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x01, 0x05, 0x00
+    };
+    // Following one is only available in ATMEL12350 MIBs
+    char sysDeviceMoreInfo[] = {
+       0x2B, 0x06, 0x01, 0x04, 0x01, 0xE0, 0x3E, 0x01, 0x01, 0x01, 0x08, 0x00
+    };
+
+    char message[200], c;
+    char **regdoms;
+    int i, rd_idx;
+    varbind varbinds[1];
+    struct sysDeviceInfo_ATMEL410 str410;
+    struct sysDeviceInfo_ATMEL12350 str12350;
+
+    /*
+     * These have to represent used sysDeviceInfo_{ATMEL410,ATMEL12350} members
+     * Note that sysOIDSize and sysOID can NOT be written using sysDevice*Info
+     * OID at all.
+     */
+    uint32_t StructVersion;    // [4]
+    char *MacAddress;          // [6]
+                               // [2 reserved for ATMEL410; 0 for ATMEL12350]
+    char Channel = 0; // ATMEL12350 specific; [0 for AT.410; 1 for ATMEL12350]
+    uint32_t RegulatoryDomain; // [4 for ATMEL410; 1 for ATMEL12350]
+    uint32_t ProductType;      // [4]
+    char *OEMName;             // [32]
+    uint32_t OEMID;            // [4]
+    char *ProductName;         // [32]
+    uint32_t HardwareRevision; // [4]
+    /* the rest is ATMEL12350 specific */
+    char *PID_VID = NULL;      // [0 for ATMEL410; 4 for ATMEL12350]
+    uint32_t sysOIDSize = 0;   // [0 for ATMEL410; 4 for ATMEL12350]
+    uint16_t *sysOID = NULL;   // [0 for ATMEL410; 32 for ATMEL12350]
+    char *CountryCode = NULL;  // [0 for ATMEL410; 3 for ATMEL12350]
+                               // [0 for ATMEL410; 1 reserved for ATMEL12350]
+    uint16_t ChannelInformation = 0; // [0 for ATMEL410; 2 for ATMEL12350]
+                               // [0 for ATMEL410; 2 reserved for ATMEL12350]
+    char *TxPower = NULL;      // [0 for ATMEL410; 14 for ATMEL12350]
+                               // [0 for ATMEL410; 10 reserved for ATMEL12350]
+    clear_main(0);
+    noecho();
+
+    wattrset(main_sub, A_BOLD);
+    mvwaddstr(main_sub, 2, 4,
+       _("THIS IS A SECRET MENU LEADING TO VERY DANGEROUS OPTIONS."));
+    mvwaddstr(main_sub, 3, 8,
+       _("It is intended only for WISPs and repair shops."));
+    wattrset(main_sub, A_NORMAL);
+
+    mvwaddstr(main_sub, 5, 1,
+       _("It allows to set OEM information stored in the AP (like its"));
+    mvwaddstr(main_sub, 6, 1,
+       _("MAC address, manuf. name, OEM ID, etc.). BE ABSOLUTELY SURE"));
+    mvwaddstr(main_sub, 7, 1,
+       _("THAT YOU KNOW WHAT YOU ARE DOING, AND THAT YOU HAVE THE"));
+    mvwaddstr(main_sub, 8, 1,
+       _("LEGAL RIGHT TO DO ANY MODIFICATION. Disobserving of these"));
+    mvwaddstr(main_sub, 9, 1,
+       _("rules may lead you into a conflict with your local"));
+    mvwaddstr(main_sub, 10, 1,
+       _("regulations and/or law."));
+    mvwaddstr(main_sub, 11, 1,
+       _("Also be warned that the setting of any from these options"));
+    mvwaddstr(main_sub, 12, 1,
+       _("may DAMAGE YOUR AP (other reason why this menu is hidden)."));
+    mvwaddstr(main_sub, 13, 1,
+       _("Values changed here will NOT be restored upon reset"));
+    mvwaddstr(main_sub, 14, 1,
+       _("of the device to factory defaults! It is advisable to"));
+    mvwaddstr(main_sub, 15, 1,
+       _("write them down somewhere prior their changing."));
+    mvwaddstr(main_sub, 16, 1,
+       _("Finally, note that you need to use MANUFACTURER community, "));
+    mvwaddstr(main_sub, 17, 1,
+       _("in order to be able to do any OEM info modification."));
+    mvwaddstr(main_sub, 18, 1,
+       _("Proceed further only at your full risk and responsibility. "));
+    mvwaddstr(main_sub, 19, 1,
+       _("You got the warnings."));
+    wrefresh(main_sub);
+
+    if (help_ysn())
+       return;
+
+    print_top(NULL, _("OEM Info settings"));
+
+    if (ap_type == ATMEL12350) {
+       sysDeviceInfo[5] = 0xE0;
+       sysDeviceInfo[6] = 0x3E;
+    }
+
+    varbinds[0].oid = sysDeviceInfo;
+    varbinds[0].len_oid = sizeof(sysDeviceInfo);
+    varbinds[0].value = sysDeviceInfo;
+    varbinds[0].len_val = 0;
+    varbinds[0].type = NULL_VALUE;
+
+    print_help(WAIT_RET);
+    if (snmp(varbinds, 1, GET) <= 0) {
+       print_helperr(ERR_RET);
+       goto exit;
+    }
+
+    if (ap_type == ATMEL410) {
+       memcpy(&str410, varbinds[0].value,
+           sizeof(struct sysDeviceInfo_ATMEL410));
+       StructVersion           = str410.StructVersion;
+       MacAddress              = str410.MacAddress;
+       RegulatoryDomain        = str410.RegulatoryDomain;
+       ProductType             = str410.ProductType;
+       OEMName                 = str410.OEMName;
+       OEMID                   = str410.OEMID;
+       ProductName             = str410.ProductName;
+       HardwareRevision        = str410.HardwareRevision;
+    } else { /* ATMEL12350 */
+       memcpy(&str12350, varbinds[0].value,
+           sizeof(struct sysDeviceInfo_ATMEL12350));
+       StructVersion           = str12350.StructVersion;
+       MacAddress              = str12350.MacAddress;
+       Channel                 = str12350.Channel;
+       RegulatoryDomain        = str12350.RegulatoryDomain;
+       ProductType             = str12350.ProductType;
+       OEMName                 = str12350.OEMName;
+       OEMID                   = str12350.OEMID;
+       ProductName             = str12350.ProductName;
+       HardwareRevision        = str12350.HardwareRevision;
+       PID_VID                 = str12350.PID_VID;
+       sysOIDSize              = str12350.sysOIDSize;
+       sysOID                  = str12350.sysOID;
+       CountryCode             = str12350.CountryCode;
+       ChannelInformation      = str12350.ChannelInformation;
+       TxPower                 = str12350.TxPower;
+    }
+
+    clear_main(0);
+
+    sprintf(message, "%s%u", S_STRUCTVERSION, StructVersion);
+    mvwaddstr(main_sub, 0, 0, message);
+
+    sprintf(message, "%s%02X%02X%02X%02X%02X%02X", S_MAC,
+       MacAddress[0] & 0xFF, MacAddress[1] & 0xFF, MacAddress[2] & 0xFF,
+       MacAddress[3] & 0xFF, MacAddress[4] & 0xFF, MacAddress[5] & 0xFF);
+    mvwaddstr(main_sub, 1, 0, message);
+    sprintf(message, "%s%s", V_OUI, oui2manufacturer(MacAddress));
+    mvwaddstr(main_sub, 2, 0, message);
+
+    rd_idx = regdom_idx(RegulatoryDomain);
+    sprintf(message, "%s%s [%d]", S_REGDOM,
+       regdom_types[rd_idx].desc, RegulatoryDomain);
+    mvwaddstr(main_sub, 3, 0, message);
+
+    mvwaddstr(main_sub, 4, 0, S_OEMNAME);
+    for (i = 0; i < 32 && OEMName[i]; i++)
+       waddch(main_sub, OEMName[i]);
+
+    sprintf(message, "%s%u", S_OEMID, OEMID);
+    mvwaddstr(main_sub, 5, 0, message);
+
+    mvwaddstr(main_sub, 6, 0, S_PRODNAME);
+    for (i = 0; i < 32 && ProductName[i]; i++)
+       waddch(main_sub, ProductName[i]);
+
+    sprintf(message, _("%s%u"), S_PRODTYPE, ProductType);
+    mvwaddstr(main_sub, 7, 0, message);
+
+    sprintf(message, "%s%u", S_HWREV, HardwareRevision);
+    mvwaddstr(main_sub, 8, 0, message);
+
+    if (ap_type == ATMEL12350) {
+       sprintf(message, "%s%02u (%u MHz)", S_DEFCHAN, Channel,
+           2407 + 5 * Channel);
+       mvwaddstr(main_sub, 9, 0, message);
+
+       wmove(main_sub, 10, 0);
+       for (i = 0; i++ < COLS - MCOLS; waddch(main_sub, ACS_BSBS));
+
+       sprintf(message, "%s%s", S_COUNTRYC, CountryCode);
+       mvwaddstr(main_sub, 11, 0, message);
+
+//     TODO: find out what format this is in [apparently 2x uint16?]
+//     sprintf(message, "%s%u %u %u %u", S_PIDVID,
+//         PID_VID[0] & 0xFF, PID_VID[1] & 0xFF,
+//         PID_VID[2] & 0xFF, PID_VID[3] & 0xFF);
+//     mvwaddstr(main_sub, 12, 0, message);
+
+//     TODO: find out what format ChannelInformation is in & enable this
+//     sprintf(message, "%s%u", S_CHANNELS, ChannelInformation);
+//     mvwaddstr(main_sub, 13, 0, message);
+
+       sprintf(message, "%s%u", S_TXPOWER,
+           TxPower[regdom_types[rd_idx].first_ch] & 0xFF);
+       mvwaddstr(main_sub, 12, 0, message);
+#if 0 /* DEBUG */
+       wmove(main_sub, 17, 0);
+       for (i = 0; i < 14; i++) {
+           sprintf(message, "%-3u ", TxPower[i] & 0xFF);
+           waddstr(main_sub, message);
+       }
+#endif /* DEBUG */
+
+       sprintf(message, "[-] First %u OID elements: .%u.%u.%u.%u",
+           sysOIDSize / 2, sysOID[0], sysOID[1], sysOID[2], sysOID[3]);
+       mvwaddstr(main_sub, 13, 0, message);
+    }
+    wrefresh(main_sub);
+
+    print_help(OEMSET_HELP);
+
+    while (1) {
+       c = getch();
+       switch (c) {
+           case 'm':
+           case 'M':
+               get_mac(MacAddress, 1, strlen(S_MAC));
+               clear_main_new(2, 3);
+               sprintf(message, "%s%s", V_OUI, oui2manufacturer(MacAddress));
+               mvwaddstr(main_sub, 2, 0, message);
+               wrefresh(main_sub);
+               continue;
+           case 'd':
+           case 'D':
+               for (i = 0; regdom_types[i].code; i++);
+               regdoms = malloc(i * sizeof(char *));
+
+               for (i = 0; regdom_types[i].code; i++) {
+                   sprintf(message, "[%3u] %s", regdom_types[i].code,
+                       regdom_types[i].desc);
+                   regdoms[i] = (char *)
+                       malloc(strlen(message) + 1);
+                   strcpy(regdoms[i], message);
+               }
+
+               rd_idx = menu_choose(3, strlen(S_REGDOM), regdoms, i);
+               clear_main_new(3, 4);
+               RegulatoryDomain = regdom_types[rd_idx].code;
+               sprintf(message, "%s [%d]", regdom_types[rd_idx].desc,
+                   RegulatoryDomain);
+               print_menusel(3, 0, S_REGDOM, message);
+
+               while (i-- != 0)
+                   free(regdoms[i]);
+
+               free(regdoms);
+
+               if (ap_type == ATMEL12350) {
+                   Channel = regdom_types[rd_idx].first_ch;
+                   sprintf(message, "%02u (%u MHz)", Channel,
+                       2407 + 5 * Channel);
+                   print_menusel(9, 0, S_DEFCHAN, message);
+               }
+               continue;
+           case 'e':
+           case 'E':
+               get_value(OEMName, 4, strlen(S_OEMNAME), -32, ANY_STRING,
+                   0, 0, NULL);
+               continue;
+           case 'i':
+           case 'I':
+               get_value(message, 5, strlen(S_OEMID), 11, INT_STRING,
+                   0, 0xFFFFFFFF, OEMSET_HELP);
+               OEMID = atoi(message);
+               continue;
+           case 'n':
+           case 'N':
+               get_value(ProductName, 6, strlen(S_PRODNAME), -32, ANY_STRING,
+                   0, 0, NULL);
+               continue;
+           case 't':
+           case 'T':
+               get_value(message, 7, strlen(S_PRODTYPE), 11, INT_STRING,
+                   0, 0xFFFFFFFF, OEMSET_HELP);
+               ProductType = atoi(message);
+               continue;
+           case 'h':
+           case 'H':
+               get_value(message, 8, strlen(S_HWREV), 11,
+                   INT_STRING, 0, 0xFFFFFFFF, OEMSET_HELP);
+               HardwareRevision = atoi(message);
+               continue;
+           case 'c':
+           case 'C':
+               if (ap_type != ATMEL12350)
+                   continue;
+
+               Channel = menu_choose(3, strlen(S_DEFCHAN) - 2,
+#ifndef NO_REG_DOMAIN
+                channels + regdom_types[rd_idx].first_ch - 1,
+                regdom_types[rd_idx].chans) + regdom_types[rd_idx].first_ch;
+#else
+                channels, 14) + 1;
+#endif
+               sprintf(message, "%02u (%u MHz)", Channel, 2407 + 5 * Channel);
+               print_menusel(9, 0, S_DEFCHAN, message);
+               continue;
+           case 'o':
+           case 'O':
+               if (ap_type != ATMEL12350)
+                   continue;
+
+               get_value(CountryCode, 11, strlen(S_COUNTRYC), 3, ANY_STRING,
+                   0, 0, NULL);
+               continue;
+           case 'p':
+           case 'P':
+               if (ap_type != ATMEL12350)
+                   continue;
+
+               memset((void *)TxPower, 0, 14);
+               get_value(message, 12, strlen(S_TXPOWER), 4, INT_STRING, 0, 255,
+                   OEMSET_HELP);
+               c = atoi(message) & 0xFF;
+               for (i = regdom_types[rd_idx].first_ch; i <
+               regdom_types[rd_idx].first_ch + regdom_types[rd_idx].chans; i++)
+                  TxPower[i - 1] = c;
+
+               continue;
+           case 'q':
+           case 'Q':
+               goto quit;
+           case 'w':
+           case 'W':
+               varbinds[0].oid = sysDeviceInfo;
+               varbinds[0].len_oid = sizeof(sysDeviceInfo);
+               varbinds[0].type = STRING_VALUE;
+
+               if (ap_type == ATMEL410) {
+                   str410.RegulatoryDomain     = RegulatoryDomain;
+                   str410.ProductType          = ProductType;
+                   str410.OEMID                = OEMID;
+                   str410.HardwareRevision     = HardwareRevision;
+                   varbinds[0].value = (char *) &str410;
+                   varbinds[0].len_val =
+                       sizeof(struct sysDeviceInfo_ATMEL410);
+               } else { /* ATMEL12350 */
+                   str12350.Channel            = Channel;
+                   str12350.RegulatoryDomain   = RegulatoryDomain;
+                   str12350.ProductType        = ProductType;
+                   str12350.OEMID              = OEMID;
+                   str12350.HardwareRevision   = HardwareRevision;
+//                 str12350.ChannelInformation = ChannelInformation;
+                   varbinds[0].value = (char *) &str12350;
+                   // first 92 bytes of struct sysDeviceInfo_ATMEL12350 here
+                   varbinds[0].len_val = 92;
+               }
+
+               print_help(WAIT_SET);
+               if (snmp(varbinds, 1, SET) <= 0) {
+                   print_helperr(ERR_SET);
+                   goto exit;
+               }
+
+               if (ap_type == ATMEL12350) {
+                   varbinds[0].oid = sysDeviceMoreInfo;
+                   varbinds[0].len_oid = sizeof(sysDeviceMoreInfo);
+                   varbinds[0].type = STRING_VALUE;
+                   // last 32 bytes of struct sysDeviceInfo_ATMEL12350 here
+                   varbinds[0].value = (char *) &str12350.CountryCode;
+                   varbinds[0].len_val = 32;
+                   if (snmp(varbinds, 1, SET) <= 0) {
+                       print_helperr(ERR_SET);
+                       goto exit;
+                   }
+               }
+
+               print_help(DONE_SET);
+               goto exit;
+       }
+    }
+
+  exit:
+    getch();
+  quit:
+    print_top(NULL, NULL);
+    clear_main(0);
+}
+