summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHarsh Sharma <harsh.sharma@multitech.com>2022-03-03 14:44:44 -0600
committerJohn Klug <john.klug@multitech.com>2022-03-03 15:00:26 -0600
commitb1eaaeca6fdcb38d9a247e2deabe1da788a1e1f0 (patch)
treec7183f8ff02d3090989530740d36164db3630620
parent964e90992d6ac73cf287722a3dc136dda86c3ac2 (diff)
downloadmts-io-sysfs-b1eaaeca6fdcb38d9a247e2deabe1da788a1e1f0.tar.gz
mts-io-sysfs-b1eaaeca6fdcb38d9a247e2deabe1da788a1e1f0.tar.bz2
mts-io-sysfs-b1eaaeca6fdcb38d9a247e2deabe1da788a1e1f0.zip
LoRa updates with MTAC-0030.2.0
-rw-r--r--.gitignore2
-rw-r--r--Makefile15
-rw-r--r--include/Device/Device.h254
-rw-r--r--include/Fpga/Fpga.h74
-rw-r--r--include/General.h87
-rw-r--r--include/Utility/Utility.h43
-rw-r--r--src/AccessoryCards/AccessoryCard.cpp26
-rw-r--r--src/AccessoryCards/AcessoryCard.cpp21
-rw-r--r--src/AccessoryCards/Gpiob.cpp36
-rw-r--r--src/AccessoryCards/LoraCard.cpp38
-rw-r--r--src/AccessoryCards/LoraCard03.cpp53
-rw-r--r--src/AccessoryCards/LoraCard10.cpp38
-rw-r--r--src/AccessoryCards/LoraCard15.cpp195
-rw-r--r--src/AccessoryCards/LoraCard21.cpp48
-rw-r--r--src/AccessoryCards/LoraCard21Ext.cpp42
-rw-r--r--src/AccessoryCards/LoraCard2G4.cpp32
-rw-r--r--src/AccessoryCards/Mfser.cpp47
-rw-r--r--src/AccessoryCards/Mtac15Fpga.cpp803
-rw-r--r--src/Device/Device.cpp434
-rw-r--r--src/MtsIoSysfs.cpp261
-rw-r--r--src/Version.cpp4
21 files changed, 1893 insertions, 660 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..3c84646
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+build/
+src/Version.cpp
diff --git a/Makefile b/Makefile
index b0c1996..16aa846 100644
--- a/Makefile
+++ b/Makefile
@@ -33,11 +33,11 @@ SOURCEDIR=src
CFLAGS += -Werror -Wno-unused-function
-CXXFLAGS += -std=c++11 -Wno-unused-function
+CXXFLAGS += -std=c++14 -Wno-unused-function
-LIBS := -lmts -lrt
+LIBS := -lmts -lrt -lssl -lcrypto
-INC=-Iinclude -Iinclude/Utility -Iinclude/AccessoryCards -Iinclude/Device
+INC=-Iinclude -Iinclude/Utility -Iinclude/AccessoryCards -Iinclude/Device -Iinclude/Fpga
INCLUDES = $(wildcard include/*.h)
SOURCES = $(wildcard $(SOURCEDIR)/**/*.cpp)
SOURCES += $(SOURCEDIR)/Version.cpp
@@ -46,7 +46,7 @@ OBJS = $(patsubst $(SOURCEDIR)/%.c,$(BUILDDIR)/%.o,$(OBJS1))
CPP_DEPPS = $(patsubst $(SOURCEDIR)/%.cpp,$(BUILDDIR)/**/%.d,$(SOURCES))
CPP_DEPPS += $(BUILDDIR)/*.o $(BUILDDIR)/*.d $(BUILDDIR)/**/*.o $(BUILDDIR)/**/*.d
JS_OBJS = $(BUILDDIR)/Version.o
-OUT_DIRS=build/AccessoryCards build/Device
+OUT_DIRS=build/AccessoryCards build/Device build/Fpga
MKDIR_P = mkdir -p
ifndef MTS_CHECK
@@ -85,7 +85,7 @@ mts-io-sysfs: $(OBJS) $(BUILDDIR)/MtsIoSysfs.o
$(BUILDDIR)/%.o: $(SOURCEDIR)/%.cpp
@echo 'Building file: $<'
- $(CXX) $(CFLAGS) $(INC) -Wall -std=c++11 -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<"
+ $(CXX) $(CFLAGS) $(INC) -Wall -std=c++14 -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
@@ -103,13 +103,10 @@ $(SOURCEDIR)/Version.cpp:
$(BUILDDIR)/MtsIo.o: $(SOURCEDIR)/MtsIo.cpp
@echo 'Building file: $<'
- $(CXX) $(CFLAGS) $(INC) -Wall -std=c++11 -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<" -DENABLE_MTS_CHECK=${MTS_CHECK}
+ $(CXX) $(CFLAGS) $(INC) -Wall -std=c++14 -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<" -DENABLE_MTS_CHECK=${MTS_CHECK}
@echo 'Finished building: $<'
@echo ' '
-install:
- mkdir -p $(DESTDIR)/opt/lora
-
strip:
$(STRIP) -S --strip-unneeded --remove-section=.note.gnu.gold-version --remove-section=.comment --remove-section=.note --remove-section=.note.gnu.build-id --remove-section=.note.ABI-tag $(BUILDDIR)/mts-io-sysfs
diff --git a/include/Device/Device.h b/include/Device/Device.h
index 198cc67..5f2bf12 100644
--- a/include/Device/Device.h
+++ b/include/Device/Device.h
@@ -1,113 +1,163 @@
#ifndef DEVICE_H_
#define DEVICE_H_
+#include "Fpga.h"
#include "General.h"
#include "Utility.h"
#include "Version.h"
+#include <math.h> /* ceil */
+
+class Mtac15Fpga;
class Device {
- private:
- bool verbose ;
- bool isRoot;
- rapidjson::Document capabilities;
- rapidjson::Document ethSwitch;
- rapidjson::Document deviceInfo;
- static const std::vector<std::string> apIdentifiers;
- rapidjson::Document accessoryCards;
- rapidjson::Value accessoryCard;
- rapidjson::Document::AllocatorType& alloc = deviceInfo.GetAllocator();
- rapidjson::Document::AllocatorType& accessoryCardsAlloc = accessoryCards.GetAllocator();
- static std::map<std::string, bool> capabilityList;
- static std::map<std::string, std::string> ethSwitchList;
- static std::map<std::string, std::string> deviceInfoList;
-
- static const std::regex apFilters;
- static const std::regex lora15Filters;
- static const std::regex loraG16Filters;
- static const std::regex loraG64Filters;
- static const std::regex gpiobFilters;
- static const std::regex mfserFilters;
- static const std::regex serialModeFilter;
- static const std::regex storeFilters;
- static const std::regex showFilters;
-
- class AccessoryCard {
- protected:
- Device& device;
- const std::string productId;
- const std::string port;
- public:
- AccessoryCard(Device& d, const std::string ProductId, const std::string Port);
- };
-
- class LoraCard : public AccessoryCard {
- protected:
- std::string spiPath;
- uint8_t fpgaVersion = 255;
- public:
- LoraCard(Device& d, const std::string ProductId, const std::string Port);
- void setCapabilities();
- };
-
- class Lora15Card : public LoraCard {
- private:
- void *spi_target_ptr = NULL;
- public:
- Lora15Card(Device& d, const std::string ProductId, const std::string Port);
- int spiOpen(const char *spidev);
- int spiRead(uint8_t address, uint8_t *data);
- int spiClose();
- };
-
- class Lora21Card : public LoraCard {
- private:
- std::string cmdFpgaVersion;
- public:
- Lora21Card(Device& d, const std::string ProductId, const std::string Port);
- };
-
- class Lora21ExtCard : public Lora21Card {
- private:
- std::string cmdFpgaVersion2;
- public:
- Lora21ExtCard(Device& d, const std::string ProductId, const std::string Port);
- };
-
- class Gpiob : public AccessoryCard {
- public:
- Gpiob(Device& d, const std::string ProductId, const std::string Port);
- };
-
- class Mfser : public AccessoryCard {
- public:
- Mfser(Device& d, const std::string ProductId, const std::string Port);
- };
-
- public:
- Device();
- void getSystemTreeJson(const char * dir_name);
- void init();
- bool isAccessoryCard(const char * d_name, const char * dir_name);
- bool isValidDirectory(const struct dirent * entry, std::string fullPath, const char * d_name);
- void load();
- void logInfo(std::string info);
- void logError(std::string info);
- void json();
- void mapFileToCapability();
- void mapFirmware();
- void mapMacAddress2();
- void printDir(const std::string dir_name, std::vector<std::string> &results);
- void printJson();
- void printVersion (std::string name);
- void printUsage(std::string program);
- void show(std::string program);
- void showTrigger(std::string name);
- void sortAccessoryCards();
- void store(std::string name, std::string value);
- void storeTrigger(std::string name, std::string value);
- void Verbose(bool val);
- bool Verbose();
- void writeJson();
+ private:
+ bool isRoot;
+ rapidjson::Document capabilities;
+ rapidjson::Document ethSwitch;
+ rapidjson::Document deviceInfo;
+ static const std::vector<std::string> apIdentifiers;
+ rapidjson::Document accessoryCards;
+ rapidjson::Value accessoryCard;
+ rapidjson::Document::AllocatorType &alloc = deviceInfo.GetAllocator();
+ rapidjson::Document::AllocatorType &acAlloc = accessoryCards.GetAllocator();
+ static std::map<std::string, bool> capabilityList;
+ static std::map<std::string, std::string> ethSwitchList;
+ static std::map<std::string, std::string> deviceInfoList;
+
+ static const std::regex apFilters;
+ static const std::regex serialModeFilter;
+ static const std::regex storeFilters;
+ static const std::regex showFilters;
+ static const std::regex mtcdt3Filters;
+ static const std::regex mtrFilters;
+
+ const unsigned int accessoryCardsListSize = 7;
+
+ class AccessoryCard {
+ protected:
+ Device &device;
+ std::regex name;
+
+ public:
+ AccessoryCard(Device &d, const std::regex Name);
+ virtual void AddToDeviceInfo(const std::string Port,
+ const std::string ProductID);
+ const std::regex GetName();
+ };
+
+ class LoraCard : public AccessoryCard {
+ protected:
+ std::string spiPath;
+ uint8_t fpgaVersion;
+
+ public:
+ LoraCard(Device &d, const std::regex Name);
+ void AddToDeviceInfo(const std::string Port,
+ const std::string ProductID);
+ };
+
+ class Lora03Card : public LoraCard {
+ private:
+ std::string spiPath1261;
+ uint8_t tmp102;
+
+ public:
+ Lora03Card(Device &d);
+ void AddToDeviceInfo(const std::string Port,
+ const std::string ProductID);
+ };
+
+ class Lora10Card : public LoraCard {
+ public:
+ Lora10Card(Device &d);
+ void AddToDeviceInfo(const std::string Port,
+ const std::string ProductID);
+ };
+
+ class Lora15Card : public LoraCard {
+ private:
+ Lora15Card();
+ void *spi_target_ptr = NULL;
+ const char pin_high = '1';
+ const char pin_low = '0';
+
+ public:
+ Lora15Card(Device &d);
+ void AddToDeviceInfo(const std::string Port,
+ const std::string ProductID);
+ };
+
+ class Lora21Card : public LoraCard {
+ private:
+ std::string cmdFpgaVersion;
+
+ public:
+ Lora21Card(Device &d);
+ Lora21Card(Device &d, const std::regex Name);
+ void AddToDeviceInfo(const std::string Port,
+ const std::string ProductID);
+ };
+
+ class Lora21ExtCard : public Lora21Card {
+ private:
+ std::string cmdFpgaVersion2;
+
+ public:
+ Lora21ExtCard(Device &d);
+ void AddToDeviceInfo(const std::string Port,
+ const std::string ProductID);
+ };
+
+ class Lora2G4Card : public LoraCard {
+ public:
+ Lora2G4Card(Device &d);
+ void AddToDeviceInfo(const std::string Port,
+ const std::string ProductID);
+ };
+
+ class Gpiob : public AccessoryCard {
+ public:
+ Gpiob(Device &d);
+ void AddToDeviceInfo(const std::string Port,
+ const std::string ProductID);
+ };
+
+ class Mfser : public AccessoryCard {
+ public:
+ Mfser(Device &d);
+ void AddToDeviceInfo(const std::string Port,
+ const std::string ProductID);
+ };
+
+ std::vector<std::unique_ptr<AccessoryCard>> accessoryCardsList;
+
+ public:
+ Device();
+ void getSystemTreeJson(const char *dir_name);
+ void init();
+ bool isAccessoryCard(const char *d_name, const char *dir_name);
+ bool isValidDirectory(const struct dirent *entry, std::string fullPath,
+ const char *d_name);
+ void load();
+ void logInfo(std::string info);
+ void logError(std::string info);
+ void json();
+ void mapFileToCapability();
+ void mapFirmware();
+ void mapMacAddress2();
+ void printDir(const std::string dir_name,
+ std::vector<std::string> &results);
+ void printJson();
+ void printVersion(std::string name);
+ void printUsage(std::string program);
+ void show(std::string program);
+ void showTrigger(std::string name);
+ void sortAccessoryCards();
+ void store(std::string name, std::string value);
+ void storeTrigger(std::string name, std::string value);
+ void Verbose(bool val);
+ bool Verbose();
+ void writeJson();
};
#endif /* DEVICE_H_ */
diff --git a/include/Fpga/Fpga.h b/include/Fpga/Fpga.h
new file mode 100644
index 0000000..986a269
--- /dev/null
+++ b/include/Fpga/Fpga.h
@@ -0,0 +1,74 @@
+#ifndef FPGA_H_
+#define FPGA_H_
+
+#include "General.h"
+#include "Utility.h"
+#include "Version.h"
+#include <math.h> /* ceil */
+#include <openssl/sha.h> /* generate hash */
+
+#define MTAC_SX1301 0x0
+#define MTAC_FPGA 0x1
+
+#define MTAC_FPGA_ADDRESS 0x1
+#define READ_ACCESS 0x00
+#define WRITE_ACCESS 0x80
+#define SPI_SPEED 8000000
+
+#define MTAC_PAGE_REG 0
+#define MTAC_SOFT_RESET 1
+#define MTAC_VERSION 2
+
+#define MTCDT_DEFAULT_FILE "/usr/lib/mts-flash-binaries/mtcdt-fpga-v31.hex"
+#define MTCAP_DEFAULT_FILE "/usr/lib/mts-flash-binaries/mtcap-fpga-v31.hex"
+
+struct mtac_reg_s {
+ int8_t page; /*!< page containing the register (-1 for all pages) */
+ uint8_t addr; /*!< base address of the register (7 bit) */
+ uint8_t offs; /*!< position of the register LSB (between 0 to 7) */
+ bool sign; /*!< 1 indicates the register is signed (2 complem.) */
+ uint8_t leng; /*!< number of bits in the register */
+ bool rdon; /*!< 1 indicates a read-only register */
+ int32_t dflt; /*!< register default value */
+};
+
+class Mtac15Fpga {
+ private:
+ HardwareType hardwareType = HARDWARE_INVALID;
+ void *spi_target_ptr = NULL;
+ const char pin_high = '1';
+ const char pin_low = '0';
+ std::string port;
+ std::string spiPath;
+ std::string input_file;
+ uint8_t fpgaVersion;
+ rapidjson::Document deviceInfo;
+ rapidjson::Document::AllocatorType &alloc = deviceInfo.GetAllocator();
+
+ void sha256_hash_string(unsigned char hash[SHA256_DIGEST_LENGTH],
+ char outputBuffer[65]);
+ void sha256(char *string, char outputBuffer[65]);
+ int sha256_file(const char *path);
+ int spiOpen();
+ int spiRead(uint8_t spi_mux_target, uint8_t address, uint8_t *data);
+ int spiWrite(uint8_t spi_mux_target, uint8_t address, uint8_t data);
+ int spiClose();
+ int busContention();
+ int cresetWrite(char num);
+ int releaseDevice();
+ int writeEnable();
+ int chipEraseVerify();
+ int chipErase();
+ int mtacErase();
+ int pageProgram(uint8_t adr_lower, uint8_t adr_higher, uint32_t data[256]);
+ int mtacProgram(const char input_file[]);
+
+ public:
+ Mtac15Fpga(std::string inputFile, std::string forcedPath);
+ Mtac15Fpga(std::string path);
+ int getFpgaVersion();
+ int FpgaVersion();
+ int upgradeFpga();
+};
+
+#endif /* FPGA_H_ */
diff --git a/include/General.h b/include/General.h
index c5be2ff..e45f06a 100644
--- a/include/General.h
+++ b/include/General.h
@@ -2,7 +2,7 @@
#define GENERAL_HPP
#ifdef _MSC_VER
-#pragma warning ( disable : 4514 4512 4710 4355)
+#pragma warning(disable : 4514 4512 4710 4355)
#endif
typedef signed char sint8;
@@ -13,71 +13,68 @@ typedef signed int sint32;
typedef unsigned int uint32;
typedef signed long long sint64;
typedef unsigned long long uint64;
-typedef signed int sint; //32 bit - even on 64 bit machines
-typedef unsigned int uint; //32 bit - even on 64 bit machines
+typedef signed int sint; // 32 bit - even on 64 bit machines
+typedef unsigned int uint; // 32 bit - even on 64 bit machines
-#define memzero(ptr) memset(ptr,0,sizeof(*(ptr)))
-#define ArrayZero(ptr,elements) memset(ptr,0,sizeof(*(ptr)) * (elements))
+#define memzero(ptr) memset(ptr, 0, sizeof(*(ptr)))
+#define ArrayZero(ptr, elements) memset(ptr, 0, sizeof(*(ptr)) * (elements))
+#include <mts/MTS_Logger.h>
#include <mts/MTS_System.h>
#include <mts/MTS_Text.h>
+#include <dirent.h>
+#include <fcntl.h> /* open */
#include <fstream>
#include <iostream>
-#include <stdlib.h>
-#include <stdio.h> /* printf fprintf */
-#include <fcntl.h> /* open */
#include <linux/spi/spidev.h>
-#include <sys/ioctl.h>
-#include <unistd.h> /* lseek, close */
-#include <dirent.h>
#include <regex>
+#include <stdio.h> /* printf fprintf */
+#include <stdlib.h>
+#include <sys/ioctl.h>
#include <sys/stat.h>
-
+#include <unistd.h> /* lseek, close */
+#include <getopt.h> /* command line parser */
#include "rapidjson/document.h"
-#include "rapidjson/writer.h"
-#include "rapidjson/stringbuffer.h"
+#include "rapidjson/filereadstream.h"
#include "rapidjson/istreamwrapper.h"
+#include "rapidjson/stringbuffer.h"
+#include "rapidjson/writer.h"
-#define MAX_ACC_CARDS 4
-
-#define VERBOSE false
-#define MTS_IO_CONTROLS_STATUS_LED false
-#define MTS_IO_CONTROLS_LS_LED false
-
-#define FIRMWARE_VERSION "Version"
-#define FIRMWARE_DATE "Date"
-
-#define SYSFS_PLATFORM "/sys/devices/platform/mts-io/"
-#define HW_VERSION_PATH "/sys/devices/platform/mts-io/hw-version"
-#define LEDS_GPIO_DIR "/sys/devices/platform/leds-gpio/leds/"
-#define FIRMWARE_FILE "/etc/issue"
-
-#define LORA_1_5_AP1_FPGA_VERSION "mts-fpga-loader -p 1 -c | grep version | awk '{printf $4}'"
-#define LORA_1_5_AP2_FPGA_VERSION "mts-fpga-loader -p 2 -c | grep version | awk '{printf $4}'"
-#define LORA_2_1_FPGA_VERSION "mts-fpga-loader -g | grep version | awk '{printf $4}'"
-#define LORA_2_1_EXT_FPGA_VERSION "mts-fpga-loader -b 1 -g | grep version | awk '{printf $4}'"
+#define MAX_ACC_CARDS 4
+#define VERBOSE false
+#define MTS_IO_CONTROLS_STATUS_LED false
+#define MTS_IO_CONTROLS_LS_LED false
-#define MTAC_SX1301 0x0
-#define MTAC_FPGA 0x1
+#define FIRMWARE_VERSION "Version"
+#define FIRMWARE_DATE "Date"
+#define FIRMWARE_RELEASE "Release"
-#define MTAC_FPGA_ADDRESS 0x1
+#define SYSFS_PLATFORM "/sys/devices/platform/mts-io/"
+#define HW_VERSION_PATH "/sys/devices/platform/mts-io/hw-version"
+#define LEDS_GPIO_DIR "/sys/devices/platform/leds-gpio/leds/"
+#define FIRMWARE_FILE "/etc/issue"
+#define CRESET "/creset"
-#define READ_ACCESS 0x00
-#define SPI_SPEED 8000000
+#define LORA_2_1_FPGA_VERSION \
+ "mts-fpga-loader -g | grep version | awk '{printf $4}'"
+#define LORA_2_1_EXT_FPGA_VERSION \
+ "mts-fpga-loader -b 1 -g | grep version | awk '{printf $4}'"
-#define DEVICE_INFO_FILE "/var/run/config/device_info.json"
-#define RESET_SHORT_CMD "reset_short_handler"
-#define RESET_LONG_CMD "reset_long_handler"
-#define KILL_SIGNAL "kill -l "
+#define DEVICE_INFO_FILE "/var/run/config/device_info.json"
+#define RESET_SHORT_CMD "reset_short_handler"
+#define RESET_LONG_CMD "reset_long_handler"
+#define KILL_SIGNAL "kill -l "
+enum HardwareType {
+ HARDWARE_MTCDT,
+ HARDWARE_MTCDT3,
+ HARDWARE_MTCAP,
+ HARDWARE_INVALID
+};
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
-
#endif
-
-
-
diff --git a/include/Utility/Utility.h b/include/Utility/Utility.h
index 8d68baa..caf5661 100644
--- a/include/Utility/Utility.h
+++ b/include/Utility/Utility.h
@@ -6,34 +6,35 @@
#include <glob.h>
/**********************************************************************
-* 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.
+ *
+ ***********************************************************************/
inline bool fileExists(std::string file) {
struct stat buffer = {};
- return (stat (file.c_str(), &buffer) == 0) ? true : false;
+ return (stat(file.c_str(), &buffer) == 0) ? true : false;
}
-inline std::string toCamelCase(const char * d_name) {
+inline std::string 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] == '_'){
+ 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);
+ transform(tempString.begin(), tempString.end(), tempString.begin(),
+ toupper);
camelString.erase(x, 2);
camelString.insert(x, tempString);
}
@@ -50,7 +51,7 @@ inline void exitHandler(int code) {
inline mode_t fileType(std::string file) {
struct stat buf = {};
- if (stat (file.c_str(), &buf) == 0) {
+ if (stat(file.c_str(), &buf) == 0) {
return buf.st_mode & S_IFMT;
} else {
return -1;
diff --git a/src/AccessoryCards/AccessoryCard.cpp b/src/AccessoryCards/AccessoryCard.cpp
new file mode 100644
index 0000000..0c7c2a0
--- /dev/null
+++ b/src/AccessoryCards/AccessoryCard.cpp
@@ -0,0 +1,26 @@
+/**********************************************************************
+ * 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"
+
+Device::AccessoryCard::AccessoryCard(Device &d, const std::regex Name)
+ : device(d), name(Name) {}
+
+void Device::AccessoryCard::AddToDeviceInfo(const std::string Port,
+ const std::string ProductID) {}
+
+const std::regex Device::AccessoryCard::GetName() { return name; } \ No newline at end of file
diff --git a/src/AccessoryCards/AcessoryCard.cpp b/src/AccessoryCards/AcessoryCard.cpp
deleted file mode 100644
index 6a7a0d8..0000000
--- a/src/AccessoryCards/AcessoryCard.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-/**********************************************************************
-* 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"
-
-Device::AccessoryCard::AccessoryCard(Device& d, const std::string ProductId, const std::string Port) : device(d), productId(ProductId), port(Port) {
-}
diff --git a/src/AccessoryCards/Gpiob.cpp b/src/AccessoryCards/Gpiob.cpp
index 44728ae..c580aeb 100644
--- a/src/AccessoryCards/Gpiob.cpp
+++ b/src/AccessoryCards/Gpiob.cpp
@@ -1,23 +1,27 @@
/**********************************************************************
-* 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"
-Device::Gpiob::Gpiob(Device& d, const std::string ProductId, const std::string Port) : AccessoryCard(d, ProductId, Port) {
+Device::Gpiob::Gpiob(Device &d)
+ : AccessoryCard(d, std::regex("(MTAC-GPIOB)|(MMTAC-GPIOI)")) {}
+
+void Device::Gpiob::AddToDeviceInfo(const std::string Port,
+ const std::string ProductID) {
capabilityList["adc"] = true;
capabilityList["din"] = true;
capabilityList["dout"] = true;
diff --git a/src/AccessoryCards/LoraCard.cpp b/src/AccessoryCards/LoraCard.cpp
index 7a248dc..fe2a8d2 100644
--- a/src/AccessoryCards/LoraCard.cpp
+++ b/src/AccessoryCards/LoraCard.cpp
@@ -1,26 +1,26 @@
/**********************************************************************
-* 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"
-Device::LoraCard::LoraCard(Device& d, const std::string ProductId, const std::string Port) : AccessoryCard(d, ProductId, Port), spiPath("/dev/spidev0.0") {}
+Device::LoraCard::LoraCard(Device &d, const std::regex Name)
+ : AccessoryCard(d, Name), spiPath("/dev/spidev0.0"), fpgaVersion(255) {}
-void Device::LoraCard::setCapabilities() {
+void Device::LoraCard::AddToDeviceInfo(const std::string Port,
+ const std::string ProductID) {
device.capabilityList["lora"] = true;
- device.accessoryCard.AddMember("fpgaVersion", fpgaVersion, device.accessoryCardsAlloc);
- device.accessoryCard.AddMember("spiPath", rapidjson::Value().SetString(spiPath.c_str(), device.accessoryCardsAlloc), device.accessoryCardsAlloc);
} \ No newline at end of file
diff --git a/src/AccessoryCards/LoraCard03.cpp b/src/AccessoryCards/LoraCard03.cpp
new file mode 100644
index 0000000..7e9f9ae
--- /dev/null
+++ b/src/AccessoryCards/LoraCard03.cpp
@@ -0,0 +1,53 @@
+/**********************************************************************
+ * 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"
+
+Device::Lora03Card::Lora03Card(Device &d)
+ : LoraCard(d, std::regex("(MTAC-003)(.*)|(MTCAP3-003)(.*)")) {}
+
+void Device::Lora03Card::AddToDeviceInfo(const std::string Port,
+ const std::string ProductID) {
+
+ LoraCard::AddToDeviceInfo(Port, ProductID);
+ /* Map the spi path to the port/hw version */
+ std::string deviceHwVersion = "";
+ MTS::System::readFile(HW_VERSION_PATH, deviceHwVersion);
+ if (deviceHwVersion.find("MTCAP3") != std::string::npos) {
+ spiPath = "/dev/spidev1.0";
+ spiPath1261 = "/dev/spidev1.1";
+ tmp102 = 0x48;
+ } else if (Port.back() == '2') {
+ spiPath = "/dev/spidev1.0";
+ spiPath1261 = "/dev/spidev1.1";
+ tmp102 = 0x49;
+ } else {
+ spiPath = "/dev/spidev0.0";
+ spiPath1261 = "/dev/spidev0.1";
+ tmp102 = 0x48;
+ }
+
+ device.accessoryCard.AddMember(
+ "spiPath",
+ rapidjson::Value().SetString(spiPath.c_str(), device.acAlloc),
+ device.acAlloc);
+ device.accessoryCard.AddMember(
+ "spiPath1261",
+ rapidjson::Value().SetString(spiPath1261.c_str(), device.acAlloc),
+ device.acAlloc);
+ device.accessoryCard.AddMember("tmp102", tmp102, device.acAlloc);
+} \ No newline at end of file
diff --git a/src/AccessoryCards/LoraCard10.cpp b/src/AccessoryCards/LoraCard10.cpp
new file mode 100644
index 0000000..e74b848
--- /dev/null
+++ b/src/AccessoryCards/LoraCard10.cpp
@@ -0,0 +1,38 @@
+/**********************************************************************
+ * 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"
+
+Device::Lora10Card::Lora10Card(Device &d)
+ : LoraCard(d, std::regex("(MTAC-LORA-915)|(MTAC-LORA-868)")) {}
+
+void Device::Lora10Card::AddToDeviceInfo(const std::string Port,
+ const std::string ProductID) {
+
+ LoraCard::AddToDeviceInfo(Port, ProductID);
+
+ if (Port.back() == '2') {
+ spiPath = "/dev/spidev1.2";
+ } else {
+ spiPath = "/dev/spidev0.2";
+ }
+
+ device.accessoryCard.AddMember(
+ "spiPath",
+ rapidjson::Value().SetString(spiPath.c_str(), device.acAlloc),
+ device.acAlloc);
+} \ No newline at end of file
diff --git a/src/AccessoryCards/LoraCard15.cpp b/src/AccessoryCards/LoraCard15.cpp
index a7a1dad..3ed0f31 100644
--- a/src/AccessoryCards/LoraCard15.cpp
+++ b/src/AccessoryCards/LoraCard15.cpp
@@ -1,172 +1,45 @@
/**********************************************************************
-* 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"
-Device::Lora15Card::Lora15Card(Device& d, const std::string ProductId, const std::string Port) : LoraCard(d, ProductId, Port) {
- int ret;
- std::string deviceHwVersion = "";
- /* Map the spi path to the device hw version/mtac product id, with the default being spidev0.0 */
- MTS::System::readFile(HW_VERSION_PATH, deviceHwVersion);
- if (deviceHwVersion.find("MTCDT3-") != std::string::npos) {
- if (port.back() == '2') {
- spiPath = "/dev/spidev1.2";
- } else {
- spiPath = "/dev/spidev0.2";
- }
- } else if (productId.find("MTAC-LORA-") == 0) {
- if (port.back() == '2') {
- spiPath = "/dev/spidev32765.2";
- } else {
- spiPath = "/dev/spidev32766.2";
- }
- }
- ret = spiOpen(spiPath.c_str());
- if (ret != 0) {
- printf("Could not open SPI port %s", spiPath.c_str());
- return;
- }
- /* detect if the gateway has an FPGA with SPI mux header support */
- ret = spiRead(MTAC_FPGA_ADDRESS, &fpgaVersion);
- if (ret != 0) {
- printf("Could not read FPGA version");
- fpgaVersion = 255;
- }
-
- spiClose();
- spi_target_ptr = NULL;
- setCapabilities();
-}
-
-int Device::Lora15Card::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;
- }
+Device::Lora15Card::Lora15Card(Device &d)
+ : LoraCard(d, std::regex("(MTAC-LORA-H)(.*)|(MTAC-LORA-F)(.*)|(MTCAP-LORA-)"
+ "(.*)|(MTLGA-)(.*)|(MTCDT3-)(.*)")) {}
- /* 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;
- }
+void Device::Lora15Card::AddToDeviceInfo(const std::string Port,
+ const std::string ProductID) {
- /* 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;
- }
+ LoraCard::AddToDeviceInfo(Port, ProductID);
- /* 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 Device::Lora15Card::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;
+ if (ProductID.rfind("MTCAP", 0) == 0) {
+ spiPath = "/dev/spidev0.0";
+ } else if (Port.back() == '2') {
+ spiPath = "/dev/spidev1.2";
} else {
- *data = in_buf[command_size - 1];
- return 0;
+ spiPath = "/dev/spidev0.2";
}
-}
-
-int Device::Lora15Card::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;
- }
+ Mtac15Fpga mtac15Fpga(spiPath);
+ mtac15Fpga.getFpgaVersion();
+ fpgaVersion = mtac15Fpga.FpgaVersion();
+ device.accessoryCard.AddMember(
+ "spiPath",
+ rapidjson::Value().SetString(spiPath.c_str(), device.acAlloc),
+ device.acAlloc);
+ device.accessoryCard.AddMember("fpgaVersion", fpgaVersion, device.acAlloc);
} \ No newline at end of file
diff --git a/src/AccessoryCards/LoraCard21.cpp b/src/AccessoryCards/LoraCard21.cpp
index d40876b..4337bfa 100644
--- a/src/AccessoryCards/LoraCard21.cpp
+++ b/src/AccessoryCards/LoraCard21.cpp
@@ -1,25 +1,39 @@
/**********************************************************************
-* 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"
-Device::Lora21Card::Lora21Card(Device& d, const std::string ProductId, const std::string Port): LoraCard(d, ProductId, Port) {
+Device::Lora21Card::Lora21Card(Device &d)
+ : LoraCard(d, std::regex("(MTAC-LORA-G16)(.*)")) {}
+Device::Lora21Card::Lora21Card(Device &d, const std::regex Name)
+ : LoraCard(d, Name) {}
+
+void Device::Lora21Card::AddToDeviceInfo(const std::string Port,
+ const std::string ProductID) {
+
+ LoraCard::AddToDeviceInfo(Port, ProductID);
+
spiPath = "/dev/spidev32766.2";
MTS::System::cmd(LORA_2_1_FPGA_VERSION, cmdFpgaVersion);
fpgaVersion = std::stoi(cmdFpgaVersion);
- setCapabilities();
+
+ device.accessoryCard.AddMember("fpgaVersion", fpgaVersion, device.acAlloc);
+ device.accessoryCard.AddMember(
+ "spiPath",
+ rapidjson::Value().SetString(spiPath.c_str(), device.acAlloc),
+ device.acAlloc);
} \ No newline at end of file
diff --git a/src/AccessoryCards/LoraCard21Ext.cpp b/src/AccessoryCards/LoraCard21Ext.cpp
index 2595286..b25dbfe 100644
--- a/src/AccessoryCards/LoraCard21Ext.cpp
+++ b/src/AccessoryCards/LoraCard21Ext.cpp
@@ -1,23 +1,31 @@
/**********************************************************************
-* 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"
-Device::Lora21ExtCard::Lora21ExtCard(Device& d, const std::string ProductId, const std::string Port): Lora21Card(d, ProductId, Port) {
+Device::Lora21ExtCard::Lora21ExtCard(Device &d)
+ : Lora21Card(d, std::regex("(MTAC-LORA-G64)(.*)")) {}
+
+void Device::Lora21ExtCard::AddToDeviceInfo(const std::string Port,
+ const std::string ProductID) {
+
+ LoraCard::AddToDeviceInfo(Port, ProductID);
+
MTS::System::cmd(LORA_2_1_EXT_FPGA_VERSION, cmdFpgaVersion2);
- device.accessoryCard.AddMember("fpgaVersion2", std::stoi(cmdFpgaVersion2), device.accessoryCardsAlloc);
+ device.accessoryCard.AddMember("fpgaVersion2", std::stoi(cmdFpgaVersion2),
+ device.acAlloc);
} \ No newline at end of file
diff --git a/src/AccessoryCards/LoraCard2G4.cpp b/src/AccessoryCards/LoraCard2G4.cpp
new file mode 100644
index 0000000..10691ce
--- /dev/null
+++ b/src/AccessoryCards/LoraCard2G4.cpp
@@ -0,0 +1,32 @@
+/**********************************************************************
+ * 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"
+
+Device::Lora2G4Card::Lora2G4Card(Device &d)
+ : LoraCard(d, std::regex("(MTAC-LORA-2G4)")) {}
+
+void Device::Lora2G4Card::AddToDeviceInfo(const std::string Port,
+ const std::string ProductID) {
+
+ LoraCard::AddToDeviceInfo(Port, ProductID);
+ std::string ttyPath = "/dev/ttyACM0";
+ device.accessoryCard.AddMember(
+ "ttyPath",
+ rapidjson::Value().SetString(ttyPath.c_str(), device.acAlloc),
+ device.acAlloc);
+} \ No newline at end of file
diff --git a/src/AccessoryCards/Mfser.cpp b/src/AccessoryCards/Mfser.cpp
index dfdfeb3..03a00b7 100644
--- a/src/AccessoryCards/Mfser.cpp
+++ b/src/AccessoryCards/Mfser.cpp
@@ -1,28 +1,37 @@
/**********************************************************************
-* 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"
-Device::Mfser::Mfser(Device& d, const std::string ProductId, const std::string Port) : AccessoryCard(d, ProductId, Port) {
- capabilityList["rs232"] = true;
+
+Device::Mfser::Mfser(Device &d)
+ : AccessoryCard(
+ d, std::regex("(MTAC-MFSER-DTE)|(MTAC-MFSER-DCE)|(MTR-)(.*)")) {}
+
+void Device::Mfser::AddToDeviceInfo(const std::string Port,
+ const std::string ProductID) {
+
+ capabilityList["rs232"] = true;
capabilityList["rs422"] = true;
capabilityList["rs485"] = true;
capabilityList["serial"] = true;
- if (!fileExists("/dev/ext_serial") && port.size() > 0) {
+ if (!fileExists("/dev/ext_serial") && Port.size() > 0) {
std::string temp;
- MTS::System::cmd(std::string("ln -s /dev/ttyAP") + port.back() + " /dev/ext_serial", temp);
+ MTS::System::cmd(std::string("ln -s /dev/ttyAP") + Port.back() +
+ " /dev/ext_serial",
+ temp);
}
} \ No newline at end of file
diff --git a/src/AccessoryCards/Mtac15Fpga.cpp b/src/AccessoryCards/Mtac15Fpga.cpp
new file mode 100644
index 0000000..151ff77
--- /dev/null
+++ b/src/AccessoryCards/Mtac15Fpga.cpp
@@ -0,0 +1,803 @@
+/**********************************************************************
+ * 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 "Fpga.h"
+
+/* -------------------------------------------------------------------------- */
+/* --- Flash opcodes ---------------------------------------------------------*/
+#define WR_STATUS_REG 0x01 /* Write Status Register */
+#define PAGE_PROGRAM 0x02 /* Write up to a Page of the Memory */
+#define READ_DATA 0x03 /* Read from the Memory */
+#define WRITE_DISABLE 0x04 /* Disable Writing to the Memory */
+#define RD_STATUS_REG_1 0x05 /* Read Status Register-1 */
+#define WRITE_ENABLE 0x06 /* Enable Writing to the Memory */
+#define FAST_READ_DATA 0x0B /* Fast Read from the Memory */
+#define SECTOR_ERASE 0x20 /* Erase a Sector (4kb) */ u
+#define RD_STATUS_REG_2 0x35 /* Read Status Register-2 */
+#define UNIQUE_ID 0x4B /* Read Unique ID */
+#define WE_STATUS_REG 0x50 /* Write Enable for Status Registers */
+#define BLOCK_ERASE_32 0x52 /* Erase a Block (32kb) */
+#define CHIP_ERASE 0x60 /* Erase Entire Chip */
+#define MNFTR_DEV_ID 0x90 /* Read Manufacturer ID followed by Device ID */
+#define JEDEC_ID 0x9F /* Read JEDEC ID */
+#define CHIP_RELEASE 0xAB /* Release chip from power down */
+#define BLOCK_ERASE_64 0xD8 /* Erase a Block (64kb) */
+
+static const uint8_t fpga_version[] = {28, 31, 33, 35, 37};
+static const struct mtac_reg_s loregs[3] = {
+ {-1, 0, 0, 0, 2, 0, 0}, /* PAGE_REG */
+ {-1, 0, 7, 0, 1, 0, 0}, /* SOFT_RESET */
+ {-1, 1, 0, 0, 8, 1, 103} /* VERSION */
+};
+
+/* -------------------------------------------------------------------------- */
+/* --- PRIVATE CONSTANTS ---------------------------------------------------- */
+
+static const char
+ *valid_hashes[3][4] =
+ {
+ {
+ "d9f811fcab57947db3c2323242885a32a7f095a069d3386a148466e7f3da53"
+ "53", /* mtcdt v28*/
+ "903c1199df46d38683b1aa9fc88310abe2f317c01c3aefa77987990874aba4"
+ "20", /* mtcdt v31*/
+ "7c190506b969aea6198daffb6c9b47685f3a4dc3ce18565c66542bac27d6f2"
+ "4e", /* mtcdt v33*/
+ "72bcdfda72bf8677d585330caa3d609615d08d4ca6d7951f0ebbcb5a93306b"
+ "3c" /* mtcdt v35*/
+ },
+ {
+ "54e41b186b2c91f1bcf249648c50357165d361101fc4fe20ee9b8f0c40dce2"
+ "5d" /* mtcdt3 v35*/
+ },
+ {
+ "07317fe9ca59393c074215c9d923d8d01025654883291a5e89b27d21668e22"
+ "63", /* mtcap v28*/
+ "f208ef5cae03e703951bb8799172a5eaadb74ddb90bf3e65c32030c008a88e"
+ "75", /* mtcap v31*/
+ "aaecd468b187703dbbf76022b00268dba2a5f25300da6486d420f476c83638"
+ "5c", /* mtcap v33*/
+ "876cc5683f612c09f96bacb27fff170358c90f3bd76a5c61ec41504eabba83"
+ "13" /* mtcap v35*/
+ },
+};
+
+/* -------------------------------------------------------------------------- */
+/* --- PRIVATE FUNCTIONS DEFINITION ------------------------------------------
+ */
+
+/* hash outputBuffer */
+void Mtac15Fpga::sha256_hash_string(unsigned char hash[SHA256_DIGEST_LENGTH],
+ char outputBuffer[65]) {
+ int i = 0;
+ for (i = 0; i < SHA256_DIGEST_LENGTH; i++) {
+ sprintf(outputBuffer + (i * 2), "%02x", (unsigned char)hash[i]);
+ }
+ outputBuffer[64] = 0;
+ printInfo("OutputBuffer hash: %s", outputBuffer);
+}
+
+/* Initialize, update and finalize sha256 */
+void Mtac15Fpga::sha256(char *string, char outputBuffer[65]) {
+ unsigned char hash[SHA256_DIGEST_LENGTH];
+ int len;
+ SHA256_CTX sha256;
+ SHA256_Init(&sha256);
+ len = strlen(string);
+ SHA256_Update(&sha256, string, len);
+ SHA256_Final(hash, &sha256);
+ int i = 0;
+ for (i = 0; i < SHA256_DIGEST_LENGTH; i++) {
+ sprintf(outputBuffer + (i * 2), "%02x", (unsigned char)hash[i]);
+ }
+ outputBuffer[64] = 0;
+ printInfo("OutputBuffer finalized: %s", outputBuffer);
+}
+
+/* Open input file and verify sha256 with verified list */
+int Mtac15Fpga::sha256_file(const char *path) {
+ printInfo("Checking hash on input file: %s", path);
+
+ FILE *file = fopen(path, "rb");
+ if (!file) {
+ printError("File %s not found", path);
+ return -1;
+ } else {
+ printInfo("Checking file %s", path);
+ }
+
+ unsigned int i;
+ char file_hash[65];
+ unsigned char hash[SHA256_DIGEST_LENGTH];
+ SHA256_CTX sha256;
+ SHA256_Init(&sha256);
+ const int bufSize = 32768;
+ unsigned char *buffer = (unsigned char *)malloc(bufSize);
+ int bytesRead = 0;
+
+ if (!buffer)
+ return ENOMEM;
+ while ((bytesRead = fread(buffer, 1, bufSize, file))) {
+ SHA256_Update(&sha256, buffer, bytesRead);
+ }
+ SHA256_Final(hash, &sha256);
+ sha256_hash_string(hash, file_hash);
+ fclose(file);
+ free(buffer);
+
+ printInfo("Calculated input file hash: %s", file_hash);
+ for (i = 0; i < sizeof(valid_hashes[hardwareType]) /
+ sizeof(valid_hashes[hardwareType][0]);
+ ++i) {
+ if (!strcmp(valid_hashes[hardwareType][i], file_hash)) {
+ printInfo("File verified");
+ return 0;
+ }
+ }
+ printError("Invalid input file");
+ return -1;
+}
+
+int Mtac15Fpga::spiOpen() {
+ 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) {
+ printError("Malloc failed");
+ return -1;
+ }
+
+ /* open SPI device */
+ dev = open(spiPath.c_str(), O_RDWR);
+ if (dev < 0) {
+ printError("Failed to open SPI device %s", spiPath.c_str());
+ 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)) {
+ printError("SPI port failed to set IOC MODE 0");
+ 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)) {
+ printError("SPI port failed to set MAX SPEED");
+ 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)) {
+ printError("SPI port failed to set MSB FIRST");
+ 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)) {
+ printError("SPI port failed to set 8 bits-per-word");
+ close(dev);
+ return -1;
+ }
+
+ *spi_device = dev;
+ spi_target_ptr = (void *)spi_device;
+ return 0;
+}
+
+int Mtac15Fpga::spiRead(uint8_t spi_mux_target, 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] = spi_mux_target;
+ 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) {
+ printError("SPI read failure");
+ return -1;
+ } else {
+ *data = in_buf[command_size - 1];
+ return 0;
+ }
+}
+
+/* Simple spi write to fpga*/
+int Mtac15Fpga::spiWrite(uint8_t spi_mux_target, uint8_t address,
+ uint8_t data) {
+ int spi_device;
+ uint8_t out_buf[3];
+ 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] = spi_mux_target;
+ out_buf[1] = WRITE_ACCESS | (address & 0x7F);
+ out_buf[2] = data;
+ command_size = 3;
+
+ /* I/O transaction */
+ memset(&k, 0, sizeof(k)); /* clear k */
+ k.tx_buf = (unsigned long)out_buf;
+ k.len = command_size;
+ k.speed_hz = SPI_SPEED;
+ k.cs_change = 1;
+ k.bits_per_word = 8;
+ a = ioctl(spi_device, SPI_IOC_MESSAGE(1), &k);
+
+ /* determine return code */
+ if (a != (int)k.len) {
+ printError("SPI write failure");
+ return -1;
+ } else {
+ printDebug("SPI write success");
+ return 0;
+ }
+}
+
+int Mtac15Fpga::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) {
+ printError("SPI port failed to close");
+ return -1;
+ } else {
+ return 0;
+ }
+}
+
+/* write to creset pin */
+int Mtac15Fpga::cresetWrite(char num) {
+ std::string cresetPath = SYSFS_PLATFORM + port + CRESET;
+ int fd = open(cresetPath.c_str(), O_WRONLY);
+ if (fd < 0) {
+ printError("Unable to lock file, are you root?");
+ return -1;
+ }
+ write(fd, &num, 1);
+ close(fd);
+ return 0;
+}
+
+/*
+ Release Power-down instruction releases the device from
+ said state allowing device communication
+*/
+int Mtac15Fpga::releaseDevice() {
+ int mtac_ret;
+ int spi_device;
+ struct spi_ioc_transfer k;
+ int ret;
+ size_t command_size = 5;
+ char out_buf[command_size];
+ char in_buf[command_size];
+
+ /* prepare frame to be sent */
+ out_buf[0] = CHIP_RELEASE;
+ out_buf[1] = 0;
+ out_buf[2] = 0;
+ out_buf[3] = 0;
+ out_buf[4] = 0;
+
+ /* I/O transaction */
+ mtac_ret = spiOpen();
+ spi_device =
+ *(int *)spi_target_ptr; /* spi_target cannot be null beforehand */
+ 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.speed_hz = SPI_SPEED;
+ k.cs_change = 1;
+ k.bits_per_word = 8;
+ ret = ioctl(spi_device, SPI_IOC_MESSAGE(1), &k);
+ mtac_ret = spiClose();
+
+ /* determine return code */
+ if (ret != (int)k.len) {
+ printError("Release failed");
+ mtac_ret = -1;
+ } else {
+ usleep(1000);
+ mtac_ret = 0;
+ }
+ return mtac_ret;
+}
+
+/*
+ Write enable instruction sets the write enable latch
+ in the status register to 1. It needs to be set before
+ a page can be programmed or chip erased
+*/
+int Mtac15Fpga::writeEnable() {
+ int mtac_ret;
+ int spi_device;
+ struct spi_ioc_transfer k;
+ int ret;
+ size_t command_size = 1;
+ char out_buf[command_size];
+ char in_buf[command_size];
+
+ /* prepare frame to be sent */
+ out_buf[0] = 0x06;
+
+ /* I/O transaction */
+ mtac_ret = spiOpen();
+ spi_device =
+ *(int *)spi_target_ptr; /* spi_target cannot be null beforehand */
+ 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.speed_hz = SPI_SPEED;
+ k.cs_change = 0;
+ k.bits_per_word = 8;
+ ret = ioctl(spi_device, SPI_IOC_MESSAGE(1), &k);
+ mtac_ret = spiClose();
+
+ /* determine return code */
+ if (ret != (int)k.len) {
+ printError("Write Enable failed");
+ mtac_ret = -1;
+ } else {
+ usleep(1000);
+ printDebug("Write Enable successful");
+ mtac_ret = 0;
+ }
+ return mtac_ret;
+}
+
+/*
+ Verify that the chip erase was successful
+*/
+int Mtac15Fpga::chipEraseVerify() {
+ int mtac_ret;
+ int spi_device;
+ struct spi_ioc_transfer k;
+ int a, ret;
+ uint16_t command_size = 256 + 5;
+ char out_buf[command_size];
+ char in_buf[command_size];
+
+ /* prepare frame to be sent */
+ out_buf[0] = 0x0B;
+ out_buf[1] = 0x00;
+ out_buf[2] = 0x00;
+ out_buf[3] = 0x00;
+ out_buf[4] = 0x00;
+
+ /* I/O transaction */
+ mtac_ret = spiOpen();
+ spi_device =
+ *(int *)spi_target_ptr; /* spi_target cannot be null beforehand */
+ 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.speed_hz = SPI_SPEED;
+ k.cs_change = 1;
+ k.bits_per_word = 8;
+ ret = ioctl(spi_device, SPI_IOC_MESSAGE(1), &k);
+
+ /* determine return code */
+ if (ret != (int)k.len) {
+ printError("Chip transfer failed");
+ mtac_ret = -1;
+ } else {
+ printDebug("Chip transfer successful");
+ mtac_ret = 0;
+ }
+ mtac_ret = spiClose();
+ /* verify that the chip was erased */
+ for (a = 5; a < command_size; a++) {
+ if (in_buf[a] != 0xFF) {
+ mtac_ret = spiClose();
+ return mtac_ret;
+ }
+ }
+ return mtac_ret;
+}
+
+/*
+ Chip erase instruction sets all memory within
+ the device to the erased state of all 1s (FFh)
+*/
+int Mtac15Fpga::chipErase() {
+ int mtac_ret;
+ int spi_device;
+ struct spi_ioc_transfer k;
+ int ret;
+ size_t command_size = 1;
+ char out_buf[command_size];
+ char in_buf[command_size];
+
+ /* prepare frame to be sent */
+ out_buf[0] = CHIP_ERASE;
+
+ /* I/O transaction */
+ mtac_ret = spiOpen();
+ spi_device =
+ *(int *)spi_target_ptr; /* spi_target cannot be null beforehand */
+ 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.speed_hz = SPI_SPEED;
+ k.cs_change = 0;
+ k.bits_per_word = 8;
+ ret = ioctl(spi_device, SPI_IOC_MESSAGE(1), &k);
+ sleep(5);
+ mtac_ret = spiClose();
+
+ /* determine return code */
+ if (ret != (int)k.len) {
+ printError("Chip Erase transfer failed");
+ mtac_ret = -1;
+ } else {
+ printDebug("Chip Erase transfer successful");
+ chipEraseVerify();
+ mtac_ret = 0;
+ }
+ return mtac_ret;
+}
+
+/* erase entire flash */
+int Mtac15Fpga::mtacErase() {
+ int ret;
+ printInfo("Erasing flash");
+ /* pull device out of powerdown state */
+ ret = releaseDevice();
+ if (ret != 0) {
+ return ret;
+ }
+
+ /* enable writing to flash */
+ ret = writeEnable();
+ if (ret != 0) {
+ return ret;
+ }
+
+ /* send chip erase command to flash */
+ ret = chipErase();
+ if (ret != 0) {
+ return ret;
+ }
+ /* pull device out of powerdown state */
+ ret = releaseDevice();
+ if (ret != 0) {
+ return ret;
+ }
+ return 0;
+}
+
+/*
+ Page Program instruction allows writing upto 256 bytes (a page) of
+ data to be programmed at previously erased memory locations Write
+ enable must be issued first
+*/
+int Mtac15Fpga::pageProgram(uint8_t adr_lower, uint8_t adr_higher,
+ uint32_t data[256]) {
+ int mtac_ret;
+ int spi_device;
+ struct spi_ioc_transfer k;
+ int a, h;
+ size_t command_size = 260;
+ char out_buf[command_size];
+ char in_buf[command_size];
+
+ /* prepare frame to be sent */
+ out_buf[0] = PAGE_PROGRAM;
+ out_buf[1] = adr_higher;
+ out_buf[2] = adr_lower;
+ out_buf[3] = 0x00;
+ for (h = 0; h < 256; h++) {
+ out_buf[h + 4] = data[h];
+ }
+
+ /* I/O transaction */
+ mtac_ret = spiOpen();
+ spi_device =
+ *(int *)spi_target_ptr; /* spi_target cannot be null beforehand */
+ 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.speed_hz = SPI_SPEED;
+ k.cs_change = 1;
+ k.bits_per_word = 8;
+ a = ioctl(spi_device, SPI_IOC_MESSAGE(1), &k);
+ printDebug("Writing Page %x%x to MTAC\r", adr_higher, adr_lower);
+ usleep(10000);
+
+ mtac_ret = spiClose();
+
+ /* determine return code */
+ if (a != (int)k.len) {
+ printError("SPI write failure");
+ mtac_ret = -1;
+ } else {
+ printDebug("SPI write success");
+ mtac_ret = 0;
+ }
+ return mtac_ret;
+}
+
+/* write to mtac card with input file */
+int Mtac15Fpga::mtacProgram(const char input_file[]) {
+ FILE *f;
+ struct stat st;
+ size_t file_size;
+ int ret = 0;
+ uint32_t i = 0, index, result, offset, page_address, no_pages,
+ page_data[256];
+ uint8_t adr_lower, adr_higher;
+
+ /* get data array from file to be writen */
+ f = fopen(input_file, "r");
+ stat(input_file, &st);
+ file_size = st.st_size;
+ uint8_t *p_array;
+ p_array = (uint8_t *)malloc(sizeof(uint8_t) * file_size);
+ unsigned int data[file_size];
+ while ((result = fscanf(f, "%x ", data + i)) == 1) {
+ i++;
+ }
+ fclose(f);
+ no_pages = ceil(i / 256.0);
+
+ /* program one page at a time */
+ for (page_address = 0x00; page_address < no_pages; page_address++) {
+ /* mask page address */
+ adr_higher = (page_address >> 8) & 0xff;
+ adr_lower = page_address & 0xff;
+ /* calculate initial data offset */
+ offset = page_address * 256;
+ /* enable writing to flash */
+ ret = writeEnable();
+ if (ret != 0) {
+ free(p_array);
+ break;
+ }
+ /* assign data for page to be written */
+ for (index = 0; index < 256; index++) {
+ page_data[index] = index + offset > i ? 0xff : data[index + offset];
+ }
+ /* program single page*/
+ ret = pageProgram(adr_lower, adr_higher, page_data);
+ if (ret != 0) {
+ free(p_array);
+ break;
+ }
+ /* release device from page program powerdown */
+ ret = releaseDevice();
+ if (ret != 0) {
+ free(p_array);
+ break;
+ }
+ }
+ free(p_array);
+ return ret;
+}
+
+/* Make sure no device is using the spidev bus to prevent contention*/
+int Mtac15Fpga::busContention() {
+ char number[1024];
+ FILE *f = popen("lsof", "r");
+ while (fgets(number, 1024, f) != NULL) {
+ if (strstr(number, "spidev") != NULL) {
+ printError("The accessory card is being used by another process: "
+ "\n %sPlease "
+ "close all LoRaWAN processes and try again",
+ number);
+ pclose(f);
+ return -1;
+ }
+ }
+ pclose(f);
+ return 0;
+}
+
+/* -------------------------------------------------------------------------- */
+/* --- PUBLIC FUNCTIONS DEFINITION ------------------------------------------ */
+
+/* Constructor used fpga upgrade utility */
+Mtac15Fpga::Mtac15Fpga(std::string inputFile, std::string forcedPath) {
+ FILE *fp = fopen(DEVICE_INFO_FILE, "r");
+ char buf[0XFFFF];
+ rapidjson::FileReadStream input(fp, buf, sizeof(buf));
+ deviceInfo.ParseStream(input);
+ fclose(fp);
+
+ if (!deviceInfo.HasMember("hardwareVersion")) {
+ printError("%s does not have hardware version info, exiting",
+ DEVICE_INFO_FILE);
+ return;
+ }
+ std::string hwVersion = deviceInfo["hardwareVersion"].GetString();
+
+ if (deviceInfo.HasMember("accessoryCards") &&
+ deviceInfo["accessoryCards"].IsArray() &&
+ deviceInfo["accessoryCards"].Size() > 0) {
+ if (hwVersion.find("MTCDT3") != std::string::npos) {
+ hardwareType = HARDWARE_MTCDT3;
+ } else if (hwVersion.find("MTCDT") != std::string::npos) {
+ hardwareType = HARDWARE_MTCDT;
+ } else {
+ return;
+ }
+ if (inputFile.empty()) {
+ input_file = MTCDT_DEFAULT_FILE;
+ } else {
+ input_file = inputFile;
+ }
+ port = deviceInfo["accessoryCards"][0]["port"].GetString();
+ if (port.back() == '2') {
+ spiPath = "/dev/spidev1.2";
+ } else {
+ spiPath = "/dev/spidev0.2";
+ }
+ getFpgaVersion();
+ printInfo("Current FPGA version: %d", fpgaVersion);
+ } else if (hwVersion.find("MTCAP") != std::string::npos) {
+ hardwareType = HARDWARE_MTCAP;
+ if (inputFile.empty()) {
+ input_file = MTCAP_DEFAULT_FILE;
+ } else {
+ input_file = inputFile;
+ }
+ spiPath = "/dev/spidev0.0";
+ getFpgaVersion();
+ printInfo("Current FPGA version: %d", fpgaVersion);
+ }
+}
+
+/* Constructor used by device_info.json generator */
+Mtac15Fpga::Mtac15Fpga(const std::string path) { spiPath = path; }
+
+int Mtac15Fpga::FpgaVersion() { return fpgaVersion; }
+
+/* Open spi device and get fpga version from register */
+int Mtac15Fpga::getFpgaVersion() {
+ int ret = spiOpen();
+ if (ret != 0) {
+ printError("Could not open SPI port %s", spiPath.c_str());
+ } else {
+ /* detect if the gateway has an FPGA with SPI mux header support */
+ ret = spiRead(MTAC_FPGA, loregs[MTAC_VERSION].addr, &fpgaVersion);
+ if (ret != 0) {
+ printError("Could not read FPGA version");
+ }
+ spiClose();
+ }
+ spi_target_ptr = NULL;
+ return ret;
+}
+
+/* setup and upgrade the mtac card with the file specified */
+int Mtac15Fpga::upgradeFpga() {
+ if (hardwareType == HARDWARE_INVALID) {
+ printError("Invalid hardware");
+ return -1;
+ }
+
+ int ret;
+
+ if (input_file.empty()) {
+ printError("Invalid input file %s", input_file.c_str());
+ return -1;
+ }
+ /* check that no other device is using the bus */
+ ret = busContention();
+ if (ret != 0) {
+ return ret;
+ }
+ /* check MTAC Hardware Compatibility */
+ printInfo("Checking hardware compatibility");
+
+ /* check input file checksum */
+ ret = sha256_file(input_file.c_str());
+ if (ret != 0) {
+ return ret;
+ }
+
+ /* pull creset down to access spi flash */
+ ret = cresetWrite('0');
+ if (ret != 0) {
+ return ret;
+ }
+ sleep(1);
+
+ /* erase chip before flashing new firmware */
+ ret = mtacErase();
+ if (ret != 0) {
+ return ret;
+ }
+
+ /* program user specified firmware */
+ printInfo("Programming flash");
+ ret = mtacProgram(input_file.c_str());
+ if (ret != 0) {
+ return ret;
+ } else {
+ printInfo("Write Complete. Resetting FPGA");
+ }
+
+ /* pull creset up to access FPGA */
+ ret = cresetWrite('1');
+ if (ret != 0) {
+ return ret;
+ }
+ sleep(5);
+ printInfo("Reading New FPGA configuration");
+ ret = getFpgaVersion();
+ if (ret != 0) {
+ return ret;
+ }
+ printInfo("New FPGA version: %d", fpgaVersion);
+ return 0;
+}
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 &ethSwitchAlloc = 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();
diff --git a/src/MtsIoSysfs.cpp b/src/MtsIoSysfs.cpp
index 390db47..c7e892a 100644
--- a/src/MtsIoSysfs.cpp
+++ b/src/MtsIoSysfs.cpp
@@ -1,75 +1,230 @@
/**********************************************************************
-* 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"
-int main(int argc, char const* const argv[]) {
+#define COMMMAND_EXTRA "--"
+#define COMMMAND_INIT "init"
+#define COMMMAND_JSON "json"
+#define COMMMAND_LOAD_FPGA "load-fpga"
+#define COMMMAND_SHOW "show"
+#define COMMMAND_SHOW_TRIGGER "show-trigger"
+#define COMMMAND_STORE "store"
+#define COMMMAND_STORE_TRIGGER "store-trigger"
+#define COMMMAND_VERSION "version"
+
+enum action_code {
+ ACTION_NONE,
+ ACTION_VERSION,
+ ACTION_INIT,
+ ACTION_JSON,
+ ACTION_LOAD_FPGA,
+ ACTION_SHOW,
+ ACTION_SHOW_TRIGGER,
+ ACTION_STORE,
+ ACTION_STORE_TRIGGER,
+};
+
+static enum action_code action;
+
+int main(int argc, char **argv) {
Device m;
+ action = ACTION_NONE;
if (argc < 2) {
m.printUsage(argv[0]);
}
+ std::string fpgaFilePath = "";
+ std::string forcedAP = "";
+ std::string name = "";
+ std::string data = "";
- 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);
- }
+ MTS::Logger::setPrintLevel(MTS::Logger::PrintLevel::INFO_LEVEL, true);
+ int c;
+ static struct option long_options[] = {
+ {"help", no_argument, nullptr, 'h'},
+ {"data", required_argument, nullptr, 'd'},
+ {"input", required_argument, nullptr, 'i'},
+ {"init", no_argument, nullptr, 'I'},
+ {"json", no_argument, nullptr, 'j'},
+ {"load-fpga", optional_argument, nullptr, 'l'},
+ {"path", required_argument, nullptr, 'p'},
+ {"show", required_argument, nullptr, 's'},
+ {"show-trigger", required_argument, nullptr, 'S'},
+ {"store", required_argument, nullptr, 't'},
+ {"show-trigger", required_argument, nullptr, 'T'},
+ {"version", no_argument, nullptr, 'v'},
+ {"verbose", no_argument, nullptr, 'V'},
+ {nullptr, no_argument, nullptr, 0}};
+
+ for (;;) {
+ int option_index = 0;
+
+ c = getopt_long(argc, argv, "d:hi:Ijl:p:s:St:T:vV", long_options,
+ &option_index);
+ if (c == -1)
+ break;
+ switch (c) {
+ case 'v': {
+ action = ACTION_VERSION;
+ break;
+ }
+ case 'V': {
+ MTS::Logger::setPrintLevel(MTS::Logger::PrintLevel::DEBUG_LEVEL,
+ true);
+ break;
+ }
+ case 'd': {
+ data = optarg;
+ break;
+ }
+ case 'i': {
+ fpgaFilePath = optarg;
+ break;
+ }
+ case 'p': {
+ forcedAP = optarg;
+ break;
+ }
+ case 'I': {
+ action = ACTION_INIT;
+ break;
+ }
+ case 'j': {
+ action = ACTION_JSON;
+ break;
+ }
+ case 's': {
+ action = ACTION_SHOW;
+ name = optarg;
+ break;
+ }
+ case 'S': {
+ action = ACTION_SHOW_TRIGGER;
+ name = optarg;
+ break;
+ }
+ case 't': {
+ action = ACTION_STORE;
+ name = optarg;
+ break;
+ }
+ case 'T': {
+ action = ACTION_STORE_TRIGGER;
+ name = optarg;
+ break;
+ }
+ case 'L': {
+ action = ACTION_LOAD_FPGA;
+ break;
+ }
+ case '?': {
+ printError("%s option requires arguement", optopt);
+ break;
+ }
+ case 'h':
+ default:
+ m.printUsage(argv[0]);
+ exit(0);
}
}
- 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]);
+
+ /* Handle old non POSIX compliant command names. */
+ int index;
+ for (index = optind; index < argc; index++) {
+ if (strcmp(argv[index], COMMMAND_INIT) == 0) {
+ action = ACTION_INIT;
+ } else if (strcmp(argv[index], COMMMAND_JSON) == 0) {
+ action = ACTION_JSON;
+ } else if (strcmp(argv[index], COMMMAND_SHOW) == 0) {
+ if (argv[index + 1]) {
+ action = ACTION_SHOW;
+ name = argv[index + 1];
} else {
- m.logError("show name");
- exitHandler(99);
+ action = ACTION_NONE;
}
- } else if (parameter == "show-trigger") {
- if (argv[i + 1] && !argv[i + 2]) {
- m.showTrigger(std::string(argv[i + 1]));
+ } else if (strcmp(argv[index], COMMMAND_STORE) == 0) {
+ if (argv[index + 1]) {
+ action = ACTION_STORE;
+ name = argv[index + 1];
+ if (argv[index + 2]) {
+ data = argv[index + 2];
+ }
} else {
- m.logError("show-trigger name");
- exitHandler(99);
+ action = ACTION_NONE;
}
- } 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 if (strcmp(argv[index], COMMMAND_SHOW_TRIGGER) == 0) {
+ if (argv[index + 1]) {
+ action = ACTION_SHOW_TRIGGER;
+ name = argv[index + 1];
} else {
- m.logError("store name value");
- exitHandler(99);
+ action = ACTION_NONE;
}
- } 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 if (strcmp(argv[index], COMMMAND_STORE_TRIGGER) == 0) {
+ if (argv[index + 1]) {
+ action = ACTION_STORE_TRIGGER;
+ name = argv[index + 1];
+ if (argv[index + 2]) {
+ data = argv[index + 2];
+ }
} else {
- m.logError("store name value");
- exitHandler(99);
+ action = ACTION_NONE;
+ }
+ } else if (strcmp(argv[index], COMMMAND_LOAD_FPGA) == 0) {
+ action = ACTION_LOAD_FPGA;
+ } else if (strcmp(argv[index], COMMMAND_VERSION) == 0) {
+ action = ACTION_VERSION;
+ } else if (strcmp(argv[index], COMMMAND_EXTRA) == 0) {
+ if (argv[index + 1]) {
+ data = argv[index + 1];
}
}
}
- m.printUsage(argv[0]);
+
+ switch (action) {
+ case ACTION_NONE: {
+ m.printUsage(argv[0]);
+ }
+ case ACTION_SHOW: {
+ m.show(name);
+ }
+ case ACTION_SHOW_TRIGGER: {
+ m.showTrigger(name);
+ }
+ case ACTION_STORE: {
+ m.store(name, data);
+ }
+ case ACTION_STORE_TRIGGER: {
+ m.storeTrigger(name, data);
+ }
+ case ACTION_INIT: {
+ m.init();
+ }
+ case ACTION_JSON: {
+ m.json();
+ }
+ case ACTION_LOAD_FPGA: {
+ Mtac15Fpga mtac15Fpga(fpgaFilePath, forcedAP);
+ return mtac15Fpga.upgradeFpga();
+ }
+ case ACTION_VERSION: {
+ m.printVersion(argv[0]);
+ }
+ default: { m.printUsage(argv[0]); }
+ }
+
+ return 0;
}
diff --git a/src/Version.cpp b/src/Version.cpp
deleted file mode 100644
index a74eb38..0000000
--- a/src/Version.cpp
+++ /dev/null
@@ -1,4 +0,0 @@
-//Pre-Build Auto-Generated Source
-#include "Version.h"
-
-const std::string Version::version("v1.0.0-15-g8d80917");