diff options
Diffstat (limited to 'src/Device/Device.cpp')
-rw-r--r-- | src/Device/Device.cpp | 197 |
1 files changed, 147 insertions, 50 deletions
diff --git a/src/Device/Device.cpp b/src/Device/Device.cpp index b2588eb..2d93ed7 100644 --- a/src/Device/Device.cpp +++ b/src/Device/Device.cpp @@ -42,16 +42,12 @@ std::map<std::string, bool> Device::capabilityList = { {"cell", 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}, @@ -60,8 +56,8 @@ std::map<std::string, bool> Device::capabilityList = { {"userDataEncryption", false}}; std::map<std::string, std::string> Device::ethSwitchList; -std::vector<std::string> Device::dInputs; -std::vector<std::string> Device::dOutputs; +std::string Device::extIoStr = "{\"dInputs\":[],\"dOutputs\":[]}";; +std::string Device::serialStr = "[]"; std::map<std::string, std::string> Device::deviceInfoList = { {"deviceId", ""}, @@ -179,19 +175,33 @@ void Device::getSystemTreeJson(const char *dir_name) { } else if (strcmp(d_name, "hw-version") == 0) { deviceInfoList["hardwareVersion"] = fileData; if (regex_match(fileData, mtcdt3HwVersionFilters)) { - capabilityList["rs232"] = true; - capabilityList["rs422"] = true; - capabilityList["rs485"] = true; capabilityList["serial"] = true; } if (regex_match(fileData, iotRtrVersionFilters)) { + mapMacAddress2Iotr(); /* The order of the elements is important! This array is used to access Digital IOs, in particular in SMS commands! */ - dInputs.push_back("USER_DIO_IN"); - dOutputs.push_back("USER_DIO_OUT"); - mapMacAddress2Iotr(); + extIoStr = "{\"dInputs\":[\"USER_DIO_IN\"],\"dOutputs\":[\"USER_DIO_OUT\"]}"; + capabilityList["serial"] = true; + serialStr = "[{" + "\"available\": true," + "\"id\": \"serial0\"," + "\"name\": \"RS232\"," + "\"device\": \"/dev/ttymxc1\"," + "\"role\": \"DCE\"," + "\"modes\": {\"RS-232\": [\"hw-flowcontrol\", \"dcd-dtr\"]}," + "\"speed\": [9600, 19200, 38400, 57600, 115200]" + "},{" + "\"available\": true," + "\"id\": \"serial1\"," + "\"name\": \"RS232/485\"," + "\"device\": \"/dev/ttymxc2\"," + "\"role\": \"DCE\"," + "\"modes\": {\"RS-232\": [\"hw-flowcontrol\"], \"RS-485-HALF\": [\"rs4xx-termination\"]}," + "\"speed\": [9600, 19200, 38400, 57600, 115200, 230400, 460800, 930600]" + "}]"; } } else if (strcmp(d_name, "mac-eth") == 0) { deviceInfoList["macAddress"] = fileData; @@ -318,28 +328,14 @@ void Device::load() { deviceInfo.AddMember("capabilities", capabilities, alloc); deviceInfo.AddMember("ethSwitch", ethSwitch, alloc); deviceInfo.AddMember("accessoryCards", accessoryCards, alloc); - rapidjson::Document inp; - auto &inpAlloc = inp.GetAllocator(); - inp.SetArray(); - for (const auto &input : dInputs) { - rapidjson::Value value; - value.SetString(input.c_str(), input.length(), inpAlloc); - inp.PushBack(value, inpAlloc); - } - rapidjson::Document out; - auto &outAlloc = out.GetAllocator(); - out.SetArray(); - for (const auto &output : dOutputs) { - rapidjson::Value value; - value.SetString(output.c_str(), output.length(), outAlloc); - out.PushBack(value, outAlloc); - } rapidjson::Document extIo; - extIo.SetObject(); + extIo.Parse<0>(extIoStr.c_str()); auto &extAlloc = extIo.GetAllocator(); - extIo.AddMember(KEY_DINPUTS, inp, extAlloc); - extIo.AddMember(KEY_DOUTPUTS, out, extAlloc); deviceInfo.AddMember(KEY_EXTIO, extIo, extAlloc); + rapidjson::Document serial; + serial.Parse<0>(serialStr.c_str()); + auto &serAlloc = serial.GetAllocator(); + deviceInfo.AddMember(KEY_SERIALS, serial, serAlloc); } void Device::mapFileToCapability() { @@ -350,10 +346,6 @@ void Device::mapFileToCapability() { S_IFREG) { /* lora-network-server is a regular file */ capabilityList["loraNetworkServer"] = true; } - 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 */ capabilityList["docker"] = true; @@ -450,9 +442,10 @@ void Device::printVersion(std::string name) { exitHandler(0); } -void Device::printUsage(std::string program) { + +void Device::printUsage() { std::vector<std::string> showResults; - printf("Usage: %s [ OPTIONS ] OBJECT [--] [ ARGUMENTS ]\n", program.c_str()); + printf("Usage: %s [ OPTIONS ] OBJECT [--] [ ARGUMENTS ]\n", program_name.c_str()); printf("Legacy OBJECT options:\n"); printf(" init : init & make device info json\n"); printf(" json : init & make device info json\n"); @@ -489,7 +482,7 @@ void Device::printUsage(std::string program) { printf("\n"); printf("show-name:\n"); printf("Usage:\n"); - printf("--show-name <name>\n"); + printf("--show <name>\n"); printDir("", showResults); sort(showResults.begin(), showResults.end()); // Unix file tree is not sorted @@ -498,10 +491,15 @@ void Device::printUsage(std::string program) { if (!regex_match(showResult, showFilters)) printf(" %s\n", showResult.c_str()); } + if (regex_match(hw_version, iotRtrVersionFilters)) { + printf(" serial1/%s\n", SERIAL_TERMINATION.c_str()); + printf(" serial1/%s\n", SERIAL_MODE.c_str()); + printf("}\n"); + } printf("\n"); printf("store-name:\n"); printf("Usage:\n"); - printf("--store-name <name> <value>\n"); + printf("--store <name> <value>\n"); for (std::string showResult : showResults) { if (showResult == "radio-reset") { printf(" %s { 0 }\n", showResult.c_str()); @@ -512,14 +510,23 @@ void Device::printUsage(std::string program) { } 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()); } } + if (regex_match(hw_version, iotRtrVersionFilters)) { + printf(" serial1/%s { 0 | 1 }\n", SERIAL_TERMINATION.c_str()); + printf(" serial1/%s {", SERIAL_MODE.c_str()); + unsigned int c = 1; + for (auto const &m : mModes) { + printf(" %s ", m.first.c_str()); + if (c != mModes.size()) { + printf("|"); + } + c++; + }; + printf("}\n"); + } printf("\n"); exitHandler(0); } @@ -697,7 +704,8 @@ unsigned int Device::gpio_request::offset() * driver. GPIOs can only be zero * or one, never a text string. */ -void Device::show(std::string name) { + +int Device::getPinValue(const std::string &name) { std::string fileData; if(isupper(name[0])) { gpio_request gr(this, name); @@ -705,10 +713,9 @@ void Device::show(std::string name) { enum gpiod_line_value lv = gpiod_line_request_get_value(gr.request(),gr.offset()); if(lv != GPIOD_LINE_VALUE_ERROR) { if(lv == GPIOD_LINE_VALUE_INACTIVE) - std::cout << "0\n"; + return 0; else - std::cout << "1\n"; - exitHandler(0); + return 1; } else simpleError("Invalid GPIO line value", errno, 109); } @@ -716,12 +723,23 @@ void Device::show(std::string name) { int32_t code = MTS::System::readFile(SYSFS_PLATFORM + name, fileData); if (code == 0) { - printf("%s", fileData.c_str()); - exitHandler(0); + if (fileData == "1") { + return 1; + }; + return 0; } printError("cat: can't open %s%s: %s", SYSFS_PLATFORM, name.c_str(),strerror(errno)); exitHandler(99); + return 99; // never be returned +} + +void Device::show(std::string name) { + if (regex_match(hw_version, iotRtrVersionFilters)) { + showSerialModesMTR3(name); + } + printf("%i", getPinValue(name)); + exitHandler(0); } // End of show void Device::showTrigger(std::string name) { @@ -745,7 +763,9 @@ void Device::store(std::string name, std::string value) { } printDebug("Setting %s to %s", name.c_str(), value.c_str()); - + if (regex_match(hw_version, iotRtrVersionFilters)) { + setSerialModesMTR3(name, value); + } if(isupper(name[0])) { enum gpiod_line_value lv = GPIOD_LINE_VALUE_ERROR; @@ -872,3 +892,80 @@ void Device::storeOutputStateToNonvolatile(const std::string& name, const std::s } writeJson(stateIo, STORED_DIGITAL_OUTPUTS_STATE_FILE); } + +void Device::setSerialModesMTR3(const std::string ¶meter, const std::string &value) { + std::vector<std::string> parts = MTS::Text::split(parameter, '/'); + if (parts.size() < 2) { + // it is not a serial things, return and compare to other options + // serial things look like `serial1/mode' + return; + } + const std::string &serialName = parts[0]; + const std::string &mode = parts[1]; + if (serialName != "serial1") { + printUsage(); + } + if ((mode != SERIAL_MODE) && (mode != SERIAL_TERMINATION)) { + printUsage(); + } + if (mode == SERIAL_MODE) { + if ((value != SERIAL_MODE_RS232) && (value != SERIAL_MODE_RS485)) { + printUsage(); + } + if (value == SERIAL_MODE_RS232) { + store(CONTROL_PIN_SERIAL_MODE, "0"); + } + if (value == SERIAL_MODE_RS485) { + store(CONTROL_PIN_SERIAL_MODE, "1"); + } + } else if (mode == SERIAL_TERMINATION) { + store(CONTROL_PIN_TERMINATION, value); + } else { + printError("Unknown mode: %s", mode.c_str()); + exitHandler(98); + } + exitHandler(0); +} + +void Device::showSerialModesMTR3(const std::string ¶meter) { + std::vector<std::string> parts = MTS::Text::split(parameter, '/'); + if (parts.size() < 2) { + // it is not a serial things, return and compare to other options + // serial things look like `serial1/mode' + return; + } + const std::string &serialName = parts[0]; + const std::string &mode = parts[1]; + if (serialName != "serial1") { + printUsage(); + } + if ((mode != SERIAL_MODE) && (mode != SERIAL_TERMINATION)) { + printUsage(); + } + if (mode == SERIAL_MODE) { + if (getPinValue(CONTROL_PIN_SERIAL_MODE) == 1) { + std::cout << SERIAL_MODE_RS485 << std::endl; + } else { + std::cout << SERIAL_MODE_RS232 << std::endl; + } + } else if (mode == SERIAL_TERMINATION) { + std::cout << getPinValue(CONTROL_PIN_TERMINATION) << std::endl; + } else { + printError("Unknown mode: %s", mode.c_str()); + exitHandler(98); + } + exitHandler(0); +} + +void Device::setProgramName(const std::string &name){ + program_name = name; +} + +void Device::setHWVersion(){ + std::ifstream is(HW_VERSION_PATH); + if (!is.is_open()) { + printDebug("Can't read to %s: %s", HW_VERSION_PATH, strerror(errno)); + return; + } + std::getline(is, hw_version); +}
\ No newline at end of file |