From 8ce2b9763c880084fd9d38fae6033e487fde58d9 Mon Sep 17 00:00:00 2001 From: Harsh Sharma Date: Thu, 19 Dec 2019 11:53:10 -0600 Subject: Initial commit --- src/AccessoryCards/AccessoryCardLora.cpp | 22 ++ src/AccessoryCards/AccessoryCardLora15.cpp | 142 ++++++++++ src/Device/Device.cpp | 422 +++++++++++++++++++++++++++++ src/MtsIoSysfs.cpp | 75 +++++ src/Version.cpp | 4 + 5 files changed, 665 insertions(+) create mode 100644 src/AccessoryCards/AccessoryCardLora.cpp create mode 100644 src/AccessoryCards/AccessoryCardLora15.cpp create mode 100644 src/Device/Device.cpp create mode 100644 src/MtsIoSysfs.cpp create mode 100644 src/Version.cpp (limited to 'src') diff --git a/src/AccessoryCards/AccessoryCardLora.cpp b/src/AccessoryCards/AccessoryCardLora.cpp new file mode 100644 index 0000000..13bbab5 --- /dev/null +++ b/src/AccessoryCards/AccessoryCardLora.cpp @@ -0,0 +1,22 @@ +#include "AccessoryCardLora.h" + +AccessoryCardLora::AccessoryCardLora(std::string ProductId, std::string Port) { + port = Port; + productId = ProductId; + spiPath = "/dev/spidev0.0"; + if ((productId.find("MTCDT3-") == 0) && (port.back() == '2')) { + spiPath = "/dev/spidev1.0"; + } else if (productId.find("MTAC-LORA-G") == 0) { + spiPath = "/dev/spidev32766.2"; + } else if (productId.find("MTAC-LORA-") == 0) { + if (port.back() == '2') { + spiPath = "/dev/spidev32765.2"; + } else { + spiPath = "/dev/spidev32766.2"; + } + } +} + +std::string AccessoryCardLora::getPath() { + return spiPath; +} diff --git a/src/AccessoryCards/AccessoryCardLora15.cpp b/src/AccessoryCards/AccessoryCardLora15.cpp new file mode 100644 index 0000000..ee99622 --- /dev/null +++ b/src/AccessoryCards/AccessoryCardLora15.cpp @@ -0,0 +1,142 @@ +#include "AccessoryCardLora15.h" + +AccessoryCardLora15::AccessoryCardLora15(std::string ProductId, std::string Port) : AccessoryCardLora(ProductId, Port) { +} + +int AccessoryCardLora15::spiOpen(const char *spidev) { + int *spi_device = NULL; + int dev; + int a = 0, b = 0; + int i; + + /* allocate memory for the device descriptor */ + spi_device = (int *)malloc(sizeof(int)); + if (spi_device == NULL) { + printf("ERROR: MALLOC FAIL\n"); + return -1; + } + + /* open SPI device */ + dev = open(spidev, O_RDWR); + if (dev < 0) { + printf("ERROR: failed to open SPI device %s\n", spidev); + return -1; + } + + /* setting SPI mode to 'mode 0' */ + i = SPI_MODE_3; + a = ioctl(dev, SPI_IOC_WR_MODE, &i); + b = ioctl(dev, SPI_IOC_RD_MODE, &i); + if ((a < 0) || (b < 0)) { + printf("ERROR: SPI PORT FAIL TO SET IN MODE 0\n"); + close(dev); + free(spi_device); + return -1; + } + + /* setting SPI max clk (in Hz) */ + i = SPI_SPEED; + a = ioctl(dev, SPI_IOC_WR_MAX_SPEED_HZ, &i); + b = ioctl(dev, SPI_IOC_RD_MAX_SPEED_HZ, &i); + if ((a < 0) || (b < 0)) { + printf("ERROR: SPI PORT FAIL TO SET MAX SPEED\n"); + close(dev); + free(spi_device); + return -1; + } + + /* setting SPI to MSB first */ + i = 0; + a = ioctl(dev, SPI_IOC_WR_LSB_FIRST, &i); + b = ioctl(dev, SPI_IOC_RD_LSB_FIRST, &i); + if ((a < 0) || (b < 0)) { + printf("ERROR: SPI PORT FAIL TO SET MSB FIRST\n"); + close(dev); + free(spi_device); + return -1; + } + + /* setting SPI to 8 bits per word */ + i = 0; + a = ioctl(dev, SPI_IOC_WR_BITS_PER_WORD, &i); + b = ioctl(dev, SPI_IOC_RD_BITS_PER_WORD, &i); + if ((a < 0) || (b < 0)) { + printf("ERROR: SPI PORT FAIL TO SET 8 BITS-PER-WORD\n"); + close(dev); + return -1; + } + + *spi_device = dev; + spi_target_ptr = (void *)spi_device; + return 0; +} +int AccessoryCardLora15::spiRead(uint8_t address, uint8_t *data) { + int spi_device; + uint8_t out_buf[3]; + uint8_t in_buf[ARRAY_SIZE(out_buf)]; + uint8_t command_size; + struct spi_ioc_transfer k; + int a; + + spi_device = *(int *)spi_target_ptr; /* spi_target cannot be null beforehand */ + + /* prepare frame to be sent */ + out_buf[0] = MTAC_FPGA; + out_buf[1] = READ_ACCESS | (address & 0x7F); + out_buf[2] = 0x00; + command_size = 3; + + /* I/O transaction */ + memset(&k, 0, sizeof(k)); /* clear k */ + k.tx_buf = (unsigned long)out_buf; + k.rx_buf = (unsigned long)in_buf; + k.len = command_size; + k.cs_change = 1; + a = ioctl(spi_device, SPI_IOC_MESSAGE(1), &k); + + /* determine return code */ + if (a != (int)k.len) { + printf("ERROR: SPI READ FAILURE\n"); + return -1; + } else { + *data = in_buf[command_size - 1]; + return 0; + } +} + +int AccessoryCardLora15::spiClose() { + int spi_device; + int a; + + /* close file & deallocate file descriptor */ + spi_device = *(int *)spi_target_ptr; /* check that spi_target is not null */ + a = close(spi_device); + free(spi_target_ptr); + + /* determine return code */ + if (a < 0) { + printf("ERROR: SPI PORT FAILED TO CLOSE\n"); + return -1; + } else { + return 0; + } +} + +uint8_t AccessoryCardLora15::getFPGAVersion() { + int ret; + uint8_t u = 255; + ret = spiOpen(getPath().c_str()); + if (ret != 0) { + printf("Could not open SPI port %s", getPath().c_str()); + return u; + } + /* detect if the gateway has an FPGA with SPI mux header support */ + ret = spiRead(MTAC_FPGA_ADDRESS, &u); + if (ret != 0) { + printf("Could not read FPGA version"); + } + + spiClose(); + spi_target_ptr = NULL; + return u; +} \ No newline at end of file diff --git a/src/Device/Device.cpp b/src/Device/Device.cpp new file mode 100644 index 0000000..573e10b --- /dev/null +++ b/src/Device/Device.cpp @@ -0,0 +1,422 @@ +/********************************************************************** +* 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 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::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::showFilters("(modalias)|(subsystem)|(uevent)"); + +Device::Device() { + isRoot = !getuid(); +} + +void Device::exitHandler(int code) { + if (code != 0) { + logError("exiting with " + std::to_string(code)); + } + exit(code); +} + +bool Device::fileExists(std::string file) { + struct stat buffer; + return (stat (file.c_str(), &buffer) == 0) ? true : false; +} + +mode_t Device::fileType(std::string file) { + struct stat buf; + stat (file.c_str(), &buf); + return buf.st_mode & S_IFMT; +} + +void Device::getSystemTreeJson(const char * dir_name) { + std::string fullPath = SYSFS_PLATFORM + std::string(dir_name); + DIR * d = opendir (fullPath.c_str()); + + if (!d) { + logError("Cannot open directory " + fullPath); + exitHandler(99); + } + while (1) { + struct dirent * entry; + const char * d_name; + entry = readdir (d); // Gets subsequent entries from "d" + if (!entry) { // If there are no more entries, exit + break; + } + d_name = entry->d_name; // Get file name + if (!(entry->d_type & DT_DIR)) { + std::string fileData; + MTS::System::readFile(fullPath + "/" + std::string(d_name), fileData); + fileData = MTS::Text::trim(fileData); + if (strlen(dir_name) > 0) { + if (std::binary_search(apIdentifiers.begin(), apIdentifiers.end(), dir_name) && !regex_match(d_name, apFilters)) { + if (accessoryCard.IsNull()) { + accessoryCard.SetObject(); + } else if (accessoryCard.HasMember(d_name)) { + accessoryCards.PushBack(accessoryCard, accessoryCardsAlloc); + accessoryCard.SetObject(); + } + if (strcmp(d_name, "product-id") == 0) { + if (regex_match(fileData, lora15Filters)) { + capabilityList["lora"] = true; + AccessoryCardLora15 mSPI(fileData, dir_name); + mSPI.getFPGAVersion(); + accessoryCard.AddMember("loraFpgaVersion", mSPI.getFPGAVersion(), accessoryCardsAlloc); + } else if (regex_match(fileData, loraG16Filters)) { + capabilityList["lora"] = true; + std::string fpgaVersion; + MTS::System::cmd(LORA_2_1_FPGA_VERSION, fpgaVersion); + accessoryCard.AddMember("loraFpgaVersion", std::stoi(fpgaVersion), accessoryCardsAlloc); + } else if (regex_match(fileData, loraG64Filters)) { + capabilityList["lora"] = true; + std::string fpgaVersion; + std::string fpgaVersion2; + MTS::System::cmd(LORA_2_1_FPGA_VERSION, fpgaVersion); + MTS::System::cmd(LORA_2_1_EXT_FPGA_VERSION, fpgaVersion2); + accessoryCard.AddMember("loraFpgaVersion", std::stoi(fpgaVersion), accessoryCardsAlloc); + accessoryCard.AddMember("loraFpgaVersion2", std::stoi(fpgaVersion2), accessoryCardsAlloc); + } else if (regex_match(fileData, gpiobFilters)) { + capabilityList["adc"] = true; + capabilityList["din"] = true; + capabilityList["dout"] = true; + capabilityList["gpio"] = true; + } else if (regex_match(fileData, mfserFilters)) { + capabilityList["rs232"] = true; + capabilityList["rs422"] = true; + capabilityList["rs485"] = true; + capabilityList["serial"] = true; + if (!fileExists("/dev/ext_serial") && strlen(dir_name) > 0) { + std::string temp; + MTS::System::cmd("ln -s /dev/ttyAP" + std::string(dir_name + strlen(dir_name) - 1) + " /dev/ext_serial", temp); + } + } + } + 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") { + capabilityList[toCamelCase(d_name)] = true; + } + } 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; + } + } + } + if (entry->d_type & DT_DIR) { /* Check that the directory is not "d" or d's parent. */ + if (strcmp (d_name, "..") != 0 && strcmp (d_name, ".") != 0) { + std::string path = fullPath + "/" + std::string(d_name); + if (path.length() >= PATH_MAX) { + logError("Path length has got too long.\n"); + exitHandler(99); + } + 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)); + exitHandler(errno); + } +} + +void Device::init() { + if (!isRoot) { + logError("Must be root to generate device_info.json"); + exitHandler(99); + } + load(); + writeJson(); + exitHandler(0); +} + +void Device::json() { + if (!isRoot) { + logError("Must be root to generate json"); + exitHandler(99); + } + load(); + printJson(); + exitHandler(0); +} + +void Device::load() { + deviceInfo.SetObject(); + capabilities.SetObject(); + accessoryCards.SetArray(); + getSystemTreeJson(""); + if (!accessoryCard.IsNull()) { + accessoryCards.PushBack(accessoryCard, accessoryCardsAlloc); + } + mapFileToCapability(); + mapFirmware(); + for (const auto capability : capabilityList) { + capabilities.AddMember(rapidjson::Value().SetString(capability.first.c_str(), + capability.first.length(), accessoryCardsAlloc), capability.second, accessoryCardsAlloc); + } + 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("capabilities", capabilities, alloc); + 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("/dev/modem_at0") == S_IFLNK && fileType("/dev/modem_at1") == S_IFLNK) { + capabilityList["cell"] = true; + } + if (fileType("/dev/modem_at0") == S_IFLNK) { + capabilityList["cell"] = true; + } + if (fileType("/dev/ext_serial") == S_IFCHR) { + capabilityList["externalSerialPort"] = true; + } + if (fileType("/opt/node-red") == S_IFDIR) { + capabilityList["nodeRed"] = true; + } + if (fileType("/opt/lora/lora-network-server") == S_IFREG) { + capabilityList["loraNetworkServer"] = true; + } +} + +void Device::mapFirmware() { + std::ifstream file(FIRMWARE_FILE); + if (!file.is_open()){ + return; + } + std::string line; + 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){ + deviceInfoList["firmwareDate"] = line.substr(line.find(" ") + 1); + } + } +} + +void Device::printDir(const std::string dir_name, std::vector &results) { + std::string fullPath = SYSFS_PLATFORM + std::string(dir_name); + DIR * d = opendir(fullPath.c_str()); + if (!d) { + logError("Cannot open directory " + std::string(fullPath)); + exitHandler(99); + } + while (1) { + struct dirent * entry = readdir (d); + if (!entry) { + break; + } + const char * d_name = entry->d_name; + if (!(entry->d_type & DT_DIR)) { + std::string result; + if (dir_name.size() > 0) { + result = (dir_name + "/"); + } + result.append(d_name); + results.push_back(result); + } + if ((entry->d_type & DT_DIR) && strcmp (d_name, "..") != 0 && strcmp (d_name, ".") != 0) { + std::string path = fullPath + "/" + std::string(d_name); + if (path.length() >= PATH_MAX) { + logError("Path length has got too long.\n"); + exitHandler(99); + } + printDir(d_name, results); + } + } + if (closedir (d)) { /* After going through all the entries, close the directory. */ + logError("Could not close " + std::string(fullPath)); + exitHandler(errno); + } +} + +void Device::printJson() { + rapidjson::StringBuffer buffer; + rapidjson::Writer writer(buffer); + deviceInfo.Accept(writer); + std::cout << buffer.GetString(); +} + +void Device::printVersion (std::string name) { + printf("%s %s\nCopyright (C) 2019 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::printUsage(std::string program) { + std::vector showResults; + 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(" }\n"); + printf("\n"); + printf(" SHOW-NAME := {\n"); + printDir("", showResults); + sort(showResults.begin(), showResults.end()); // Unix file tree is not sorted + + for (std::string showResult: showResults) { + if (!regex_match(showResult, showFilters)) + printf (" %s\n", showResult.c_str()); + } + printf(" }\n"); + printf("\n"); + printf(" STORE-NAME := {\n"); + for (std::string showResult: showResults) { + if (showResult == "radio-reset") { + 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()); + } else if (showResult == "reset-monitor-intervals") { + 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()); + } else if (!regex_match(showResult, storeFilters)) { + printf (" %s BOOLEAN\n", showResult.c_str()); + } + } + printf(" OPTIONS := {\n"); + printf(" --verbose\n"); + printf(" }\n"); + printf("\n"); + printf(" BOOLEAN := { OFF | ON }\n"); + printf(" OFF := 0\n"); + printf(" ON := 1\n"); + printf("\n"); + exitHandler(1); +} + +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()); + exitHandler(0); + } else { + logError("cat: can't open " + std::string(SYSFS_PLATFORM) + name + ": No such file or directory"); + exitHandler(99); + } + +} + +void Device::showTrigger(std::string name) { + std::string fileData; + int32_t code = MTS::System::readFile(LEDS_GPIO_DIR + name + "/trigger", fileData); + if (code == 0) { + 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"); + exitHandler(99); + } +} + +void Device::store(std::string name, std::string value) { + if (!isRoot) { + logError("Must be root to store to " + name); + exitHandler(99); + } + logInfo("setting " + name + " to " + value); + 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"); + exitHandler(99); + } + +} + +void Device::storeTrigger(std::string name, std::string value) { + if (!isRoot) { + logError("Must be root to storeTrigger to " + name + "/trigger"); + exitHandler(99); + } + logInfo("setting " + name + " to " + value); + 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"); + exitHandler(99); + } + +} + +std::string Device::toCamelCase(const char * d_name) { + std::string camelString = strdup(d_name); + std::string tempString = ""; + for (size_t x = 0; x < camelString.length(); x++){ + if (camelString[x] == '-' || camelString[x] == '_'){ + tempString = camelString.substr(x + 1, 1); + transform(tempString.begin(), tempString.end(), tempString.begin(), toupper); + camelString.erase(x, 2); + camelString.insert(x, tempString); + } + } + return camelString; +} + +void Device::Verbose(bool val) { + verbose = val; +} + +bool Device::Verbose() { + return verbose; +} + +void Device::writeJson() { + rapidjson::StringBuffer buffer; + rapidjson::Writer writer(buffer); + deviceInfo.Accept(writer); + std::string json (buffer.GetString(), buffer.GetSize()); + std::ofstream of ("/var/run/config/device_info.json"); + of << json; + if (!of.good()) { + logError("Can't write to /var/run/config/device_info.json"); + exitHandler(99); + } else { + exitHandler(0); + } +} diff --git a/src/MtsIoSysfs.cpp b/src/MtsIoSysfs.cpp new file mode 100644 index 0000000..0c9dc2e --- /dev/null +++ b/src/MtsIoSysfs.cpp @@ -0,0 +1,75 @@ +/********************************************************************** +* 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" + +int main(int argc, char const* const argv[]) { + Device m; + if (argc < 2) { + m.printUsage(argv[0]); + } + + for (int i = 1; i < argc; i++) { + if (argv[i][0] == '-') { + std::string parameter = &argv[i][1]; + if (parameter == "-version") { + m.printVersion(argv[0]); + } else if (parameter == "-help") { + m.printUsage(argv[0]); + } else if (parameter == "-verbose") { + m.Verbose(true); + } + } + } + for (int i = 1; i < argc; i++) { + std::string parameter = argv[i]; + if (parameter == "init") { + m.init(); + } else if (parameter == "json") { + m.json(); + } else if (parameter == "show") { + if (argv[i + 1] && !argv[i + 2]) { + m.show(argv[i + 1]); + } else { + m.logError("show name"); + m.exitHandler(99); + } + } else if (parameter == "show-trigger") { + if (argv[i + 1] && !argv[i + 2]) { + m.showTrigger(std::string(argv[i + 1])); + } else { + m.logError("show-trigger name"); + m.exitHandler(99); + } + } else if (parameter == "store") { + if (argv[i + 1] && argv[i + 2] && !argv[i + 3]) { + m.store(std::string(argv[i + 1]), std::string(argv[i + 2])); + } else { + m.logError("store name value"); + m.exitHandler(99); + } + } else if (parameter == "store-trigger") { + if (argv[i + 1] && argv[i + 2] && !argv[i + 3]) { + m.storeTrigger(std::string(argv[i + 1]), std::string(argv[i + 2])); + } else { + m.logError("store name value"); + m.exitHandler(99); + } + } + } + m.printUsage(argv[0]); +} diff --git a/src/Version.cpp b/src/Version.cpp new file mode 100644 index 0000000..5585cc1 --- /dev/null +++ b/src/Version.cpp @@ -0,0 +1,4 @@ +//Pre-Build Auto-Generated Source +#include "Version.h" + +const std::string Version::version("4.2.3-12-g42e11db"); -- cgit v1.2.3