Home | History | Annotate | Download | only in ti-utils
      1 #include <stdbool.h>
      2 #include <errno.h>
      3 #include <time.h>
      4 #include <net/if.h>
      5 #include <unistd.h>
      6 #include <sys/types.h>
      7 #include <sys/stat.h>
      8 #include <fcntl.h>
      9 #include <sys/mman.h>
     10 
     11 #include "calibrator.h"
     12 #include "plt.h"
     13 #include "ini.h"
     14 #include "nvs.h"
     15 
     16 SECTION(get);
     17 SECTION(set);
     18 
     19 static int handle_push_nvs(struct nl80211_state *state,
     20             struct nl_cb *cb,
     21             struct nl_msg *msg,
     22             int argc, char **argv)
     23 {
     24     void *map = MAP_FAILED;
     25     int fd, retval = 0;
     26     struct nlattr *key;
     27     struct stat filestat;
     28 
     29     if (argc != 1) {
     30         return 1;
     31     }
     32 
     33     fd = open(argv[0], O_RDONLY);
     34     if (fd < 0) {
     35         perror("Error opening file for reading");
     36         return 1;
     37     }
     38 
     39     if (fstat(fd, &filestat) < 0) {
     40         perror("Error stating file");
     41         return 1;
     42     }
     43 
     44     map = mmap(0, filestat.st_size, PROT_READ, MAP_SHARED, fd, 0);
     45     if (map == MAP_FAILED) {
     46         perror("Error mmapping the file");
     47         goto nla_put_failure;
     48     }
     49 
     50     key = nla_nest_start(msg, NL80211_ATTR_TESTDATA);
     51     if (!key) {
     52         goto nla_put_failure;
     53     }
     54 
     55     NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_NVS_PUSH);
     56     NLA_PUT(msg, WL1271_TM_ATTR_DATA, filestat.st_size, map);
     57 
     58     nla_nest_end(msg, key);
     59 
     60     goto cleanup;
     61 
     62 nla_put_failure:
     63     retval = -ENOBUFS;
     64 
     65 cleanup:
     66     if (map != MAP_FAILED) {
     67         munmap(map, filestat.st_size);
     68     }
     69 
     70     close(fd);
     71 
     72     return retval;
     73 }
     74 
     75 COMMAND(set, push_nvs, "<nvs filename>",
     76     NL80211_CMD_TESTMODE, 0, CIB_PHY, handle_push_nvs,
     77     "Push NVS file into the system");
     78 
     79 #if 0
     80 static int handle_fetch_nvs(struct nl80211_state *state,
     81             struct nl_cb *cb,
     82             struct nl_msg *msg,
     83             int argc, char **argv)
     84 {
     85     char *end;
     86     void *map = MAP_FAILED;
     87     int fd, retval = 0;
     88     struct nlattr *key;
     89     struct stat filestat;
     90 
     91     if (argc != 0)
     92         return 1;
     93 
     94     key = nla_nest_start(msg, NL80211_ATTR_TESTDATA);
     95     if (!key)
     96         goto nla_put_failure;
     97 
     98     NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_NVS_PUSH);
     99     NLA_PUT_U32(msg, WL1271_TM_ATTR_IE_ID, WL1271_TM_CMD_NVS_PUSH);
    100 
    101     nla_nest_end(msg, key);
    102 
    103     goto cleanup;
    104 
    105 nla_put_failure:
    106     retval = -ENOBUFS;
    107 
    108 cleanup:
    109     if (map != MAP_FAILED)
    110         munmap(map, filestat.st_size);
    111 
    112     close(fd);
    113 
    114     return retval;
    115 }
    116 
    117 COMMAND(set, fetch_nvs, NULL,
    118     NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_fetch_nvs,
    119     "Send command to fetch NVS file");
    120 #endif
    121 static int get_nvs_mac(struct nl80211_state *state, struct nl_cb *cb,
    122             struct nl_msg *msg, int argc, char **argv)
    123 {
    124     unsigned char mac_buff[12];
    125     int fd;
    126 
    127     argc -= 2;
    128     argv += 2;
    129 
    130     if (argc != 1) {
    131         return 2;
    132     }
    133 
    134     fd = open(argv[0], O_RDONLY);
    135     if (fd < 0) {
    136         perror("Error opening file for reading");
    137         return 1;
    138     }
    139 
    140     read(fd, mac_buff, 12);
    141 
    142     printf("MAC addr from NVS: %02x:%02x:%02x:%02x:%02x:%02x\n",
    143         mac_buff[11], mac_buff[10], mac_buff[6],
    144         mac_buff[5], mac_buff[4], mac_buff[3]);
    145 
    146     close(fd);
    147 
    148     return 0;
    149 }
    150 
    151 COMMAND(get, nvs_mac, "<nvs filename>", 0, 0, CIB_NONE, get_nvs_mac,
    152     "Get MAC addr from NVS file (offline)");
    153 
    154 /*
    155  * Sets MAC address in NVS.
    156  * The default value for MAC is random where 1 byte zero.
    157  */
    158 static int set_nvs_mac(struct nl80211_state *state, struct nl_cb *cb,
    159             struct nl_msg *msg, int argc, char **argv)
    160 {
    161     unsigned char mac_buff[12];
    162     unsigned char in_mac[6];
    163     int fd;
    164 
    165     argc -= 2;
    166     argv += 2;
    167 
    168     if (argc < 1 || (argc == 2 && (strlen(argv[1]) != 17))) {
    169         return 2;
    170     }
    171 
    172     if (argc == 2) {
    173         sscanf(argv[1], "%2x:%2x:%2x:%2x:%2x:%2x",
    174         (unsigned int *)&in_mac[0], (unsigned int *)&in_mac[1],
    175         (unsigned int *)&in_mac[2], (unsigned int *)&in_mac[3],
    176         (unsigned int *)&in_mac[4], (unsigned int *)&in_mac[5]);
    177     } else {
    178         srand((unsigned)time(NULL));
    179 
    180         in_mac[0] = 0x0;
    181         in_mac[1] = rand()%256;
    182         in_mac[2] = rand()%256;
    183         in_mac[3] = rand()%256;
    184         in_mac[4] = rand()%256;
    185         in_mac[5] = rand()%256;
    186     }
    187 
    188     fd = open(argv[0], O_RDWR);
    189     if (fd < 0) {
    190         perror("Error opening file for reading");
    191         return 1;
    192     }
    193 
    194     read(fd, mac_buff, 12);
    195 #if 0
    196     printf("Got MAC addr for NVS: %02x:%02x:%02x:%02x:%02x:%02x\n",
    197         in_mac[0], in_mac[1], in_mac[2],
    198         in_mac[3], in_mac[4], in_mac[5]);
    199 
    200     printf("Got MAC addr from NVS: %02x:%02x:%02x:%02x:%02x:%02x\n",
    201         mac_buff[11], mac_buff[10], mac_buff[6],
    202         mac_buff[5], mac_buff[4], mac_buff[3]);
    203 #endif
    204     mac_buff[11] = in_mac[0];
    205     mac_buff[10] = in_mac[1];
    206     mac_buff[6]  = in_mac[2];
    207     mac_buff[5]  = in_mac[3];
    208     mac_buff[4]  = in_mac[4];
    209     mac_buff[3]  = in_mac[5];
    210 
    211     lseek(fd, 0L, 0);
    212 
    213     write(fd, mac_buff, 12);
    214 
    215     close(fd);
    216 
    217     return 0;
    218 }
    219 
    220 COMMAND(set, nvs_mac, "<nvs file> [<mac addr>]", 0, 0, CIB_NONE, set_nvs_mac,
    221     "Set MAC addr in NVS file (offline), like XX:XX:XX:XX:XX:XX");
    222 
    223 static int set_ref_nvs(struct nl80211_state *state, struct nl_cb *cb,
    224             struct nl_msg *msg, int argc, char **argv)
    225 {
    226     struct wl12xx_common cmn = {
    227         .arch = UNKNOWN_ARCH,
    228         .parse_ops = NULL,
    229         .dual_mode = DUAL_MODE_UNSET,
    230         .done_fem = NO_FEM_PARSED
    231     };
    232 
    233     argc -= 2;
    234     argv += 2;
    235 
    236     if (argc != 1) {
    237         return 1;
    238     }
    239 
    240     if (read_ini(*argv, &cmn)) {
    241         fprintf(stderr, "Fail to read ini file\n");
    242         return 1;
    243     }
    244 
    245     cfg_nvs_ops(&cmn);
    246 
    247     if (create_nvs_file(&cmn)) {
    248         fprintf(stderr, "Fail to create reference NVS file\n");
    249         return 1;
    250     }
    251 #if 0
    252     printf("\n\tThe NVS file (%s) is ready\n\tCopy it to %s and "
    253         "reboot the system\n\n",
    254         NEW_NVS_NAME, CURRENT_NVS_NAME);
    255 #endif
    256     return 0;
    257 }
    258 
    259 COMMAND(set, ref_nvs, "<ini file>", 0, 0, CIB_NONE, set_ref_nvs,
    260     "Create reference NVS file");
    261 
    262 static int set_ref_nvs2(struct nl80211_state *state, struct nl_cb *cb,
    263             struct nl_msg *msg, int argc, char **argv)
    264 {
    265     struct wl12xx_common cmn = {
    266         .arch = UNKNOWN_ARCH,
    267         .parse_ops = NULL,
    268         .dual_mode = DUAL_MODE_UNSET,
    269         .done_fem = NO_FEM_PARSED
    270     };
    271 
    272     argc -= 2;
    273     argv += 2;
    274 
    275     if (argc != 2) {
    276         return 1;
    277     }
    278 
    279     if (read_ini(*argv, &cmn)) {
    280         return 1;
    281     }
    282 
    283     argv++;
    284     if (read_ini(*argv, &cmn)) {
    285         return 1;
    286     }
    287 
    288     cfg_nvs_ops(&cmn);
    289 
    290     if (create_nvs_file(&cmn)) {
    291         fprintf(stderr, "Fail to create reference NVS file\n");
    292         return 1;
    293     }
    294 #if 0
    295     printf("\n\tThe NVS file (%s) is ready\n\tCopy it to %s and "
    296         "reboot the system\n\n",
    297         NEW_NVS_NAME, CURRENT_NVS_NAME);
    298 #endif
    299     return 0;
    300 }
    301 
    302 COMMAND(set, ref_nvs2, "<ini file> <ini file>", 0, 0, CIB_NONE, set_ref_nvs2,
    303     "Create reference NVS file for 2 FEMs");
    304 
    305 static int set_upd_nvs(struct nl80211_state *state, struct nl_cb *cb,
    306     struct nl_msg *msg, int argc, char **argv)
    307 {
    308     char *fname = NULL;
    309     struct wl12xx_common cmn = {
    310         .arch = UNKNOWN_ARCH,
    311         .parse_ops = NULL
    312     };
    313 
    314     argc -= 2;
    315     argv += 2;
    316 
    317     if (argc < 1) {
    318         return 1;
    319     }
    320 
    321     if (read_ini(*argv, &cmn)) {
    322         fprintf(stderr, "Fail to read ini file\n");
    323         return 1;
    324     }
    325 
    326     cfg_nvs_ops(&cmn);
    327 
    328     if (argc == 2) {
    329         fname = *++argv;
    330     }
    331 
    332     if (update_nvs_file(fname, &cmn)) {
    333         fprintf(stderr, "Fail to update NVS file\n");
    334         return 1;
    335     }
    336 #if 0
    337     printf("\n\tThe updated NVS file (%s) is ready\n\tCopy it to %s and "
    338         "reboot the system\n\n", NEW_NVS_NAME, CURRENT_NVS_NAME);
    339 #endif
    340     return 0;
    341 }
    342 
    343 COMMAND(set, upd_nvs, "<ini file> [<nvs file>]", 0, 0, CIB_NONE, set_upd_nvs,
    344     "Update values of a NVS from INI file");
    345 
    346 static int get_dump_nvs(struct nl80211_state *state, struct nl_cb *cb,
    347             struct nl_msg *msg, int argc, char **argv)
    348 {
    349     char *fname = NULL;
    350     struct wl12xx_common cmn = {
    351         .arch = UNKNOWN_ARCH,
    352         .parse_ops = NULL
    353     };
    354 
    355     argc -= 2;
    356     argv += 2;
    357 
    358     if (argc > 0) {
    359         fname = *argv;
    360     }
    361 
    362     if (dump_nvs_file(fname, &cmn)) {
    363         fprintf(stderr, "Fail to dump NVS file\n");
    364         return 1;
    365     }
    366 
    367     return 0;
    368 }
    369 
    370 COMMAND(get, dump_nvs, "[<nvs file>]", 0, 0, CIB_NONE, get_dump_nvs,
    371     "Dump NVS file, specified by option or current");
    372 
    373 static int set_autofem(struct nl80211_state *state, struct nl_cb *cb,
    374             struct nl_msg *msg, int argc, char **argv)
    375 {
    376     char *fname = NULL;
    377     unsigned char val;
    378     struct wl12xx_common cmn = {
    379         .arch = UNKNOWN_ARCH,
    380         .parse_ops = NULL
    381     };
    382 
    383     argc -= 2;
    384     argv += 2;
    385 
    386     if (argc < 1) {
    387         fprintf(stderr, "Missing argument\n");
    388         return 2;
    389     }
    390 
    391     sscanf(argv[0], "%2x", (unsigned int *)&val);
    392 
    393     if (argc == 2) {
    394         fname = argv[1];
    395     }
    396 
    397     if (set_nvs_file_autofem(fname, val, &cmn)) {
    398         fprintf(stderr, "Fail to set AutoFEM\n");
    399         return 1;
    400     }
    401 
    402     return 0;
    403 }
    404 
    405 COMMAND(set, autofem, "<0-manual|1-auto> [<nvs file>]", 0, 0, CIB_NONE, set_autofem,
    406     "Set Auto FEM detection, where 0 - manual, 1 - auto detection");
    407 
    408 static int set_fem_manuf(struct nl80211_state *state, struct nl_cb *cb,
    409             struct nl_msg *msg, int argc, char **argv)
    410 {
    411     char *fname = NULL;
    412     unsigned char val;
    413     struct wl12xx_common cmn = {
    414         .arch = UNKNOWN_ARCH,
    415         .parse_ops = NULL
    416     };
    417 
    418     argc -= 2;
    419     argv += 2;
    420 
    421     if (argc < 1) {
    422         fprintf(stderr, "Missing argument\n");
    423         return 2;
    424     }
    425 
    426     sscanf(argv[0], "%2x", (unsigned int *)&val);
    427 
    428     if (argc == 2) {
    429         fname = argv[1];
    430     }
    431 
    432     if (set_nvs_file_fem_manuf(fname, val, &cmn)) {
    433         fprintf(stderr, "Fail to set AutoFEM\n");
    434         return 1;
    435     }
    436 
    437     return 0;
    438 }
    439 
    440 COMMAND(set, fem_manuf, "<0|1> [<nvs file>]", 0, 0, CIB_NONE, set_fem_manuf,
    441     "Set FEM manufacturer");
    442 
    443