/* * Create an image file for the MTCDP ID EEPROM * * Copyright (C) 2016, 2019 by Multi-Tech Systems * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * 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 * * 2012-07-30 JSR - Added wifi and bluetooth capa flags */ #include #include #include #include #include #include #include #include #include #include #include #ifdef MTCDT3B #include #include #endif #include "log.h" #include "eeprom.h" #define EEPROM_LAYOUT_VERSION 1 static int eeprom_size = 512; static void mts_id_eeprom_inspect(struct mts_id_eeprom_layout *id_eeprom); static void mts_ap_eeprom_inspect(struct mts_ap_eeprom_layout *ap_eeprom); #ifdef MTCDT3B static void mtcdt3b_eeprom_inspect(struct mtcdt3b_eeprom_layout *mtcdt3b_eeprom); static void mtcdt3dc_eeprom_inspect(struct mtcdt3dc_eeprom_layout *mtcdt3dc_eeprom); #endif //Returns 0 on success, 1 on failure static unsigned int charToInt(char ch, unsigned int* i) { if (ch >= '0' && ch <= '9') { *i = ch - '0'; } else if (ch >= 'a' && ch <= 'f') { *i = ch - 'a' + 10; } else if (ch >= 'A' && ch <= 'F') { *i = ch - 'A' + 10; } else { return 1; } return 0; } //Retuns number of bytes converted, -1 on error static int asciiHexToBin(const char* asciiHex, char* bin) { int count = 0; unsigned int upper, lower; while(asciiHex[0] && asciiHex[1]) { if(charToInt(asciiHex[0], &upper) == 0 && charToInt(asciiHex[1], &lower) == 0) { *bin = (upper << 4) + lower; bin++; asciiHex += 2; count++; } else { return -1; } } return count; } static int hwaddr_aton(const char *str, uint8_t *buf, size_t len) { size_t count = 0; for (;;) { unsigned acc; char ch; acc = 0; while ((ch = *str) != ':' && ch != 0) { if (ch >= '0' && ch <= '9') { ch -= '0'; } else if (ch >= 'a' && ch <= 'f') { ch -= 'a' - 10; } else if (ch >= 'A' && ch <= 'F') { ch -= 'A' - 10; } else { return 0; } acc = (acc << 4) + ch; str++; } if (acc > 255) { return 0; } if (count >= len) { return 0; } buf[count] = acc; count++; if (ch == 0) { break; } str++; } if (count < len) { return 0; } return 1; } static int id_yaml_out(const char *name, struct mts_id_eeprom_layout *id_eeprom) { int i; char buf[64] = {0}; char* ptr; FILE *file; if (!strcmp(name, "-")) { file = stdout; } else { file = fopen(name, "w+"); if (!file) { log_error("could not open %s: %m", name); return -1; } } fprintf(file, "---\n"); fprintf(file, "\n"); fprintf(file, "EEPROM-Layout-Version: \"%u\"\n", id_eeprom->eeprom_layout_version); fprintf(file, "vendor-id: \"%.32s\"\n", id_eeprom->vendor_id); fprintf(file, "product-id: \"%.32s\"\n", id_eeprom->product_id); fprintf(file, "device-id: \"%.32s\"\n", id_eeprom->device_id); fprintf(file, "hw-version: \"%.32s\"\n", id_eeprom->hw_version); fprintf(file, "mac-addr: \"%02X:%02X:%02X:%02X:%02X:%02X\"\n", id_eeprom->mac_addr[0], id_eeprom->mac_addr[1], id_eeprom->mac_addr[2], id_eeprom->mac_addr[3], id_eeprom->mac_addr[4], id_eeprom->mac_addr[5]); fprintf(file, "imei: \"%.32s\"\n", id_eeprom->imei); fprintf(file, "capa-gps: %s\n", DEVICE_CAPA(id_eeprom->capa, CAPA_GPS) ? "true" : "false"); fprintf(file, "capa-din: %s\n", DEVICE_CAPA(id_eeprom->capa, CAPA_DIN) ? "true" : "false"); fprintf(file, "capa-dout: %s\n", DEVICE_CAPA(id_eeprom->capa, CAPA_DOUT) ? "true" : "false"); fprintf(file, "capa-adc: %s\n", DEVICE_CAPA(id_eeprom->capa, CAPA_ADC) ? "true" : "false"); fprintf(file, "capa-wifi: %s\n", DEVICE_CAPA(id_eeprom->capa, CAPA_WIFI) ? "true" : "false"); fprintf(file, "capa-bluetooth: %s\n", DEVICE_CAPA(id_eeprom->capa, CAPA_BLUETOOTH) ? "true" : "false"); fprintf(file, "capa-lora: %s\n", DEVICE_CAPA(id_eeprom->capa, CAPA_LORA) ? "true" : "false"); fprintf(file, "capa-lora-lbt: %s\n", DEVICE_CAPA(id_eeprom->capa, CAPA_LORA_LBT) ? "true" : "false"); fprintf(file, "capa-battery: %s\n", DEVICE_CAPA(id_eeprom->capa, CAPA_BATTERY) ? "true" : "false"); fprintf(file, "capa-supercap: %s\n", DEVICE_CAPA(id_eeprom->capa, CAPA_SUPERCAP) ? "true" : "false"); fprintf(file, "capa-cellular: %s\n", DEVICE_CAPA(id_eeprom->capa, CAPA_CELLULAR) ? "true" : "false"); fprintf(file, "capa-user-data-encryption: %s\n", DEVICE_CAPA(id_eeprom->capa, CAPA_USER_DATA_ENCRYPTION) ? "true" : "false"); fprintf(file, "capa: \""); for (i = 0; i < sizeof(id_eeprom->capa); i++) { fprintf(file, "\\x%02X", id_eeprom->capa[i]); } fprintf(file, "\"\n"); fprintf(file, "mac-bluetooth: \"%02X:%02X:%02X:%02X:%02X:%02X\"\n", id_eeprom->mac_bluetooth[0], id_eeprom->mac_bluetooth[1], id_eeprom->mac_bluetooth[2], id_eeprom->mac_bluetooth[3], id_eeprom->mac_bluetooth[4], id_eeprom->mac_bluetooth[5]); fprintf(file, "mac-wifi: \"%02X:%02X:%02X:%02X:%02X:%02X\"\n", id_eeprom->mac_wifi[0], id_eeprom->mac_wifi[1], id_eeprom->mac_wifi[2], id_eeprom->mac_wifi[3], id_eeprom->mac_wifi[4], id_eeprom->mac_wifi[5]); ptr = (char*)buf; for(i = 0; i < 16; i++) { ptr += sprintf(ptr, "%02X", id_eeprom->uuid[i]); } fprintf(file, "uuid: \"%s\"\n", (char*)buf); fprintf(file, "lora-eui: \"%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\"\n", id_eeprom->lora_eui[0], id_eeprom->lora_eui[1], id_eeprom->lora_eui[2], id_eeprom->lora_eui[3], id_eeprom->lora_eui[4], id_eeprom->lora_eui[5], id_eeprom->lora_eui[6], id_eeprom->lora_eui[7]); fprintf(file, "lora-product-id: \"%.32s\"\n", id_eeprom->lora_product_id); fprintf(file, "lora-hw-version: \"%.32s\"\n", id_eeprom->lora_hw_version); #ifdef MTRE fprintf(file, "oem-string1: %.32s\n", id_eeprom->oem_string1); fprintf(file, "oem-string2: %.32s\n", id_eeprom->oem_string2); #endif fprintf(file, "...\n"); fclose(file); return 0; } static int ap_yaml_out(const char *name, struct mts_ap_eeprom_layout *ap_eeprom) { FILE *file; if (!strcmp(name, "-")) { file = stdout; } else { file = fopen(name, "w+"); if (!file) { log_error("could not open %s: %m", name); return -1; } } fprintf(file, "---\n"); fprintf(file, "\n"); fprintf(file, "vendor-id: \"%.32s\"\n", ap_eeprom->vendor_id); fprintf(file, "product-id: \"%.32s\"\n", ap_eeprom->product_id); fprintf(file, "device-id: \"%.32s\"\n", ap_eeprom->device_id); fprintf(file, "hw-version: \"%.32s\"\n", ap_eeprom->hw_version); fprintf(file, "mac-addr: \"%02X:%02X:%02X:%02X:%02X:%02X\"\n", ap_eeprom->mac_addr[0], ap_eeprom->mac_addr[1], ap_eeprom->mac_addr[2], ap_eeprom->mac_addr[3], ap_eeprom->mac_addr[4], ap_eeprom->mac_addr[5]); fprintf(file, "eui: \"%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\"\n", ap_eeprom->eui[0], ap_eeprom->eui[1], ap_eeprom->eui[2], ap_eeprom->eui[3], ap_eeprom->eui[4], ap_eeprom->eui[5], ap_eeprom->eui[6], ap_eeprom->eui[7]); fprintf(file, "...\n"); fclose(file); return 0; } #ifdef MTCDT3B static int mtcdt3b_yaml_out(const char *name, struct mtcdt3b_eeprom_layout *mtcdt3b_eeprom) { int i; FILE *file; char buf[64] = {0}; char *ptr; if (!strcmp(name, "-")) { file = stdout; } else { file = fopen(name, "w+"); if (!file) { log_error("could not open %s: %m", name); return -1; } } fprintf(file, "---\n"); fprintf(file, "\n"); fprintf(file, "vendor-id: \"%.32s\"\n", mtcdt3b_eeprom->vendor_id); fprintf(file, "product-id: \"%.32s\"\n", mtcdt3b_eeprom->product_id); fprintf(file, "device-id: \"%.32s\"\n", mtcdt3b_eeprom->device_id); fprintf(file, "hw-version: \"%.32s\"\n", mtcdt3b_eeprom->hw_version); ptr = (char*)buf; for(i = 0; i < 16; i++) { ptr += sprintf(ptr, "%02X", mtcdt3b_eeprom->uuid[i]); } fprintf(file, "uuid: \"%s\"\n", (char*)buf); fprintf(file, "mac-addr: \"%02X:%02X:%02X:%02X:%02X:%02X\"\n", mtcdt3b_eeprom->mac_addr[0], mtcdt3b_eeprom->mac_addr[1], mtcdt3b_eeprom->mac_addr[2], mtcdt3b_eeprom->mac_addr[3], mtcdt3b_eeprom->mac_addr[4], mtcdt3b_eeprom->mac_addr[5]); for(i=0;i<2;i++) { fprintf(file,"slot %d:\n",i); fprintf(file, " lora-device-id: \"%.32s\"\n", mtcdt3b_eeprom->slot[i].device_id); fprintf(file, " lora-eui: \"%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\"\n", mtcdt3b_eeprom->slot[i].lora_eui[0], mtcdt3b_eeprom->slot[i].lora_eui[1], mtcdt3b_eeprom->slot[i].lora_eui[2], mtcdt3b_eeprom->slot[i].lora_eui[3], mtcdt3b_eeprom->slot[i].lora_eui[4], mtcdt3b_eeprom->slot[i].lora_eui[5], mtcdt3b_eeprom->slot[i].lora_eui[6], mtcdt3b_eeprom->slot[i].lora_eui[7]); } fprintf(file, "capa-eth-switch: %s\n", DEVICE_CAPA(mtcdt3b_eeprom->capa, MTCDT3B_CAPA_ETH_SWITCH) ? "true" : "false"); fprintf(file, "eth-switch-version: %hu\n", mtcdt3b_eeprom->hw_version_eth_switch); fprintf(file, "eth-switch-mac-addr: \"%02X:%02X:%02X:%02X:%02X:%02X\"\n", mtcdt3b_eeprom->mac_eth_switch[0], mtcdt3b_eeprom->mac_eth_switch[1], mtcdt3b_eeprom->mac_eth_switch[2], mtcdt3b_eeprom->mac_eth_switch[3], mtcdt3b_eeprom->mac_eth_switch[4], mtcdt3b_eeprom->mac_eth_switch[5]); fprintf(file, "...\n"); fclose(file); return 0; } static int mtcdt3dc_yaml_out(const char *name, struct mtcdt3dc_eeprom_layout *mtcdt3dc_eeprom) { FILE *file; if (!strcmp(name, "-")) { file = stdout; } else { file = fopen(name, "w+"); if (!file) { log_error("could not open %s: %m", name); return -1; } } fprintf(file, "---\n"); fprintf(file, "\n"); fprintf(file, "vendor-id: \"%.32s\"\n", mtcdt3dc_eeprom->vendor_id); fprintf(file, "product-id: \"%.32s\"\n", mtcdt3dc_eeprom->product_id); fprintf(file, "device-id: \"%.32s\"\n", mtcdt3dc_eeprom->device_id); fprintf(file, "hw-version: \"%.32s\"\n", mtcdt3dc_eeprom->hw_version); fprintf(file, "capa-mei-serial: %.32s\n", DEVICE_CAPA(mtcdt3dc_eeprom->capa, MTCDT3DC_CAPA_SERIAL) ? "true" : "false"); fprintf(file, "capa-mtac: %.32s\n", DEVICE_CAPA(mtcdt3dc_eeprom->capa, MTCDT3DC_CAPA_MTAC) ? "true" : "false"); fprintf(file, "mei-serial-count: %hu\n", mtcdt3dc_eeprom->serial_cnt); fprintf(file, "mtac-count: %hu\n", mtcdt3dc_eeprom->mtac_cnt); fprintf(file, "...\n"); fclose(file); return 0; } #endif static int bin_out(const char *name, char *eeprom) { int fd; int tmp; if (!strcmp(name, "-")) { fd = fileno(stdout); } else { fd = open(name, O_CREAT | O_WRONLY, 0644); if (fd < 0) { log_error("could not open %s: %m", name); return fd; } } tmp = write(fd, eeprom, eeprom_size); if (tmp < 0) { log_error("writing %s failed: %m", name); return fd; } else if (tmp != eeprom_size) { log_error("only wrote %d bytes to %s", tmp, name); return -1; } close(fd); return tmp; } static void mts_id_eeprom_inspect(struct mts_id_eeprom_layout *id_eeprom) { int i; char buf[64] = {0}; char* ptr; log_info("sizeof: %u", sizeof(struct mts_id_eeprom_layout)); log_info("EEPROM Layout Version: %u", id_eeprom->eeprom_layout_version); log_info("vendor-id: %.32s", id_eeprom->vendor_id); log_info("product-id: %.32s", id_eeprom->product_id); log_info("device-id: %.32s", id_eeprom->device_id); log_info("hw-version: %.32s", id_eeprom->hw_version); log_info("mac-addr: %02X:%02X:%02X:%02X:%02X:%02X", id_eeprom->mac_addr[0], id_eeprom->mac_addr[1], id_eeprom->mac_addr[2], id_eeprom->mac_addr[3], id_eeprom->mac_addr[4], id_eeprom->mac_addr[5]); log_info("imei: %.32s", id_eeprom->imei); log_info("capa-gps: %s", DEVICE_CAPA(id_eeprom->capa, CAPA_GPS) ? "yes" : "no"); log_info("capa-din: %s", DEVICE_CAPA(id_eeprom->capa, CAPA_DIN) ? "yes" : "no"); log_info("capa-dout: %s", DEVICE_CAPA(id_eeprom->capa, CAPA_DOUT) ? "yes" : "no"); log_info("capa-adc: %s", DEVICE_CAPA(id_eeprom->capa, CAPA_ADC) ? "yes" : "no"); log_info("capa-wifi: %s", DEVICE_CAPA(id_eeprom->capa, CAPA_WIFI) ? "yes" : "no"); log_info("capa-bluetooth: %s", DEVICE_CAPA(id_eeprom->capa, CAPA_BLUETOOTH) ? "yes" : "no"); log_info("capa-lora: %s", DEVICE_CAPA(id_eeprom->capa, CAPA_LORA) ? "yes" : "no"); log_info("capa-lora-lbt: %s", DEVICE_CAPA(id_eeprom->capa, CAPA_LORA_LBT) ? "yes" : "no"); log_info("capa-supercap: %s", DEVICE_CAPA(id_eeprom->capa, CAPA_SUPERCAP) ? "yes" : "no"); log_info("capa-cellular: %s", DEVICE_CAPA(id_eeprom->capa, CAPA_CELLULAR) ? "yes" : "no"); log_info("capa-user-data-encryption: %s", DEVICE_CAPA(id_eeprom->capa, CAPA_USER_DATA_ENCRYPTION) ? "yes" : "no"); log_info("mac-bluetooth: %02X:%02X:%02X:%02X:%02X:%02X", id_eeprom->mac_bluetooth[0], id_eeprom->mac_bluetooth[1], id_eeprom->mac_bluetooth[2], id_eeprom->mac_bluetooth[3], id_eeprom->mac_bluetooth[4], id_eeprom->mac_bluetooth[5]); log_info("mac-wifi: %02X:%02X:%02X:%02X:%02X:%02X", id_eeprom->mac_wifi[0], id_eeprom->mac_wifi[1], id_eeprom->mac_wifi[2], id_eeprom->mac_wifi[3], id_eeprom->mac_wifi[4], id_eeprom->mac_wifi[5]); ptr = (char*)buf; for(i = 0; i < 16; i++) { ptr += sprintf(ptr, "%02X", id_eeprom->uuid[i]); } log_info("uuid: %s", (char*)buf); log_info("lora-eui: \"%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\"", id_eeprom->lora_eui[0], id_eeprom->lora_eui[1], id_eeprom->lora_eui[2], id_eeprom->lora_eui[3], id_eeprom->lora_eui[4], id_eeprom->lora_eui[5], id_eeprom->lora_eui[6], id_eeprom->lora_eui[7]); log_info("lora-product-id: %.32s", id_eeprom->lora_product_id); log_info("lora-hw-version: %.32s", id_eeprom->lora_hw_version); #ifdef MTRE log_info("oem-string1: %.32s", id_eeprom->oem_string1); log_info("oem-string2: %.32s", id_eeprom->oem_string2); #endif } static void mts_ap_eeprom_inspect(struct mts_ap_eeprom_layout *ap_eeprom) { log_info("sizeof: %u", sizeof(struct mts_ap_eeprom_layout)); log_info("vendor-id: %.32s", ap_eeprom->vendor_id); log_info("product-id: %.32s", ap_eeprom->product_id); log_info("device-id: %.32s", ap_eeprom->device_id); log_info("hw-version: %.32s", ap_eeprom->hw_version); log_info("mac-addr: %02X:%02X:%02X:%02X:%02X:%02X", ap_eeprom->mac_addr[0], ap_eeprom->mac_addr[1], ap_eeprom->mac_addr[2], ap_eeprom->mac_addr[3], ap_eeprom->mac_addr[4], ap_eeprom->mac_addr[5]); log_info("eui: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", ap_eeprom->eui[0], ap_eeprom->eui[1], ap_eeprom->eui[2], ap_eeprom->eui[3], ap_eeprom->eui[4], ap_eeprom->eui[5], ap_eeprom->eui[6], ap_eeprom->eui[7]); } #ifdef MTCDT3B static void mtcdt3b_eeprom_inspect(struct mtcdt3b_eeprom_layout *mtcdt3b_eeprom) { int i; char buf[64] = {0}; char* ptr; log_info("sizeof: %u", sizeof(struct mtcdt3b_eeprom_layout)); log_info("vendor-id: %.32s", mtcdt3b_eeprom->vendor_id); log_info("product-id: %.32s", mtcdt3b_eeprom->product_id); log_info("device-id: %.32s", mtcdt3b_eeprom->device_id); log_info("hw-version: %.32s", mtcdt3b_eeprom->hw_version); ptr = (char*)buf; for(i = 0; i < 16; i++) { ptr += sprintf(ptr, "%02X", mtcdt3b_eeprom->uuid[i]); } log_info("uuid: %s", (char*)buf); log_info("mac-addr: \"%02X:%02X:%02X:%02X:%02X:%02X\"", mtcdt3b_eeprom->mac_addr[0], mtcdt3b_eeprom->mac_addr[1], mtcdt3b_eeprom->mac_addr[2], mtcdt3b_eeprom->mac_addr[3], mtcdt3b_eeprom->mac_addr[4], mtcdt3b_eeprom->mac_addr[5]); for(i=0;i<2;i++) { log_info("slot %d:",i); log_info(" lora-device-id: \"%.32s\"", mtcdt3b_eeprom->slot[i].device_id); log_info(" lora-eui: \"%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\"", mtcdt3b_eeprom->slot[i].lora_eui[0], mtcdt3b_eeprom->slot[i].lora_eui[1], mtcdt3b_eeprom->slot[i].lora_eui[2], mtcdt3b_eeprom->slot[i].lora_eui[3], mtcdt3b_eeprom->slot[i].lora_eui[4], mtcdt3b_eeprom->slot[i].lora_eui[5], mtcdt3b_eeprom->slot[i].lora_eui[6], mtcdt3b_eeprom->slot[i].lora_eui[7]); } log_info("capa-eth-switch: %s", DEVICE_CAPA(mtcdt3b_eeprom->capa, MTCDT3B_CAPA_ETH_SWITCH) ? "yes" : "no"); log_info("eth-switch-version: %hu", mtcdt3b_eeprom->hw_version_eth_switch); log_info("eth-switch-mac-addr: \"%02X:%02X:%02X:%02X:%02X:%02X\"", mtcdt3b_eeprom->mac_eth_switch[0], mtcdt3b_eeprom->mac_eth_switch[1], mtcdt3b_eeprom->mac_eth_switch[2], mtcdt3b_eeprom->mac_eth_switch[3], mtcdt3b_eeprom->mac_eth_switch[4], mtcdt3b_eeprom->mac_eth_switch[5]); } static void mtcdt3dc_eeprom_inspect(struct mtcdt3dc_eeprom_layout *mtcdt3dc_eeprom) { log_info("vendor-id: %.32s", mtcdt3dc_eeprom->vendor_id); log_info("product-id: %.32s", mtcdt3dc_eeprom->product_id); log_info("device-id: %.32s", mtcdt3dc_eeprom->device_id); log_info("hw-version: %.32s", mtcdt3dc_eeprom->hw_version); log_info("capa-mei-serial: %.32s", DEVICE_CAPA(mtcdt3dc_eeprom->capa, MTCDT3DC_CAPA_MTAC) ? "true" : "false"); log_info("capa-mtac: %.32s", DEVICE_CAPA(mtcdt3dc_eeprom->capa, MTCDT3DC_CAPA_SERIAL) ? "true" : "false"); log_info("mei-serial count: %hu", mtcdt3dc_eeprom->serial_cnt); log_info("mtac count: %hu", mtcdt3dc_eeprom->mtac_cnt); } #endif static void print_version(const char *name) { printf("%s (" PACKAGE ") " VERSION " (" __DATE__ " " __TIME__ ")\n", name); printf("EEPROM Version %d\n",EEPROM_LAYOUT_VERSION); printf("Copyright (C) 2015, 2019, 2020 by Multi-Tech Systems\n"); printf( "This program is free software; you may redistribute it under the terms of\n" "the GNU General Public License version 2 or (at your option) any later version.\n" "This program has absolutely no warranty.\n"); } static void usage(FILE *out) { fprintf(out, "usage: mts-id-eeprom [ OPTIONS ... ]\n"); fprintf(out, "where OPTIONS := { \n"); fprintf(out, " --in-file |\n"); fprintf(out, " --out-file |\n"); fprintf(out, " --vendor-id |\n"); fprintf(out, " --product-id |\n"); fprintf(out, " --device-id |\n"); fprintf(out, " --uuid |\n"); fprintf(out, " --hw-version |\n"); fprintf(out, " --mac-addr |\n"); fprintf(out, " --mac-bluetooth |\n"); fprintf(out, " --mac-wifi |\n"); fprintf(out, " --lora-eui |\n"); fprintf(out, " --lora-hw-version |\n"); fprintf(out, " --lora-product-id |\n"); #ifdef MTRE fprintf(out, " --oem-string1 |\n"); fprintf(out, " --oem-string2 |\n"); #endif fprintf(out, " --imei |\n"); fprintf(out, " --capa-gps |\n"); fprintf(out, " --capa-din |\n"); fprintf(out, " --capa-dout |\n"); fprintf(out, " --capa-adc |\n"); fprintf(out, " --capa-wifi |\n"); fprintf(out, " --capa-bluetooth |\n"); fprintf(out, " --capa-lora |\n"); fprintf(out, " --capa-lora-lbt |\n"); fprintf(out, " --capa-battery |\n"); fprintf(out, " --capa-supercap |\n"); fprintf(out, " --capa-cellular |\n"); fprintf(out, " --capa-user-data-encryption |\n"); fprintf(out, " --capa-clear (clears all flags) |\n"); fprintf(out, " --hex-to-bin | \n"); fprintf(out, " --out-format { bin | yaml (default) } |\n"); fprintf(out, " --update |\n"); fprintf(out, " --accessory-card\n"); #ifdef MTCDT3B fprintf(out, " --base-board\n"); fprintf(out, " --daughter-board\n"); fprintf(out, " --slot i=0,device-id=,lora-eui=,i=1,...\n"); fprintf(out, " --capa-eth-switch \n"); fprintf(out, " --capa-mtac \n"); fprintf(out, " --capa-serial \n"); fprintf(out, " --mtac-count \n"); fprintf(out, " --serial-count \n"); fprintf(out, " --eth-switch-version \n"); fprintf(out, " --eth-switch-mac-addr \n"); #endif fprintf(out, " }\n"); fprintf(out, "\n"); } enum { CMD_OPT_IN_FILE = 128, CMD_OPT_OUT_FILE, CMD_OPT_VENDOR_ID, CMD_OPT_PRODUCT_ID, CMD_OPT_DEVICE_ID, CMD_OPT_UUID, CMD_OPT_HW_VERSION, CMD_OPT_MAC_ADDR, CMD_OPT_MAC_BLUETOOTH, CMD_OPT_MAC_WIFI, CMD_OPT_LORA_EUI, CMD_OPT_LORA_HW_VERSION, CMD_OPT_LORA_PRODUCT_ID, CMD_OPT_IMEI, CMD_OPT_CAPA_GPS, CMD_OPT_CAPA_DIN, CMD_OPT_CAPA_DOUT, CMD_OPT_CAPA_ADC, CMD_OPT_CAPA_WIFI, CMD_OPT_CAPA_BLUETOOTH, CMD_OPT_CAPA_LORA, CMD_OPT_CAPA_LORA_LBT, CMD_OPT_CAPA_BATTERY, CMD_OPT_CAPA_SUPERCAP, CMD_OPT_CAPA_CELLULAR, CMD_OPT_CAPA_USER_DATA_ENCRYPTION, CMD_OPT_CAPA_CLEAR, CMD_OPT_OUT_FORMAT, CMD_OPT_UPDATE, CMD_OPT_ACCESSORY_CARD, #ifdef MTRE CMD_OPT_OEM_STRING1, CMD_OPT_OEM_STRING2, #endif #ifdef MTCDT3B CMD_OPT_BASE_BOARD, CMD_OPT_DAUGHTER_BOARD, CMD_OPT_SLOTS, CMD_OPT_CAPA_ETH_SWITCH, CMD_OPT_ETH_SWITCH_VERSION, CMD_OPT_ETH_SWITCH_MAC_ADDR, CMD_OPT_CAPA_MTAC, CMD_OPT_CAPA_SERIAL, CMD_OPT_NUM_MTAC, CMD_OPT_NUM_SERIAL, #endif CMD_OPT_VERSION, CMD_OPT_HELP, CMD_OPT_HEX_TO_BIN, }; static char *short_options = "f:"; static struct option long_options[] = { {"in-file", 1, NULL, CMD_OPT_IN_FILE}, {"out-file", 1, NULL, CMD_OPT_OUT_FILE}, {"vendor-id", 1, NULL, CMD_OPT_VENDOR_ID}, {"product-id", 1, NULL, CMD_OPT_PRODUCT_ID}, {"device-id", 1, NULL, CMD_OPT_DEVICE_ID}, {"uuid", 1, NULL, CMD_OPT_UUID}, {"hw-version", 1, NULL, CMD_OPT_HW_VERSION}, {"lora-product-id", 1, NULL, CMD_OPT_LORA_PRODUCT_ID}, {"lora-hw-version", 1, NULL, CMD_OPT_LORA_HW_VERSION}, #ifdef MTRE {"oem-string1", 1, NULL, CMD_OPT_OEM_STRING1}, {"oem-string2", 1, NULL, CMD_OPT_OEM_STRING2}, #endif {"mac-addr", 1, NULL, CMD_OPT_MAC_ADDR}, {"mac-bluetooth", 1, NULL, CMD_OPT_MAC_BLUETOOTH}, {"mac-wifi", 1, NULL, CMD_OPT_MAC_WIFI}, {"lora-eui", 1, NULL, CMD_OPT_LORA_EUI}, {"imei", 1, NULL, CMD_OPT_IMEI}, {"capa-gps", 0, NULL, CMD_OPT_CAPA_GPS}, {"capa-din", 0, NULL, CMD_OPT_CAPA_DIN}, {"capa-dout", 0, NULL, CMD_OPT_CAPA_DOUT}, {"capa-adc", 0, NULL, CMD_OPT_CAPA_ADC}, {"capa-wifi", 0, NULL, CMD_OPT_CAPA_WIFI}, {"capa-bluetooth", 0, NULL, CMD_OPT_CAPA_BLUETOOTH}, {"capa-lora", 0, NULL, CMD_OPT_CAPA_LORA}, {"capa-lora-lbt", 0, NULL, CMD_OPT_CAPA_LORA_LBT}, {"capa-battery", 0, NULL, CMD_OPT_CAPA_BATTERY}, {"capa-supercap", 0, NULL, CMD_OPT_CAPA_SUPERCAP}, {"capa-cellular", 0, NULL, CMD_OPT_CAPA_CELLULAR}, {"capa-user-data-encryption", 0, NULL, CMD_OPT_CAPA_USER_DATA_ENCRYPTION}, {"capa-clear", 0, NULL, CMD_OPT_CAPA_CLEAR}, {"hex-to-bin", 0, NULL, CMD_OPT_HEX_TO_BIN}, {"out-format", 1, NULL, CMD_OPT_OUT_FORMAT}, {"update", 0, NULL, CMD_OPT_UPDATE}, {"accessory-card", 0, NULL, CMD_OPT_ACCESSORY_CARD}, #ifdef MTCDT3B {"base-board", 0, NULL, CMD_OPT_BASE_BOARD}, {"daughter-board", 0, NULL, CMD_OPT_DAUGHTER_BOARD}, {"slots", 1, NULL, CMD_OPT_SLOTS}, {"capa-eth-switch", 0, NULL, CMD_OPT_CAPA_ETH_SWITCH}, {"capa-mtac", 0, NULL, CMD_OPT_CAPA_MTAC}, {"capa-serial", 0, NULL, CMD_OPT_CAPA_SERIAL}, {"mtac-count", 1, NULL, CMD_OPT_NUM_MTAC}, {"serial-count", 1, NULL, CMD_OPT_NUM_SERIAL}, {"eth-switch-version", 1, NULL, CMD_OPT_ETH_SWITCH_VERSION}, {"eth-switch-mac-addr", 1, NULL, CMD_OPT_ETH_SWITCH_MAC_ADDR}, #endif {"version", 0, NULL, CMD_OPT_VERSION}, {"help", 0, NULL, CMD_OPT_HELP}, {0, 0, 0, 0}, }; enum { SLOT_INDEX = 0, SLOT_DEVICE_ID, SLOT_LORA_EUI, }; char *slot_tokens[] = { [SLOT_INDEX] = "i", [SLOT_DEVICE_ID] = "device-id", [SLOT_LORA_EUI] = "lora-eui", NULL }; int main(int argc, char *argv[]) { int i; int option_index; int tmp; int fd; int capa_clear = 0; char *in_file = NULL; char *out_file = "-"; char *out_format = "yaml"; int update = 0; int accessory_card = 0; #ifdef MTCDT3B int base_board = 0; int daughter_board = 0; char *slots = NULL; #endif char *vendor_id = NULL; char *product_id = NULL; char *device_id = NULL; char *hw_version = NULL; char *mac_addr = NULL; char *lora_eui = NULL; char *lora_product_id = NULL; char *lora_hw_version = NULL; #ifdef MTRE char *oem_string1 = NULL; char *oem_string2 = NULL; #endif struct mts_id_eeprom_layout id_eeprom; struct mts_ap_eeprom_layout ap_eeprom; #ifdef MTCDT3B struct mtcdt3b_eeprom_layout mtcdt3b_eeprom; memset (&mtcdt3b_eeprom, 0, eeprom_size); if (sizeof mtcdt3b_eeprom != eeprom_size) { fprintf(stderr,"Internal error:\n mtcdt3b_eeprom is not the correct size: expected %d, but %d is defined for the part\n", eeprom_size,sizeof mtcdt3b_eeprom); exit(1); } struct mtcdt3dc_eeprom_layout mtcdt3dc_eeprom; memset (&mtcdt3dc_eeprom, 0, eeprom_size); if (sizeof mtcdt3dc_eeprom != eeprom_size) { fprintf(stderr, "Internal error:\n mtcdt3dc_eeprom is not the correct size: expected %d, but %d is defined for the part\n", eeprom_size,sizeof mtcdt3dc_eeprom); exit(1); } #endif memset(&id_eeprom, 0, eeprom_size); memset(&ap_eeprom, 0, eeprom_size); // parse options once to get input file and accessory_card flag only while((i = getopt_long(argc, argv, short_options, long_options, &option_index)) >= 0) { switch(i) { case 0: break; case CMD_OPT_IN_FILE: in_file = optarg; break; case CMD_OPT_ACCESSORY_CARD: accessory_card = 1; break; #ifdef MTCDT3B case CMD_OPT_BASE_BOARD: base_board = 1; break; case CMD_OPT_DAUGHTER_BOARD: daughter_board = 1; break; #endif case CMD_OPT_VERSION: print_version("mts-id-eeprom"); exit(0); break; case CMD_OPT_HELP: usage(stdout); exit(0); break; } } // read eeprom before parsing other options and modifying fields // this is needed if --update is specified if (in_file) { fd = open(in_file, O_RDONLY); if (fd < 0) { log_error("could not open in-file %s: %m", in_file); exit(1); } if (accessory_card) { tmp = read(fd, (char *) &ap_eeprom, eeprom_size); #ifdef MTCDT3B } else if (base_board) { tmp = read(fd, (char *) &mtcdt3b_eeprom, eeprom_size); } else if (daughter_board) { tmp = read(fd, (char *) &mtcdt3dc_eeprom, eeprom_size); #endif } else { tmp = read(fd, (char *) &id_eeprom, eeprom_size); } if (tmp < 0) { log_error("reading %s failed: %m", in_file); exit(1); } else if (tmp != eeprom_size) { log_error("only read %d bytes from %s", tmp, in_file); exit(1); } if (accessory_card) { log_info("loaded ap eeprom from %s successfully", in_file); mts_ap_eeprom_inspect(&ap_eeprom); #ifdef MTCDT3B } else if (base_board) { log_info("loaded ap eeprom from %s successfully", in_file); mtcdt3b_eeprom_inspect(&mtcdt3b_eeprom); } else if (daughter_board) { mtcdt3dc_eeprom_inspect(&mtcdt3dc_eeprom); #endif } else { log_info("loaded id eeprom from %s successfully", in_file); mts_id_eeprom_inspect(&id_eeprom); } close(fd); } // reset getopt index and parse again optind = 0; while((i = getopt_long(argc, argv, short_options, long_options, &option_index)) >= 0) { switch(i) { case 0: break; case CMD_OPT_IN_FILE: // handled above break; case CMD_OPT_UPDATE: update = 1; break; case CMD_OPT_ACCESSORY_CARD: // handled above break; #ifdef MTCDT3B case CMD_OPT_BASE_BOARD: // handled above break; case CMD_OPT_DAUGHTER_BOARD: // handled above break; case CMD_OPT_SLOTS: // concatenate slots arguments if (base_board) { int length = 0; int init = 1; if (slots) { length = strlen(slots) + 1; init = 0; // Already initialized } if (optarg) length += strlen(optarg) + 1; slots = realloc(slots,length); if (init) slots[0] = 0; else strcat(slots,","); slots = strcat(slots,optarg); } else { log_error("Only the base board can have slots"); usage(stderr); exit(1); } break; #endif case CMD_OPT_OUT_FILE: out_file = optarg; break; case CMD_OPT_VENDOR_ID: vendor_id = optarg; break; case CMD_OPT_PRODUCT_ID: product_id = optarg; break; case CMD_OPT_LORA_PRODUCT_ID: lora_product_id = optarg; break; #ifdef MTRE case CMD_OPT_OEM_STRING1: oem_string1 = optarg; break; case CMD_OPT_OEM_STRING2: oem_string2 = optarg; break; #endif case CMD_OPT_DEVICE_ID: device_id = optarg; break; case CMD_OPT_UUID: if (accessory_card) { log_error("UUID not supported on accessory card eeprom"); usage(stderr); exit(1); } #ifdef MTCDT3B if(asciiHexToBin(optarg, mtcdt3b_eeprom.uuid) != sizeof(mtcdt3b_eeprom.uuid)) { log_error("invalid uuid %s", optarg); usage(stderr); exit(1); } else #endif if(asciiHexToBin(optarg, id_eeprom.uuid) != sizeof(id_eeprom.uuid)) { log_error("invalid uuid %s", optarg); usage(stderr); exit(1); } break; case CMD_OPT_HW_VERSION: hw_version = optarg; break; case CMD_OPT_LORA_HW_VERSION: lora_hw_version = optarg; break; case CMD_OPT_MAC_ADDR: mac_addr = optarg; break; case CMD_OPT_MAC_BLUETOOTH: tmp = hwaddr_aton(optarg, id_eeprom.mac_bluetooth, sizeof(id_eeprom.mac_bluetooth)); if (!tmp) { log_error("invalid mac-bluetooth %s", optarg); usage(stderr); exit(1); } break; case CMD_OPT_MAC_WIFI: tmp = hwaddr_aton(optarg, id_eeprom.mac_wifi, sizeof(id_eeprom.mac_wifi)); if (!tmp) { log_error("invalid mac-wifi %s", optarg); usage(stderr); exit(1); } break; case CMD_OPT_LORA_EUI: lora_eui = optarg; break; case CMD_OPT_IMEI: strncpy(id_eeprom.imei, optarg, sizeof(id_eeprom.imei) - 1); break; case CMD_OPT_CAPA_GPS: DEVICE_CAPA_SET(id_eeprom.capa, CAPA_GPS); break; case CMD_OPT_CAPA_DIN: DEVICE_CAPA_SET(id_eeprom.capa, CAPA_DIN); break; case CMD_OPT_CAPA_DOUT: DEVICE_CAPA_SET(id_eeprom.capa, CAPA_DOUT); break; case CMD_OPT_CAPA_ADC: DEVICE_CAPA_SET(id_eeprom.capa, CAPA_ADC); break; case CMD_OPT_CAPA_WIFI: DEVICE_CAPA_SET(id_eeprom.capa, CAPA_WIFI); break; case CMD_OPT_CAPA_BLUETOOTH: DEVICE_CAPA_SET(id_eeprom.capa, CAPA_BLUETOOTH); break; case CMD_OPT_CAPA_LORA: DEVICE_CAPA_SET(id_eeprom.capa, CAPA_LORA); break; #ifdef MTCDT3B case CMD_OPT_CAPA_MTAC: if (daughter_board) { DEVICE_CAPA_SET(mtcdt3dc_eeprom.capa, MTCDT3DC_CAPA_MTAC); } break; case CMD_OPT_CAPA_SERIAL: if (daughter_board) { DEVICE_CAPA_SET(mtcdt3dc_eeprom.capa, MTCDT3DC_CAPA_SERIAL); } break; #endif case CMD_OPT_CAPA_LORA_LBT: DEVICE_CAPA_SET(id_eeprom.capa, CAPA_LORA_LBT); break; case CMD_OPT_CAPA_BATTERY: DEVICE_CAPA_SET(id_eeprom.capa, CAPA_BATTERY); break; case CMD_OPT_CAPA_SUPERCAP: DEVICE_CAPA_SET(id_eeprom.capa, CAPA_SUPERCAP); break; case CMD_OPT_CAPA_CELLULAR: DEVICE_CAPA_SET(id_eeprom.capa, CAPA_CELLULAR); break; case CMD_OPT_CAPA_USER_DATA_ENCRYPTION: DEVICE_CAPA_SET(id_eeprom.capa, CAPA_USER_DATA_ENCRYPTION); break; case CMD_OPT_CAPA_CLEAR: capa_clear = 1; break; case CMD_OPT_OUT_FORMAT: if (strcmp(optarg, "bin") && strcmp(optarg, "yaml")) { log_error("invalid out-format %s", optarg); usage(stderr); exit(1); } out_format = optarg; break; case CMD_OPT_HEX_TO_BIN: { char buf[1025]; char outbuf[1024]; size_t sz, len; while((sz=read(0,buf,sizeof buf)) > 0) { buf[sz] = 0; sz = asciiHexToBin(buf,outbuf); len = write(1,outbuf,sz); if(len != sz) { log_error("failure to write to stdout: %s",strerror(errno)); exit(1); } } exit(0); } #ifdef MTCDT3B case CMD_OPT_CAPA_ETH_SWITCH: if (base_board) { DEVICE_CAPA_SET(mtcdt3b_eeprom.capa, MTCDT3B_CAPA_ETH_SWITCH); } break; case CMD_OPT_ETH_SWITCH_VERSION: if (base_board) { uint16_t u16; if (sscanf(optarg, "%hu", &u16) != 1) { log_error("invalid eth-switch-version %s", optarg); usage(stderr); exit(1); } if (u16 < ETH_SWITCH_MIN || u16 >= ETH_SWITCH_MAX) { log_error("invalid eth-switch-version %s", optarg); usage(stderr); exit(1); } mtcdt3b_eeprom.hw_version_eth_switch = u16; } break; case CMD_OPT_ETH_SWITCH_MAC_ADDR: if (base_board) { tmp = hwaddr_aton(optarg, mtcdt3b_eeprom.mac_eth_switch, sizeof(mtcdt3b_eeprom.mac_eth_switch)); if (!tmp) { log_error("invalid eth-switch-mac-addr %s", optarg); usage(stderr); exit(1); } } break; case CMD_OPT_NUM_MTAC: if (daughter_board) { uint16_t u16_mtac_test; if (sscanf(optarg, "%hu", &u16_mtac_test) != 1) { log_error("invalid mtac count %s", optarg); usage(stderr); exit(1); } if (u16_mtac_test < MTAC_MIN || u16_mtac_test >MTAC_MAX) { log_error("invalid mtac count %s", optarg); usage(stderr); exit(1); } mtcdt3dc_eeprom.mtac_cnt = u16_mtac_test; } break; case CMD_OPT_NUM_SERIAL: if (daughter_board) { uint16_t u16_serial_test; if (sscanf(optarg, "%hu", &u16_serial_test) !=1) { log_error("invalid serial count %s", optarg); usage(stderr); exit(1); } if (u16_serial_test < SERIAL_MIN || u16_serial_test > SERIAL_MAX) { log_error("invalid serial count %s", optarg); usage(stderr); exit(1); } mtcdt3dc_eeprom.serial_cnt = u16_serial_test; } break; #endif default: usage(stderr); exit(1); } } #ifdef MTCDT3B if(base_board && capa_clear) { memset(mtcdt3b_eeprom.capa, 0, sizeof(mtcdt3b_eeprom.capa)); capa_clear = 0; } if(daughter_board && capa_clear) { memset(mtcdt3dc_eeprom.capa, 0, sizeof(mtcdt3dc_eeprom.capa)); capa_clear = 0; } #endif if(capa_clear) { memset(id_eeprom.capa, 0, sizeof(id_eeprom.capa)); capa_clear = 0; } #define EEPROM_SET(eeprom,field) (strncpy(eeprom.field, field, sizeof(eeprom.field) - 1)); /* these fields can apply to the on board EEPROM or the accessory card EEPROM */ if (vendor_id) { if (accessory_card) EEPROM_SET(ap_eeprom,vendor_id) #ifdef MTCDT3B else if (base_board) EEPROM_SET(mtcdt3b_eeprom,vendor_id) else if (daughter_board) EEPROM_SET(mtcdt3dc_eeprom,vendor_id) #endif else EEPROM_SET(id_eeprom,vendor_id) } if (product_id) { if (accessory_card) EEPROM_SET(ap_eeprom,product_id) #ifdef MTCDT3B else if (base_board) EEPROM_SET(mtcdt3b_eeprom,product_id) else if (daughter_board) EEPROM_SET(mtcdt3dc_eeprom,product_id) #endif else EEPROM_SET(id_eeprom,product_id) } if (device_id) { if (accessory_card) EEPROM_SET(ap_eeprom,device_id) #ifdef MTCDT3B else if (base_board) EEPROM_SET(mtcdt3b_eeprom,device_id) else if (daughter_board) EEPROM_SET(mtcdt3dc_eeprom,device_id) #endif else EEPROM_SET(id_eeprom,device_id) } if (hw_version) { if (accessory_card) EEPROM_SET(ap_eeprom,hw_version) #ifdef MTCDT3B else if (base_board) EEPROM_SET(mtcdt3b_eeprom,hw_version) else if (daughter_board) EEPROM_SET(mtcdt3dc_eeprom,hw_version) #endif else EEPROM_SET(id_eeprom,hw_version) } if (mac_addr) { if (accessory_card) tmp = hwaddr_aton(mac_addr, ap_eeprom.mac_addr, sizeof(ap_eeprom.mac_addr)); #ifdef MTCDT3B else if(base_board) tmp = hwaddr_aton(mac_addr, mtcdt3b_eeprom.mac_addr, sizeof(mtcdt3b_eeprom.mac_addr)); #endif else tmp = hwaddr_aton(mac_addr, id_eeprom.mac_addr, sizeof(id_eeprom.mac_addr)); if (!tmp) { log_error("invalid mac-addr %s", mac_addr); usage(stderr); exit(1); } } // on-board lora product id if (lora_product_id) { if (accessory_card) { log_error("--lora-product-id option is not supported on accessory card eeprom"); usage(stderr); exit(1); } else EEPROM_SET(id_eeprom,lora_product_id) } // on-board lora hw version if (lora_hw_version) { if (accessory_card) { log_error("--lora-hw-version option is not supported on accessory card eeprom"); usage(stderr); exit(1); } else EEPROM_SET(id_eeprom,lora_hw_version) } #ifdef MTRE if (oem_string1) { if (! accessory_card) { strncpy(id_eeprom.oem_string1, oem_string1, sizeof(id_eeprom.oem_string1) - 1); } else { log_error("--oem-string1 option is not supported on accessory card eeprom"); usage(stderr); exit(1); } } if (oem_string2) { if (! accessory_card) { strncpy(id_eeprom.oem_string2, oem_string2, sizeof(id_eeprom.oem_string2) - 1); } else { log_error("--oem-string2 option is not supported on accessory card eeprom"); usage(stderr); exit(1); } } #endif if (lora_eui) { if (accessory_card) tmp = hwaddr_aton(lora_eui, ap_eeprom.eui, sizeof(ap_eeprom.eui)); #ifdef MTCDT3B else if(base_board) { log_error("--lora-eui option is not supported on base board eeprom"); usage(stderr); exit(1); } #endif else tmp = hwaddr_aton(lora_eui, id_eeprom.lora_eui, sizeof(id_eeprom.lora_eui)); if (!tmp) { log_error("invalid EUI %s", lora_eui); usage(stderr); exit(1); } } #ifdef MTCDT3B #define EEPROM_SETP(eeprom,field,value) (strncpy(eeprom->field, value, sizeof(eeprom->field) - 1)); if (slots) { // Populate slots on main board int slot_index = -1; char *value; char *saved; struct lora_slot *sp; int slot_count, numtoken; slot_count = sizeof mtcdt3b_eeprom.slot / sizeof mtcdt3b_eeprom.slot[0]; while(1) { char *saved = slots; numtoken=getsubopt(&slots,slot_tokens,&value); if (numtoken == -1 && *slots == 0) break; // Out of tokens switch(numtoken) { case SLOT_INDEX: if (value == NULL) { log_error("Missing have index value (i=NUM) for slot"); usage(stderr); exit(1); } slot_index = atoi(value); if((slot_index < 0) || (slot_index+1 > slot_count)) { log_error("Slot index: %s is not >=0 or < %d",value,slot_count); usage(stderr); exit(1); } break; case SLOT_LORA_EUI: if(slot_index == -1) { log_error("Slot index (i=NUM) is not set before setting %s",slot_tokens[numtoken]); usage(stderr); exit(1); } sp = &(mtcdt3b_eeprom.slot[slot_index]); if(sp->lora_eui[0]) { log_error("Slot index %d already has %s set",slot_index,slot_tokens[numtoken]); usage(stderr); exit(1); } if (value == NULL) { log_error("Must value %s=? for slot %d",slot_tokens[numtoken],slot_index); usage(stderr); exit(1); } tmp = hwaddr_aton(value, sp->lora_eui, sizeof(sp->lora_eui)); if (!tmp) { log_error("invalid EUI %s for slot %d", value, slot_index); usage(stderr); exit(1); } break; case SLOT_DEVICE_ID: if(slot_index == -1) { log_error("SLOT_DEVICE_ID: %d, numtoken=%d, %s",SLOT_DEVICE_ID,numtoken,slot_tokens[numtoken]); log_error("Slot index (i=NUM) is not set before setting %s",slot_tokens[numtoken]); usage(stderr); exit(1); } sp = &(mtcdt3b_eeprom.slot[slot_index]); if(sp->device_id[0]) { log_error("Slot index %d already has %s set",slot_index,slot_tokens[numtoken]); usage(stderr); exit(1); } if (value == NULL) { log_error("Must have value %s=? for slot %d",slot_tokens[numtoken],slot_index); usage(stderr); exit(1); } EEPROM_SETP(sp,device_id,value) break; default: log_error("Unknown suboption %s",saved); usage(stderr); exit(1); } // END switch on slot suboptions } // END while more slots } // END Populate slots on main board #endif // updating eeprom in place, force bin format if (update && in_file) { out_file = in_file; out_format = "bin"; } if (out_file) { if (!strcmp(out_format, "bin")) { if (accessory_card) bin_out(out_file, (char*) &ap_eeprom); #ifdef MTCDT3B else if (base_board) bin_out(out_file, (char*) &mtcdt3b_eeprom); else if (daughter_board) bin_out(out_file, (char*) &mtcdt3dc_eeprom); #endif else { id_eeprom.eeprom_layout_version = EEPROM_LAYOUT_VERSION; bin_out(out_file, (char*) &id_eeprom); } } else if (!strcmp(out_format, "yaml")) { if (accessory_card) ap_yaml_out(out_file, &ap_eeprom); #ifdef MTCDT3B else if (base_board) mtcdt3b_yaml_out(out_file, &mtcdt3b_eeprom); else if (daughter_board) mtcdt3dc_yaml_out(out_file, &mtcdt3dc_eeprom); #endif else id_yaml_out(out_file, &id_eeprom); } else { log_error("un-handled out-format"); exit(1); } /* print out what we wrote to the eeprom, unless stdout */ if (strcmp(out_file, "-")) { log_info("Data written to %s", out_file); if (accessory_card) mts_ap_eeprom_inspect(&ap_eeprom); #ifdef MTCDT3B else if (base_board) mtcdt3b_eeprom_inspect(&mtcdt3b_eeprom); else if (daughter_board) mtcdt3dc_eeprom_inspect(&mtcdt3dc_eeprom); #endif else mts_id_eeprom_inspect(&id_eeprom); } } return 0; }