diff options
Diffstat (limited to 'src/Device/Device.cpp')
| -rw-r--r-- | src/Device/Device.cpp | 434 | 
1 files changed, 278 insertions, 156 deletions
| diff --git a/src/Device/Device.cpp b/src/Device/Device.cpp index f1ab675..04dbfef 100644 --- a/src/Device/Device.cpp +++ b/src/Device/Device.cpp @@ -1,141 +1,219 @@  /********************************************************************** -* COPYRIGHT 2020 MULTI-TECH SYSTEMS, INC. -* -* ALL RIGHTS RESERVED BY AND FOR THE EXCLUSIVE BENEFIT OF -* MULTI-TECH SYSTEMS, INC. -* -* MULTI-TECH SYSTEMS, INC. - CONFIDENTIAL AND PROPRIETARY -* INFORMATION AND/OR TRADE SECRET. -* -* NOTICE: ALL CODE, PROGRAM, INFORMATION, SCRIPT, INSTRUCTION, -* DATA, AND COMMENT HEREIN IS AND SHALL REMAIN THE CONFIDENTIAL -* INFORMATION AND PROPERTY OF MULTI-TECH SYSTEMS, INC. -* USE AND DISCLOSURE THEREOF, EXCEPT AS STRICTLY AUTHORIZED IN A -* WRITTEN AGREEMENT SIGNED BY MULTI-TECH SYSTEMS, INC. IS PROHIBITED. -* -***********************************************************************/ + * COPYRIGHT 2020 MULTI-TECH SYSTEMS, INC. + * + * ALL RIGHTS RESERVED BY AND FOR THE EXCLUSIVE BENEFIT OF + * MULTI-TECH SYSTEMS, INC. + * + * MULTI-TECH SYSTEMS, INC. - CONFIDENTIAL AND PROPRIETARY + * INFORMATION AND/OR TRADE SECRET. + * + * NOTICE: ALL CODE, PROGRAM, INFORMATION, SCRIPT, INSTRUCTION, + * DATA, AND COMMENT HEREIN IS AND SHALL REMAIN THE CONFIDENTIAL + * INFORMATION AND PROPERTY OF MULTI-TECH SYSTEMS, INC. + * USE AND DISCLOSURE THEREOF, EXCEPT AS STRICTLY AUTHORIZED IN A + * WRITTEN AGREEMENT SIGNED BY MULTI-TECH SYSTEMS, INC. IS PROHIBITED. + * + ***********************************************************************/  #include "Device.h" -const std::vector<std::string> Device::apIdentifiers = {"ap1", "ap2", "lora", "lora-2", "slot1", "slot2"}; -const std::regex Device::apFilters("(modalias)|(power)(.*)|(subsystem)|(uevent)"); -const std::regex Device::lora15Filters("(MTAC-LORA-)(.*)|(MTCAP-LORA-)(.*)|(MTLGA-)(.*)|(MTCDT3-)(.*)"); -const std::regex Device::loraG16Filters("(MTAC-LORA-G16)(.*)"); -const std::regex Device::loraG64Filters("(MTAC-LORA-G64)(.*)"); -const std::regex Device::gpiobFilters("(MTAC-GPIOB)|(MMTAC-GPIOI)"); -const std::regex Device::mfserFilters("(MTAC-MFSER-DTE)|(MTAC-MFSER-DCE)|(MTR-)(.*)"); +const std::vector<std::string> Device::apIdentifiers = { +    "ap1", "ap2", "lora", "lora-2", "slot1", "slot2"}; +const std::regex +    Device::apFilters("(modalias)|(power)(.*)|(subsystem)|(uevent)");  const std::regex Device::serialModeFilter("(.*)(serial-mode)"); -const std::regex Device::storeFilters("(.*)(mac-)(.*)|(.*)(-id)|(uuid)|(.*)(/eui)|(.*)(/cdone)|(.*)(hw-version)|(imei)|(capability)(.*)|(radio-reset-backoff-seconds)|(modalias)|(power)|((subsystem)(.*))|(uevent)|(board-temperature)|(reset)|(led3)|(led-ls)|(usbhd-ps-oc)|(.*)(adc[0-9])|(.*)(din[0-9])|(gpi[0-9])|(gpi[0-9][0-9])"); +const std::regex Device::mtcdt3Filters("(MTCDT3AC)(.*)"); +const std::regex Device::mtrFilters("(MTR-)(.*)"); +const std::regex Device::storeFilters( +    "(.*)(mac-)(.*)|(.*)(-id)|(uuid)|(.*)(/eui)|(.*)(/" +    "cdone)|(.*)(hw-version)|(oem-string)(.*)|(imei)|(capability)(.*)|(radio-" +    "reset-backoff-seconds)|(modalias)|(power)|((subsystem)(.*))|(uevent)|(" +    "board-temperature)|(reset)|(led3)|(led-ls)|(usbhd-ps-oc)|(.*)(adc[0-9])|(." +    "*)(din[0-9])|(gpi[0-9])|(gpi[0-9][0-9])");  const std::regex Device::showFilters("(modalias)|(subsystem)|(uevent)"); -std::map<std::string, bool> Device::capabilityList = {{"adc", false},{"battery", false},{"bluetooth", false}, -    {"cell", false},{"cellWwan", false},{"din", false},{"dout", false},{"externalSerialPort", false}, -    {"gpio", false},{"gps", false},{"lora", false},{"loraNetworkServer", false}, -    {"nodeRed", false},{"rs232", false},{"rs422", false},{"rs485", false},{"serial", false}, -	{"supercap", false},{"wifi", false},{"docker", false},{"tpm", false}}; +std::map<std::string, bool> Device::capabilityList = { +    {"adc", false}, +    {"battery", false}, +    {"bluetooth", false}, +    {"cell", false}, +    {"cellWwan", false}, +    {"din", false}, +    {"dout", false}, +    {"externalSerialPort", false}, +    {"gpio", false}, +    {"gps", false}, +    {"lora", false}, +    {"loraLbt", false}, +    {"loraNetworkServer", false}, +    {"nodeRed", false}, +    {"rs232", false}, +    {"rs422", false}, +    {"rs485", false}, +    {"serial", false}, +    {"supercap", false}, +    {"wifi", false}, +    {"docker", false}, +    {"tpm", false}};  std::map<std::string, std::string> Device::ethSwitchList; -std::map<std::string, std::string> Device::deviceInfoList = {{"deviceId", ""},{"hardwareVersion", ""}, -    {"imei", ""},{"macAddress", "00:00:00:00:00:00"},{"macBluetooth", "00:00:00:00:00:00"}, -    {"macWifi", "00:00:00:00:00:00"},{"productId", ""},{"uuid", ""},{"vendorId", ""}}; +std::map<std::string, std::string> Device::deviceInfoList = { +    {"deviceId", ""}, +    {"hardwareVersion", ""}, +    {"imei", ""}, +    {"macAddress", "00:00:00:00:00:00"}, +    {"macBluetooth", "00:00:00:00:00:00"}, +    {"macWifi", "00:00:00:00:00:00"}, +    {"productId", ""}, +    {"uuid", ""}, +    {"vendorId", ""}, +    {"oemString1", ""}, +    {"oemString2", ""}};  Device::Device() {      isRoot = !getuid(); -    verbose = false; +    accessoryCardsList.reserve(accessoryCardsListSize); +    accessoryCardsList.push_back(std::make_unique<Lora21Card>(*this)); +    accessoryCardsList.push_back(std::make_unique<Lora21ExtCard>(*this)); +    accessoryCardsList.push_back(std::make_unique<Lora03Card>(*this)); +    accessoryCardsList.push_back(std::make_unique<Lora10Card>(*this)); +    accessoryCardsList.push_back(std::make_unique<Lora15Card>(*this)); +    accessoryCardsList.push_back(std::make_unique<Lora2G4Card>(*this)); +    accessoryCardsList.push_back(std::make_unique<Gpiob>(*this)); +    accessoryCardsList.push_back(std::make_unique<Mfser>(*this));  } -bool Device::isAccessoryCard(const char * d_name, const char * dir_name) { -    return std::binary_search(apIdentifiers.begin(), apIdentifiers.end(), dir_name) && !regex_match(d_name, apFilters); +bool Device::isAccessoryCard(const char *d_name, const char *dir_name) { +    return std::binary_search(apIdentifiers.begin(), apIdentifiers.end(), +                              dir_name) && +           !regex_match(d_name, apFilters);  }  void Device::sortAccessoryCards() {      rapidjson::SizeType i, j;      for (i = 0; i < accessoryCards.Size() - 1; i++) {          for (j = 0; j < accessoryCards.Size() - i - 1; j++) { -            if (accessoryCards[j]["port"].GetString() < accessoryCards[j+1]["port"].GetString()) { -                accessoryCards[j].Swap( accessoryCards[j+1]); +            if (accessoryCards[j]["port"].GetString() < +                accessoryCards[j + 1]["port"].GetString()) { +                accessoryCards[j].Swap(accessoryCards[j + 1]);              }          }      }  } -bool Device::isValidDirectory(const struct dirent * entry, std::string fullPath, const char * d_name) { +bool Device::isValidDirectory(const struct dirent *entry, std::string fullPath, +                              const char *d_name) {      std::string path = fullPath + "/" + std::string(d_name); -    return (entry->d_type & DT_DIR) && strcmp (d_name, "..") != 0 && strcmp (d_name, ".") != 0 && (path.length() < PATH_MAX); +    return (entry->d_type & DT_DIR) && strcmp(d_name, "..") != 0 && +           strcmp(d_name, ".") != 0 && (path.length() < PATH_MAX);  } -void Device::getSystemTreeJson(const char * dir_name) { +void Device::getSystemTreeJson(const char *dir_name) {      std::string fullPath = SYSFS_PLATFORM + std::string(dir_name); -    DIR * d = opendir (fullPath.c_str()); +    DIR *d = opendir(fullPath.c_str());      if (!d) { -        logError("Cannot open directory " + fullPath); +        printError("Cannot open directory %s", fullPath);          exitHandler(99);      }      while (1) { -        struct dirent * entry = readdir (d);        /* Gets subsequent entries from "d" */ -        if (!entry) {                               /* If there are no more entries, exit */ +        struct dirent *entry = +            readdir(d); /* Gets subsequent entries from "d" */ +        if (!entry) {   /* If there are no more entries, exit */              break;          } -        const char * d_name = entry->d_name;        /* Get file name */ +        const char *d_name = entry->d_name; /* Get file name */          std::string fileData; -        if (!(entry->d_type & DT_DIR) && (MTS::System::readFile(fullPath + "/" + std::string(d_name), fileData) == 0)) { +        if (!(entry->d_type & DT_DIR) && +            (MTS::System::readFile(fullPath + "/" + std::string(d_name), +                                   fileData) == 0)) {              fileData = MTS::Text::trim(fileData);              if (strlen(dir_name) > 0) {                  if (isAccessoryCard(d_name, dir_name)) {                      if (accessoryCard.IsNull()) {                          accessoryCard.SetObject(); -                        accessoryCard.AddMember("port", rapidjson::Value().SetString(dir_name, accessoryCardsAlloc), accessoryCardsAlloc); +                        accessoryCard.AddMember( +                            "port", +                            rapidjson::Value().SetString(dir_name, acAlloc), +                            acAlloc);                      } else if (accessoryCard["port"] != dir_name) { -                        accessoryCards.PushBack(accessoryCard, accessoryCardsAlloc); +                        accessoryCards.PushBack(accessoryCard, acAlloc);                          accessoryCard.SetObject(); -                        accessoryCard.AddMember("port", rapidjson::Value().SetString(dir_name, accessoryCardsAlloc), accessoryCardsAlloc); +                        accessoryCard.AddMember( +                            "port", +                            rapidjson::Value().SetString(dir_name, acAlloc), +                            acAlloc);                      } -                    if (strcmp(d_name, "product-id") == 0) { /* Map card specific details based on the product id */ -                        if (regex_match(fileData, loraG16Filters)) { -                            Lora21Card lora21(*this, fileData, dir_name); -                        } else if (regex_match(fileData, loraG64Filters)) { -                            Lora21ExtCard lora21Ext(*this, fileData, dir_name); -                        } else if (regex_match(fileData, lora15Filters)) { -                            Lora15Card lora15(*this, fileData, dir_name); -                        } else if (regex_match(fileData, gpiobFilters)) { -                            Gpiob ppiob(*this, fileData, dir_name); -                        } else if (regex_match(fileData, mfserFilters)) { -                            Mfser msfer(*this, fileData, dir_name); +                    if (strcmp(d_name, "product-id") == +                        0) { /* Map card specific details based on the product +                                id */ +                        for (unsigned int i = 0; i < accessoryCardsList.size(); +                             i++) { +                            if (regex_match(fileData, +                                            accessoryCardsList[i]->GetName())) { +                                accessoryCardsList[i]->AddToDeviceInfo( +                                    dir_name, fileData); +                                break; +                            }                          }                      } -                    accessoryCard.AddMember(rapidjson::Value().SetString(toCamelCase(d_name).c_str(), accessoryCardsAlloc), rapidjson::Value().SetString(fileData.c_str(), accessoryCardsAlloc), accessoryCardsAlloc); -                } else if (strcmp (dir_name, "capability") == 0 && fileData == "1") { +                    accessoryCard.AddMember( +                        rapidjson::Value().SetString( +                            toCamelCase(d_name).c_str(), acAlloc), +                        rapidjson::Value().SetString(fileData.c_str(), acAlloc), +                        acAlloc); +                } else if (strcmp(dir_name, "capability") == 0 && +                           fileData == "1") {                      capabilityList[toCamelCase(d_name)] = true; -                } else if (strcmp (dir_name, "eth-switch") == 0) { +                } else if (strcmp(dir_name, "eth-switch") == 0) {                      ethSwitchList[toCamelCase(d_name)] = fileData;                  } -            } else if ((entry->d_type != DT_LNK)){ +            } else if ((entry->d_type != DT_LNK)) {                  if (deviceInfoList.count(toCamelCase(d_name)) > 0) {                      deviceInfoList[toCamelCase(d_name)] = fileData;                  } else if (strcmp(d_name, "hw-version") == 0) {                      deviceInfoList["hardwareVersion"] = fileData;                  } else if (strcmp(d_name, "mac-eth") == 0) {                      deviceInfoList["macAddress"] = fileData; -                } else if (strcmp(d_name, "has-radio") == 0 && fileData == "1") { +                } else if (strcmp(d_name, "has-radio") == 0 && +                           fileData == "1") {                      capabilityList["cell"] = true; +                } else if (strcmp(d_name, "oem-string1") == 0) { +                    deviceInfoList["oemString1"] = fileData; +                } else if (strcmp(d_name, "oem-string2") == 0) { +                    deviceInfoList["oemString2"] = fileData; +                }; +                if (strcmp(d_name, "product-id") == 0) { +                    if (regex_match(fileData, mtcdt3Filters)) { +                        capabilityList["rs232"] = true; +                        capabilityList["rs422"] = true; +                        capabilityList["rs485"] = true; +                        capabilityList["serial"] = true; +                    } +                    if (regex_match(fileData, mtrFilters)) { +                        capabilityList["rs232"] = true; +                        capabilityList["serial"] = true; +                    }                  }              }          } -        if (isValidDirectory(entry, fullPath, d_name)) { /* Check that the directory is not "d" or d's parent */ +        if (isValidDirectory(entry, fullPath, +                             d_name)) { /* Check that the directory is not "d" +                                           or d's parent */              getSystemTreeJson(d_name);  /* Recursively call with the new path */          }      } -    if (closedir (d)) { /* After going through all the entries, close the directory */ -        logError("Could not close " + std::string(fullPath)); +    if (closedir( +            d)) { /* After going through all the entries, close the directory */ +        printError("Could not close %s", fullPath);          exitHandler(errno);      }  }  void Device::init() {      if (!isRoot) { -        logError("Must be root to generate device_info.json"); +        printError("Must be root to generate device_info.json");          exitHandler(99);      }      load(); @@ -145,7 +223,7 @@ void Device::init() {  void Device::json() {      if (!isRoot) { -        logError("Must be root to generate json"); +        printError("Must be root to generate json");          exitHandler(99);      }      load(); @@ -160,7 +238,7 @@ void Device::load() {      accessoryCards.SetArray();      getSystemTreeJson("");      if (!accessoryCard.IsNull()) { -        accessoryCards.PushBack(accessoryCard, accessoryCardsAlloc); +        accessoryCards.PushBack(accessoryCard, acAlloc);          if (accessoryCards.Size() > 1) {              sortAccessoryCards();          } @@ -170,48 +248,58 @@ void Device::load() {      mapFirmware();      mapMacAddress2();      for (const auto capability : capabilityList) { -        capabilities.AddMember(rapidjson::Value().SetString(capability.first.c_str(), -            capability.first.length(), accessoryCardsAlloc), capability.second, accessoryCardsAlloc); +        capabilities.AddMember( +            rapidjson::Value().SetString(capability.first.c_str(), +                                         capability.first.length(), acAlloc), +            capability.second, acAlloc);      } -     +      if (ethSwitchList.count("chip") && ethSwitchList.count("numPorts")) { -        auto& ethSwitchAlloc = ethSwitch.GetAllocator(); -        const std::string& chip = ethSwitchList.at("chip"); +        auto ðSwitchAlloc = ethSwitch.GetAllocator(); +        const std::string &chip = ethSwitchList.at("chip");          ethSwitch.AddMember("chip", -            rapidjson::Value().SetString(chip.c_str(), chip.length(), ethSwitchAlloc),  -            ethSwitchAlloc); +                            rapidjson::Value().SetString( +                                chip.c_str(), chip.length(), ethSwitchAlloc), +                            ethSwitchAlloc);          rapidjson::Value ports;          ports.SetObject(); -        for (int i=0; i < std::stoi(ethSwitchList.at("numPorts")); ++i) { +        for (int i = 0; i < std::stoi(ethSwitchList.at("numPorts")); ++i) {              const std::string num = std::to_string(i);              const std::string keyLabel = "port" + num + "Label";              const std::string keyId = "port" + num + "Id"; -            const std::string keyMac = "port" + num + "Mac";; -            if (ethSwitchList.count(keyLabel) && -                ethSwitchList.count(keyId) && +            const std::string keyMac = "port" + num + "Mac"; +            ; +            if (ethSwitchList.count(keyLabel) && ethSwitchList.count(keyId) &&                  ethSwitchList.count(keyMac)) {                  rapidjson::Value port;                  port.SetObject(); -                port.AddMember("id", rapidjson::Value().SetInt(std::stoi(ethSwitchList.at(keyId))), ethSwitchAlloc); +                port.AddMember("id", +                               rapidjson::Value().SetInt( +                                   std::stoi(ethSwitchList.at(keyId))), +                               ethSwitchAlloc);                  port.AddMember("mac", -                                rapidjson::Value().SetString(ethSwitchList.at(keyMac).c_str(), -                                                             ethSwitchList.at(keyMac).length(), -                                                             ethSwitchAlloc), -                                ethSwitchAlloc); -                ports.AddMember(rapidjson::Value().SetString(ethSwitchList.at(keyLabel).c_str(), -                                                             ethSwitchList.at(keyLabel).length(), -                                                             ethSwitchAlloc), -                                std::move(port), -                                ethSwitchAlloc); +                               rapidjson::Value().SetString( +                                   ethSwitchList.at(keyMac).c_str(), +                                   ethSwitchList.at(keyMac).length(), +                                   ethSwitchAlloc), +                               ethSwitchAlloc); +                ports.AddMember(rapidjson::Value().SetString( +                                    ethSwitchList.at(keyLabel).c_str(), +                                    ethSwitchList.at(keyLabel).length(), +                                    ethSwitchAlloc), +                                std::move(port), ethSwitchAlloc);              }          }          ethSwitch.AddMember("ports", std::move(ports), ethSwitchAlloc);      }      for (const auto device : deviceInfoList) { -        deviceInfo.AddMember(rapidjson::Value().SetString(device.first.c_str(), -            device.first.length(), alloc), rapidjson::Value().SetString(device.second.c_str(), -            device.second.length(), alloc), alloc); +        deviceInfo.AddMember( +            rapidjson::Value().SetString(device.first.c_str(), +                                         device.first.length(), alloc), +            rapidjson::Value().SetString(device.second.c_str(), +                                         device.second.length(), alloc), +            alloc);      }      deviceInfo.AddMember("capabilities", capabilities, alloc); @@ -219,40 +307,34 @@ void Device::load() {      deviceInfo.AddMember("accessoryCards", accessoryCards, alloc);  } -void Device::logError(std::string info) { -    printf("error: %s\n", info.c_str()); -} - -void Device::logInfo(std::string info) { -    if (verbose) { -        printf("info: %s\n", info.c_str()); -    } -} -  void Device::mapFileToCapability() { -    if (fileType("/opt/node-red") == S_IFDIR) {     /* node-red is a directory */ +    if (fileType("/opt/node-red") == S_IFDIR) { /* node-red is a directory */          capabilityList["nodeRed"] = true;      } -    if (fileType("/opt/lora/lora-network-server") == S_IFREG) {     /* lora-network-server is a regular file */ +    if (fileType("/opt/lora/lora-network-server") == +        S_IFREG) { /* lora-network-server is a regular file */          capabilityList["loraNetworkServer"] = true;      } -    if (fileType("/dev/cdc-wdm0") == S_IFCHR) {     /* Cellular modem is wwan/qmi character device */ +    if (fileType("/dev/cdc-wdm0") == +        S_IFCHR) { /* Cellular modem is wwan/qmi character device */          capabilityList["cellWwan"] = true;      } -    if (fileType("/dev/ext_serial") == S_IFCHR) {   /* ext_serial is a character device */ +    if (fileType("/dev/ext_serial") == +        S_IFCHR) { /* ext_serial is a character device */          capabilityList["externalSerialPort"] = true;      } -    if (fileType("/usr/bin/dockerd") == S_IFREG) {   /* Docker is a regular file */ +    if (fileType("/usr/bin/dockerd") == +        S_IFREG) { /* Docker is a regular file */          capabilityList["docker"] = true;      } -    if (findFileGlob("/dev/tpm*") == S_IFCHR) {     /* tpm* is a character device */ +    if (findFileGlob("/dev/tpm*") == S_IFCHR) { /* tpm* is a character device */          capabilityList["tpm"] = true;      }  }  void Device::mapMacAddress2() {      std::ifstream file("/sys/devices/platform/mts-io/base/mac-eth"); -    if (file.is_open()){ +    if (file.is_open()) {          std::string line = "";          std::getline(file, line);          deviceInfoList["macAddress1"] = line; @@ -261,32 +343,35 @@ void Device::mapMacAddress2() {  void Device::mapFirmware() {      std::ifstream file(FIRMWARE_FILE); -    if (!file.is_open()){ +    if (!file.is_open()) {          return;      }      std::string line; -    while (std::getline(file, line)){ -        if (line.find(FIRMWARE_VERSION) != std::string::npos){ +    while (std::getline(file, line)) { +        if (line.find(FIRMWARE_VERSION) != std::string::npos) {              deviceInfoList["firmware"] = line.substr(line.find(" ") + 1); -        } else if (line.find(FIRMWARE_DATE) != std::string::npos){ +        } else if (line.find(FIRMWARE_DATE) != std::string::npos) {              deviceInfoList["firmwareDate"] = line.substr(line.find(" ") + 1); +        } else if (line.find(FIRMWARE_RELEASE) != std::string::npos) { +            deviceInfoList["firmwareRelease"] = line.substr(line.find(" ") + 1);          }      }  } -void Device::printDir(const std::string dir_name, std::vector<std::string> &results) { +void Device::printDir(const std::string dir_name, +                      std::vector<std::string> &results) {      std::string fullPath = SYSFS_PLATFORM + std::string(dir_name); -    DIR * d = opendir(fullPath.c_str()); +    DIR *d = opendir(fullPath.c_str());      if (!d) { -        logError("Cannot open directory " + std::string(fullPath)); +        printError("Cannot open directory %s", fullPath);          exitHandler(99);      }      while (1) { -        struct dirent * entry = readdir (d); +        struct dirent *entry = readdir(d);          if (!entry) {              break;          } -        const char * d_name = entry->d_name; +        const char *d_name = entry->d_name;          if (!(entry->d_type & DT_DIR)) {              std::string result;              if (dir_name.size() > 0) { @@ -295,12 +380,15 @@ void Device::printDir(const std::string dir_name, std::vector<std::string> &resu              result.append(d_name);              results.push_back(result);          } -        if (isValidDirectory(entry, fullPath, d_name)) { /* Check that the directory is not "d" or d's parent. */ +        if (isValidDirectory(entry, fullPath, +                             d_name)) { /* Check that the directory is not "d" +                                           or d's parent. */              printDir(d_name, results);          }      } -    if (closedir (d)) { /* After going through all the entries, close the directory. */ -        logError("Could not close " + std::string(fullPath)); +    if (closedir(d)) { /* After going through all the entries, close the +                          directory. */ +        printError("Could not close %s", fullPath);          exitHandler(errno);      }  } @@ -312,42 +400,80 @@ void Device::printJson() {      std::cout << buffer.GetString();  } -void Device::printVersion (std::string name) { -    printf("%s %s\nCopyright (C) 2020 by Multi-Tech Systems\nThis program is free software; you may redistribute it under the terms of\nthe GNU General Public License version 2 or (at your option) any later version.\nThis program has absolutely no warranty.\n",name.c_str(), Version::version.c_str()); +void Device::printVersion(std::string name) { +    printInfo( +        "%s %s\nCopyright (C) 2021 by Multi-Tech Systems\nThis program is free " +        "software; you may redistribute it under the terms of\nthe GNU General " +        "Public License version 2 or (at your option) any later version.\nThis " +        "program has absolutely no warranty.", +        name.c_str(), Version::version.c_str()); +    exitHandler(0);  }  void Device::printUsage(std::string program) {      std::vector<std::string> showResults; -    printf("Usage: %s [ OPTIONS ] OBJECT [--] [ ARGUMENTS ]\n", program.c_str()); +    printf("Usage: %s [ OPTIONS ] OBJECT [--] [ ARGUMENTS ]\n", +           program.c_str());      printf("where  OBJECT := {\n");      printf("         init |\n");      printf("         show SHOW-NAME |\n");      printf("         store STORE-NAME |\n");      printf("         json |\n"); +    printf("         load-fpga FPGA-OPTIONS |\n");      printf("       }\n");      printf("\n"); +    printf("       FPGA-OPTIONS := {\n"); +    printf("          -c        Check FPGA Version\n"); +    printf("          -i        Specify input file. Default is " +           "mtcdt-fpga-v31.hex for a MultiConnect Conduit\n"); +    printf("                    and mtcap-fpga-v31.hex for MultiConnect Access " +           "Point\n"); +    printf("          -p        Specify port 1 or 2 (MultiConnect Conduit " +           "Only)\n"); +    printf( +        "          -s        Print FPGA versions supported by the utility\n"); +    printf("          Examples :=\n"); +    printf("          %s load-fpga -c                       Check existing " +           "FPGA version\n", +           program.c_str()); +    printf("          %s load-fpga -i <upgrade file>        Upgrade the FPGA " +           "on the default port using the file specified\n", +           program.c_str()); +    printf("          %s load-fpga -p 2 -i <upgrade file>   Upgrade the FPGA " +           "on ap2 using the file specified\n", +           program.c_str()); +    printf("          %s                                    Upgrade the FPGA " +           "on the default port and upgrade file\n", +           program.c_str()); +    printf("       }\n");      printf("       SHOW-NAME := {\n");      printDir("", showResults); -    sort(showResults.begin(), showResults.end());       // Unix file tree is not sorted +    sort(showResults.begin(), +         showResults.end()); // Unix file tree is not sorted -    for (std::string showResult: showResults) { +    for (std::string showResult : showResults) {          if (!regex_match(showResult, showFilters)) -            printf ("          %s\n", showResult.c_str()); +            printf("          %s\n", showResult.c_str());      }      printf("       }\n");      printf("\n");      printf("       STORE-NAME := {\n"); -    for (std::string showResult: showResults) { +    for (std::string showResult : showResults) {          if (showResult == "radio-reset") { -            printf ("          %s { 0 }\n", showResult.c_str()); +            printf("          %s { 0 }\n", showResult.c_str());          } else if (showResult == "reset-monitor") { -            printf ("          %s { pid short-signal long-signal [extra-long-signal] }\n", showResult.c_str()); +            printf("          %s { pid short-signal long-signal " +                   "[extra-long-signal] }\n", +                   showResult.c_str());          } else if (showResult == "reset-monitor-intervals") { -            printf ("          %s { short-interval long-interval }\n", showResult.c_str()); +            printf("          %s { short-interval long-interval }\n", +                   showResult.c_str());          } else if (regex_match(showResult, serialModeFilter)) { -            printf ("          %s { loopback | rs232 | rs485-half | rs422-485-full }\n", showResult.c_str()); +            printf("          %s { loopback | rs232 | rs485-half | " +                   "rs422-485-full }\n", +                   showResult.c_str());          } else if (!regex_match(showResult, storeFilters)) { -            printf ("          %s BOOLEAN\n", showResult.c_str()); +            printf("          %s BOOLEAN\n", showResult.c_str());          }      }      printf("       OPTIONS := {\n"); @@ -365,76 +491,72 @@ void Device::show(std::string name) {      std::string fileData;      int32_t code = MTS::System::readFile(SYSFS_PLATFORM + name, fileData);      if (code == 0) { -        printf("%s",fileData.c_str()); +        printf("%s", fileData.c_str());          exitHandler(0);      } else { -        logError("cat: can't open " + std::string(SYSFS_PLATFORM) + name + ": No such file or directory"); +        printError("cat: can't open %s%s: No such file or directory", +                   SYSFS_PLATFORM, name.c_str());          exitHandler(99);      }  }  void Device::showTrigger(std::string name) {      std::string fileData; -    int32_t code = MTS::System::readFile(LEDS_GPIO_DIR + name + "/trigger", fileData); +    int32_t code = +        MTS::System::readFile(LEDS_GPIO_DIR + name + "/trigger", fileData);      if (code == 0) { -        printf("%s",fileData.c_str()); +        printf("%s", fileData.c_str());          exitHandler(0);      } else { -        logError("can't not open '" + std::string(LEDS_GPIO_DIR) + name + "/trigger': No such file or directory"); +        printError("Can't not open %s%s/trigger': No such file or directory", +                   LEDS_GPIO_DIR, name.c_str());          exitHandler(99);      }  }  void Device::store(std::string name, std::string value) {      if (!isRoot) { -        logError("Must be root to store to " + name); +        printError("Must be root to store to %s", name.c_str());          exitHandler(99);      } -    logInfo("setting " + name + " to " + value); +    printDebug("Setting %s to %s", name.c_str(), value.c_str());      std::ofstream fileToWrite(SYSFS_PLATFORM + name);      if (!fileToWrite.bad()) {          fileToWrite << value;          fileToWrite.close();          exitHandler(0);      } else { -        logError("can't not open '" + std::string(SYSFS_PLATFORM) + name + "': No such file or directory"); +        printError("Can't open %s%s: No such file or directory", SYSFS_PLATFORM, +                   name.c_str());          exitHandler(99);      } -  }  void Device::storeTrigger(std::string name, std::string value) {      if (!isRoot) { -        logError("Must be root to storeTrigger to " + name + "/trigger"); +        printError("Must be root to storeTrigger to %s/trigger", name.c_str());          exitHandler(99);      } -    logInfo("setting " + name + " to " + value); +    printDebug("Setting %s to %s", name.c_str(), value.c_str());      std::ofstream fileToWrite(LEDS_GPIO_DIR + name + "/trigger");      if (!fileToWrite.bad()) {          fileToWrite << value;          fileToWrite.close();          exitHandler(0);      } else { -        logError("can't not open '" + std::string(LEDS_GPIO_DIR) + name + "/trigger': No such file or directory"); +        printError("Can't not open %s%s/trigger': No such file or directory", +                   LEDS_GPIO_DIR, name.c_str());          exitHandler(99);      }  } -void Device::Verbose(const bool val) { -    verbose = val; -} - -bool Device::Verbose() { -    return verbose; -} -  void Device::writeJson() {      rapidjson::StringBuffer buffer;      rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);      deviceInfo.Accept(writer);      std::ofstream os(DEVICE_INFO_FILE);      if (!os) { -        logError("Can't write to " + std::string(DEVICE_INFO_FILE)); +        printError("Can't write to %s", DEVICE_INFO_FILE);          exitHandler(99);      } else {          os << buffer.GetString(); | 
